)
简介CSDN博客专家、《Android系统多媒体进阶实战》作者博主新书推荐《Android系统多媒体进阶实战》Android Audio工程师专栏地址Audio工程师进阶系列【原创干货持续更新中……】Android多媒体专栏地址多媒体系统工程师系列【原创干货持续更新中……】专题一 二AAOS车载系统AOSP14系统攻城狮入门视频实战课专题三Android14 Binder之HIDL与AIDL通信实战课专题四Android15快速自定义与集成音效实战课专题五Android15音频策略实战课专题六Android15音频性能实战课(无声/杂音/断音/爆音实战案例)人生格言人生从来没有捷径只有行动才是治疗恐惧和懒惰的唯一良药.更多原创,欢迎关注Android系统攻城狮文章目录1.前言2.应用场景和用法2.1按名称选择输入格式2.2函数原型与返回语义3.调用流程剖析3.1遍历已注册格式并匹配名称3.2设备输入格式需要注册4.实战案例4.1准备V4L2输入格式查找4.2调用接口并检查描述符4.3完整代码5.总结1.前言本篇目的理解av_find_input_format()如何按短名称查找AVInputFormat分析查找过程与设备格式注册的关系并通过查找V4L2输入格式的代码观察返回结果。FFmpeg处理输入时需要先确定由哪种AVInputFormat解析输入。文件探测可以根据内容猜测格式当应用已经知道输入格式或需要选择特定设备输入格式时可以按名称查找对应描述符。av_find_input_format()只查找并返回格式描述符不打开文件、不访问设备也不解析音视频流。返回的描述符由FFmpeg管理调用者不需要释放。是否输入格式短名称遍历已注册输入格式匹配格式名称或别名找到匹配项返回AVInputFormat描述符返回空指针2.应用场景和用法2.1按名称选择输入格式当输入来自摄像头、采集卡等设备应用通常已经知道应使用哪种设备输入格式。av_find_input_format()可以把格式短名称转换为AVInputFormat描述符供后续打开输入或设备枚举接口使用。场景调用方式结果已知容器格式传入容器短名称得到对应的输入格式描述符选择设备输入先注册设备再传入设备格式名称得到设备输入格式描述符检查构建能力查找目标格式并检查是否为空判断当前FFmpeg是否包含该输入格式格式名包含别名传入某个别名可能返回名称列表中包含该别名的描述符2.2函数原型与返回语义函数原型如下constAVInputFormat*av_find_input_format(constchar*short_name);short_name是输入格式的短名称。实现会遍历可用输入格式并使用名称匹配逻辑比较short_name与格式描述符中的名称列表。找到时返回对应的AVInputFormat没有匹配项时返回NULL。返回值是FFmpeg维护的格式描述符不是新分配的对象。调用者不能修改或释放它。若要查找设备输入格式在FFmpeg6.1中应先调用avdevice_register_all()让已编译的设备格式进入输入格式遍历范围。最小调用方式如下constAVInputFormat*input_format;avdevice_register_all();input_formatav_find_input_format(v4l2);if(input_formatNULL){/* 当前构建中未找到V4L2输入格式 */}这里找到v4l2只表示取得了格式描述符不代表系统中存在摄像头也不代表设备已经打开。打开输入需要继续调用相应的libavformat接口。3.调用流程剖析3.1遍历已注册格式并匹配名称函数的主体逻辑是遍历输入格式列表逐项检查格式名称constAVInputFormat*av_find_input_format(constchar*short_name){constAVInputFormat*fmtNULL;void*i0;while((fmtav_demuxer_iterate(i)))if(av_match_name(short_name,fmt-name))returnfmt;returnNULL;}av_demuxer_iterate()每次返回一个可用输入格式av_match_name()负责比较调用者传入的短名称与格式描述符的名称。格式名称可能包含多个别名因此查找依据是名称匹配不是文件扩展名或输入数据内容。匹配成功后函数立即返回该描述符。遍历结束仍未匹配时返回NULL。函数没有创建AVFormatContext也没有打开文件或设备。是否且还有格式否且遍历结束传入short_name初始化输入格式迭代器取得下一个AVInputFormat名称匹配立即返回格式描述符返回NULL3.2设备输入格式需要注册普通容器输入格式和设备输入格式都由AVInputFormat描述但设备输入格式由libavdevice提供。FFmpeg6.1的avdevice_register_all()会把当前构建包含的设备输入格式注册到libavformat可遍历的列表中。因此查找V4L2、ALSA等设备格式时调用顺序应为调用avdevice_register_all()。用设备格式短名称调用av_find_input_format()。检查返回值再将描述符传给后续设备或输入接口。调用av_find_input_format()查不到设备格式可能是名称不匹配也可能是对应设备模块没有编译进当前FFmpeg构建。4.实战案例4.1准备V4L2输入格式查找本案例查找名称为v4l2的输入格式。程序只检查FFmpeg构建中是否提供该格式描述符不访问摄像头也不验证设备节点。V4L2格式是否可用取决于当前FFmpeg构建选项。若对应设备模块未编译查找结果会是NULL。4.2调用接口并检查描述符程序先注册设备输入格式再查找v4l2。找到描述符后读取其名称字段未找到时输出错误并返回失败。4.3完整代码#includelibavdevice/avdevice.h#includelibavformat/avformat.h#includestdio.hintmain(void){constAVInputFormat*input_format;/* 注册当前构建包含的设备输入格式 */avdevice_register_all();/* 按设备格式短名称查找描述符 */input_formatav_find_input_format(v4l2);if(input_formatNULL){fprintf(stderr,V4L2 input format is not available\n);return1;}/* 读取格式描述符名称不打开摄像头设备 */printf(input format: %s\n,input_format-name);return0;}5.总结av_find_input_format()按照短名称遍历并匹配已注册的输入格式返回FFmpeg维护的AVInputFormat描述符不负责打开输入或探测媒体内容。