FFmpeg教程(三)視訊解碼器
視訊解碼知識
純淨的視訊解碼流程
壓縮編碼資料->畫素資料。
例如解碼H.264,就是“H.264碼流->YUV”。一般的視訊解碼流程
視訊碼流一般儲存在一定的封裝格式(例如MP4、AVI等)中。封裝格式中通常還包含音訊碼流等內容。
對於封裝格式中的視訊,需要先從封裝格式中提取中視訊碼流,然後再進行解碼。
例如解碼MKV格式的視訊檔案,就是“MKV->H.264碼流->YUV”
FFmpeg庫的簡介
FFmpeg一共包含8個庫:
avcodec:編解碼(最重要的庫)。
avformat:封裝格式處理。
avfilter:濾鏡特效處理。
avdevice:各種裝置的輸入輸出
avutil:工具庫(大部分庫都需要這個庫的支援)。
postproc:後加工。
swresample:音訊取樣資料格式轉換。
swscale:視訊畫素資料格式轉換
FFmpeg解碼函式簡介
av_register_all():註冊所有元件。
avformat_open_input():開啟輸入視訊檔案。
avformat_find_stream_info():獲取視訊檔案資訊。
avcodec_find_decoder():查詢解碼器。
avcodec_open2():開啟解碼器。
av_read_frame():從輸入檔案讀取一幀壓縮資料。
avcodec_decode_video2():解碼一幀壓縮資料。
avcodec_close():關閉解碼器。
avformat_close_input():關閉輸入視訊檔案
FFmpeg資料結構簡介
AVFormatContext
封裝格式上下文結構體,也是統領全域性的結構提,儲存了視訊檔案愛你封裝格式相關資訊。
AVIputFormat
每種封裝格式(如FLV,MKV,MP4,AVI)對應一個該結構體。
AVStream
視訊檔案中每個視訊(音訊)流對應一個該結構體。
AVCodecContext
編碼器上下文結構體,儲存了視訊(音訊)編碼相關資訊
AVCodec
每種視訊(音訊)編碼器(例如H.264編碼器)對應一個該結構體。
AVPacket
儲存一幀壓縮編碼資料
AVFrame
儲存一幀解碼後像素(取樣)資料
FFmpeg資料結構分析
AVFormatContext
iformat:輸入視訊的AVInputFormat
nb_streams:輸入視訊的AVStream個數
streams:輸入視訊的AVStream[]陣列
duration:輸入視訊的時長(以微妙為單位)
bit_rate:輸入視訊的位元速率
AVInputFormat
name:封裝格式名稱
long_name:封裝格式的長名稱
extensions:封裝格式的副檔名
id:封裝格式ID
一些封裝格式處理的介面函式
AVStream
id:序號
codec:該流對應的AVCodecContext
time_base:該流的時基
r_frame_rate:該流的幀率
AVCodecContext
codec:編碼器的AVCodec
width,height:影象的寬高(只針對視訊)
pix_fmt:畫素格式(只針對視訊)
sample_rate:取樣率(只針對音訊)
channels:聲道數(只針對音訊)
sample_fmt:取樣格式(只針對音訊)
AVCodec
name:編碼器名稱
long_name:編碼器長名稱
type:編碼器型別
id:編碼器ID
一些編碼器的介面函式
AVPacket
pts:顯示時間戳
dts:解碼時間戳
data:壓縮編碼資料
size:壓縮編碼資料大小
stream_index:所屬的AVStream
AVFrame
data:解碼後的影象畫素資料(音訊取樣資料)
linesize:對視訊來說影象中一行畫素的大小;對音訊來說整個音訊幀的大小
width,height:影象的寬高(只針對視訊)
key_frame:是否為關鍵幀(只針對視訊)
pict_type:幀型別(只針對視訊)
解碼後的資料為什麼要經過sws_scale()函式處理?
解碼後YUV格式的視訊畫素資料儲存在AVFrame的data[0]、data[1]、data[2]中。但是這些畫素值並不是連續儲存的,每行有效畫素之後儲存 了 一 些 無 效 像 素 。 以 亮 度 Y 數 據 為 例 , data[0] 中 一 共 包 含 了linesize[0]*height個數據。但是出於優化等方面的考慮,linesize[0]實際上並不等於寬度width,而是一個比寬度大一些的值。因此需要使用sws_scale()進行轉換。轉換後去除了無效資料,width和linesize[0]取值相等。