Commit 7e2eb4ba authored by Alexander Strange's avatar Alexander Strange Committed by Michael Niedermayer

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: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent 2d2b5a14
...@@ -715,7 +715,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex ...@@ -715,7 +715,7 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex
copy_fields(h, h1, short_ref, cabac_init_idc); 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->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); copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT+2, s, s1);
h->last_slice_type = h1->last_slice_type; h->last_slice_type = h1->last_slice_type;
...@@ -930,6 +930,8 @@ static void decode_postinit(H264Context *h){ ...@@ -930,6 +930,8 @@ static void decode_postinit(H264Context *h){
if(out_of_order || pics > s->avctx->has_b_frames){ if(out_of_order || pics > s->avctx->has_b_frames){
out->reference &= ~DELAYED_PIC_REF; 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++) for(i=out_idx; h->delayed_pic[i]; i++)
h->delayed_pic[i] = h->delayed_pic[i+1]; h->delayed_pic[i] = h->delayed_pic[i+1];
} }
...@@ -2049,9 +2051,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ ...@@ -2049,9 +2051,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
s0->first_field = FIELD_PICTURE; s0->first_field = FIELD_PICTURE;
} }
if((!FIELD_PICTURE || s0->first_field) && ff_h264_frame_start(h) < 0) { if(!FIELD_PICTURE || s0->first_field) {
s0->first_field = 0; if (ff_h264_frame_start(h) < 0) {
return -1; s0->first_field = 0;
return -1;
}
} else {
ff_release_unused_pictures(s, 0);
} }
} }
if(h != h0) if(h != h0)
......
...@@ -316,6 +316,7 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared){ ...@@ -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; 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) 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->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; return 0;
fail: //for the FF_ALLOCZ_OR_GOTO macro fail: //for the FF_ALLOCZ_OR_GOTO macro
...@@ -946,6 +947,21 @@ void init_vlc_rl(RLTable *rl) ...@@ -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; i<s->picture_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 ff_find_unused_picture(MpegEncContext *s, int shared){
int i; int i;
...@@ -1025,12 +1041,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) ...@@ -1025,12 +1041,7 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
} }
if(!s->encoding){ if(!s->encoding){
/* release non reference frames */ ff_release_unused_pictures(s, 1);
for(i=0; i<s->picture_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]);
}
}
if(s->current_picture_ptr && s->current_picture_ptr->data[0]==NULL) 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) pic= s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header)
......
...@@ -76,6 +76,8 @@ enum OutputFormat { ...@@ -76,6 +76,8 @@ enum OutputFormat {
#define EXT_START_CODE 0x000001b5 #define EXT_START_CODE 0x000001b5
#define USER_START_CODE 0x000001b2 #define USER_START_CODE 0x000001b2
struct MpegEncContext;
/** /**
* Picture. * Picture.
*/ */
...@@ -132,10 +134,9 @@ typedef struct Picture{ ...@@ -132,10 +134,9 @@ typedef struct Picture{
uint8_t *mb_mean; ///< Table for MB luminance uint8_t *mb_mean; ///< Table for MB luminance
int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove
int b_frame_score; /* */ int b_frame_score; /* */
struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture
} Picture; } Picture;
struct MpegEncContext;
/** /**
* Motion estimation context. * Motion estimation context.
*/ */
...@@ -712,6 +713,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h); ...@@ -712,6 +713,7 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h);
void ff_mpeg_flush(AVCodecContext *avctx); void ff_mpeg_flush(AVCodecContext *avctx);
void ff_print_debug_info(MpegEncContext *s, AVFrame *pict); void ff_print_debug_info(MpegEncContext *s, AVFrame *pict);
void ff_write_quant_matrix(PutBitContext *pb, uint16_t *matrix); 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); int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src); void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment