///////////////////////////////////////////////////////
函数av_probe_input_buffer2()是在函数s->io_open()之后被调用。
其工作流程是:首先会通过函数avio_read()读取文件中的数据,然后调用函数av_probe_input_format2()对已读取的数据进行分析,
主要分析的是文件内的格式,并根据相似度给出相应的评分score。
其调用栈如下:
av_probe_input_buffer2()
avio_read() //读取文件中的数据
av_probe_input_format2()
av_probe_input_format3()
av_iformat_next()
fmt1->read_probe()
a)根据不同的format,fmt1->read_probe()会映射不同的API来进行数据分析,
比如acm格式会调用函数acm_probe(), act格式会调用函数probe(), adp格式会调
用函数adp_probe(), ac3格式会调用函数ac3_eac3_probe()等等。
b)同时还会分析文件格式是否符合格式扩展fmt1->extensions。
c)以上操作都会根据比对分析的结果会给出一定的评分score.
///////////////////////////////////////////////////////
函数ff_id3v2_read()分析:
ff_id3v2_read()函数的调用栈如下:
ff_id3v2_read()
id3v2_read_internal() //对AVIOContext{}中的文件指针进行操作
avio_tell()
avio_read() //读取文件中的内容
ff_id3v2_match() //比较流中是否有特定字符,即文件流的头
id3v2_parse() //未分析
avio_seek()
ff_metadata_conv()
///////////////////////////////////////////////////////
函数s->iformat->read_header()分析:
该函数的映射是由函数av_probe_input_format3()来决定的。在xx_format3()函数中主要通过从format链表first_iformat中不断取出链表项同数据流中包含的格式信息进行比对,当找到符合的表项的时候,
就将表项中的信息都保存在AVInputFormat{}结构体中:AVFormatContext{}->AVInputFormat{iformat}
s->iformat->read_header()
mov_read_header() //入参为AVFormatContext,是否MOV header
mov_read_default()
如该例子中就是确认媒体流的数据格式是MOV,则调用mov_read_header()函数进行处理。
///////////////////////////////////////////////////////
函数ff_id3v2_parse_apic()分析:
当媒体流格式为”mp3”,”aac”,”tta”的时候,该函数就会被调用。
ff_id3v2_parse_apic()
avformat_new_stream() //申请memory
a) 函数avformat_new_stream()分配memory给结构体数组
AVFormatContext{}->AVStream{*streams[]}
b) 函数ff_id3v2_parse_apic()主要判断:
ID3v2ExtraMeta **extra_meta带进来的数据中的tag标记是否是”APIC”,
是否extra_meta含有数据0x89504e470d0a1a0a
解析extra_meta中的数据放入AVFormatContext{}->AVStream{*streams[]}