ffmpeg命令分析-vframe - 弦外之音

/ 0评 / 0

本文 以 ffmpeg4.4 源码为准,a.mp4下载链接:百度网盘,提取码:nl0s 。


命令如下:

ffmpeg.exe -i a.mp4 -ss 00:00:7.435 -vframes 1 out.png

上面的命令是 偏移到 7 秒左右的地方,截图 一张图片来进行保存。

-ss 在 《ffmpeg命令分析-ss》里面已经讲过,本文不再分析,本文主要讲解 -vframes 参数在 ffmpeg 工程中的实现。

vframes 的定义如下:

{ "vframes",      OPT_VIDEO | HAS_ARG  | OPT_PERFILE | OPT_OUTPUT,           { .func_arg = opt_video_frames },
    "set the number of video frames to output", "number" },

会调用 opt_video_frames 函数,opt_video_frames 函数如下:

static int opt_video_frames(void *optctx, const char *opt, const char *arg)
{
    OptionsContext *o = optctx;
    return parse_option(o, "frames:v", arg, options);
}

从上面代码可以看出,-vframes 实际上 是 -frames:v 的另一种写法,所以真正的 定义是 -frames,定义如下:

{ "frames",         OPT_INT64 | HAS_ARG | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(max_frames) },
    "set the number of frames to output", "number" },

从上面的代码可以看出,frames 最后就解析到 max_frames ,OFFSET 是一个宏,定位到 OptionsContext 的偏移位置。max_frames 实际上是 OptionsContext 里面的 max_frames 。



下面就看看 哪些地方使用了 max_frames 这个变量。

通过全局搜索 max_frames 可知,new_output_stream() 函数里面有使用,代码如下:

#ffmpeg_opt.c 1537行
ost->max_frames = INT64_MAX;
MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);

从上面代码可以看出,命令行中的 max_frames 最后会赋值给 ost->max_frames,ost 是一个 struct OutputStream 结构。

继续分析,ost->max_frames 又在哪里被使用了呢?答案如下:

在本文命令下,在 do_video_out() 函数中使用了 ost->max_frames,代码如下:

//ffmpeg.c 1262行
nb_frames = FFMIN(nb_frames, ost->max_frames - ost->frame_number);
nb0_frames = FFMIN(nb0_frames, nb_frames);

do_video_out() 函数 的逻辑之前在 《ffmpeg源码分析-reap_filter》里详细讲过。

从上面两句代码可以看出,输出流的已经丢给编码器的 frame_number 如果等于大于 ost->max_framesnb_frames 变量 就会是0。

nb_frames 变成 0 就会导致 do_video_out 后面的 for (i = 0; i < nb_frames; i++) {} 循环不会执行,也就不会再有 AVFrame 输入给编码器。

这样就实现了 最大帧的功能。

最后 ost->max_frames 还在 need_output() 函数使用了一下,用于退出程序的。


版权所属:知识星球:弦外之音,QQ:2338195090。 由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注