summaryrefslogtreecommitdiff
path: root/libavcodec/h264.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-11-01 11:33:36 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-11-01 12:59:08 +0100
commit78265fcfeee153e5e26ad4dbc7831a84ade447d6 (patch)
tree92bc81fca00966f3c867baa7dd339eb5c62730c4 /libavcodec/h264.c
parent2acc525d786f0ee4b0a354858a5f146ce6580658 (diff)
parent28096e0a806e57376541e6222d315619906e3c55 (diff)
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.c61
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;