告诉libavcodec / ffmpeg丢帧

时间:2011-07-05 21:27:52

标签: c ffmpeg video-encoding libavcodec

我正在构建一个可以创建视频的应用。 问题是,有时(好的......大部分时间)帧采集过程不够快。

我目前正在做的是如果我迟到了就跳过当前的帧获取,但是FFMPEG / libavcodec认为每一帧都传递给它作为下一帧的行,所以如果我从2帧中删除1帧,一个20秒的视频只会持续10个。一旦我添加声音就会出现更多问题,因为声音处理速度更快......

我想告诉FFMPEG:“最后一帧应该比原先预期的时间长两倍”,或者任何可以让我实时处理的东西。

我试图将帧堆叠在一个点上,但最终会杀死我的所有内存(我还试图在硬盘中“堆叠”我的帧,这是我预期的慢速方式)

我想我必须手动处理pts,但我的所有尝试都失败了,并且阅读其他一些使用ffmpeg的应用程序代码,例如VLC,没有太大的帮助...所以任何建议非常感谢!

提前多多感谢!

4 个答案:

答案 0 :(得分:1)

您的输出可能会被视为可变帧速率(vfr),但您可以在帧到达时使用挂钟时间生成时间戳,并在编码之前将其应用于AVFrame。然后帧将在播放时的正确时间显示。

有关如何执行此操作的示例(至少指定您自己的时间戳部分),请参阅ffmpeg发行版中的doc / examples / muxing.c(我当前git pull中的第491行):

frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);

这里作者在视频编解码器的时基中将帧时间戳递增1,重新调整为视频流的时基,但在您的情况下,您可以简单地重新调整自从您开始从任意时基捕获帧到输出视频的秒数流的时基(如上例所示)。例如,如果您的任意时基为1/1000,并且自开始捕获后您收到0.25秒的帧,请执行以下操作:

AVRational my_timebase = {1, 1000};
frame->pts = av_rescale_q(250, my_timebase, avstream->time_base);

然后像往常一样对帧进行编码。

答案 1 :(得分:0)

许多(大多数?)视频格式不允许遗漏帧。相反,如果无法及时获得新视频帧,请尝试重复使用旧视频帧。

答案 2 :(得分:0)

只是一个想法..当它与处理滞后时你试图再次传递给它同一帧(并删除当前帧)?也许它可以快速处理重复的帧。

答案 3 :(得分:0)

这个ffmpeg命令行开关-threads ...用于多核处理,所以你应该能够用API做类似的事情(虽然我不知道如何)。这可能会解决您的问题。