avio_open2 主要实现创建并初始化一个 AVIOContext,用于访问由 url 指定文件。
avio_open2 声明和定义
1
2
| int avio_open2(AVIOContext **s, const char *url, int flags,
const AVIOInterruptCB *int_cb, AVDictionary **options);
|
各个参数的含义如下:
AVIOContext **s
:函数调用成功后,创建并初始化该AVIOContext
结构体。
const char *url
:输入输出协议的地址。
int flags
:打开地址的方式(只读、只写、读写)。AVIO_FLAG_READ/AVIO_FLAG_WRITE/AVIO_FLAG_READ_WRITE.
const AVIOInterruptCB *int_cb
: 调用函数。
AVDictionary **options
: 一般为NULL。
与avio_open2
相似的还有avio_open
函数,avio_open
会调用avio_open2
,并将 int_cb 和 options 设置为 NULL。
avio_open2 调动关系
avio_open2
的调用函数关系如下:
avio_open2 源码分析
avio_open2
函数的定义如下:
avio_open2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| int avio_open2(AVIOContext **s, const char *filename, int flags,
const AVIOInterruptCB *int_cb, AVDictionary **options)
{
URLContext *h;
int err;
err = ffurl_open(&h, filename, flags, int_cb, options);
if(err < 0)
return err;
er = ffio_fdopen(s, h);
if(err < 0){
ffurl_close(h);
return err;
}
return 0;
}
|
avio_open2
调用的两个函数,ffurl_open
和ffio_fdopen
。ffurl_open
用于初始化URLContext
,ffio_fdopen
用于根据URLContext
初始化AVIOContext
。
ffurl_open 函数
其中的ffurl_open
函数定义如下:
ffurl_open
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| int ffurl_open(URLContext **puc, const char *filename, int flags,
const AVIOInterruptCB *int_cb, AVDictionary **options)
{
int ret = ffurl_alloc(puc, filename, flags, int_cb);
if(ret < 0)
return ret;
if(options && (*puc)->prot->priv_data_class &&
(ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
goto fail;
if((ret = av_opt_set_dict(*puc, options)) < 0)
goto fail;
ret = ffurl_connect(*puc, options);
if(!ret)
return 0;
fail:
ffurl_close(*puc);
*puc = NULL;
return ret;
}
|
ffurl_open
主要调用两个函数ffurl_alloc
和ffurl_connect
。
ffurl_alloc 函数
ffurl_alloc
用于查找合适的URLProtocol
,并创建一个URLContext
;
ffurl_alloc
1
2
3
4
5
6
7
8
9
| int ffurl_alloc(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb)
{
URLProtocol *p = NULL;
……
p = url_find_protocol(filename);
if(p)
return url_alloc_for_protocol(puc, p, filename, flags, int_cb);
……
}
|
ffurl_alloc
调用两个函数:url_find_protocol
根据文件路径查找合适的URLProtocol
,url_alloc_for_protocol
为查找到的URLProtocol
创建URLContext
。
ffurl_connect
1
2
3
4
5
| int ffurl_connect(URLContext *uc, AVDictionary **options)
{
int err = uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options):
uc->prot->url_open(uc, uc->filename, uc->flags);
}
|
ffurl_connect 函数
ffurl_connect
用于打开获得的URLProtocol
.如果以UDP
为例的话,它的URLProtocol
定义如下,打开URLProtocol
时,会调用到udp_open
函数。
ff_udp_protocol
1
2
3
4
5
6
7
8
9
10
11
| URLProtocol ff_udp_protocol = {
.name = "udp",
.url_open = udp_open,
.url_read = udp_read,
.url_write = udp_write,
.url_close = udp_close,
.url_get_file_handle = udp_get_file_handle,
.priv_data_size = sizeof(UDPContext),
.priv_data_class = &udp_class,
.flags = URL_PROTOCOL_FLAG_NETWORK,
};
|
ffio_fdopen 函数
ffio_fdopen
函数定义如下:
ffio_fdopen
1
2
3
4
5
6
7
8
9
10
11
| int ffio_fdopen(AVIOContext **s, URLContext *h)
{
uint8_t *buffer;
……
buffer = av_malloc(buffer_size);
*s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
(int (*)(void *, uint8_t *, int))ffurl_read,
(int (*)(void *, uint8_t *, int))ffurl_write,
(int64_t (*)(void *, uint64_t, int))ffurl_ffurl_seek).
}
|
ffio_fdopen
会调用avio_alloc_context
初始化一个AVIOContext
, avio_alloc_context
函数成功执行后会返回一个创建好的AVIOContext
。