将视频文件加载到 C++ 中的缓冲区中

Posted

技术标签:

【中文标题】将视频文件加载到 C++ 中的缓冲区中【英文标题】:loading video files into a buffer in C++ 【发布时间】:2011-05-04 18:39:12 【问题描述】:

我目前正在尝试创建一个程序来获取视频文件,通常是 AVI,并尝试将其转换为图像。到目前为止,我的过程完美无缺,如果需要,我可以独自一人。但是,我想看看是否可以对其进行优化以提高速度。所以我的问题是是否可以将视频文件的一部分逐块加载到内存中而不是流式传输。也许将 2 - 3 分钟的剪辑加载到缓冲区中,对其进行处理,然后在接下来的 2 - 3 分钟的视频中重复使用它。我已经研究过 Direct Show 和 OpenCV 来加载和播放视频文件,但到目前为止还没有找到任何关于将视频加载到缓冲区中的信息。非常感谢任何指向教程或概念的链接。

如果有帮助,这将在 Windows XP/7 机器上开发。

【问题讨论】:

【参考方案1】:

你可以做的是从磁盘加载几个帧,我们称之为 N 帧的一个块,到一个队列中。一旦为缓冲区设置了限制,您就可以将帧拉出并处理它们。您可以使用两个队列(Q1 和 Q2)和两个线程(T1 和 T2)并行执行此操作。在使用 T2 处理来自 Q1 的帧时,您可以使用 T1 加载 Q2。您将在一个队列已满时进行上下文切换,并将帧拉出并处理它们,而另一个队列正在从磁盘加载帧。当然,您需要处理与这种方法相关的线程/并行化复杂性,在这种情况下,BOOST 线程可能会有所帮助。

【讨论】:

我明白,但我要问的问题是如何将帧加载到缓冲区中。 @Seb,如果你的意思是一般的内存,我可以说你创建了一个 IPLImage 类型的队列。一旦可用,您只需将框架推到那里。我以这种方式考虑缓冲区。 @Wajih,听起来好像可以。在那种情况下,我是否能够打开视频文件两次,并让每个线程将所需图像的一部分排队?就像线程 1 从视频文件的 0:00 到 1:59 和线程 2 从 2:00 到 3:59 一样,还是会成为瓶颈? @Seb 好吧,您可能需要打开视频文件两次,但我怀疑 OpenCV 会允许这样的事情(不知道 directShow)。这里要注意的一点是,启动 Q1 会占用第一组帧,而 Q2 处于空闲状态,一旦 Q1 正在处理(帧被拉出),现在 Q2 有机会被填充,然后切换回来到 Q1,而 Q2 正在处理。我不认为这里会有很大的瓶颈。只是启动可能会很慢,一旦 Q 满了,应该会很快。 @Wajih,感谢您的帮助。我将开始研究您提到的方法,看看是否能提高平均性能。【参考方案2】:

此类应用程序的瓶颈是从磁盘读取文件,以及将每一帧转换为图像。你无法逃避这些任务。除非您以错误的方式执行此操作,否则您无法显着加快应用程序的执行速度。

希望您不必将这些图像写回磁盘。

【讨论】:

图像必须在某个时候写入磁盘。在这种情况下,我正在考虑处理视频文件的一部分,直到达到最大数量的缓冲区。然后处理这些缓冲区以生成图像。如果我发现内存消耗不错,我会从他们那里重复该过程,或者在重复该过程之前开始将图像推送到磁盘。 让一个线程读取文件并将帧转换为图像,而另一个线程仅检索这些图像并将它们写入磁盘。有时,开发此系统所涉及的工作量并不能证明它们提供的短期性能提升是合理的。

以上是关于将视频文件加载到 C++ 中的缓冲区中的主要内容,如果未能解决你的问题,请参考以下文章

HTML5 视频 - 文件加载完成事件?

从音频缓冲区和视频缓冲区 C++ Windows 构造 mp4 文件

使用 OpenCV 将视频帧读取到指定的指针(C++)

使用 C++ 加载视频和抓取图像的最佳方式

从视频文件中提取音频并在 OpenAL 中播放

将视频文件从 torrent 加载到 html5 视频