typedef struct AVCodecContext { enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */ const struct AVCodec *codec; //指向相應的解碼器,如: ff_h264_decoder enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */ void *priv_data;//指向具體相應的解碼器的 context,如 H264Context int bit_rate; int frame_number; int thread_count; //編解碼時的線程數量,由用戶設置,與CPU核心數有關,最佳效果通常設置爲CPU核心數*2. AVRational time_base; //時間的基準單位 unsigned char *extradata;//擴展數據,如 mov 格式-> audio trak ->aac -> esds 格式中的附加解碼信息、H.264解碼器的存儲SPS,PPS信息等. int extradata_size;//擴展數據的 size int width, height; //視頻的原始的寬度與高度,僅針對視頻 enum PixelFormat pix_fmt;//視頻一幀圖像的格式,如 YUV420 int sample_rate; //採樣率(僅音頻)。
int channels; //聲道數(僅音頻)。
enum AVSampleFormat sample_fmt; //音頻採樣格式,編碼:由用戶設置。解碼:由libavcodec設置。
int frame_size; //音頻幀中每一個聲道的採樣數。編碼:由libavcodec在avcodec_open2()中設置。 解碼:能夠由一些解碼器設置以指示恆定的幀大小.
int frame_number; //幀計數器,由libavcodec設置。解碼:從解碼器返回的幀的總數。編碼:到目前爲止傳遞給編碼器的幀的總數。
uint64_t channel_layout; //音頻聲道佈局。編碼:由用戶設置。解碼:由用戶設置,可能被libavcodec覆蓋。
enum AVAudioServiceType audio_service_type; //音頻流傳輸的服務類型。編碼:由用戶設置。解碼:由libavcodec設置。 int bits_per_sample; int block_align; //公共操做函數 int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame); int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); int (*decode_params)(AVCodecContext *avctx, int type, const uint8_t *buf, uint32_t buf_size); int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); int (*end_frame)(AVCodecContext *avctx); }AVCodecContext;
其中codec成員結構體爲AVCodec.數據結構
typedef struct AVCodec { const char *name;// 標示 Codec 的名字, 好比, "h264" "h263" 等。 const char *long_name; //表示Codec的長名字,好比h264的長名字爲"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" enum AVMediaType type; // 標示 Codec 的類型,有 video , audio ,字幕等類型。 enum AVCodecID id; // 標示 Codec 的 ID,有 AV_CODEC_ID_H264等。 int priv_data_size; // 標示具體的 Codec 對應的 Context 的 size,好比h264的等於sizeof(H264Context) struct AVCodec *next; //以鏈表的形式指向下一個Codec(ID+1) // 如下標示 Codec 對外提供的操做,每一種解碼器都會實現這些操做。 int(*init)(AVCodecContext*); int(*encode)(AVCodecContext *, uint8_t *buf, int buf_size, void *data); int(*close)(AVCodecContext*); int(*decode)(AVCodecContext *, void *outdata, int *outdata_size, uint8_t *buf, int buf_size); }AVCodec;
H264 的主要結構的初始化以下:ide
AVCodec ff_h264_decoder = { .name = "h264", .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .priv_data_size = sizeof(H264Context), .init = h264_decode_init, .close = h264_decode_end, .decode = h264_decode_frame, .capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_EXPORTS_CROPPING | FF_CODEC_CAP_ALLOCATE_PROGRESS | FF_CODEC_CAP_INIT_CLEANUP, .flush = h264_decode_flush, .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), .profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles), .priv_class = &h264_class, }
打開一個視頻解碼器示例函數
videoStream = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);//獲取視頻流
AVCodec *vcodec = avcodec_find_decoder(ic->streams[videoStream]->codecpar->codec_id);//獲取codec
AVCodecContext *vc = avcodec_alloc_context3(vcodec); //構造AVCodecContext ,並將vcodec填入AVCodecContext中
avcodec_parameters_to_context(vc, ic->streams[videoStream]->codecpar); //初始化AVCodecContext
int ret = avcodec_open2(vc, NULL,NULL); //打開解碼器,因爲以前調用avcodec_alloc_context3(vcodec)初始化了vc,那麼codec(第2個參數)能夠填NULL