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

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

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

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

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

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

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

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

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

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

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

点击获取二维码

🍉🍉🍉文章目录🍉🍉🍉

🌻1.前言

本篇目的:理解av_dump_format()如何读取AVFormatContext中的容器、流和元数据信息,并通过FFmpeg输入流程观察它输出的格式摘要。

打开媒体文件并获取流信息后,程序通常需要确认输入容器、时长、码率和各路音视频参数。av_dump_format()把这些信息写入FFmpeg日志,便于开发者检查探测结果。它只负责打印,不负责探测媒体、解码数据或改变流参数。
#mermaid-svg-V9d7W8glGQRdFg4H{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-V9d7W8glGQRdFg4H .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V9d7W8glGQRdFg4H .error-icon{fill:#552222;}#mermaid-svg-V9d7W8glGQRdFg4H .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V9d7W8glGQRdFg4H .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V9d7W8glGQRdFg4H .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V9d7W8glGQRdFg4H .marker.cross{stroke:#333333;}#mermaid-svg-V9d7W8glGQRdFg4H svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V9d7W8glGQRdFg4H p{margin:0;}#mermaid-svg-V9d7W8glGQRdFg4H .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-V9d7W8glGQRdFg4H .cluster-label text{fill:#333;}#mermaid-svg-V9d7W8glGQRdFg4H .cluster-label span{color:#333;}#mermaid-svg-V9d7W8glGQRdFg4H .cluster-label span p{background-color:transparent;}#mermaid-svg-V9d7W8glGQRdFg4H .label text,#mermaid-svg-V9d7W8glGQRdFg4H span{fill:#333;color:#333;}#mermaid-svg-V9d7W8glGQRdFg4H .node rect,#mermaid-svg-V9d7W8glGQRdFg4H .node circle,#mermaid-svg-V9d7W8glGQRdFg4H .node ellipse,#mermaid-svg-V9d7W8glGQRdFg4H .node polygon,#mermaid-svg-V9d7W8glGQRdFg4H .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-V9d7W8glGQRdFg4H .rough-node .label text,#mermaid-svg-V9d7W8glGQRdFg4H .node .label text,#mermaid-svg-V9d7W8glGQRdFg4H .image-shape .label,#mermaid-svg-V9d7W8glGQRdFg4H .icon-shape .label{text-anchor:middle;}#mermaid-svg-V9d7W8glGQRdFg4H .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-V9d7W8glGQRdFg4H .rough-node .label,#mermaid-svg-V9d7W8glGQRdFg4H .node .label,#mermaid-svg-V9d7W8glGQRdFg4H .image-shape .label,#mermaid-svg-V9d7W8glGQRdFg4H .icon-shape .label{text-align:center;}#mermaid-svg-V9d7W8glGQRdFg4H .node.clickable{cursor:pointer;}#mermaid-svg-V9d7W8glGQRdFg4H .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-V9d7W8glGQRdFg4H .arrowheadPath{fill:#333333;}#mermaid-svg-V9d7W8glGQRdFg4H .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-V9d7W8glGQRdFg4H .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-V9d7W8glGQRdFg4H .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V9d7W8glGQRdFg4H .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-V9d7W8glGQRdFg4H .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V9d7W8glGQRdFg4H .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-V9d7W8glGQRdFg4H .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-V9d7W8glGQRdFg4H .cluster text{fill:#333;}#mermaid-svg-V9d7W8glGQRdFg4H .cluster span{color:#333;}#mermaid-svg-V9d7W8glGQRdFg4H 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-V9d7W8glGQRdFg4H .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-V9d7W8glGQRdFg4H rect.text{fill:none;stroke-width:0;}#mermaid-svg-V9d7W8glGQRdFg4H .icon-shape,#mermaid-svg-V9d7W8glGQRdFg4H .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V9d7W8glGQRdFg4H .icon-shape p,#mermaid-svg-V9d7W8glGQRdFg4H .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-V9d7W8glGQRdFg4H .icon-shape .label rect,#mermaid-svg-V9d7W8glGQRdFg4H .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V9d7W8glGQRdFg4H .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-V9d7W8glGQRdFg4H .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-V9d7W8glGQRdFg4H :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 输入媒体文件
AVFormatContext
探测容器和流信息
av_dump_format
FFmpeg日志中的格式摘要

🌻2.应用场景和用法

2.1查看容器和流信息

av_dump_format()适合放在输入探测或输出封装配置之后,用来检查FFmpeg当前掌握的格式信息。

场景 调用时机 观察内容
输入文件探测 avformat_find_stream_info()成功后 输入格式、时长、码率和流参数
多轨媒体分析 流信息探测后 音视频流编号、编码类型和时间基
输出封装检查 输出流和封装器配置完成后 输出格式及输出流参数
定位媒体信息异常 打开文件或协商参数后 上下文中实际存在的信息是否符合预期

函数将摘要写入FFmpeg日志系统,常见级别为AV_LOG_INFO。日志级别或回调配置会影响信息是否显示。

2.2函数原型与参数
c 复制代码
void
av_dump_format (AVFormatContext *ic,
                int index,
                const char *url,
                int is_output);
参数 含义
ic 已填充输入或输出信息的AVFormatContext
index 日志中显示的文件或输出上下文编号
url 输出摘要中显示的媒体地址或文件名
is_output 为0表示输入,为非0表示输出

函数没有返回值,也不接管AVFormatContext的所有权。输入场景需要先打开媒体并探测流信息;输出场景应在输出格式和流信息已经准备后调用。它与相邻接口的分工如下:

接口 职责
avformat_open_input() 打开输入并识别输入格式
avformat_find_stream_info() 读取数据以补充流信息
av_dump_format() 把当前上下文中的格式信息写入日志
avformat_close_input() 关闭输入并释放输入上下文

🌻3.调用流程剖析

3.1从格式上下文读取信息

av_dump_format()根据is_output选择上下文中的输入格式或输出格式名称,再通过av_log()打印文件方向、编号和URL。

输入场景会额外打印时长、起始时间和码率。函数随后遍历章节、节目和普通流,并调用内部的流格式输出逻辑整理各流信息。输出摘要来自当前AVFormatContext及其关联的流参数,因此调用时机很重要:如果流探测尚未完成,摘要中就可能缺少信息。
#mermaid-svg-1yI0PfSJHKpisJhq{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-1yI0PfSJHKpisJhq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1yI0PfSJHKpisJhq .error-icon{fill:#552222;}#mermaid-svg-1yI0PfSJHKpisJhq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1yI0PfSJHKpisJhq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1yI0PfSJHKpisJhq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1yI0PfSJHKpisJhq .marker.cross{stroke:#333333;}#mermaid-svg-1yI0PfSJHKpisJhq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1yI0PfSJHKpisJhq p{margin:0;}#mermaid-svg-1yI0PfSJHKpisJhq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1yI0PfSJHKpisJhq .cluster-label text{fill:#333;}#mermaid-svg-1yI0PfSJHKpisJhq .cluster-label span{color:#333;}#mermaid-svg-1yI0PfSJHKpisJhq .cluster-label span p{background-color:transparent;}#mermaid-svg-1yI0PfSJHKpisJhq .label text,#mermaid-svg-1yI0PfSJHKpisJhq span{fill:#333;color:#333;}#mermaid-svg-1yI0PfSJHKpisJhq .node rect,#mermaid-svg-1yI0PfSJHKpisJhq .node circle,#mermaid-svg-1yI0PfSJHKpisJhq .node ellipse,#mermaid-svg-1yI0PfSJHKpisJhq .node polygon,#mermaid-svg-1yI0PfSJHKpisJhq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1yI0PfSJHKpisJhq .rough-node .label text,#mermaid-svg-1yI0PfSJHKpisJhq .node .label text,#mermaid-svg-1yI0PfSJHKpisJhq .image-shape .label,#mermaid-svg-1yI0PfSJHKpisJhq .icon-shape .label{text-anchor:middle;}#mermaid-svg-1yI0PfSJHKpisJhq .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1yI0PfSJHKpisJhq .rough-node .label,#mermaid-svg-1yI0PfSJHKpisJhq .node .label,#mermaid-svg-1yI0PfSJHKpisJhq .image-shape .label,#mermaid-svg-1yI0PfSJHKpisJhq .icon-shape .label{text-align:center;}#mermaid-svg-1yI0PfSJHKpisJhq .node.clickable{cursor:pointer;}#mermaid-svg-1yI0PfSJHKpisJhq .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1yI0PfSJHKpisJhq .arrowheadPath{fill:#333333;}#mermaid-svg-1yI0PfSJHKpisJhq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1yI0PfSJHKpisJhq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1yI0PfSJHKpisJhq .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1yI0PfSJHKpisJhq .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1yI0PfSJHKpisJhq .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1yI0PfSJHKpisJhq .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1yI0PfSJHKpisJhq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1yI0PfSJHKpisJhq .cluster text{fill:#333;}#mermaid-svg-1yI0PfSJHKpisJhq .cluster span{color:#333;}#mermaid-svg-1yI0PfSJHKpisJhq 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-1yI0PfSJHKpisJhq .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1yI0PfSJHKpisJhq rect.text{fill:none;stroke-width:0;}#mermaid-svg-1yI0PfSJHKpisJhq .icon-shape,#mermaid-svg-1yI0PfSJHKpisJhq .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1yI0PfSJHKpisJhq .icon-shape p,#mermaid-svg-1yI0PfSJHKpisJhq .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1yI0PfSJHKpisJhq .icon-shape .label rect,#mermaid-svg-1yI0PfSJHKpisJhq .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1yI0PfSJHKpisJhq .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1yI0PfSJHKpisJhq .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1yI0PfSJHKpisJhq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 传入格式上下文和方向
选择输入或输出格式
打印文件与容器信息
遍历章节和节目
逐流整理编码与时间基
通过av_log输出摘要

3.2它不负责探测或校验媒体

av_dump_format()只根据传入上下文中已有的数据生成日志。它不会调用输入探测过程,也不会判断媒体能否完整解码,更不会保证日志显示的参数一定符合应用预期。

排查时应先确认avformat_open_input()和avformat_find_stream_info()的返回值,再观察摘要。如果输入信息未探测完成,优先检查探测流程;如果摘要内容与预期不同,则检查输入文件、流选择和上下文状态。

🌻4.实战案例

4.1打开输入并探测流信息

示例接收媒体路径作为命令行参数。调用av_dump_format()前,先通过avformat_open_input()打开文件,再通过avformat_find_stream_info()补充流信息。

4.2打印输入格式摘要

探测成功后,将输入上下文、文件编号、媒体路径和输入方向传给av_dump_format()。示例使用avformat_close_input()释放输入上下文。

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

int
main (int argc, char *argv[])
{
  AVFormatContext *format_context = NULL;
  int ret;

  if (argc < 2) {
    fprintf (stderr, "请提供媒体文件路径\n");
    return 1;
  }

  /* 打开输入文件并读取容器信息 */
  ret = avformat_open_input (
      &format_context,
      argv[1],
      NULL,
      NULL);
  if (ret < 0) {
    fprintf (stderr, "无法打开输入文件\n");
    return 1;
  }

  /* 探测音视频流参数,再打印完整摘要 */
  ret = avformat_find_stream_info (format_context, NULL);
  if (ret < 0) {
    fprintf (stderr, "无法获取流信息\n");
    avformat_close_input (&format_context);
    return 1;
  }

  /* is_output为0,表示当前上下文用于输入 */
  av_dump_format (format_context, 0, argv[1], 0);

  /* 释放输入上下文及其关联资源 */
  avformat_close_input (&format_context);

  return 0;
}

🌻5.总结

av_dump_format()根据AVFormatContext当前已有的输入或输出信息生成格式摘要日志,不负责打开媒体、探测流或解码数据。

相关推荐
Android系统攻城狮2 小时前
Linux FFmpeg深度解析之avcodec_find_decoder调用流程与实战(十二)
linux·运维·服务器·ffmpeg·1024程序员节·音视频进阶
1-1=02 小时前
.NET Core 文件系统
.net·.netcore·1024程序员节
Hommy882 小时前
【直播切片工作台】第23章:媒体探测与转码:ffprobe 与 ffmpeg 封装
人工智能·ffmpeg·直播切片
小白的码BUG之路2 小时前
K8s -- 启动一主二从节点
linux·运维·服务器
Escalating_xu3 小时前
【Linux 网络编程】IP 分片与重组:3000 字节的数据报,怎样拆开又拼回来?
linux·网络·tcp/ip
FPGA小迷弟3 小时前
FPGA 与卫星:从星载硬件到在轨智能的完整技术解析
fpga开发·架构·fpga·1024程序员节·无线电
小相会自律3 小时前
全平台远程控制软件推荐2026:Win/Mac/Linux/手机/鸿蒙互通哪款好
linux·macos·智能手机·todesk·teamviewer·向日葵
码匠许师傅3 小时前
【C++三方组件】FFmpeg:音视频处理的瑞士军刀
c++·ffmpeg·音视频
yyzc111113 小时前
合规稳定资金结算收款系统助力门店发展
大数据·运维·人工智能