/*打开输入流并读取标题。编解码器未打开。
*流必须用avformat_close_input()关闭。
*
* @param ps指向用户提供的AVFormatContext的指针(由avformat_alloc_context分配)。
*可能是一个指向NULL的指针,在这种情况下,AVFormatContext被该函数分配并写入ps。
*请注意,用户提供的AVFormatContext将在失败时释放。
* @param url要打开的流的URL。
* @param fmt如果非NULL,则此参数强制使用特定的输入格式。否则格式是自动检测的。
* @param选项填充AVFormatContext和demuxer-private选项的字典。
*返回时,这个参数将被销毁,并替换为一个包含字典
*找不到的选项。可能是NULL。
*
* @成功返回0,失败时出现负面AVERROR。
*
* @note 如果您想使用自定义IO,请预先分配格式上下文并设置其pb字段。
* /
int avformat_open_input(AVFormatContext **ps, const char *filename,
AVInputFormat *fmt, AVDictionary **options)
{
AVFormatContext *s = *ps;
int i, ret = 0;
AVDictionary *tmp = NULL;
ID3v2ExtraMeta *id3v2_extra_meta = NULL;
//创建avformat上下文
if (!s && !(s = avformat_alloc_context()))
return AVERROR(ENOMEM);
/**
av_class 记录和@ref avoptions的类。 由avformat_alloc_context()设置。
导出(解)复用器私人选项,如果它们存在。
**/
if (!s->av_class) {
av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");
return AVERROR(EINVAL);
}
//如果用户指定了输入格式,直接使用它
if (fmt)
s->iformat = fmt;
if (options)
av_dict_copy(&tmp, *options, 0);
if (s->pb) // must be before any goto fail
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if ((ret = av_opt_set_dict(s, &tmp)) < 0)
goto fail;
if ((ret = init_input(s, filename, &tmp)) < 0)