ffmpeg里提供了很多的encoder,decoder,詳見avcodec.h里的枚舉變量CodecID。
?
宏定義
#define REGISTER_ENCODER(X,x) { /
????????? extern AVCodec x##_encoder; /
????????? if(##X##_ENCODER)? avcodec_register(&x##_encoder); }
?
#define REGISTER_DECODER(X,x) { /
???? extern AVCodec x##_decoder; /
?????????? if(##CODEC_ID_##X##)? avcodec_register(&x##_decoder); }
?
比如:
?REGISTER_DECODER (H264, h264);
就相當于extern AVCodec h264_decoder;
??????????? if(CODEC_ID_H264)
??????????? avcodec_register(&h264_decoder);
?
而這三行代碼的實際作用就是:
?????????? AVCodec codec;
?????????? codec = &h264_decoder;
?
配置好codec之后,
定義全局變量AVCodecContext *avctx;
然后avctx->codec = codec;
?
后續就可以調用通用的API:
???????????????????? avctx->codec->init???????? 初始化
???????????????????? avctx->codec->decode? 解碼
????????????????? 或avctx->codec->encode? 編碼
???????????????????? avctx->codec->close???? 關閉
實現編碼或解碼功能
?
codec是一個結構體,定義如下:
typedef struct AVCodec {
??? const char *name;
??? enum CodecType type;
??? enum CodecID id;
??? int priv_data_size;
??? 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, AVPacket *avpkt); //解碼函數
對于不同的codec,這三個API對應的函數不同。
???對于CODEC_ID_H264,h264_decoder的定義為
?
AVCodec h264_decoder = {
??? "h264",
??? CODEC_TYPE_VIDEO,
??? CODEC_ID_H264,
??? sizeof(H264Context),
??? decode_init,
??? NULL,
??? decode_end,
??? decode_frame,
?}
對于CODEC_ID_H263,h263_decoder的定義如下:
?AVCodec h263_decoder = {
??? "h263",
??? CODEC_TYPE_VIDEO,
??? CODEC_ID_H263,
??? sizeof(MpegEncContext),
??? ff_h263_decode_init,
??? NULL,
??? ff_h263_decode_end,
??? ff_h263_decode_frame,
??? CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
? //? .flush= ff_mpeg_flush,
? //? .long_name= NULL_IF_CONFIG_SMALL("H.263 / H.263-1996, H.263+ / H.263-1998 / H.263 version 2"),
? //? .pix_fmts= ff_hwaccel_pixfmt_list_420,
};
?
對于CODEC_ID_MPEG4,mpeg4_decoder的定義如下:
AVCodec mpeg4_decoder = {
??? "mpeg4",
??? CODEC_TYPE_VIDEO,
??? CODEC_ID_MPEG4,
??? sizeof(MpegEncContext),
??? ff_h263_decode_init,
??? NULL,
??? ff_h263_decode_end,
??? ff_h263_decode_frame,
??? CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY,
//??? .flush= ff_mpeg_flush,
//??? .long_name= NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
//??? .pix_fmts= ff_hwaccel_pixfmt_list_420,
};
?