Raj*_*aju 4 multimedia ffmpeg decode media-player
我正在使用 ffmpeg 多媒体框架实现视频播放器。我能够实现播放、暂停、提高速度、降低速度、向前搜索、向后搜索功能。但是视频的反向播放不是那么流畅,卡顿很多。请帮助我理解视频反向播放。什么是更好的方法?
有没有其他支持反向视频播放的多媒体框架?
提前谢谢了。
所以,首先,对这个问题进行一些框架。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(取决于帧大小)。然后,使用对和 的顺序调用对N 帧进行前向解码,并将它们保存在应用程序的内存中。例如,您现在可能在内存中有第 7-17 帧。开始显示第 17 帧,然后显示第 16、15 帧,依此类推(从内存中),直到您点击 index=7。当你打到 7 时,寻找下一个位置,让你在内存中保存 N 帧(在 N=10 的情况下,索引=0),并在内存中保存第 0-6 帧,并显示索引=6, 5 以此类推直到 0。av_read_frame()avcodec_decode_videoN()
我实际上已经实现了这个确切的功能,并且使用这种方法效果很好,并且它仍然(几乎)正确地使用了多线程。高分辨率视频上的大 N 值确实需要相当多的内存,因此鼓励您使 N 依赖于帧大小并使 N * 分辨率可以在应用程序的首选项中设置,或者至少使其依赖软件运行所在的计算机上的可用内存总量。
请注意,搜索并不是最简单的事情,因为您不能随机搜索任何视频中的任何一点并期望它起作用。对于大多数实现 P 帧或 B 帧的编解码器,您只能寻找关键帧或 I/IDR 帧。这意味着文件格式需要在其索引中设置关键帧标志。如果不是这种情况,您将不得不在最初加载文件时综合生成索引(例如,av_read_frame()在您点击 EOF 之前调用)。
关于您的另一个问题:我确定还有其他媒体框架实现了特技播放(反向播放等),例如GStreamer。但是,这通常仅适用于有限数量的文件格式,而不适用于媒体框架中所有支持的文件格式。