天天看點

FFmpeg:AVCodecContext結構體解析AVCodecContext初始化結構定義及成員解讀

文檔:傳送門

AVCodecContext

AVCodecContext

也是FFmpeg使用過程中比較重要的結構體,儲存了編解碼器上下文相關資訊。不管是編碼,還是解碼都會用到,但在兩種不同應用場景中,結構體中部分字段作用和表現并不一緻,這一點需要特别注意。

AVFormatContext

包含了一個媒體流的解碼器的上下文資訊,比較重要的有:

  • AVMediaType:解碼器類型,表示這個解碼器是用來處理什麼流的,音頻、視訊還是字母等。
  • AVCodec:解碼器結構體指針,在AVCodecContext建立之初就傳進來。初始化後不可更改。
  • AVCodecID:是什麼類型的解碼器,AV_CODEC_ID_MPEG1VIDEO還是AV_CODEC_ID_H263等。
  • bit_rate:平均比特率,編碼時為使用者設定。解碼時也可以使用者設定,但也可能被libavcodec覆寫。
  • gop_size: GOP的大小,編碼時使用者設定。解碼時不會使用。
  • sample_aspect_ratio:采樣率。
  • sample_rate:音頻采樣率。
  • channels:聲道數(音頻概念)。
  • AVSampleFormat:音頻采樣格式。

初始化

AVCodec *videoCodec = avcodec_find_decoder(formatCtx->streams[videoStream]->codecpar->codec_id);
AVCodecContext *videoCodecContext = avcodec_alloc_context3(videoCodec);
           

首先使用

AVFormatContext

中儲存的解碼器的codec_id資訊,通過

avcodec_find_decoder

函數,擷取一個解碼器(AVCodec)。然後以此為參數,通過

avcodec_alloc_context3

函數分初始化

AVCodecContext

指針。

結構定義及成員解讀

typedef struct AVCodecContext {
    const AVClass *av_class; // av_log資訊,通過avcodec_alloc_context3函數設定
    int log_level_offset; // log 級别
    enum AVMediaType codec_type; // 解碼器類型,例如:AVMEDIA_TYPE_VIDEO、AVMEDIA_TYPE_AUDIO
    const struct AVCodec  *codec; // 解碼器結構體指針,在AVCodecContext建立之初就傳進來。
    enum AVCodecID     codec_id; // 解碼器ID
    unsigned int codec_tag; // 解碼器tag
    void *priv_data; // 私有資料
    // 内部使用的上下文,通常被用在libavcodec的函數中,并且不是解碼器指定的卻别與priv_data
    struct AVCodecInternal *internal;
    void *opaque; // 使用者的私有資料,可以攜帶特定應用内容。不管是編碼還是解碼時,都是被使用者設定使用。
    // 平均比特率,編碼時為使用者設定。解碼時也可以使用者設定,但也可能被libavcodec覆寫。
    int64_t bit_rate;
    int bit_rate_tolerance; // 允許比特流偏離參考的比特數。 編碼時使用者設定,解碼時不會用到。
    int global_quality; // 編解碼器的全局品質,應與MPEG-1/2/4 qscale成比例。編碼時使用
    int compression_level; // 壓縮水準,編碼時使用
    AVRational time_base; // 時基
    int width, height; // 隻有在視訊編解碼時使用。
    // 比特流寬度/高度可以與寬度/高度不同,例如 當在輸出之前裁剪解碼的幀或者啟用lowres時。解碼時使用,可能被解碼器覆寫。
    int coded_width, coded_height;
    int gop_size; // GOP的大小,編碼時使用者設定。解碼時不會使用
    // 像素格式,請參閱AV_PIX_FMT_xxx。 如果從頭檔案中知道,可以由分路器設定。 如果解碼器知道更好,可能會  被解碼器覆寫。
    enum AVPixelFormat pix_fmt;
    int max_b_frames; // 非B幀之間的最大B幀數
    int has_b_frames; // 解碼器中幀重排序緩沖區的大小。 對于MPEG-2,它是1個IPB幀或0個低延遲IP幀。
    int slice_count; // slice數
    int *slice_offset; // 以位元組為機關切片幀中的偏移量
    AVRational sample_aspect_ratio; // 采樣率
    int slice_flags; // slice 标志
    int keyint_min; // 最小GOP大小
    int refs; // 參考幀數
    enum AVColorSpace colorspace; // YUV色彩空間類型。
    enum AVColorRange color_range; // MPEG與JPEG YUV範圍。
    int slices; // 切片數量。 表示圖檔細分的數量。 用于并行解碼。
    int sample_rate; //采樣率,隻用于音頻
    int channels; // 聲道數
    enum AVSampleFormat sample_fmt; // 音頻采樣格式
    int frame_size; // 音頻幀中每個聲道的采樣數。
    int frame_number; // 幀計數器,由libavcodec設定。
    int block_align; // 每個資料包的位元組數
    uint64_t channel_layout;
    enum AVSampleFormat request_sample_fmt; // 所需的采樣格式
  	// 在每個幀的開頭調用此回調以擷取它的資料緩沖區。
    int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
		// 通過vcodec_decode_video2()和avcodec_decode_audio4()調用傳回的解碼後的幀數
    int refcounted_frames; 
    struct AVHWAccel *hwaccel; // 正在使用的硬體加速器
		// 硬體加速器上下文 對于某些硬體加速器,使用者需要提供全局上下文。
    void *hwaccel_context;
    int thread_count; // 線程計數用于決定應該将多少獨立任務傳遞給execute()
    /**
     * 使用哪種多線程方法。
     * 使用FF_THREAD_FRAME會使每個線程的解碼延遲增加一幀,是以無法提供未來幀的用戶端不應使用它。
     */
    int thread_type;
    int active_thread_type; // 編解碼器正在使用哪種多線程方法。
    // 編解碼器可以調用它來執行幾個獨立的事情。隻有在完成所有任務後才會傳回。使用者可以用一些多線程實作替換它,預設實作将串行執行這些部分。
    int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
    enum AVDiscard skip_loop_filter; // 對所選幀進行跳過循環過濾。
    enum AVDiscard skip_frame; // 跳過所選幀的解碼操作。
    uint8_t *subtitle_header; // 包含文本字幕樣式資訊的字母頭。
    int subtitle_header_size; // 字母頭的大小
    // 僅限音頻。 編碼器在音頻開頭插入的“啟動”樣本(填充)的數量。即調用者必須丢棄此數量的前導解碼樣本,以獲得原始音頻而不帶前導填充。
    int initial_padding;
    AVRational pkt_timebase; // pkt_dts / pts和AVPacket.dts / pts的時基。
    // PTS校正的目前統計資料。
    int64_t pts_correction_num_faulty_pts; /// 到目前為止,不正确的PTS值的數量
    int64_t pts_correction_num_faulty_dts; /// 到目前為止,DTS值的錯誤數量
    int64_t pts_correction_last_pts;       /// 最後一幀的PTS
    int64_t pts_correction_last_dts;       /// 最後一幀的DTS
    char *codec_whitelist; // 解碼器白名單,以 ','分割。
    // 僅限音頻。 編碼器附加到音頻末尾的填充量(在樣本中)。 即調用者必須從流的末尾丢棄此數量的解碼樣本,以獲得原始音頻而不進行任何尾随填充。
    int trailing_padding;
    int64_t max_pixels; // 每個圖像允許的最大像素點數。
} AVCodecContext;
           

AVCodecContext

結構題的成員還有很多,這裡隻是摘取了常見的做了說明,還有很多等待大家發掘。