int url_open_protocol (URLContext **puc, // 输出参数: URL上下文
struct URLProtocol *up, // URL协议
const char *filename, // 文件名
int flags) // 标志
{
URLContext *uc;
int err;
// 网络初始化
#if CONFIG_NETWORK
if (!ff_network_init())
return AVERROR(EIO);
#endif
// 分配URL上下文并加上文件名的存储空间
uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
if (!uc) {
err = AVERROR(ENOMEM);
goto fail;
}
// 初始化URL上下文
#if LIBAVFORMAT_VERSION_MAJOR >= 53
uc->av_class = &urlcontext_class;
#endif
// 记录文件名
uc->filename = (char *) &uc[1];
strcpy(uc->filename, filename);
uc->prot = up; // URL协议
uc->flags = flags; // 标志
uc->is_streamed = 0; // 默认不是流, 可以在up->url_open函数里修改
uc->max_packet_size = 0; // 包最大多大, 默认为0, 可以在up->url_open函数里修改
// 打开URL
err = up->url_open(uc, filename, flags);
if (err < 0) {
av_free(uc);
goto fail;
}
if( (flags & (URL_WRONLY | URL_RDWR)) // 如果以可写方式打开
|| !strcmp(up->name, "file")) // 或且是文件协议
// 如果不是流并且不可以url_seek
if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
uc->is_streamed= 1; // 强制为流
// 输出 参数: URL上下文
*puc = uc;
return 0;
fail:
*puc = NULL;
#if CONFIG_NETWORK
ff_network_close();
#endif
return err;
}
|