From 7a06ff148d0321e863a682334c59f59b3e8e7b6d Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 17 Jul 2003 12:29:07 +0000 Subject: [PATCH] AVCodec.flush() ff_draw_horiz_band() in coded order / cleanup Originally committed as revision 2064 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/avcodec.h | 12 +++++++++--- libavcodec/h263dec.c | 2 ++ libavcodec/huffyuv.c | 13 +++++++------ libavcodec/mpeg12.c | 1 + libavcodec/mpegvideo.c | 43 +++++++++++++++++++++++++----------------- libavcodec/mpegvideo.h | 1 + libavcodec/svq1.c | 1 + libavcodec/utils.c | 36 +++++------------------------------ 8 files changed, 52 insertions(+), 57 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 0ccc77cd27..82fd85a88e 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -15,8 +15,8 @@ extern "C" { #define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION "0.4.6" -#define LIBAVCODEC_BUILD 4669 -#define LIBAVCODEC_BUILD_STR "4669" +#define LIBAVCODEC_BUILD 4670 +#define LIBAVCODEC_BUILD_STR "4670" #define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR @@ -473,7 +473,7 @@ typedef struct AVCodecContext { * - decoding: set by user. */ void (*draw_horiz_band)(struct AVCodecContext *s, - uint8_t **src_ptr, int linesize, + AVFrame *src, int offset[4], int y, int width, int height); /* audio only */ @@ -1209,6 +1209,7 @@ typedef struct AVCodec { int capabilities; const AVOption *options; struct AVCodec *next; + void (*flush)(AVCodecContext *); } AVCodec; /** @@ -1400,7 +1401,12 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic); void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic); void avcodec_default_free_buffers(AVCodecContext *s); +/** + * opens / inits the AVCodecContext. + * not thread save! + */ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, uint8_t *buf, int buf_size); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 067627c16c..aee93e82f1 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -723,6 +723,7 @@ AVCodec mpeg4_decoder = { ff_h263_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, .options = mpeg4_decoptions, + .flush= ff_mpeg_flush, }; AVCodec h263_decoder = { @@ -735,6 +736,7 @@ AVCodec h263_decoder = { ff_h263_decode_end, ff_h263_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, + .flush= ff_mpeg_flush, }; AVCodec msmpeg4v1_decoder = { diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index e9233c28e2..4c8229a3c3 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -673,7 +673,7 @@ static void decode_bgr_bitstream(HYuvContext *s, int count){ static void draw_slice(HYuvContext *s, int y){ int h, cy; - uint8_t *src_ptr[3]; + int offset[4]; if(s->avctx->draw_horiz_band==NULL) return; @@ -686,13 +686,14 @@ static void draw_slice(HYuvContext *s, int y){ }else{ cy= y; } - - src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y; - src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy; - src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy; + + offset[0] = s->picture.linesize[0]*y; + offset[1] = s->picture.linesize[1]*cy; + offset[2] = s->picture.linesize[2]*cy; + offset[3] = 0; emms_c(); - s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h); + s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, s->width, h); s->last_slice_end= y + h; } diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 8871769a3b..e5491f3fa7 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -2356,4 +2356,5 @@ AVCodec mpeg_decoder = { mpeg_decode_end, mpeg_decode_frame, CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, + .flush= ff_mpeg_flush, }; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 69b06bcfb3..a24500dabf 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -2725,29 +2725,26 @@ static int pix_diff_vcmp16x8(uint8_t *s1, uint8_t*s2, int stride){ //FIXME move * @param h is the normal height, this will be reduced automatically if needed for the last row */ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ - if ( s->avctx->draw_horiz_band - && (s->last_picture_ptr || s->low_delay) ) { + if (s->avctx->draw_horiz_band) { uint8_t *src_ptr[3]; - int offset; + int offset[4]; h= FFMIN(h, s->height - y); - if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME) - offset = 0; - else - offset = y * s->linesize; - - if(s->pict_type==B_TYPE || s->low_delay){ - src_ptr[0] = s->current_picture.data[0] + offset; - src_ptr[1] = s->current_picture.data[1] + (offset >> 2); - src_ptr[2] = s->current_picture.data[2] + (offset >> 2); - } else { - src_ptr[0] = s->last_picture.data[0] + offset; - src_ptr[1] = s->last_picture.data[1] + (offset >> 2); - src_ptr[2] = s->last_picture.data[2] + (offset >> 2); + if(s->pict_type==B_TYPE && s->picture_structure == PICT_FRAME){ + offset[0]= + offset[1]= + offset[2]= + offset[3]= 0; + }else{ + offset[0]= y * s->linesize;; + offset[1]= + offset[2]= (y>>1) * s->uvlinesize;; + offset[3]= 0; } + emms_c(); - s->avctx->draw_horiz_band(s->avctx, src_ptr, s->linesize, + s->avctx->draw_horiz_band(s->avctx, (AVFrame*)s->current_picture_ptr, offset, y, s->width, h); } } @@ -3076,6 +3073,18 @@ int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size) return 0; } +void ff_mpeg_flush(AVCodecContext *avctx){ + int i; + MpegEncContext *s = avctx->priv_data; + + for(i=0; ipicture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL + || s->picture[i].type == FF_BUFFER_TYPE_USER)) + avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]); + } + s->last_picture_ptr = s->next_picture_ptr = NULL; +} + #ifdef CONFIG_ENCODERS void ff_copy_bits(PutBitContext *pb, uint8_t *src, int length) { diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 9626d61da3..3546d85a37 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -713,6 +713,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int src_x, int src_y, int w, int h); #define END_NOT_FOUND -100 int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); +void ff_mpeg_flush(AVCodecContext *avctx); void ff_print_debug_info(MpegEncContext *s, Picture *pict); void ff_er_frame_start(MpegEncContext *s); diff --git a/libavcodec/svq1.c b/libavcodec/svq1.c index e416f52daf..54690d3dae 100644 --- a/libavcodec/svq1.c +++ b/libavcodec/svq1.c @@ -838,4 +838,5 @@ AVCodec svq1_decoder = { svq1_decode_end, svq1_decode_frame, CODEC_CAP_DR1, + .flush= ff_mpeg_flush, }; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 5c25463747..eeffde2c9e 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -590,39 +590,13 @@ void avcodec_init(void) dsputil_static_init(); } -/* this can be called after seeking and before trying to decode the next keyframe */ +/** + * Flush buffers, should be called when seeking or when swicthing to a different stream. + */ void avcodec_flush_buffers(AVCodecContext *avctx) { - int i; - MpegEncContext *s = avctx->priv_data; - - switch(avctx->codec_id){ - case CODEC_ID_MPEG1VIDEO: - case CODEC_ID_H263: - case CODEC_ID_RV10: -// case CODEC_ID_MJPEG: -// case CODEC_ID_MJPEGB: - case CODEC_ID_MPEG4: - case CODEC_ID_MSMPEG4V1: - case CODEC_ID_MSMPEG4V2: - case CODEC_ID_MSMPEG4V3: - case CODEC_ID_WMV1: - case CODEC_ID_WMV2: - case CODEC_ID_H263P: - case CODEC_ID_H263I: - case CODEC_ID_FLV1: - case CODEC_ID_SVQ1: - for(i=0; ipicture[i].data[0] && ( s->picture[i].type == FF_BUFFER_TYPE_INTERNAL - || s->picture[i].type == FF_BUFFER_TYPE_USER)) - avctx->release_buffer(avctx, (AVFrame*)&s->picture[i]); - } - s->last_picture_ptr = s->next_picture_ptr = NULL; - break; - default: - //FIXME - break; - } + if(avctx->codec->flush) + avctx->codec->flush(avctx); } void avcodec_default_free_buffers(AVCodecContext *s){