FFMPEG 和 OPENGL - 原始帧

Posted

技术标签:

【中文标题】FFMPEG 和 OPENGL - 原始帧【英文标题】:FFMPEG & OPENGL - RAW Frames 【发布时间】:2015-03-27 14:12:04 【问题描述】:

我正在使用 BlackMagic DeckLink 卡构建录音机。 该程序使用 OpenGL 显示帧和 FFMPEG(使用 glReadPixels() 方法)来记录它们。 我在我的程序中设置视口以应用自动信箱/邮筒,无论图像/监视器是 16:9/4:3。 这个问题的问题是,当我捕获此视口的这些帧时,它们当然会以我的视口的分辨率记录(即全高清源 -> 视口,由于监视器具有 1600x1200 分辨率 -> 信箱降至 1600x900)等等 FFMPEG 记录那些在顶部/底部带有黑条的 1600x1200。

是否有可能在原始帧通过 setViewport 函数和所有重新缩放的东西传递之前抓取它?

【问题讨论】:

【参考方案1】:

嗯,在某些时候图像被传递给 OpenGL。为什么不直接获取这些数据并将其传递给 FFMPEG,而不是通过 OpenGL 进行冗长、低效且昂贵的往返。

如果 OpenGL 用于实时色彩空间转换,我建议您将渲染到带有与视频分辨率大小相关的纹理的 FBO,在该 FBO 上使用 glReadPixels(最好是 PBO);最后以该窗口分辨率将渲染到纹理的内容绘制到主屏幕上。

但是,如果您可以简单地将原始帧直接提供给 FFMPEG(它也可以进行色彩空间转换),我强烈建议您这样做。

【讨论】:

感谢您的回答,现在我认为方法一会相当困难,因为我认为图像以某种专有格式传递(我认为)。 HERE 是指向我的代码的链接,它处理整个 OpenGL 的东西。注意方法“DrawFrame”,它得到了一些奇怪的“IDeckLinkVideoFrame”格式。如果您可以查看代码,那就太好了,我对 OpenGL 和 C++ 很陌生 在 Google 中输入“IDeckLinkVideoFrame”会给我一个 DeckLinkAPI.h 文件。 IDeckLinkVideoFrame 是一个所谓的“抽象”接口类。它有一些子类,实现了该类的所谓“纯虚函数”。相关功能都在github.com/kylemcdonald/ofxBlackmagic/blob/master/libs/DeckLink/… @MarcoReisacher:IDeckLinkVideoFrame 的函数为您提供有关帧格式和原始像素字节的信息。这就是你需要的一切。这是传递给 OpenGL 的内容,也是您可以传递给 FFmpeg 的内容。 听起来是个好消息。那我该如何通过呢?我认为使用 glReadPixels 是行不通的。很抱歉这些菜鸟问题,但我仍在学习所有这些东西 我想我现在进去了。我必须通过调用theFrame->GetBytes(buffer) 在框架上使用GetBytes 函数。然后使用 FFMPEG 处理该缓冲区。但是当我使用该函数传递我的缓冲区时,我得到一个访问冲突错误,尽管在源代码中传递给“GetBytes”函数的缓冲区被标记为“/out/”。查看错误here

以上是关于FFMPEG 和 OPENGL - 原始帧的主要内容,如果未能解决你的问题,请参考以下文章

FFmpeg - 通过管道输入原始帧 - FFmpeg不检测管道关闭

Android - 获取视频帧的 FFmpeg 替代方案。 (由于许可)

ffmpeg如何从url获取视频帧数据

在 c++ 中以可变帧速率使用 FFmpeg 库(不是 libav 分支)以编程方式捕获视频

FFmpeg 无法解码 H264 流/帧数据

回复@吾爱林有关用ffmpeg加速视频和改变帧率测试