FFmpeg 基本数据结构 AVCodecContext分析
1、AVCodecContext 结构体定义
AVCodecContext 是 FFmpeg 多媒体框架中最核心的编解码上下文结构,负责管理编解码器的所有参数、状态和操作。作为 FFmpeg 编解码流水线的中枢,它承载着从参数配置到实际编解码的所有关键信息。 AVCodecContext 是 FFmpeg 中用于存储编解码器(Codec)所有上下文信息和参数的主结构体。 它承载了一次编解码操作所需的全部状态和数据。
- 核心功能:
1.参数容器:统一存储编解码所有配置参数
2.状态管理:跟踪编解码过程的状态变化
3.资源分配:管理内存、硬件资源等
4.操作枢纽:连接 avcodec_send_* 和 avcodec_receive_* API
5.性能载体:承载多线程、硬件加速等优化特性
2、AVCodecContext 成员变量说明
AVCodecContext 各个成员说明如下:
typedef struct AVCodecContext {const AVClass *av_class;int log_level_offset;enum AVMediaType codec_type;const struct AVCodec *codec;enum AVCodecID codec_id;unsigned int codec_tag;void *priv_data;struct AVCodecInternal *internal;void *opaque;int64_t bit_rate;int flags;int flags2;uint8_t *extradata;int extradata_size;AVRational time_base;AVRational pkt_timebase;AVRational framerate;attribute_deprecatedint ticks_per_frame;int delay;int width, height;int coded_width, coded_height;AVRational sample_aspect_ratio;enum AVPixelFormat pix_fmt;enum AVPixelFormat sw_pix_fmt;enum AVColorPrimaries color_primaries;enum AVColorTransferCharacteristic color_trc;enum AVColorSpace colorspace;enum AVColorRange color_range;enum AVChromaLocation chroma_sample_location;enum AVFieldOrder field_order;int refs;int has_b_frames;int slice_flags;void (*draw_horiz_band)(struct AVCodecContext *s,const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],int y, int type, int height);enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);int max_b_frames;float b_quant_factor;float b_quant_offset;float i_quant_factor;float i_quant_offset;float lumi_masking;float temporal_cplx_masking;float spatial_cplx_masking;float p_masking;float dark_masking;int nsse_weight;int me_cmp;int me_sub_cmp;int mb_cmp;int ildct_cmp;int dia_size;int last_predictor_count;int me_pre_cmp;int pre_dia_size;int me_subpel_quality;int me_range;int mb_decision;uint16_t *intra_matrix;uint16_t *inter_matrix;uint16_t *chroma_intra_matrix;int intra_dc_precision;int mb_lmin;int mb_lmax;int bidir_refine;int keyint_min;int gop_size;int mv0_threshold;int slices;int sample_rate;enum AVSampleFormat sample_fmt;AVChannelLayout ch_layout;int frame_size;int block_align;int cutoff;enum AVAudioServiceType audio_service_type;enum AVSampleFormat request_sample_fmt;int initial_padding;int trailing_padding;int seek_preroll;int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);int bit_rate_tolerance;int global_quality;int compression_level;float qcompress;float qblur;int qmin;int qmax;int max_qdiff;int rc_buffer_size;int rc_override_count;RcOverride *rc_override;int64_t rc_max_rate;int64_t rc_min_rate;float rc_max_available_vbv_use;float rc_min_vbv_overflow_use;int rc_initial_buffer_occupancy;int trellis;char *stats_out;char *stats_in;int workaround_bugs;int strict_std_compliance;int error_concealment;int err_recognition;const struct AVHWAccel *hwaccel;void *hwaccel_context;AVBufferRef *hw_frames_ctx;AVBufferRef *hw_device_ctx;int hwaccel_flags;int extra_hw_frames;uint64_t error[AV_NUM_DATA_POINTERS];int dct_algo;int idct_algo;int bits_per_coded_sample;int bits_per_raw_sample;int thread_count;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);int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);int profile;int level;unsigned properties;enum AVDiscard skip_loop_filter;enum AVDiscard skip_idct;enum AVDiscard skip_frame;int skip_alpha;int skip_top;int skip_bottom;int lowres;const struct AVCodecDescriptor *codec_descriptor;char *sub_charenc;int sub_charenc_mode;int subtitle_header_size;uint8_t *subtitle_header;uint8_t *dump_separator;char *codec_whitelist;AVPacketSideData *coded_side_data;int nb_coded_side_data;int export_side_data;int64_t max_pixels;int apply_cropping;int discard_damaged_percentage;int64_t max_samples;int (*get_encode_buffer)(struct AVCodecContext *s, AVPacket *pkt, int flags);int64_t frame_num;int *side_data_prefer_packet;unsigned nb_side_data_prefer_packet;AVFrameSideData **decoded_side_data;int nb_decoded_side_data;
} AVCodecContext;
// av_class: 指向一个 AVClass 结构体的指针,用于提供关于编码器的详细信息。
// log_level_offset: 用于调整日志级别的偏移量。
// codec_type: 表示编码器的媒体类型,如视频、音频或字幕等。
// codec: 指向一个 AVCodec 结构体的指针,用于表示编码器。
// codec_id: 表示编码器的 ID。
// codec_tag: 表示编码器的标签。
// priv_data: 指向一个私有数据的指针,用于存储编码器特定的数据。
// internal: 指向一个 AVCodecInternal 结构体的指针,用于存储编码器内部的实现细节。
// opaque: 用于存储编码器 opaque 数据。
// bit_rate: 表示编码器的比特率。
// flags: 表示编码器的一些标志。
// flags2: 表示编码器的一些附加标志。
// extradata: 指向一个包含编码器额外数据的 uint8_t 类型的指针。
// extradata_size: 表示编码器额外数据的大小。
// time_base: 表示编码器的时间基准,用于计算帧之间的时间差。
// pkt_timebase: 表示编码器 packet 时间基准,用于计算 packet 之间的时间差。
// framerate: 表示编码器的帧率。
// ticks_per_frame: 表示编码器每帧的 tick 数。
// delay: 表示编码器延迟。
// width 和 height: 表示编码器处理的视频帧的宽度和高度。
// coded_width 和 coded_height: 表示编码器处理的视频帧的编码宽度 和 编码高度。
// sample_aspect_ratio: 表示编码器处理的视频帧的采样纵横比。
// pix_fmt: 表示编码器处理的视频帧的像素格式。
// sw_pix_fmt: 表示编码器处理的视频帧的软件像素格式。
// color_primaries: 表示编码器处理的视频帧的颜色主原点。
// color_trc: 表示编码器处理的视频帧的颜色传输特性。
// colorspace: 表示编码器处理的视频帧的颜色空间。
// color_range: 表示编码器处理的视频帧的颜色范围。
// chroma_sample_location: 表示编码器处理的视频帧的色度采样位置。
// field_order: 表示编码器处理的视频帧的字段顺序。
// refs: 表示编码器处理的视频帧的参考帧数量。
// has_b_frames: 表示编码器处理的视频帧是否包含 B 帧。
// slice_flags: 表示编码器处理的视频帧的切片标志。
// draw_horiz_band: 指向一个用于绘制水平带子的函数指针,该函数用于处理视频帧的特定部分。
// get_format: 指向一个用于获取像素格式的函数指针,该函数用于处理视频帧的特定部分。
// max_b_frames: 表示编码器处理的视频帧的最大 B 帧数量。
// b_quant_factor: 表示 B 帧的量化因子。
// b_quant_offset: 表示 B 帧的量化偏移量。
// i_quant_factor: 表示 I 帧的量化因子。
// i_quant_offset: 表示 I 帧的量化偏移量。
// lumi_masking: 表示亮度掩蔽因子。
3、AVCodecContext 核心组件解析
-
基础标识字段
![[图片]](https://i-blog.csdnimg.cn/direct/eabc16b54c694fdbac677d499ec42b58.png)
-
视频关键参数
![[图片]](https://i-blog.csdnimg.cn/direct/4d11b58ea45b4727ba3b7f15ba10c871.png)
-
音频关键参数
![[图片]](https://i-blog.csdnimg.cn/direct/daca139d13bd44d982f6316b6ce7a88a.png)
- 与相关结构体的关系
AVCodec:编解码器描述,包含编解码能力信息
AVCodecParameters:编解码参数,用于存储流的静态参数
AVPacket:编码后的数据包
AVFrame:解码后的原始数据帧
4、AVCodecContext 使用示例
// 创建解码器上下文
AVCodecContext *dec_ctx = NULL;// 查找解码器
const AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!codec) {// 错误处理
}// 分配解码器上下文
dec_ctx = avcodec_alloc_context3(codec);
if (!dec_ctx) {// 错误处理
}// 从流参数复制到解码器上下文
if (avcodec_parameters_to_context(dec_ctx, stream->codecpar) < 0) {// 错误处理
}// 打开解码器
if (avcodec_open2(dec_ctx, codec, NULL) < 0) {// 错误处理
}
