From 7e2eb4bacd70541702bd086ab2a39cb7653d314e Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Mon, 18 Apr 2011 00:47:35 +0200 Subject: [PATCH] Merge remote-tracking branch 'ffmpeg-mt/master' * ffmpeg-mt/master: Release unused pictures even when not calling ff_h264_frame_start() h264: Fix decoding race condition with PAFF h264: cosmetic whitespace change Duplicate Fix REBASE_PICTURE with h.264 Not pulled Update test scripts to use ffmpeg instead of ffmpeg_g Duplicate Fix ffmpeg-mt fixme in h264 Signed-off-by: Michael Niedermayer --- libavcodec/h264.c | 14 ++++++++++---- libavcodec/mpegvideo.c | 23 +++++++++++++++++------ libavcodec/mpegvideo.h | 6 ++++-- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 48a2455b22..c64e6fb3f9 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -715,7 +715,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex copy_fields(h, h1, short_ref, cabac_init_idc); copy_picture_range(h->short_ref, h1->short_ref, 32, s, s1); - copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1); + copy_picture_range(h->long_ref, h1->long_ref, 32, s, s1); copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT+2, s, s1); h->last_slice_type = h1->last_slice_type; @@ -930,6 +930,8 @@ static void decode_postinit(H264Context *h){ if(out_of_order || pics > s->avctx->has_b_frames){ out->reference &= ~DELAYED_PIC_REF; + out->owner2 = s; // for frame threading, the owner must be the second field's thread + // or else the first thread can release the picture and reuse it unsafely for(i=out_idx; h->delayed_pic[i]; i++) h->delayed_pic[i] = h->delayed_pic[i+1]; } @@ -2049,9 +2051,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s0->first_field = FIELD_PICTURE; } - if((!FIELD_PICTURE || s0->first_field) && ff_h264_frame_start(h) < 0) { - s0->first_field = 0; - return -1; + if(!FIELD_PICTURE || s0->first_field) { + if (ff_h264_frame_start(h) < 0) { + s0->first_field = 0; + return -1; + } + } else { + ff_release_unused_pictures(s, 0); } } if(h != h0) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 676c3ebe8a..819f58dc95 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -316,6 +316,7 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){ s->prev_pict_types[0]= s->dropable ? FF_B_TYPE : s->pict_type; if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == FF_B_TYPE) pic->age= INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway. + pic->owner2 = s; return 0; fail: //for the FF_ALLOCZ_OR_GOTO macro @@ -946,6 +947,21 @@ void init_vlc_rl(RLTable *rl) } } +void ff_release_unused_pictures(MpegEncContext *s, int remove_current) +{ + int i; + + /* release non reference frames */ + for(i=0; ipicture_count; i++){ + if(s->picture[i].data[0] && !s->picture[i].reference + && s->picture[i].owner2 == s + && (remove_current || &s->picture[i] != s->current_picture_ptr) + /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ + free_frame_buffer(s, &s->picture[i]); + } + } +} + int ff_find_unused_picture(MpegEncContext *s, int shared){ int i; @@ -1025,12 +1041,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) } if(!s->encoding){ - /* release non reference frames */ - for(i=0; ipicture_count; i++){ - if(s->picture[i].data[0] && !s->picture[i].reference /*&& s->picture[i].type!=FF_BUFFER_TYPE_SHARED*/){ - free_frame_buffer(s, &s->picture[i]); - } - } + ff_release_unused_pictures(s, 1); if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL) pic= s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header) diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index fee75b248d..3836a6ef38 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -76,6 +76,8 @@ enum OutputFormat { #define EXT_START_CODE 0x000001b5 #define USER_START_CODE 0x000001b2 +struct MpegEncContext; + /** * Picture. */ @@ -132,10 +134,9 @@ typedef struct Picture{ uint8_t *mb_mean; ///< Table for MB luminance int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove int b_frame_score; /* */ + struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture } Picture; -struct MpegEncContext; - /** * Motion estimation context. */ @@ -712,6 +713,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h); void ff_mpeg_flush(AVCodecContext *avctx); void ff_print_debug_info(MpegEncContext *s, AVFrame *pict); void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix); +void ff_release_unused_pictures(MpegEncContext *s, int remove_current); int ff_find_unused_picture(MpegEncContext *s, int shared); void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);