从学龄前开始解读FFMPEG代码 之 avformat_open_input函数 三
开始学龄前学习前想说的话
这一部分的内容是回到init_input函数,并在完成init_input函数的学习之后,解决avformat_open_input剩下的内容,其实在第二章中,搞懂了三个主要的函数,剩下的内容就不是很多了(坑了许久,捡起来拍拍灰尘)。
init_input()使用三个函数做了什么
在这一部分的第一篇文章中,简单展示了init_input函数的作用,现在,再回顾一下:
static int init_input(AVFormatContext *s, const char *filename,
AVDictionary **options)
{
int ret;
AVProbeData pd = {
filename, NULL, 0 };
int score = AVPROBE_SCORE_RETRY;
if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
return av_probe_input_buffer2(s->pb, &s->iformat, filename,
s, 0, s->format_probesize);
else if (s->iformat->flags & AVFMT_NOFILE)
av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
"will be ignored with AVFMT_NOFILE format.\n");
return 0;
}
if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
(!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
return score;
if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | s->avio_flags, options)) < 0)
return ret;
if (s->iformat)
return 0;
return av_probe_input_buffer2(s->pb, &s->iformat, filename,
s, 0, s->format_probesize);
}
在第二篇文章中,我们对这里面所调用的三个函数av_probe_input_buffer2(),av_probe_input_format2()以及avio_read,进行了总结,分别用一句话总结功能就是:
av_probe_input_buffer2()函数的主要功能就是从输入的url中推断出文件的format
avio_read()函数所做的事就是从IO上下文的文件数据读入到缓存buffer中
av_probe_input_format2()函数所做的事就是循环查format表,让注册的format调用自己的probe函数来判断文件是否属于该种文件format
init_input函数整体并不算长,主要由四个if以及最后一个return构成:
init_input中进来的第一个if,首先判断输入的AVFormatContext中的pb是否设置好。这个pb实际上是一个AVIOContext,这pb,要么就在执行avformat_open_input之前,由调用函数的用户手动设置好,要么,就由avformat_open_input来设置好。在pb已经设置好的时候,情况就很简单了,这代表着用户(实际上代码里写作caller,也就是调用接口的一方,不过我喜欢称作为用户,我就算是ffmpeg的用户嘛)已经设置好了,这个时候,对s所包含的flag标记位置中加上一个 AVFMT_FLAG_CUSTOM_IO,意味着,这个format是由用户来设置好IO的,不需要你open_input多插手。(当然也有可能open_input_format被重复调用了,设置好了之后这也防止了重复设置,没有意义了)
然后,判断s中的输入format,即iformat有没有设置好,没设置好那么就直接调用av_probe_input_buffer2()来用buffer的方式查出文件的format就好了。如果设置好了,那也不需要去probe了,唯一的异常情况就是输入iformat中设置了AVFMT_NOFILE的标记位,这代表着没有输入文件,这种情况下,给个warning,ffmpeg也就撒手不管了(return 0)。
接下来,来到了第二个if,在第二个if中,有两种可能,第一种是输入文件不存在的情况,还有一种可能是s中没有设置好输入iformat,并且进行一次av_probe_input_format2来猜出了具体的format是什么,这个时候,score已经确定下来了(第一种可能,直接返回25分,第二种,通过probe已经得到了对应的得分),那么直接返回score就好。
然后是第三个if,这里,调用了s的io_open函数,并传入了所需要的参数,来获取到最终的ret,一开始看到io_open函数我还以为漏分析了函数,后来才发现这个io_open是回调函数,也就是说,需要每种AVFormatContext在注册时自己就写好的,不同的AVFormatContext拥有自己独特的io_open函数,这个函数的用法就是创建并设置好一个AVIOContext,在这里的话也就是s的pb了,就像第一个if中说的,这个pb也可能由avformat_open_input来做好设置。通过s的io_open,就可以创建IOContext并打开文件里视频流了,这个回调函数最终也会返回一个int的ret
第四个if里,如果文件已经设置好了iformat,那么不需要做无意义的检查,ffmpeg直接撒手摆烂。(return 0)
最后的return中,还是av_probe_input_buffer2()来终结一切可能存在的不知道文件格式的情况,通过载入数

最低0.47元/天 解锁文章
3227

被折叠的 条评论
为什么被折叠?



