diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index f01a7dec2d..9c70cf1e89 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1089,6 +1089,17 @@ typedef struct AVCodecContext { */ int color_table_id; + /** + * internal_buffer count. + * Dont touch, used by lavc default_get_buffer() + */ + int internal_buffer_count; + + /** + * internal_buffers. + * Dont touch, used by lavc default_get_buffer() + */ + void *internal_buffer; } AVCodecContext; @@ -1320,6 +1331,7 @@ AVFrame *avcodec_alloc_frame(void); 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); int avcodec_open(AVCodecContext *avctx, AVCodec *codec); int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, diff --git a/libavcodec/dv.c b/libavcodec/dv.c index eb8dbb7c00..d686aca9c6 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -624,15 +624,8 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, static int dvvideo_decode_end(AVCodecContext *avctx) { DVVideoDecodeContext *s = avctx->priv_data; - int i; - - if(avctx->get_buffer == avcodec_default_get_buffer){ - for(i=0; i<4; i++){ - av_freep(&s->picture.base[i]); - s->picture.data[i]= NULL; - } - av_freep(&s->picture.opaque); - } + + avcodec_default_free_buffers(avctx); return 0; } diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 31cb749636..4e1375dcc2 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -3868,6 +3868,7 @@ fprintf(stderr, "FMO not supported\n"); |) | | | | slice_group_id[ i ] |1 |u(v) | #endif + break; } } pps->ref_count[0]= get_ue_golomb(&s->gb) + 1; @@ -4366,6 +4367,6 @@ AVCodec h264_decoder = { NULL, decode_end, decode_frame, - /*CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | */CODEC_CAP_TRUNCATED, + /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED, }; diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index ecf22bb2c6..a4193fdea4 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -959,14 +959,8 @@ static int decode_end(AVCodecContext *avctx) for(i=0; i<3; i++){ free_vlc(&s->vlc[i]); } - - if(avctx->get_buffer == avcodec_default_get_buffer){ - for(i=0; i<4; i++){ - av_freep(&s->picture.base[i]); - s->picture.data[i]= NULL; - } - av_freep(&s->picture.opaque); - } + + avcodec_default_free_buffers(avctx); return 0; } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 7f11869a68..7a79d4ec74 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -305,15 +305,8 @@ static void free_picture(MpegEncContext *s, Picture *pic){ av_freep(&pic->motion_val[i]); av_freep(&pic->ref_index[i]); } - - if(pic->type == FF_BUFFER_TYPE_INTERNAL){ - for(i=0; i<4; i++){ - av_freep(&pic->base[i]); - pic->data[i]= NULL; - } - av_freep(&pic->opaque); - pic->type= 0; - }else if(pic->type == FF_BUFFER_TYPE_SHARED){ + + if(pic->type == FF_BUFFER_TYPE_SHARED){ for(i=0; i<4; i++){ pic->base[i]= pic->data[i]= NULL; @@ -524,6 +517,7 @@ void MPV_common_end(MpegEncContext *s) for(i=0; ipicture[i]); } + avcodec_default_free_buffers(s->avctx); s->context_initialized = 0; } @@ -978,6 +972,7 @@ alloc: s->last_picture_ptr= s->next_picture_ptr; s->next_picture_ptr= s->current_picture_ptr; } + if(s->last_picture_ptr) s->last_picture= *s->last_picture_ptr; if(s->next_picture_ptr) s->next_picture= *s->next_picture_ptr; if(s->new_picture_ptr ) s->new_picture = *s->new_picture_ptr; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 156ceddd20..4ca39d43d7 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -119,29 +119,39 @@ void register_avcodec(AVCodec *format) format->next = NULL; } -typedef struct DefaultPicOpaque{ +typedef struct InternalBuffer{ int last_pic_num; + uint8_t *base[4]; uint8_t *data[4]; -}DefaultPicOpaque; +}InternalBuffer; + +#define INTERNAL_BUFFER_SIZE 32 int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ int i; const int width = s->width; const int height= s->height; - DefaultPicOpaque *opaque; + InternalBuffer *buf; assert(pic->data[0]==NULL); - assert(pic->type==0 || pic->type==FF_BUFFER_TYPE_INTERNAL); + assert(INTERNAL_BUFFER_SIZE > s->internal_buffer_count); - if(pic->opaque){ - opaque= (DefaultPicOpaque *)pic->opaque; - for(i=0; i<3; i++) - pic->data[i]= opaque->data[i]; + if(s->internal_buffer==NULL){ + s->internal_buffer= av_mallocz(INTERNAL_BUFFER_SIZE*sizeof(InternalBuffer)); + } +#if 0 + s->internal_buffer= av_fast_realloc( + s->internal_buffer, + &s->internal_buffer_size, + sizeof(InternalBuffer)*FFMAX(99, s->internal_buffer_count+1)/*FIXME*/ + ); +#endif + + buf= &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; -// printf("get_buffer %X coded_pic_num:%d last:%d\n", pic->opaque, pic->coded_picture_number, opaque->last_pic_num); - pic->age= pic->coded_picture_number - opaque->last_pic_num; - opaque->last_pic_num= pic->coded_picture_number; -//printf("age: %d %d %d\n", pic->age, c->picture_number, pic->coded_picture_number); + if(buf->base[0]){ + pic->age= pic->coded_picture_number - buf->last_pic_num; + buf->last_pic_num= pic->coded_picture_number; }else{ int align, h_chroma_shift, v_chroma_shift; int w, h, pixel_size; @@ -174,11 +184,7 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ h+= EDGE_WIDTH*2; } - opaque= av_mallocz(sizeof(DefaultPicOpaque)); - if(opaque==NULL) return -1; - - pic->opaque= opaque; - opaque->last_pic_num= -256*256*256*64; + buf->last_pic_num= -256*256*256*64; for(i=0; i<3; i++){ const int h_shift= i==0 ? 0 : h_chroma_shift; @@ -186,32 +192,51 @@ int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic){ pic->linesize[i]= pixel_size*w>>h_shift; - pic->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16 - if(pic->base[i]==NULL) return -1; - - memset(pic->base[i], 128, pic->linesize[i]*h>>v_shift); + buf->base[i]= av_mallocz((pic->linesize[i]*h>>v_shift)+16); //FIXME 16 + if(buf->base[i]==NULL) return -1; + memset(buf->base[i], 128, pic->linesize[i]*h>>v_shift); if(s->flags&CODEC_FLAG_EMU_EDGE) - pic->data[i] = pic->base[i]; + buf->data[i] = buf->base[i]; else - pic->data[i] = pic->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift); - - opaque->data[i]= pic->data[i]; + buf->data[i] = buf->base[i] + (pic->linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift); } pic->age= 256*256*256*64; pic->type= FF_BUFFER_TYPE_INTERNAL; } + for(i=0; i<4; i++){ + pic->base[i]= buf->base[i]; + pic->data[i]= buf->data[i]; + } + s->internal_buffer_count++; + return 0; } void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic){ int i; - + InternalBuffer *buf, *last, temp; + assert(pic->type==FF_BUFFER_TYPE_INTERNAL); - - for(i=0; i<3; i++) + + for(i=0; iinternal_buffer_count; i++){ //just 3-5 checks so is not worth to optimize + buf= &((InternalBuffer*)s->internal_buffer)[i]; + if(buf->data[0] == pic->data[0]) + break; + } + assert(i < s->internal_buffer_count); + s->internal_buffer_count--; + last = &((InternalBuffer*)s->internal_buffer)[s->internal_buffer_count]; + + temp= *buf; + *buf= *last; + *last= temp; + + for(i=0; i<3; i++){ pic->data[i]=NULL; +// pic->base[i]=NULL; + } //printf("R%X\n", pic->opaque); } @@ -592,6 +617,23 @@ void avcodec_flush_buffers(AVCodecContext *avctx) } } +void avcodec_default_free_buffers(AVCodecContext *s){ + int i, j; + + if(s->internal_buffer==NULL) return; + + for(i=0; iinternal_buffer)[i]; + for(j=0; j<4; j++){ + av_freep(&buf->base[j]); + buf->data[j]= NULL; + } + } + av_freep(&s->internal_buffer); + + s->internal_buffer_count=0; +} + int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ int exact=1, sign=0; int64_t gcd, larger;