diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fee760c56c..61ce24e3dd 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1236,6 +1236,7 @@ void *av_mallocz(unsigned int size); void av_free(void *ptr); void __av_freep(void **ptr); #define av_freep(p) __av_freep((void **)(p)) +void *av_fast_realloc(void *ptr, int *size, int min_size); /* for static data only */ /* call av_free_static to release all staticaly allocated tables */ void av_free_static(void); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 3e4610658c..1ac7366290 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -401,41 +401,19 @@ uint64_t time= rdtsc(); if (buf_size == 0) { return 0; } - + if(s->flags&CODEC_FLAG_TRUNCATED){ int next; - ParseContext *pc= &s->parse_context; - pc->last_index= pc->index; - if(s->codec_id==CODEC_ID_MPEG4){ next= mpeg4_find_frame_end(s, buf, buf_size); }else{ fprintf(stderr, "this codec doesnt support truncated bitstreams\n"); return -1; } - if(next==-1){ - if(buf_size + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){ - pc->buffer_size= buf_size + pc->index + 10*1024; - pc->buffer= realloc(pc->buffer, pc->buffer_size); - } - - memcpy(&pc->buffer[pc->index], buf, buf_size); - pc->index += buf_size; + + if( ff_combine_frame(s, next, &buf, &buf_size) < 0 ) return buf_size; - } - - if(pc->index){ - if(next + FF_INPUT_BUFFER_PADDING_SIZE + pc->index > pc->buffer_size){ - pc->buffer_size= next + pc->index + 10*1024; - pc->buffer= realloc(pc->buffer, pc->buffer_size); - } - - memcpy(&pc->buffer[pc->index], buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); - pc->index = 0; - buf= pc->buffer; - buf_size= pc->last_index + next; - } } retry: diff --git a/libavcodec/mem.c b/libavcodec/mem.c index 0c876a851e..e59b25a223 100644 --- a/libavcodec/mem.c +++ b/libavcodec/mem.c @@ -71,6 +71,17 @@ void *av_malloc(unsigned int size) return ptr; } +/** + * realloc which does nothing if the block is large enogh + */ +void *av_fast_realloc(void *ptr, int *size, int min_size){ + if(min_size < *size) return ptr; + + *size= min_size + 10*1024; + + return realloc(ptr, *size); +} + /* NOTE: ptr = NULL is explicetly allowed */ void av_free(void *ptr) { diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index c262191390..4d47dd4e0d 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -2627,6 +2627,35 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y) #endif } +/** + * combines the (truncated) bitstream to a complete frame + * @returns -1 if no complete frame could be created + */ +int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size){ + ParseContext *pc= &s->parse_context; + + pc->last_index= pc->index; + + if(next==-1){ + pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(&pc->buffer[pc->index], *buf, *buf_size); + pc->index += *buf_size; + return -1; + } + + if(pc->index){ + pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); + + memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); + pc->index = 0; + *buf= pc->buffer; + *buf_size= pc->last_index + next; + } + + return 0; +} + void ff_copy_bits(PutBitContext *pb, UINT8 *src, int length) { int bytes= length>>4; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 8408507071..7ecc6fd38c 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -604,6 +604,7 @@ void ff_draw_horiz_band(MpegEncContext *s); void ff_emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h, int src_x, int src_y, int w, int h); char ff_get_pict_type_char(int pict_type); +int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); extern enum PixelFormat ff_yuv420p_list[2];