FFmpeg命令行参数分析-re—ffmpeg.c源码分析

作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音

re 的全称是 rate emulator(速率模拟),可以用这个选项来模拟输入的速度。因为 ffmpeg.exe 默认情况下是尽量以最快的速度来读取输入数据,具体多快,取决于 CPU 的性能。

下面这条命令就是未使用 -re 的场景,可以看到,速度是 5 倍速。

ffmpeg.exe -i juren.mp4 juren.flv

ffmpeg-usage-1-1

现在我们加上 -re 选项之后的效果如下:

ffmpeg.exe -re -i juren.mp4 juren.flv

1-1

可以看到加上 -re 选项之后,处理速度变成了一倍速。

一倍速意味着什么呢?它意味着处理完 2小时的视频,就需要 2小时。从另一个角度来解释,如果这个视频是 1 秒 24 帧的视频,那就是 ffmpeg.exe 会每隔 40 毫秒从输入文件读取一个 AVPacket 进行处理。

如果你不加 -reffmpeg.exe 处理完一个 AVPacket 就会立即去读下一个 AVPacket,它不会等够 40 毫秒。

-re 在推直播流的时候非常有用,当你需要将一个 mp4 推送到 rtmp 服务器,基本都会加上 -re 来模拟摄像头采集画面的速度。


下面就让我们来学习一下在 ffmpeg.c 里面是怎么实现 -re 模拟速率的功能的,-re 的定义如下:

{ "re", OPT_BOOL | OPT_EXPERT | OPT_OFFSET | OPT_INPUT, { .off = OFFSET(rate_emu) },

.off = OFFSET(rate_emu) 这句代码是重点,代表这个 -re 会赋值给 OptionsContext 结构里面的 rate_emu 字段,由于 -reOPT_BOOL(布尔类型),所以 OptionsContext::rate_emu 会被设置为 1。

rate_emu 字段在哪里被使用呢?如下:

1-2

ffmpeg_opt.copen_input_file() 函数里把 OptionsContext 里面的 rate_emu 赋值给了 InputFilerate_emu

然后,如果 InputFilerate_emu 被设置为 1,会导致 input_streamsstart 字段被设置,如下:

1-3

input_streamsstart 字段字段代表什么意思呢?它代表什么时候开始读取 AVPacket。


然后在 get_input_packet 获取 AVPacket 的时候,就会根据这个 start 字段,计算当前任务已经运行了多久,跟 input_streams 的 dts 字段进行比较,如果 运行时间小于 input_streams 的 dts,就会返回 EAGAIN,如下:

1-3-2

input_streamsdts 是什么意思,它记录的是最后一个从输入文件读取出来的 AVPacket 的 dts,如下:

1-4

这个时间如果细细研究,是有点绕的。不过也可以不用细究。我举个简单的例子,例如现在 ffmpeg.exe 启动了 80 毫秒,他已经读到了第 3 帧视频,第三帧的视频的 dts 是 120毫秒。

所以,此时此刻,上图中的 now 就等于 80 毫秒,而 pts 就 等于 120 毫秒,代码如下:

for (i = 0; i < f->nb_streams; i++) {
    InputStream *ist = input_streams[f->ist_index + i];
    int64_t pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
    int64_t now = av_gettime_relative() - ist->start;
    if (120 > 80)
        return AVERROR(EAGAIN);
}

120 大于 80,所以就会返回 EAGAIN,继续等待。当 ffmpeg.exe 运行足够久了,now 就会变成大于 120 的值,就会继续去读 AVPacket 进行处理。

不过需要注意的是,他上面这段代码,是遍历一个输入文件里面的所有流的,也就是音频流,视频流,都会做速率模拟。只要有其中一个流不符合速度,就会返回 EAGAIN

通常情况下,音频流的速度是采样率决定的,视频流的速度是帧率决定的。



感谢 NETINT(镕铭微电子) 赞助《FFmpeg原理》免费版一书的服务器费用,下面是 VPU 产品介绍

版权所属 xianwanzhiyin.net 罗上文 2024 all right reserved,powered by Gitbook该文件修订时间: 2023-07-26 11:33:03

results matching ""

    No results matching ""