1. 程式人生 > >FFmpeg教程(三)視訊解碼器

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]取值相等。