diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 43f6cf87ca..5155c8fd24 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -8,7 +8,7 @@ enum CodecID { CODEC_ID_MP2, CODEC_ID_AC3, CODEC_ID_MJPEG, - CODEC_ID_OPENDIVX, + CODEC_ID_MPEG4, CODEC_ID_PCM, CODEC_ID_RAWVIDEO, CODEC_ID_MSMPEG4, @@ -45,6 +45,11 @@ extern int motion_estimation_method; #define CODEC_FLAG_HQ 0x0001 /* high quality (non real time) encoding */ #define CODEC_FLAG_QSCALE 0x0002 /* use fixed qscale */ +/* codec capabilities */ + +/* decoder can use draw_horiz_band callback */ +#define CODEC_CAP_DRAW_HORIZ_BAND 0x0001 + #define FRAME_RATE_BASE 10000 typedef struct AVCodecContext { @@ -57,6 +62,15 @@ typedef struct AVCodecContext { int width, height; int gop_size; /* 0 = intra only */ int pix_fmt; /* pixel format, see PIX_FMT_xxx */ + + /* if non NULL, 'draw_horiz_band' is called by the libavcodec + decoder to draw an horizontal band. It improve cache usage. Not + all codecs can do that. You must check the codec capabilities + before */ + void (*draw_horiz_band)(struct AVCodecContext *s, + UINT8 **src_ptr, int linesize, + int y, int width, int height); + /* audio only */ int sample_rate; /* samples per sec */ int channels; @@ -72,6 +86,7 @@ typedef struct AVCodecContext { void *priv_data; /* the following fields are ignored */ + void *opaque; /* can be used to carry app specific stuff */ char codec_name[32]; int codec_type; /* see CODEC_TYPE_xxx */ int codec_id; /* see CODEC_ID_xxx */ @@ -88,6 +103,7 @@ typedef struct AVCodec { int (*close)(AVCodecContext *); int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, UINT8 *buf, int buf_size); + int capabilities; struct AVCodec *next; } AVCodec; @@ -104,11 +120,11 @@ extern AVCodec h263_encoder; extern AVCodec h263p_encoder; extern AVCodec rv10_encoder; extern AVCodec mjpeg_encoder; -extern AVCodec opendivx_encoder; +extern AVCodec mpeg4_encoder; extern AVCodec msmpeg4_encoder; extern AVCodec h263_decoder; -extern AVCodec opendivx_decoder; +extern AVCodec mpeg4_decoder; extern AVCodec msmpeg4_decoder; extern AVCodec mpeg_decoder; extern AVCodec h263i_decoder; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 02fedd90a7..7f2a6dd20d 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -30,6 +30,7 @@ static int h263_decode_init(AVCodecContext *avctx) MpegEncContext *s = avctx->priv_data; int i; + s->avctx = avctx; s->out_format = FMT_H263; s->width = avctx->width; @@ -39,7 +40,7 @@ static int h263_decode_init(AVCodecContext *avctx) switch(avctx->codec->id) { case CODEC_ID_H263: break; - case CODEC_ID_OPENDIVX: + case CODEC_ID_MPEG4: s->time_increment_bits = 4; /* default value for broken headers */ s->h263_pred = 1; break; @@ -148,6 +149,20 @@ static int h263_decode_frame(AVCodecContext *avctx, } MPV_decode_mb(s, s->block); } + if (avctx->draw_horiz_band) { + UINT8 *src_ptr[3]; + int y, h, offset; + y = s->mb_y * 16; + h = s->height - y; + if (h > 16) + h = 16; + offset = y * s->linesize; + src_ptr[0] = s->current_picture[0] + offset; + src_ptr[1] = s->current_picture[1] + (offset >> 2); + src_ptr[2] = s->current_picture[2] + (offset >> 2); + avctx->draw_horiz_band(avctx, src_ptr, s->linesize, + y, s->width, h); + } } MPV_frame_end(s); @@ -164,15 +179,16 @@ static int h263_decode_frame(AVCodecContext *avctx, return buf_size; } -AVCodec opendivx_decoder = { - "opendivx", +AVCodec mpeg4_decoder = { + "mpeg4", CODEC_TYPE_VIDEO, - CODEC_ID_OPENDIVX, + CODEC_ID_MPEG4, sizeof(MpegEncContext), h263_decode_init, NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec h263_decoder = { @@ -184,6 +200,7 @@ AVCodec h263_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec msmpeg4_decoder = { @@ -195,6 +212,7 @@ AVCodec msmpeg4_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, }; AVCodec h263i_decoder = { @@ -206,5 +224,6 @@ AVCodec h263i_decoder = { NULL, h263_decode_end, h263_decode_frame, + CODEC_CAP_DRAW_HORIZ_BAND, };