通过ffmpeg反向播放视频

时间:2016-01-15 04:15:35

标签: ffmpeg media-player decode multimedia

我正在使用ffmpeg多媒体框架实现视频播放器。我能够实现播放,暂停,提高速度,降低速度,前向搜索,后向搜索功能。但是视频的反向播放并不是那么顺利,它的结果很多。请帮我理解视频反向播放。对此有什么更好的方法?

是否有其他多媒体框架支持反向视频播放?

非常感谢提前。

1 个答案:

答案 0 :(得分:2)

所以,首先,这个问题的一些框架。 FFmpeg是一个极低级别的库,它试图在原始媒体文件访问的基础上提供一个瘦API。这意味着你基本上可以完全了解媒体文件中的内容。对于视频,这是来自分路器的压缩视频分组流,然后是来自解码器的解码图像流。由于B / P帧预测,这是一个严格的线性和单向过程。另请注意,在大多数实际情况中,FFmpeg使用多线程,这也是一个严格的线性过程。如果您有4个线程解码帧8,9,10,11,并且您在此之后寻找第7帧(因此解码第7,8,9和10帧),那么您实际上会产生永久的浪费。

因此:使用反序av_seek_frame()的反向播放本质上与FFmpeg基本设计不兼容。这并不意味着您无法在所有使用FFmpeg 执行此操作,但 意味着如果您执行使用FFmpeg来做它,需要一些努力。话虽如此,你将如何完成反向播放?你缓存了!

您可以创建N帧组(其中N至少与线程数一样大,但仍允许您在内存中保留这么多帧),例如N = 10或N = 100(取决于帧大小)。然后,使用对av_read_frame()avcodec_decode_videoN()的顺序调用正向解码 N帧,并将它们保存在应用程序的内存中。例如,您现在可能在内存中有第7-17帧。开始显示第17帧,然后显示第16,15页等等(从内存中),直到你达到index = 7。当你点击7时,寻找下一个位置,允许你在内存中保存N帧(在N = 10的情况下,这将是index = 0),并在内存中保持帧0-6,并显示index = 6, 5等等,直到0。

我实际上实现了这个确切的功能,并且使用这种方法效果很好,并且它仍然使用多线程(几乎)正确。对于高分辨率视频上的大N值,它确实需要相当多的内存,因此建议您使N依赖于帧大小并使N *分辨率可在应用程序的首选项中设置,或者至少制作它取决于软件运行的计算机上可用的内存总量。

请注意,搜索并不是最简单的事情,因为您无法随机搜索任何视频中的任何一点并期望它能够正常工作。对于大多数实现P帧或B帧的编解码器,您只能寻找关键帧或I / IDR帧。这意味着文件格式需要在其索引中设置关键帧标志。如果情况并非如此,那么您在初始加载文件时必须综合生成索引(例如,在您点击EOF之前调用av_read_frame())。

关于你的另一个问题:我确定还有其他媒体框架实现特技播放(反向播放等),例如: GStreamer。但是,这通常仅适用于媒体框架中的有限数量的文件格式not for all supported file formats