资讯详情

资讯详情

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

简介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.前言本篇目的理解avformat_open_input()如何创建并初始化输入AVFormatContext分析它如何打开输入、选择解复用器并读取文件头再通过独立的C程序观察调用结果。读取媒体文件时应用首先需要一个能够描述输入源和解复用状态的AVFormatContext。avformat_open_input()负责打开输入并调用对应解复用器读取文件头。它不会替应用打开正式解码流程缺失的流参数通常由后续的avformat_find_stream_info()探测。输入URL或自定义IOavformat_open_input输入格式与选项选择解复用器并读取文件头返回已初始化的AVFormatContext2.应用场景和用法2.1打开输入并读取容器头部avformat_open_input()是FFmpeg解复用流程的入口常见于播放器、转码器、媒体分析工具和流媒体客户端。它根据URL或调用者提供的输入格式建立输入上下文并让解复用器读取文件头。一些容器的文件头已经包含音视频流数量、编码格式等信息。另一些格式没有完整头部或者头部信息不足调用成功后仍需执行avformat_find_stream_info()补充流参数。它主要完成输入打开和解复用器初始化不负责把压缩数据解码成音视频帧也不保证AVStream中的全部参数已经探测完成。2.2函数原型与返回语义函数原型如下intavformat_open_input(AVFormatContext**ps,constchar*url,constAVInputFormat*fmt,AVDictionary**options);参数含义psAVFormatContext指针的地址指向NULL时函数会分配上下文url输入URL或文件路径使用自定义IO时可以传入NULLfmt非NULL时强制使用指定的AVInputFormat否则自动探测options输入上下文和解复用器选项成功返回后保留未识别的选项返回0表示打开成功负值表示错误。成功后调用者通过*ps取得输入上下文并在使用完成后调用avformat_close_input()释放。如果调用者预先分配了AVFormatContext打开失败时该上下文也会被释放*ps会被设为NULL。传入的options在成功返回时会被替换为未识别选项组成的字典调用者仍需释放剩余字典。3.调用流程剖析3.1分配上下文并选择输入格式调用时avformat_open_input()先读取*ps。如果它是NULL函数调用avformat_alloc_context()创建AVFormatContext。传入了fmt时函数将其记录为输入格式否则进入init_input()确定格式。init_input()根据输入状态选择路径如果调用者提供了自定义AVIOContext就使用该IO如果输入格式已经指定或格式不需要文件IO就沿用现有配置其他情况下先打开输入再调用探测逻辑识别解复用器。是否AVFormatContext与输入参数分配或复用输入上下文是否指定输入格式或自定义IO使用调用者提供的输入配置打开IO并探测解复用器3.2调用解复用器读取文件头格式确定后函数为解复用器分配私有数据应用选项再调用AVInputFormat中的read_header()读取容器头部。解复用器可能在这一步创建AVStream并写入部分codecpar参数。成功后函数处理文件头中的元数据和附加图片更新内部流上下文并把初始化后的AVFormatContext写回*ps。打开失败时则执行清理释放相关上下文和内部IO资源。已选定AVInputFormat配置解复用器私有数据read_header读取容器头部创建或更新AVStream返回AVFormatContextavformat_open_input()成功返回后输入已打开且文件头已处理但解码器尚未由应用打开。需要补充流信息时再调用avformat_find_stream_info()需要读取压缩数据时使用av_read_frame()。4.实战案例4.1准备输入参数程序从命令行取得媒体文件路径将AVFormatContext初始化为NULL让avformat_open_input()负责分配上下文。示例不指定输入格式和选项因此使用自动格式探测。4.2打开输入并检查上下文调用成功后检查iformat和nb_streams确认解复用器已经选择、文件头阶段得到的流信息已经写入上下文。这里不调用avformat_find_stream_info()以便单独观察打开接口的职责范围。4.3完整代码#includelibavformat/avformat.h#includelibavutil/error.h#includestdio.hstaticvoidprint_av_error(interror_code){charerror_text[AV_ERROR_MAX_STRING_SIZE];av_strerror(error_code,error_text,sizeof(error_text));fprintf(stderr,FFmpeg error: %s\n,error_text);}intmain(intargc,char*argv[]){AVFormatContext*format_contextNULL;intret;if(argc2){fprintf(stderr,Usage: %s input\n,argv[0]);return1;}/* 由FFmpeg自动分配上下文并探测输入格式 */retavformat_open_input(format_context,argv[1],NULL,NULL);if(ret0){print_av_error(ret);/* 打开失败时format_context由接口清理并置为NULL */avformat_close_input(format_context);return1;}/* 文件头已读取检查解复用器和当前可见的流数量 */if(format_context-iformat!NULL){printf(demuxer: %s\n,format_context-iformat-name);}printf(streams from header: %u\n,format_context-nb_streams);/* 释放输入上下文及FFmpeg内部打开的输入IO */avformat_close_input(format_context);return0;}5.总结avformat_open_input()负责打开输入、确定解复用器并读取文件头返回初始化后的AVFormatContext但不负责应用侧的音视频解码。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →