diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-11-01 11:33:36 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-11-01 12:59:08 +0100 |
commit | 78265fcfeee153e5e26ad4dbc7831a84ade447d6 (patch) | |
tree | 92bc81fca00966f3c867baa7dd339eb5c62730c4 /libavcodec/h264.c | |
parent | 2acc525d786f0ee4b0a354858a5f146ce6580658 (diff) | |
parent | 28096e0a806e57376541e6222d315619906e3c55 (diff) | |
download | ffmpeg-78265fcfeee153e5e26ad4dbc7831a84ade447d6.tar.gz |
Merge commit '28096e0a806e57376541e6222d315619906e3c55'
* commit '28096e0a806e57376541e6222d315619906e3c55':
h264: wait for initial complete frame before outputing frames
Conflicts:
doc/APIchanges
libavcodec/h264.c
libavcodec/mpegvideo.h
libavutil/frame.h
libavutil/version.h
See: a64b028aeb6579636e578ceb73f69b468bddb2f0 (as well as various later commits)
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/h264.c')
-rw-r--r-- | libavcodec/h264.c | 61 |
1 files changed, 43 insertions, 18 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index cd6fff8d78..e317319d72 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -361,10 +361,10 @@ static int ref_picture(H264Context *h, Picture *dst, Picture *src) dst->field_picture = src->field_picture; dst->needs_realloc = src->needs_realloc; dst->reference = src->reference; - dst->sync = src->sync; dst->crop = src->crop; dst->crop_left = src->crop_left; dst->crop_top = src->crop_top; + dst->recovered = src->recovered; return 0; fail: @@ -1902,7 +1902,7 @@ static int decode_update_thread_context(AVCodecContext *dst, copy_picture_range(h->delayed_pic, h1->delayed_pic, MAX_DELAYED_PIC_COUNT + 2, h, h1); - h->sync = h1->sync; + h->frame_recovered = h1->frame_recovered; if (context_reinitialized) h264_set_parameter_from_sps(h); @@ -1919,6 +1919,8 @@ static int decode_update_thread_context(AVCodecContext *dst, h->prev_frame_num = h->frame_num; h->outputed_poc = h->next_outputed_poc; + h->recovery_frame = h1->recovery_frame; + return err; } @@ -1959,12 +1961,12 @@ static int h264_frame_start(H264Context *h) * See decode_nal_units(). */ pic->f.key_frame = 0; - pic->sync = 0; pic->mmco_reset = 0; + pic->recovered = 0; if ((ret = alloc_picture(h, pic)) < 0) return ret; - if(!h->sync && !h->avctx->hwaccel && + if(!h->frame_recovered && !h->avctx->hwaccel && !(h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU)) avpriv_color_frame(&pic->f, c); @@ -2189,8 +2191,15 @@ static void decode_postinit(H264Context *h, int setup_finished) av_log(h->avctx, AV_LOG_DEBUG, "no picture %s\n", out_of_order ? "ooo" : ""); } - if (h->next_output_pic && h->next_output_pic->sync) { - h->sync |= 2; + if (h->next_output_pic) { + if (h->next_output_pic->recovered) { + // We have reached an recovery point and all frames after it in + // display order are "recovered". + h->frame_recovered |= FRAME_RECOVERED_SEI; + } +#if 0 + h->next_output_pic->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_SEI); +#endif } if (setup_finished && !h->avctx->hwaccel) @@ -2781,8 +2790,8 @@ static void flush_change(H264Context *h) memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0])); memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1])); ff_h264_reset_sei(h); - h->recovery_frame= -1; - h->sync= 0; + h->recovery_frame = -1; + h->frame_recovered = 0; h->list_count = 0; h->current_slice = 0; h->mmco_reset = 1; @@ -4844,8 +4853,8 @@ again: if ( h->sei_recovery_frame_cnt >= 0 && ( h->recovery_frame<0 || ((h->recovery_frame - h->frame_num) & ((1 << h->sps.log2_max_frame_num)-1)) > h->sei_recovery_frame_cnt)) { - h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) % - (1 << h->sps.log2_max_frame_num); + h->recovery_frame = (h->frame_num + h->sei_recovery_frame_cnt) & + ((1 << h->sps.log2_max_frame_num) - 1); if (!h->valid_recovery_point) h->recovery_frame = h->frame_num; @@ -4854,14 +4863,22 @@ again: h->cur_pic_ptr->f.key_frame |= (hx->nal_unit_type == NAL_IDR_SLICE); - if (h->recovery_frame == h->frame_num) { - h->cur_pic_ptr->sync |= 1; - h->recovery_frame = -1; + if (hx->nal_unit_type == NAL_IDR_SLICE || + h->recovery_frame == h->frame_num) { + h->recovery_frame = -1; + h->cur_pic_ptr->recovered = 1; } - - h->sync |= !!h->cur_pic_ptr->f.key_frame; - h->sync |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL); - h->cur_pic_ptr->sync |= h->sync; + // If we have an IDR, all frames after it in decoded order are + // "recovered". + if (hx->nal_unit_type == NAL_IDR_SLICE) + h->frame_recovered |= FRAME_RECOVERED_IDR; + h->frame_recovered |= 3*!!(avctx->flags2 & CODEC_FLAG2_SHOW_ALL); + h->frame_recovered |= 3*!!(avctx->flags & CODEC_FLAG_OUTPUT_CORRUPT); +#if 1 + h->cur_pic_ptr->recovered |= h->frame_recovered; +#else + h->cur_pic_ptr->recovered |= !!(h->frame_recovered & FRAME_RECOVERED_IDR); +#endif if (h->current_slice == 1) { if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS)) @@ -5135,7 +5152,15 @@ not_extra: /* Wait for second field. */ *got_frame = 0; - if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { +#if 1 + if (h->next_output_pic && (h->next_output_pic->recovered || h->frame_recovered>1)) { +#else + if (h->next_output_pic && ( + h->next_output_pic->recovered)) { +#endif + if (!h->next_output_pic->recovered) + h->next_output_pic->f.flags |= AV_FRAME_FLAG_CORRUPT; + ret = output_frame(h, pict, h->next_output_pic); if (ret < 0) return ret; |