ffmpeg中的av_read_frame()的作用是讀取碼流中的音頻若幹幀或者視訊一幀。例如,解碼視訊的時候,每解碼一個視訊幀,需要先調用 av_read_frame()獲得一幀視訊的壓縮資料,然後才能對該資料進行解碼(例如H.264中一幀壓縮資料通常對應一個NAL)。
對該函數源代碼的分析是很久之前做的了,現在翻出來,用部落格記錄一下。
上代碼之前,先參考了其他人對av_read_frame()的解釋,在此做一個參考:
通過av_read_packet(***),讀取一個包,需要說明的是此函數必須是包含整數幀的,不存在半幀的情況,以ts流為例,是讀取一個完整的PES包(一個完整pes包包含若幹視訊或音頻es包),讀取完畢後,通過av_parser_parse2(***)分析出視訊一幀(或音頻若幹幀),傳回,下次進入循環的時候,如果上次的資料沒有完全取完,則st = s->cur_st;不會是NULL,即再此進入av_parser_parse2(***)流程,而不是下面的av_read_packet(**)流程,這樣就保證了,如果讀取一次包含了N幀視訊資料(以視訊為例),則調用av_read_frame(***)N次都不會去讀資料,而是傳回第一次讀取的資料,直到全部解析完畢。
av_read_frame()的源代碼如下:
一些說明:
1、新版本的ffmpeg用的是av_read_frame,而老版本的是av_read_packet。差別是av_read_packet讀出的是包,它可能是半幀或多幀,不保證幀的完整性。av_read_frame對av_read_packet進行了封裝,使讀出的資料總是完整的幀。
2、一般情況下,av_read_frame會調用read_frame_internal(),其代碼如下所示:
更新:ffmpeg 2.1中,原文中提到的av_paser_parse2()已經被舍棄,新采用的方法随着學習的深入慢慢分析。