ffmpeg命令分析-acc - C语言音视频技术

/ 0评 / 0

本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8

本系列主要分析各种 ffmpeg 命令参数 在代码里是如何实现的。a.mp4下载链接:百度网盘,提取码:nl0s 。


命令如下:ffmpeg -i a.mp4 -vn -acodec copy output.aac

FFmpeg 抽取音视频文件 中的 AAC 音频 流,与上一条命令 ffmpeg -i a.mp4 -vn -acodec copy output.mp4 相比。

只是封装格式不同,这篇文章就来讲解,如果输出文件不是 mp4,而是aac的封装格式,ffmpeg是如何处理。



命令行参数 -vn 上篇文章已经讲解过它的实现原理,就不再重复讲解了。

输出文件 output.aac 跟 output.mp4 ,格式虽然不同,但在 ffmpeg.c 这个工程里面其实并没有做任何特殊的处理,你调 ffmpeg 的api函数 avio_open2(),只要传递不同后缀的文件名,avio_open2 内部就会根据不同的文件名后缀,生成不同的 AVOutputFormat 放进去 AVFormatContext 的 oformat 字段里。

请看下图,在 avio_open2() 后面打了断点。

然后,在ffmpeg 4.2 的源码里搜索 "ADTS AAC (Advanced Audio Coding)" 字符串,可以发现 aac 的封装格式是在 libavformat 目录的 adtsenc.c 里面,如下:

libavformat/adtsenc.c 229行
AVOutputFormat ff_adts_muxer = {
    .name              = "adts",
    .long_name         = NULL_IF_CONFIG_SMALL("ADTS AAC (Advanced Audio Coding)"),
    .mime_type         = "audio/aac",
    .extensions        = "aac,adts",
    .priv_data_size    = sizeof(ADTSContext),
    .audio_codec       = AV_CODEC_ID_AAC,
    .video_codec       = AV_CODEC_ID_NONE,
    .init              = adts_init,
    .write_header      = adts_write_header,
    .write_packet      = adts_write_packet,
    .write_trailer     = adts_write_trailer,
    .priv_class        = &adts_muxer_class,
    .flags             = AVFMT_NOTIMESTAMPS,
};

MP4 后缀的文件名,原理类似,mp4 的封装格式文件是 libavformat/movenc.c,具体自行查看。

虽然 aac 是编码层的封装格式,mp4 是容器层的格式,但是ffmpeg把他们都放到了 libavformat 下,个人觉得比较新奇。

总结:

ffmpeg 实现不同封装格式,是通过一种多态的方式实现的。不同后缀,就用不同的AVOutputFormat来实现。

在使用 avio_open2() API函数的时候,可以不管底层实现,直接传递不同后缀的文件名 即可完成不同格式的封装。


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

发表回复

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