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

简介: CSDN博客专家、《Android系统多媒体进阶实战》作者

博主新书推荐:《Android系统多媒体进阶实战》🚀

Android Audio工程师专栏地址:Audio工程师进阶系列【原创干货持续更新中...... 】🚀

Android多媒体专栏地址:多媒体系统工程师系列【原创干货持续更新中...... 】🚀

专题一 二:AAOS车载系统+AOSP14系统攻城狮入门视频实战课 🚀

专题三:Android14 Binder之HIDL与AIDL通信实战课 🚀

专题四:Android15快速自定义与集成音效实战课 🚀

专题五:Android15音频策略实战课 🚀

专题六:Android15音频性能实战课(无声/杂音/断音/爆音实战案例) 🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
更多原创,欢迎关注:Android系统攻城狮

点击获取二维码

🍉🍉🍉文章目录🍉🍉🍉

🌻1.前言

本篇目的:理解av_guess_format()如何根据格式名、文件名扩展名和MIME类型查找输出封装格式,并通过独立案例观察查找结果如何用于创建输出上下文。

创建FFmpeg输出上下文前,需要确定使用哪种复用器。调用者可以直接指定格式名,也可以让FFmpeg根据文件名或MIME类型进行匹配。

av_guess_format()负责在已注册的输出格式中查找最合适的AVOutputFormat。它只返回格式描述对象,不创建AVFormatContext,也不会打开文件。
#mermaid-svg-hgztPjIdDaxfQhQt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hgztPjIdDaxfQhQt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hgztPjIdDaxfQhQt .error-icon{fill:#552222;}#mermaid-svg-hgztPjIdDaxfQhQt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hgztPjIdDaxfQhQt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hgztPjIdDaxfQhQt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hgztPjIdDaxfQhQt .marker.cross{stroke:#333333;}#mermaid-svg-hgztPjIdDaxfQhQt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hgztPjIdDaxfQhQt p{margin:0;}#mermaid-svg-hgztPjIdDaxfQhQt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hgztPjIdDaxfQhQt .cluster-label text{fill:#333;}#mermaid-svg-hgztPjIdDaxfQhQt .cluster-label span{color:#333;}#mermaid-svg-hgztPjIdDaxfQhQt .cluster-label span p{background-color:transparent;}#mermaid-svg-hgztPjIdDaxfQhQt .label text,#mermaid-svg-hgztPjIdDaxfQhQt span{fill:#333;color:#333;}#mermaid-svg-hgztPjIdDaxfQhQt .node rect,#mermaid-svg-hgztPjIdDaxfQhQt .node circle,#mermaid-svg-hgztPjIdDaxfQhQt .node ellipse,#mermaid-svg-hgztPjIdDaxfQhQt .node polygon,#mermaid-svg-hgztPjIdDaxfQhQt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hgztPjIdDaxfQhQt .rough-node .label text,#mermaid-svg-hgztPjIdDaxfQhQt .node .label text,#mermaid-svg-hgztPjIdDaxfQhQt .image-shape .label,#mermaid-svg-hgztPjIdDaxfQhQt .icon-shape .label{text-anchor:middle;}#mermaid-svg-hgztPjIdDaxfQhQt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hgztPjIdDaxfQhQt .rough-node .label,#mermaid-svg-hgztPjIdDaxfQhQt .node .label,#mermaid-svg-hgztPjIdDaxfQhQt .image-shape .label,#mermaid-svg-hgztPjIdDaxfQhQt .icon-shape .label{text-align:center;}#mermaid-svg-hgztPjIdDaxfQhQt .node.clickable{cursor:pointer;}#mermaid-svg-hgztPjIdDaxfQhQt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hgztPjIdDaxfQhQt .arrowheadPath{fill:#333333;}#mermaid-svg-hgztPjIdDaxfQhQt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hgztPjIdDaxfQhQt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hgztPjIdDaxfQhQt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hgztPjIdDaxfQhQt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hgztPjIdDaxfQhQt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hgztPjIdDaxfQhQt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hgztPjIdDaxfQhQt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hgztPjIdDaxfQhQt .cluster text{fill:#333;}#mermaid-svg-hgztPjIdDaxfQhQt .cluster span{color:#333;}#mermaid-svg-hgztPjIdDaxfQhQt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hgztPjIdDaxfQhQt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hgztPjIdDaxfQhQt rect.text{fill:none;stroke-width:0;}#mermaid-svg-hgztPjIdDaxfQhQt .icon-shape,#mermaid-svg-hgztPjIdDaxfQhQt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hgztPjIdDaxfQhQt .icon-shape p,#mermaid-svg-hgztPjIdDaxfQhQt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hgztPjIdDaxfQhQt .icon-shape .label rect,#mermaid-svg-hgztPjIdDaxfQhQt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hgztPjIdDaxfQhQt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hgztPjIdDaxfQhQt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hgztPjIdDaxfQhQt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 格式名或文件信息
av_guess_format
遍历已注册输出格式并评分
返回匹配的AVOutputFormat

🌻2.应用场景和用法

2.1输出封装格式选择

av_guess_format()适合在输出格式尚未确定时,根据已有信息查找复用器。

输入信息 典型用途 匹配依据
格式短名 调用者明确指定格式 与输出格式的name别名匹配
文件名 根据扩展名推断容器 文件名后缀与格式扩展名匹配
MIME类型 网络或媒体接口已提供类型 与格式声明的MIME字符串比较
多种信息同时提供 同时有格式名和输出目标 按匹配得分选择较优格式

该接口只查找输出格式。查找失败时返回NULL,调用者不能直接解引用结果,也不能把它误当作输出上下文。选定格式之后,通常还要创建AVFormatContext、添加流、打开IO并写入文件头。

2.2函数原型与匹配规则

函数原型如下:

c 复制代码
const AVOutputFormat *
av_guess_format (const char *short_name,
                 const char *filename,
                 const char *mime_type);
参数 含义
short_name 输出格式短名,可为NULL
filename 输出文件名,函数根据扩展名匹配,可为NULL
mime_type MIME类型字符串,可为NULL

当前源码的匹配评分为:短名匹配加100分,MIME类型匹配加10分,扩展名匹配加5分。函数保留得分最高的格式;若多个格式得分相同,则遍历时先遇到的格式保留。三个参数都不能匹配时,函数返回NULL。

返回的AVOutputFormat是格式描述信息,不是调用者新分配的对象,不能通过av_free()释放。格式对象可作为avformat_alloc_output_context2()的格式参数,创建真正的输出上下文。

🌻3.调用流程剖析

3.1遍历输出格式并比较得分

函数通过av_muxer_iterate()遍历已注册的输出格式。对每个格式分别检查短名、MIME类型和文件扩展名,并累计匹配分数。只有分数高于当前最高分时,才更新候选格式。
#mermaid-svg-tsViPAfwmzV6a5T1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-tsViPAfwmzV6a5T1 .error-icon{fill:#552222;}#mermaid-svg-tsViPAfwmzV6a5T1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-tsViPAfwmzV6a5T1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-tsViPAfwmzV6a5T1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-tsViPAfwmzV6a5T1 .marker.cross{stroke:#333333;}#mermaid-svg-tsViPAfwmzV6a5T1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-tsViPAfwmzV6a5T1 p{margin:0;}#mermaid-svg-tsViPAfwmzV6a5T1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster-label text{fill:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster-label span{color:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster-label span p{background-color:transparent;}#mermaid-svg-tsViPAfwmzV6a5T1 .label text,#mermaid-svg-tsViPAfwmzV6a5T1 span{fill:#333;color:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 .node rect,#mermaid-svg-tsViPAfwmzV6a5T1 .node circle,#mermaid-svg-tsViPAfwmzV6a5T1 .node ellipse,#mermaid-svg-tsViPAfwmzV6a5T1 .node polygon,#mermaid-svg-tsViPAfwmzV6a5T1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-tsViPAfwmzV6a5T1 .rough-node .label text,#mermaid-svg-tsViPAfwmzV6a5T1 .node .label text,#mermaid-svg-tsViPAfwmzV6a5T1 .image-shape .label,#mermaid-svg-tsViPAfwmzV6a5T1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-tsViPAfwmzV6a5T1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-tsViPAfwmzV6a5T1 .rough-node .label,#mermaid-svg-tsViPAfwmzV6a5T1 .node .label,#mermaid-svg-tsViPAfwmzV6a5T1 .image-shape .label,#mermaid-svg-tsViPAfwmzV6a5T1 .icon-shape .label{text-align:center;}#mermaid-svg-tsViPAfwmzV6a5T1 .node.clickable{cursor:pointer;}#mermaid-svg-tsViPAfwmzV6a5T1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-tsViPAfwmzV6a5T1 .arrowheadPath{fill:#333333;}#mermaid-svg-tsViPAfwmzV6a5T1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-tsViPAfwmzV6a5T1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-tsViPAfwmzV6a5T1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tsViPAfwmzV6a5T1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-tsViPAfwmzV6a5T1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tsViPAfwmzV6a5T1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster text{fill:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 .cluster span{color:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-tsViPAfwmzV6a5T1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-tsViPAfwmzV6a5T1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-tsViPAfwmzV6a5T1 .icon-shape,#mermaid-svg-tsViPAfwmzV6a5T1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-tsViPAfwmzV6a5T1 .icon-shape p,#mermaid-svg-tsViPAfwmzV6a5T1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-tsViPAfwmzV6a5T1 .icon-shape .label rect,#mermaid-svg-tsViPAfwmzV6a5T1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-tsViPAfwmzV6a5T1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-tsViPAfwmzV6a5T1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-tsViPAfwmzV6a5T1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
短名文件名MIME类型
遍历已注册Muxer
计算匹配得分
得分高于当前最高分
更新候选格式
保留当前候选
返回最高分格式或NULL

图像序列有一个特殊分支:当短名为空、文件名包含序列编号且能够推断图像编码时,函数会转而查找image2格式。普通文件则按短名、MIME和扩展名的得分进行选择。

3.2从格式描述创建输出上下文

av_guess_format()返回的格式描述通常作为后续输出初始化的输入。调用者检查返回值后,可以将它传给avformat_alloc_output_context2()。后者才创建AVFormatContext并把选定格式记录到上下文中。
#mermaid-svg-HDEs6igqolWwlOkC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HDEs6igqolWwlOkC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HDEs6igqolWwlOkC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HDEs6igqolWwlOkC .error-icon{fill:#552222;}#mermaid-svg-HDEs6igqolWwlOkC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HDEs6igqolWwlOkC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HDEs6igqolWwlOkC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HDEs6igqolWwlOkC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HDEs6igqolWwlOkC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HDEs6igqolWwlOkC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HDEs6igqolWwlOkC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HDEs6igqolWwlOkC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HDEs6igqolWwlOkC .marker.cross{stroke:#333333;}#mermaid-svg-HDEs6igqolWwlOkC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HDEs6igqolWwlOkC p{margin:0;}#mermaid-svg-HDEs6igqolWwlOkC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HDEs6igqolWwlOkC .cluster-label text{fill:#333;}#mermaid-svg-HDEs6igqolWwlOkC .cluster-label span{color:#333;}#mermaid-svg-HDEs6igqolWwlOkC .cluster-label span p{background-color:transparent;}#mermaid-svg-HDEs6igqolWwlOkC .label text,#mermaid-svg-HDEs6igqolWwlOkC span{fill:#333;color:#333;}#mermaid-svg-HDEs6igqolWwlOkC .node rect,#mermaid-svg-HDEs6igqolWwlOkC .node circle,#mermaid-svg-HDEs6igqolWwlOkC .node ellipse,#mermaid-svg-HDEs6igqolWwlOkC .node polygon,#mermaid-svg-HDEs6igqolWwlOkC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HDEs6igqolWwlOkC .rough-node .label text,#mermaid-svg-HDEs6igqolWwlOkC .node .label text,#mermaid-svg-HDEs6igqolWwlOkC .image-shape .label,#mermaid-svg-HDEs6igqolWwlOkC .icon-shape .label{text-anchor:middle;}#mermaid-svg-HDEs6igqolWwlOkC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HDEs6igqolWwlOkC .rough-node .label,#mermaid-svg-HDEs6igqolWwlOkC .node .label,#mermaid-svg-HDEs6igqolWwlOkC .image-shape .label,#mermaid-svg-HDEs6igqolWwlOkC .icon-shape .label{text-align:center;}#mermaid-svg-HDEs6igqolWwlOkC .node.clickable{cursor:pointer;}#mermaid-svg-HDEs6igqolWwlOkC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HDEs6igqolWwlOkC .arrowheadPath{fill:#333333;}#mermaid-svg-HDEs6igqolWwlOkC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HDEs6igqolWwlOkC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HDEs6igqolWwlOkC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HDEs6igqolWwlOkC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HDEs6igqolWwlOkC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HDEs6igqolWwlOkC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HDEs6igqolWwlOkC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HDEs6igqolWwlOkC .cluster text{fill:#333;}#mermaid-svg-HDEs6igqolWwlOkC .cluster span{color:#333;}#mermaid-svg-HDEs6igqolWwlOkC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HDEs6igqolWwlOkC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HDEs6igqolWwlOkC rect.text{fill:none;stroke-width:0;}#mermaid-svg-HDEs6igqolWwlOkC .icon-shape,#mermaid-svg-HDEs6igqolWwlOkC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HDEs6igqolWwlOkC .icon-shape p,#mermaid-svg-HDEs6igqolWwlOkC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HDEs6igqolWwlOkC .icon-shape .label rect,#mermaid-svg-HDEs6igqolWwlOkC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HDEs6igqolWwlOkC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HDEs6igqolWwlOkC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HDEs6igqolWwlOkC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 文件名或格式名
av_guess_format查找
AVOutputFormat描述对象
avformat_alloc_output_context2
AVFormatContext输出上下文

格式查找与文件创建是两个动作。查找成功不代表目标路径可写,也不代表该格式支持当前编码器或流参数;这些条件还需要在后续打开IO和写入文件头时检查。

🌻4.实战案例

4.1准备输出文件名和查找参数

案例使用sample.mkv作为输出文件名,通过扩展名查找封装格式。随后再以matroska短名查找一次,用于观察两种输入方式都能返回格式描述对象。

4.2创建并验证输出上下文

程序检查每次查找结果,避免对NULL解引用。扩展名查找得到的格式描述被传给avformat_alloc_output_context2(),创建输出上下文后检查oformat是否已设置,最后释放上下文。

4.3完整代码
c 复制代码
#include <libavformat/avformat.h>

#include <stdio.h>

int
main (void)
{
  const char *filename = "sample.mkv";
  const AVOutputFormat *by_extension;
  const AVOutputFormat *by_name;
  AVFormatContext *format_context = NULL;
  int ret;

  /* 根据文件扩展名查找输出封装格式 */
  by_extension = av_guess_format (NULL, filename, NULL);
  if (by_extension == NULL) {
    fprintf (stderr, "No output format matches the filename\n");
    return 1;
  }

  /* 通过短名单独查找同类格式 */
  by_name = av_guess_format ("matroska", NULL, NULL);
  if (by_name == NULL) {
    fprintf (stderr, "Matroska muxer is unavailable\n");
    return 1;
  }

  /* 查找返回格式描述,不会自动创建输出上下文 */
  ret = avformat_alloc_output_context2 (
      &format_context,
      by_extension,
      NULL,
      filename);
  if (ret < 0 || format_context == NULL) {
    fprintf (stderr, "Could not allocate output context\n");
    return 1;
  }

  /* 输出上下文引用已选格式,可在此基础上继续添加流和写文件头 */
  if (format_context->oformat == NULL) {
    avformat_free_context (format_context);
    return 1;
  }

  avformat_free_context (format_context);
  return 0;
}

🌻5.总结

av_guess_format()就是根据短名、文件扩展名和MIME类型在已注册Muxer中查找输出格式,并返回供输出上下文创建使用的格式描述对象。

相关推荐
进击的荆棘34 分钟前
Linux系统——线程概念与控制之线程封装
linux·运维·服务器·线程
叼烟扛炮36 分钟前
[LangChain] 学习笔记(05):提示词模板(Prompt)与少样本注入(Few-Shot)实战
linux·人工智能·笔记·学习·langchain·prompt
CodeYp201940 分钟前
第5讲:Socket 编程 TCP
linux·socket·tcp
咔_1 小时前
有IPv6地址,为什么外面还是连不进来?让同一台服务分别卡在四个位置
linux·计算机网络
CodeYp20191 小时前
第3讲:网络命令
linux·网络·命令
一个天蝎座 白勺 程序猿9 小时前
KingbaseES数据库归档重做日志文件管理:从配置到运维的实战指南
运维·数据库·oracle·kingbasees·金仓数据库
天诰12 小时前
SA-K-11 检索会消失吗与四个未解问题
java·服务器·人工智能·python·机器学习·ai编程
2035去旅行13 小时前
bootcmd 详细讲解
linux·嵌入式·arm·soc
分布式存储与RustFS13 小时前
镜像仓库的层别堆本地盘:用 RustFS 给 Docker Registry 当 S3 后端
运维·云原生·开源·对象存储·分布式存储·s3·性能基准