FFmpeg 基本API avio_open函数内部调用流程分析

1、avio_open 函数定义

avio_open() 是 FFmpeg 的一个工具函数,用于打开一个用于读写的 AVIOContext,即 FFmpeg 的 I/O 上下文对象。它的主要作用是:

  • 初始化一个 AVIOContext
  • 调用 FFmpeg 协议层(如 file, http, tcp, udp)进行 URL 打开
  • 设置好 read_packet / write_packet / seek 等函数指针
  • 在 avformat_open_input() 中,如果没有提供自定义 AVIOContext,就会调用它打开默认的AVIOContext结构。
    函数原型如下:
cpp 复制代码
int avio_open(AVIOContext **s, const char *filename, int flags) {
    // 调用avio_open2 函数
    return avio_open2(s, filename, flags, NULL, NULL);
}
int avio_open2(AVIOContext **s, const char *filename, int flags,
               const AVIOInterruptCB *int_cb, AVDictionary **options)
{
    // 调用ffio_open_whitelist 函数
    return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
}
int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
                        const AVIOInterruptCB *int_cb, AVDictionary **options,
                        const char *whitelist, const char *blacklist)
{
    URLContext *h;
    *s = NULL;
    // 1.分配URLContext结构体(根据文件名判断协议类型)
    err = ffurl_open_whitelist(&h, filename, 
    	flags, int_cb, options, whitelist, blacklist, NULL);
    // 2.根据URLContext结构体分配AVIOContext结构体
    err = ffio_fdopen(s, h);
    return 0;
}

参数说明:

  • AVIOContext **s:这是一个指向指针的指针(二级指针)。函数成功执行后,会分配并初始化一个新的 AVIOContext 结构体,并通过这个参数将其地址返回。AVIOContext 是 FFmpeg I/O 操作的核心数据结构,它封装了所有关于数据读写的操作和信息。

  • const char *url:要打开的资源定位符,也就是"文件名"或"URL"。支持多种协议,FFmpeg 会根据 URL 的前缀(如 http://, file:, rtmp://)自动选择对应的协议处理器。

复制代码
     "input.mp4" (本地文件)
     "file:input.mp4" (明确指定本地文件)
     "http://example.com/video.mpd" (HTTP 流)
     "rtmp://live.example.com/app/streamkey" (RTMP 推流)
  • int flags

    打开模式的标志位。指定读取数据还是写入数据。常用标志:

    AVIO_FLAG_READ:以只读方式打开。用于解复用(解码) ------ 从文件/网络流中读取数据。

    AVIO_FLAG_WRITE:以只写方式打开。用于复用(编码) ------ 将数据写入文件/网络流。

    AVIO_FLAG_READ_WRITE:以读写方式打开(较少使用)。

  • 返回值:

  • 成功:返回 >= 0 的值(通常是 0)。

  • 失败:返回一个负数的错误码(如 AVERROR(EACCES) 表示权限不足,AVERROR(ENOENT) 表示文件不存在)。

2、avio_open函数内部调用流程

  • 1.avio_open() → avio_open2()

    • 入口函数,验证参数后调用 avio_open2()。
  • 2.avio_open2() → ffio_open_whitelist()

    • 设置协议白名单(安全限制),传递协议处理函数列表。
  • 3.ffio_open_whitelist() → ffurl_open_whitelist()

    • 核心步骤:打开底层协议(如文件、TCP、HTTP等):
    • ffurl_alloc():
      • 遍历已注册协议(URLProtocol 链表),匹配 URL 的协议头(如 file://, http://)。
      • 为匹配的协议分配 URLContext 结构体,关联协议操作函数(URLProtocol)。
    • ffurl_connect():
      • 调用协议特定的 url_open() 方法(如 tcp_open(), file_open())。
      • 执行实际连接操作(如打开文件、建立套接字连接)。
    1. 初始化 AVIOContext
    • ffio_init_context():
      • 创建 AVIOContext 并绑定缓冲区。
    • 设置关键回调函数:
      • read_packet → url_read()
      • write_packet → url_write()
      • seek → url_seek()
        这些回调通过 URLContext 调用具体协议的读写方法。

3、avio_open调用时序图

相关推荐
神仙别闹2 小时前
基于 C++ 实现两个有序链表序列的交集
java·c++·链表
论文复现现场3 小时前
ComfyUI部署MiniMax H3:8G本地卡、RTX 4090和RTX 5090怎么选?
人工智能·云计算·音视频·gpu算力
hansang_IR4 小时前
【题解】[APIO2023] 赛博乐园 / cyberland
c++·算法·图论
一颗小行星!4 小时前
免费在线 MP3、录音、视频转文本工具推荐对比
音视频
落羽的落羽4 小时前
【AI】快速理解AI应用的相关名词概念
linux·c++·人工智能·python·计算机网络·算法
刚入门的大一新生4 小时前
Linux-进程控制
linux·运维·服务器·c++
刃神太酷啦5 小时前
Redis 进阶核心:持久化 (RDB/AOF)、事务与主从复制全解析----《Hello Redis!》(5)
linux·c语言·数据库·c++·redis·缓存·bootstrap
天天进步20155 小时前
Pixelle-Video 源码解析 #18:声音克隆功能:参考音频如何影响解说效果?
数据库·音视频
林墨聊AIGC6 小时前
动漫AI视频创作工具在哪找到的?2026年最新动漫AI视频平台与软件指南
大数据·人工智能·ai作画·aigc·音视频
喜欢吃燃面8 小时前
深入 C++ STL:从 unordered_set与unordered_map到底层哈希表的原理与实现
数据结构·c++·散列表