1. 程式人生 > 其它 >FFmpeg: AVFrame中的data和extend_data的區別

FFmpeg: AVFrame中的data和extend_data的區別

FFmpeg中音視訊資料基本上都有PackedPlanar兩種儲存方式,對於雙聲道音訊來說,Packed方式為兩個聲道的資料交錯儲存;Planar方式為兩個聲道分開儲存。假設一個L/R為一個取樣點,資料儲存的方式如下所示:

Packed: L R L R L R L R
Planar: L L L L R R R R
FFmpeg音訊解碼後的資料是存放在AVFrame結構中的。

Packed格式,frame.data[0] 或 frame.extended_data[0]包含所有的音訊資料中。
Planar格式,frame.data[i] 或者 frame.extended_data[i] 表示第i個聲道的資料(假設聲道0是第一個), AVFrame.data陣列大小固定為8,如果聲道數超過8,需要從frame.extended_data獲取聲道資料

#define AV_NUM_DATA_POINTERS 8
    /**
     * pointer to the picture/channel planes.
     * This might be different from the first allocated byte
     *
     * Some decoders access areas outside 0,0 - width,height, please
     * see avcodec_align_dimensions2(). Some filters and swscale can read
     * up to 16 bytes beyond the planes, if these filters are to be used,
     * then 16 extra bytes must be allocated.
     *
     * NOTE: Except for hwaccel formats, pointers not needed by the format
     * MUST be set to NULL.
     
*/ uint8_t *data[AV_NUM_DATA_POINTERS];

下面為FFmpeg內部儲存音訊使用的取樣格式,所有的Planar格式後面都有字母P標識。

enum AVSampleFormat {
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
    AV_SAMPLE_FMT_FLT,         
///< float AV_SAMPLE_FMT_DBL, ///< double AV_SAMPLE_FMT_U8P, ///< unsigned 8 bits, planar AV_SAMPLE_FMT_S16P, ///< signed 16 bits, planar AV_SAMPLE_FMT_S32P, ///< signed 32 bits, planar AV_SAMPLE_FMT_FLTP, ///< float, planar AV_SAMPLE_FMT_DBLP, ///< double, planar AV_SAMPLE_FMT_S64, ///< signed 64 bits AV_SAMPLE_FMT_S64P, ///< signed 64 bits, planar AV_SAMPLE_FMT_NB ///< Number of sample formats. DO NOT USE if linking dynamically };

說明:

  • Planar模式是ffmpeg內部儲存模式,我們實際使用的音訊檔案都是Packed模式的。
  • FFmpeg解碼不同格式的音訊輸出的音訊取樣格式不是一樣。測試發現,其中AAC解碼輸出的資料為浮點型的 AV_SAMPLE_FMT_FLTP 格式,MP3解碼輸出的資料為 AV_SAMPLE_FMT_S16P 格式(使用的mp3檔案為16位深)。具體取樣格式可以檢視解碼後的AVFrame中的format成員或解碼器的AVCodecContext中的sample_fmt成員。
  • Planar或者Packed模式直接影響到儲存檔案時寫檔案的操作,操作資料的時候一定要先檢測音訊取樣格式。

參考連結:

1.AVFrame 中data與extend_data的區別