2011-10-27 61 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);