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())。
- 执行实际连接操作(如打开文件、建立套接字连接)。
-
- 初始化 AVIOContext
- ffio_init_context():
- 创建 AVIOContext 并绑定缓冲区。
- 设置关键回调函数:
- read_packet → url_read()
- write_packet → url_write()
- seek → url_seek()
这些回调通过 URLContext 调用具体协议的读写方法。
3、avio_open调用时序图
