2011-10-27 60 views
0

我有一個IDS ueye凸輪,並通過PBO捕獲到OpenGL(OpenTK)。在我的開發者電腦上它效果很好,但在較慢的機器上,視頻會在一段時間後凍結。opengl視頻凍結

代碼通過OpenGL分配存儲器和映射到的uEye,所以相機在這裏節約了處理的圖像:

// Generate PBO and save id 
GL.GenBuffers(1, out this.frameBuffer[i].BufferID); 

// Define the type of the buffer. 
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, this.frameBuffer[i].BufferID); 

// Define buffer size. 
GL.BufferData(BufferTarget.PixelUnpackBuffer, new IntPtr(width * height * depth), IntPtr.Zero, BufferUsageHint.StreamDraw); 

// Get pointer to by openGL allocated buffer and 
// lock global with uEye. 
this.frameBuffer[i].PointerToNormalMemory = GL.MapBuffer(BufferTarget.PixelUnpackBuffer, BufferAccess.WriteOnly); 
this.frameBuffer[i].PointerToLockedMemory = uEye.GlobalLock(this.frameBuffer[i].PointerToNormalMemory); 

// Unmap PBO after use. 
GL.UnmapBuffer(BufferTarget.PixelUnpackBuffer); 

// Set selected PBO to none. 
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); 

// Register buffer to uEye 
this.Succeeded("SetAllocatedImageMem", this.cam.SetAllocatedImageMem(width, height, depth, this.frameBuffer[i].PointerToLockedMemory, ref this.frameBuffer[i].MemId)); 

// Add buffer to uEye-Ringbuffer 
this.Succeeded("AddToSequence", this.cam.AddToSequence(this.frameBuffer[i].PointerToLockedMemory, this.frameBuffer[i].MemId)); 

要從PBO圖像複製到紋理(質地被創建和OK):

// Select PBO with new video image 
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, nextBufferId); 

// Select videotexture as current 
GL.BindTexture(TextureTarget.Texture2D, this.videoTextureId); 

// Copy PBO to texture    
GL.TexSubImage2D(
    TextureTarget.Texture2D, 
    0, 
    0, 
    0, 
    nextBufferSize.Width, 
    nextBufferSize.Height, 
    OpenTK.Graphics.OpenGL.PixelFormat.Bgr, 
    PixelType.UnsignedByte, 
    IntPtr.Zero); 

// Release Texture 
GL.BindTexture(TextureTarget.Texture2D, 0); 

// Release PBO 
GL.BindBuffer(BufferTarget.PixelUnpackBuffer, 0); 

也許有人可以看到錯誤...大約6秒後,ueye事件不再傳送任何圖像。當我刪除TexSubImage2D時,效果很好,但當然不會出現圖像。 有沒有可能來自opengl的鎖或東西? 在此先感謝 - 托馬斯

回答

1

它似乎是一個共享緩衝區問題。你可以嘗試實現一個簡單的隊列機制來擺脫這個問題。

示例代碼(不是要工作):

queue< vector<BYTE> > frames; 

...

frames.push(vector<BYTE>(frameBuffer, frameBuffer + frameSize)); 

...

// use frame here at GL.TexSubImage2D using frames.front() 
frames.pop(); 
+0

這實際上就是我所做的。該凸輪有一個環緩衝區,每次我收到一個新的幀我把緩衝區ID傳遞給opengl。目前我在緩衝區中有2個元素,但錯誤也發生在更多;但比花了更長的時間... –

+0

,因爲我無法看到所有的代碼(如nextBufferId分配等),我不能告訴你,如果你的隊列機制是完全安全的。我的猜測是你的多個緩衝區實現有問題。如果你不太難,請嘗試使用上面的std :: queue和std :: vector。 –

+0

我很舒服,這工作正常。 NextBufferId是我從GenBuffer獲得的那個... –

0

由我自己發現的故障。只需將StreamDraw上面的代碼替換爲StreamRead即可。

GL.BufferData(BufferTarget.PixelUnpackBuffer, new IntPtr(width * height * depth), IntPtr.Zero, BufferUsageHint.StreamRead);