如何设置解复用器参数

简介: 解复用器 (demuxer)的参数 分为 通用部分 跟 私有部分。通用部分是指所有文件格式都有的属性,例如 formatprobesize 是 MP4 跟 FLV都有的属性。而 export_all 是只有 MP4 自己才有的属性。

解复用器 (demuxer)的参数 分为 通用部分私有部分。通用部分是指所有文件格式都有的属性,例如 formatprobesize 是 MP4 跟 FLV都有的属性。而 export_all 是只有 MP4 自己才有的属性。


通用部分的参数可以通过以下命令来查看:

ffmpeg.exe -h > t.txt

私有部分的参数可以通过指定 解复用器来查看:

ffmpeg.exe -hide_banner 1 -h demuxer=mp4


无论是通用还是私有属性,都是使用 AVDictionary 来设置 demuxer 的属性的,就是最后一个参数 AVDictionary **options,如下:

int avformat_open_input(AVFormatContext **ps, const char *url, ff_const59 AVInputFormat *fmt, AVDictionary **options);

读者可能会疑惑,设置复用器的属性,直接设置他的字段不就行了,为什么要搞一个 AVDictionary 出来。因为 FFmpeg 社区有大量的命令行用户,他们习惯通过 字符串传参 来 设置 复用器,解码器等等的属性。有些用户是不会写 C/C++ 代码的。

AVDictionary 这个结构就是为了 命令行的字符串传参 这个需求而设计出来的,它的定义如下:

struct AVDictionary {
    int count;
    AVDictionaryEntry *elems;
};
typedef struct AVDictionaryEntry {
    char *key;
    char *value;
} AVDictionaryEntry;

可以看到,非常简单,AVDictionary 就是一个列表,里面存储着多个 AVDictionaryEntry,而 AVDictionaryEntry 是一个 key value 的结构体。


下面就来演示一下如何用 AVDictionary 来设置 MP4 解复用器的属性。本文的代码可再 GitHub 上下载。

代码运行结果如下:

可以看到,当 AVDictionary 里面的值被使用了,就会剔除掉。剩下的 option 就是用不上的,什么情况会用不上?就是写错了名称。例如,上面代码中的 export_666 就是故意写错的。


上面的代码有两个重点:

第一,我没有在代码里申请 AVDictionary 的内存,那他的内存是从哪里来的?

答:是从 av_dict_set() 函数内部申请的内存,如果你传 NULL 给它,av_dict_set() 内部就会申请一块内存,可以看到函数的第一个参数是一个二级指针

在用完 AVDictionary 之后,需要调 av_dict_free() 手动释放堆内存


第二,如何申请一个栈内存的 AVDictionary ,也就是局部变量。

答:无法做到,AVDictionary 只能以指针指向堆内存的方式来使用,如果你想创建一个 局部变量 AVDictionary opts 放在栈内存里面,编译器会报 incomplete type 未实现类型错误。如下:

这是因为 AVDictionary 这个类型的定义 放在 dict.c 文件里面了,而 这个 .c 文件已经被编译器编译进去 dll,编译器看不到这个结构体的实现了。


上面讲的是 demuxer (解复用器)的参数设置。muxer (复用器)的参数也是这样设置的。不过 复用器 是通过 avio_open2() 函数来设置,如下:

int avio_open2(AVIOContext **s, const char *filename, int flags,
               const AVIOInterruptCB *int_cb, AVDictionary **options)

最后一个参数就是 AVDictionary **options。可以通过以下命令 查询 复用器支持的参数。

ffmpeg.exe -hide_banner 1 -h muxer=mp4

我下面的截图是用 clionwatch point 功能 追踪命令行参数 -movflags empty_moovffmpeg.c 里面怎么传进去的。

ffmpeg.exe -i juren-5s.mp4 -movflags empty_moov ttt.mp4

可以看到,就是从 avio_open2() 函数里传进去的。


Loken1
+关注
目录
打赏
0
0
0
0
4
分享
相关文章
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
用C++实现视频编码器:FFmpeg与SDL技术结合,轻松编写高效编解码器
1232 0
设计师集体破防!UNO:字节跳动创新AI图像生成框架,多个参考主体同框生成,位置/材质/光影完美对齐
UNO是字节跳动开发的AI图像生成框架,通过渐进式跨模态对齐和通用旋转位置嵌入技术,解决了多主体场景下的生成一致性问题。该框架支持单主体特征保持与多主体组合生成,在虚拟试穿、产品设计等领域展现强大泛化能力。
237 4
设计师集体破防!UNO:字节跳动创新AI图像生成框架,多个参考主体同框生成,位置/材质/光影完美对齐
音视频同步的方法:深入探索基于FFmpeg的音视频同步策略(一)
音视频同步的方法:深入探索基于FFmpeg的音视频同步策略
1485 1
入门视频采集与处理(学会分析YUV数据)
做视频采集与处理,自然少不了要学会分析YUV数据。因为从采集的角度来说,一般的视频采集芯片输出的码流一般都是YUV数据流的形式,而从视频处理(例如H.264、MPEG视频编解码)的角度来说,也是在原始YUV码流进行编码和解析,所以,了解如何分析YUV数据流对于做视频领域的人而言,至关重要。
1577 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问