首页 / 资讯中心 / 文章详情

Linux FFmpeg深度解析之av_demuxer_iterate调用流程与实战(十)

Linux FFmpeg深度解析之av_demuxer_iterate调用流程与实战(十) ★ FEATURED ARTICLE
简介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准备输入格式枚举程序4.2遍历并检查格式描述4.3完整代码5.总结1.前言本篇目的理解av_demuxer_iterate()如何遍历当前FFmpeg构建中注册的输入格式分析迭代状态和返回对象并通过C程序列出可用的demuxer。FFmpeg打开媒体时需要从当前构建可用的输入格式中选择候选项。av_demuxer_iterate()提供逐个遍历这些格式描述对象的接口。它只负责返回下一个AVInputFormat不读取媒体数据、不探测文件内容也不打开输入文件。文件探测和打开由其他API完成。当前构建的输入格式列表av_demuxer_iterate调用者迭代状态下一个AVInputFormat格式枚举或后续探测2.应用场景和用法2.1遍历输入格式的应用场景av_demuxer_iterate()适合需要了解或检查当前FFmpeg构建所支持输入格式的场景。场景使用方式能得到什么列出可用demuxer循环调用接口直到返回NULL获取每个AVInputFormat描述对象检查定制构建遍历并查看格式名称确认目标格式是否包含在当前构建中按名称查找格式遍历并比较AVInputFormat.name实现类似av_find_input_format()的查找逻辑自定义探测流程遍历格式并按需调用探测回调获取候选格式探测逻辑仍由调用者负责返回列表取决于FFmpeg构建时启用的组件。被配置排除的demuxer不会出现在列表中。调用者不能把“列表里没有”直接解释成媒体类型不受FFmpeg支持也要考虑当前二进制的构建配置。2.2函数原型与返回语义函数原型如下constAVInputFormat*av_demuxer_iterate(void**opaque);参数或返回值含义opaque由调用者持有的迭代状态指针开始遍历时必须指向NULL返回值下一个已注册输入格式的描述对象返回NULL当前迭代已经结束最小调用方式如下void*iterNULL;constAVInputFormat*fmt;while((fmtav_demuxer_iterate(iter))!NULL){/* 使用fmt-name、fmt-long_name等描述字段 */}opaque是接口内部使用的迭代状态。调用者应原样传回不要解引用、修改或释放它。每次独立遍历都要使用新的状态变量或在开始前重新设为NULL。返回的AVInputFormat是FFmpeg注册表中的格式描述对象类型为const指针。它不是新分配给调用者的对象不需要释放。接口本身不创建AVFormatContext也不触发文件读取或格式探测。相邻接口的职责不同接口作用av_demuxer_iterate()逐个返回已注册输入格式av_find_input_format()按名称从输入格式中查找对象av_probe_input_format3()根据探测数据和候选格式计算匹配结果avformat_open_input()打开输入并创建或使用AVFormatContext3.调用流程剖析3.1从编译生成的格式列表中返回对象FFmpeg构建时会生成demuxer列表。av_demuxer_iterate()把调用者传入的opaque解释为当前遍历位置再从静态demuxer_list中取出对应的格式描述对象。核心逻辑如下constAVInputFormat*av_demuxer_iterate(void**opaque){staticconstuintptr_tsizesizeof(demuxer_list)/sizeof(demuxer_list[0])-1;uintptr_ti(uintptr_t)*opaque;constAVInputFormat*fNULL;if(isize){fdemuxer_list[i];}if(f)*opaque(void*)(i1);returnf;}每次成功返回一个格式对象内部位置就前进一项。列表结束后函数返回NULL调用者应结束循环。实际源码还会检查是否注册了libavdevice输入设备列表如果存在也可以继续从该列表中返回输入设备格式。使用avdevice_register_all()注册输入设备属于libavdevice的职责不是av_demuxer_iterate()自动完成的。是否是否opaque指向当前迭代位置读取demuxer_list当前位置存在格式对象返回AVInputFormat更新opaque位置检查已注册输入设备列表还有输入格式返回NULL结束遍历3.2在查找和探测流程中的位置av_find_input_format()内部也通过av_demuxer_iterate()遍历格式再使用格式名称匹配目标项。av_probe_input_format3()则会遍历候选格式并根据探测数据调用相应格式的探测逻辑累计匹配分数。因此这三个动作处于不同层次迭代接口提供格式描述对象查找接口按名称筛选对象探测接口结合媒体数据判断格式。迭代本身不会判断某个文件究竟是什么格式。输入格式注册表av_demuxer_iterateAVInputFormat候选对象按名称查找或执行格式探测得到匹配格式交给输入打开流程4.实战案例4.1准备输入格式枚举程序程序使用一个初始化为NULL的void *保存迭代状态并通过av_demuxer_iterate()逐个获取输入格式。每次返回的对象都可读取name和long_name循环以返回NULL结束。4.2遍历并检查格式描述观察两个内容每次调用是否返回一个AVInputFormat对象。迭代结束时是否返回NULL以及遍历期间累计了多少个格式对象。格式名称来自当前FFmpeg构建中实际生成的列表。若需要同时枚举输入设备应链接libavdevice并按其接口完成设备注册。4.3完整代码#includelibavformat/avformat.h#includestdio.hintmain(void){void*iterNULL;constAVInputFormat*fmt;unsignedintcount0;/* 从NULL状态开始逐个读取当前构建注册的输入格式 */while((fmtav_demuxer_iterate(iter))!NULL){constchar*long_namefmt-long_name?fmt-long_name:无描述;/* name是短名称long_name是可读格式说明 */printf(%-20s %s\n,fmt-name,long_name);count;}/* count反映本次遍历实际返回的格式对象数量 */printf(demuxer count: %u\n,count);return0;}5.总结av_demuxer_iterate()根据调用者保存的迭代状态逐个返回当前构建中注册的AVInputFormat对象供格式枚举、查找或后续探测流程使用。
阅读完成 · 觉得有帮助?
咨询建站