AVCodec 是类似COM 接口的数据结构,表示音视频编解码器,着重于功能函数,一种媒体类型对应一个
AVCodec 结构,在程序运行时有多个实例。next 变量用于把所有支持的编解码器连接成链表,便于遍历查找;id 确
定了唯一编解码器;priv_data_size 表示具体的Codec 对应的Context 结构大小,比如MsrleContext
或TSContext,这些具体的结够定义散落于各个.c 文件中,为避免太多的if else 类语句判断类型再计算大小,这
里就直接指明大小,因为这是一个编译时静态确定的字段,所以放在AVCodec 而不是AVCodecContext中。
//H264 的主要结构的初始化如下:
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_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,
.flush = flush_dpb,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
.profiles = NULL_IF_CONFIG_SMALL(ff_h264_profiles),
.priv_class = &h264_class,
};
typedef struct AVCodec
{
// 标示 Codec 的名字, 比如,"h264" "h263" 等。
const char *name;
//长名称 "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"
const char *long_name;
// 标示 Codec 的类型,有 video ,audio 等类型。
enum CodecType type;
// 标示 Codec 的 ID,有 CODEC_ID_H264 等。
enum CodecID id;
// 标示具体的 Codec 对应的 Context 的 size,如:H264Context。
int priv_data_size;
//初始化Codec静态数据
void (*init_static_data)(struct AVCodec *codec);
// 以下标示 Codec 对外提供的操作,每一种解码器都会实现这些操作。
int(*init)(AVCodecContext*);
int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size, const struct AVSubtitle *sub);
//编码数据
int(*encode2)(AVCodecContext *, uint8_t *buf, int buf_size, void *data);
//关闭codec
int(*close)(AVCodecContext*);
//解码数据
int(*decode)(AVCodecContext *, void *outdata, int *outdata_size,
//发送解码后视频数据
int (*send_frame)(AVCodecContext *avctx, const AVFrame *frame);
//接收解码后音视频数据
int (*receive_frame)(AVCodecContext *avctx, AVFrame *frame);
//接收解码后的音视频压缩数据
int (*receive_packet)(AVCodecContext *avctx, AVPacket *avpkt);
//刷新缓冲区
void (*flush)(AVCodecContext *);
//next指针
struct AVCodec *next;
}AVCodec;