AVCodecContext數組
這是一個描述編解碼器上下文的數據結構,包含了衆多編解碼器須要的參數信息數據結構
若是是單純使用libavcodec,這部分信息須要調 用者進行初始化;若是是使用整個FFMPEG庫,這部分信息在調用 av_open_input_file和av_find_stream_info的過程當中根據文件的頭信息及媒體流內的頭部信息完成初始化。其中幾個主要 域的釋義以下:ide
extradata/extradata_size: 這個buffer中存放了解碼器可能會用到的額外信息,在av_read_frame中填充。通常來講,首先,某種具體格式的demuxer在讀取格式頭 信息的時候會填充extradata,其次,若是demuxer沒有作這個事情,好比可能在頭部壓根兒就沒有相關的編解碼信息,則相應的parser會繼 續從已經解複用出來的媒體流中繼續尋找。在沒有找到任何額外信息的狀況下,這個buffer指針爲空。函數
time_base:編碼
width/height:視頻的寬和高。spa
sample_rate/channels:音頻的採樣率和信道數目。指針
sample_fmt: 音頻的原始採樣格式。code
codec_name/codec_type/codec_id/codec_tag:編解碼器的信息。orm
AVStream視頻
該結構體描述一個媒體流
主要域的釋義以下,其中大部分域的值能夠由av_open_input_file根據文件頭的信息肯定,缺乏的信息須要經過調用av_find_stream_info讀幀及軟解碼進一步獲取:
index/id:index對應流的索引,這個數字是自動生成的,根據index能夠從AVFormatContext::streams表中索引到該流;而id則是流的標識,依賴於具體的容器格式。好比對於MPEG TS格式,id就是pid。
time_base:流的時間基準,是一個實數,該流中媒體數據的pts和dts都將以這個時間基準爲粒度。一般,使用av_rescale/av_rescale_q能夠實現不一樣時間基準的轉換。
start_time:流的起始時間,以流的時間基準爲單位,一般是該流中第一個幀的pts。
duration:流的總時間,以流的時間基準爲單位。
need_parsing:對該流parsing過程的控制域。
nb_frames:流內的幀數目。
r_frame_rate/framerate/avg_frame_rate:幀率相關。
codec:指向該流對應的AVCodecContext結構,調用av_open_input_file時生成。
parser:指向該流對應的AVCodecParserContext結構,調用av_find_stream_info時生成。
AVFormatContext
這個結構體描述了一個媒體文件或媒體流的構成和基本信息
這是FFMpeg中最爲基本的一個結構,是其餘全部結構的根,是一個多媒體文件或流的根本抽象。其中:nb_streams和streams所表示的AVStream結構指針數組包含了全部內嵌媒體流的描述;iformat和oformat指向對應的demuxer和muxer指針;pb則指向一個控制底層數據讀寫的ByteIOContext結構。
start_time和duration是從streams數組的各個AVStream中推斷出的多媒體文件的起始時間和長度,以微妙爲單位。
一般,這個結構由av_open_input_file在內部建立並以缺省值初始化部分紅員。可是,若是調用者但願本身建立該結構,則須要顯式爲該結構的一些成員置缺省值——若是沒有缺省值的話,會致使以後的動做產生異常。如下成員須要被關注:
probesize
mux_rate
packet_size
flags
max_analyze_duration
key
max_index_size
max_picture_buffer
max_delay
AVPacket
AVPacket定義在avcodec.h中
FFMPEG使用AVPacket來暫存解複用以後、解碼以前的媒體數據(一個音/視頻幀、一個字幕包等)及附加信息(解碼時間戳、顯示時間戳、時長等)。其中:
dts 表示解碼時間戳,pts表示顯示時間戳,它們的單位是所屬媒體流的時間基準。
stream_index 給出所屬媒體流的索引;
data 爲數據緩衝區指針,size爲長度;
duration 爲數據的時長,也是以所屬媒體流的時間基準爲單位;
pos 表示該數據在媒體流中的字節偏移量;
destruct 爲用於釋放數據緩衝區的函數指針;
flags 爲標誌域,其中,最低爲置1表示該數據是一個關鍵幀。
AVPacket 結構自己只是個容器,它使用data成員指向實際的數據緩衝區,這個緩衝區能夠經過av_new_packet建立,能夠經過 av_dup_packet 拷貝,也能夠由FFMPEG的API產生(如av_read_frame),使用以後須要經過調用av_free_packet釋放。
av_free_packet調用的是結構體自己的 destruct函數,它的值有兩種狀況:(1)av_destruct_packet_nofree或 0;(2)av_destruct_packet,其中,前者僅僅是將data和size的值清0而已,後者纔會真正地釋放緩衝區。FFMPEG內部使用 AVPacket結構創建緩衝區裝載數據,同時提供destruct函數,若是FFMPEG打算本身維護緩衝區,則將destruct設爲 av_destruct_packet_nofree,用戶調用av_free_packet清理緩衝區時並不可以將其釋放;若是FFMPEG不會再使用 該緩衝區,則將destruct設爲av_destruct_packet,表示它可以被釋放。對於緩衝區不可以被釋放的AVPackt,用戶在使用以前 最好調用av_dup_packet進行緩衝區的克隆,將其轉化爲緩衝區可以被釋放的AVPacket,以避免對緩衝區的不當佔用形成異常錯誤。而 av_dup_packet會爲destruct指針爲av_destruct_packet_nofree的AVPacket新建一個緩衝區,而後將原 緩衝區的數據拷貝至新緩衝區,置data的值爲新緩衝區的地址,同時設destruct指針爲av_destruct_packet。
時間信息
時間信息用於實現多媒體同步。
同步的目的在於展現多媒體信息時,可以保持媒體對象之間 固有的時間關係。同步有兩類,一類是流內同步,其主要任務是保證單個媒體流內的時間關係,以知足感知 要求,如按照規定的幀率播放一段視頻;另外一類是流間同步,主要任務是保證不一樣媒體流之間的時間關係,如音頻和視頻之間的關係(lipsync)。
對於固定速率的媒體,如固定幀率的視頻或固定比特率的音頻,能夠將時間信息(幀率或比特率)置於文件首部(header),如AVI的hdrl List、MP4的moov box,還有一種相對複雜的方案是將時間信息嵌入媒體流的內部,如MPEG TS和Real video,這種方案能夠處理變速率的媒體,亦可有效避免同步過程當中的時間漂移。
FFMPEG會爲每個數據包打上時間標 籤,以更有效地支持上層應用的同步機制。時間標籤有兩種,一種是DTS,稱爲解碼時間標籤,另外一種是PTS,稱爲顯示時間標籤。對於聲音來講 ,這兩個時間標籤是相同的,但對於某些視頻編碼格式,因爲採用了雙向預測技術,會形成DTS和PTS的不一致。
時間信息的獲取:
經過調用av_find_stream_info,多媒體應用能夠從AVFormatContext對象中拿到媒體文件的時間信息:主要是總時間長度和開始時間,此外還有與時間信息相關的比特率和文件大小。其中時間信息的單位是AV_TIME_BASE:微秒。