opengl 视频冻结

发布于 2024-12-12 08:00:08 字数 2072 浏览 0 评论 0原文

我有一个 IDS ueye 摄像头,并通过 PBO 到 OpenGL (OpenTK) 进行捕获。在我的开发人员电脑上,它工作得很好,但在速度较慢的机器上,视频在一段时间后就会冻结。

通过 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 复制到纹理(纹理已创建并且正常):

// 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 events 不再提供任何图像。当我删除 TexSubImage2D 时,它运行良好,但当然没有图像出现。 是否有来自 opengl 的锁或其他东西? 提前致谢 - 托马斯

I have an IDS ueye cam and proceed the capture via PBO to OpenGL (OpenTK). On my developer-pc it works great, but on slower machines the video freezes after some time.

Code for allocating memory via opengl and map to ueye, so camera saves processed images in here:

// 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));

To copy the image from pbo to an texture (Texture is created and 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);

Maybe someone can see the mistake... After about 6 seconds the ueye events don't deliver any images any more. When I remove TexSubImage2D it works well, but of course no image appears.
Is there maybe a lock or something from opengl?
Thanks in advance - Thomas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

静若繁花 2024-12-19 08:00:08

这似乎是一个共享缓冲区问题。您可以尝试实现一个简单的队列机制来解决这个问题。

代码(不意味着工作):

queue< vector<BYTE> > frames;

......

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

示例

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

it seems like a shared buffer problem. you may try to implement a simple queue mechanism to get rid of that problem.

sample code (not meant to be working):

queue< vector<BYTE> > frames;

...

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

...

// use frame here at GL.TexSubImage2D using frames.front()
frames.pop();
旧街凉风 2024-12-19 08:00:08

自己发现失败了。只需将上面代码中的 StreamDraw 替换为 StreamRead 即可。

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

Found the failure by myself. Just replace in the code above StreamDraw with StreamRead.

GL.BufferData(BufferTarget.PixelUnpackBuffer, new IntPtr(width * height * depth), IntPtr.Zero, BufferUsageHint.StreamRead);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文