av_find_stream_info()中是要不斷的讀取數據包,解碼得到相應的信息ide
其中:函數
st->codec->codec_type:0:視頻,1:音頻,2:數據編碼
st->codec->codec_id: 音視頻編解碼類型對應的值指針
ic->nb_streams: 表示包裏面包含的流的總數code
pkt->stream_index: 表示每一個流的索引號,例如音頻的爲0,視頻的爲2orm
pkt->size: 表示每一個包的大小視頻
read_size: 表示pkt->size的累計和索引
pkt->duration: 相鄰兩個包的時間差,例如對於mp3,44100採樣率,1152點/幀,duration =26; 視頻幀率爲25,duration = 40get
st->info->codec_info_duration : 每一個流從開始到解析到當前幀的時間和it
probesize = ic->probesize2: 解析緩衝區的大小
max_analyze_duration: 解析的時間範圍
avformat_find_stream_info() ->
read_frame_internal() ->
ff_read_packet() -> //讀取packet裏面的數據
parse_packet()-> //解析packet包裏面的數據
ff_read_packet():
對於flv封裝格式,對應函數flv_read_packet功能:
讀取flv tag header,能夠獲得tag屬於音頻,視頻或者metadata。
若是屬於metadata tag,則解析meta data數據;
若是屬於audio tag,則不只須要解析11 字節的tag header,另外須要解析緊跟着tag header的一個字節的數據,能夠獲得編碼格式(SoundFormat),採樣率(SoundRate),採樣點大小(SoundSize),聲音類型(SoundType)。
若是屬於video tag,一樣不只須要解析11 字節的tag header,另外須要解析緊跟着tag header的一個字節的數據,獲得編碼格式(frame type),幀類型(CodeID);若是對於AVC編碼,還須要解析一個字節的數據,即獲得包類型(AVCPacketType)的值。
對於第一次解析到的AVC視頻流,須要調用create_stream(),使ic->nb_streams值加1,接着執行flv_set_video_codec(),若是AVCPacketType()是SPS包,則從flv_read_packet()返回,而且返回值爲-11. 所以會執行
if (ret == AVERROR(EAGAIN))
continue;
緊接着執行第二次調用read_frame_internal(),ff_read_packet(),此時解析到的是video tag,而後調用av_get_packet(),將讀到的這兩個packet的數據保存到AVPacket指針變量裏面,最後read_frame_internal()調用parse_packet()。
parse_packet():
執行av_parser_parse2()解析packet包裏面的數據,經過調用s->parser->parser_parse()實際對數據進行解析。對於h264,實際調用h264_parse()這個函數進行真正的解析操做,即經過調用parse_nal_units()解析獲得NAL的值,以及SPS的信息。 在SPS中,能夠解析到profile, level,width,height,SAR,frame rate(timing info)。
fps_analyze_framecount = 20;
if (av_q2d(st->time_base) > 0.0005)
fps_analyze_framecount *= 2;
/* variable fps and no guess at the real fps */
if (!(st->r_frame_rate.num && st->avg_frame_rate.num) &&
st->info->duration_count < fps_analyze_framecount &&
st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
break;
因此須要檢測40 幀視頻圖像。