[FFmpeg-cvslog] Merge commit 'e26c64148be8a20ace7512d96503172fb5e9753b'
Timothy Gu
git at videolan.org
Thu Aug 4 21:17:01 EEST 2016
ffmpeg | branch: master | Timothy Gu <timothygu99 at gmail.com> | Wed Aug 3 19:46:06 2016 -0700| [de625312862a99500ce7aa1703b5d783ae66d704] | committer: Timothy Gu
Merge commit 'e26c64148be8a20ace7512d96503172fb5e9753b'
* commit 'e26c64148be8a20ace7512d96503172fb5e9753b':
h264: discard slices of redundant pictures right after parsing the slice header
Conflicts:
libavcodec/h264_slice.c
libavcodec/h264dec.c
TODO: fix indentation
Merged-by: Timothy Gu <timothygu99 at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=de625312862a99500ce7aa1703b5d783ae66d704
---
libavcodec/h264_slice.c | 4 ++++
libavcodec/h264dec.c | 5 +++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index c2490cb..c6f40e5 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1738,6 +1738,10 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl,
if (ret < 0)
return ret;
+ // discard redundant pictures
+ if (sl->redundant_pic_count > 0)
+ return 0;
+
if (sl->first_mb_addr == 0 || !h->current_slice) {
if (h->setup_finished) {
av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n");
diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 9779774..c72a7fc 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -799,6 +799,9 @@ again:
if ((err = ff_h264_decode_slice_header(h, sl, nal)))
break;
+ if (sl->redundant_pic_count > 0)
+ break;
+
if (h->sei.recovery_point.recovery_frame_cnt >= 0) {
const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt;
@@ -845,7 +848,6 @@ again:
#endif
}
- if (sl->redundant_pic_count == 0) {
if (avctx->hwaccel) {
ret = avctx->hwaccel->decode_slice(avctx,
nal->raw_data,
@@ -864,7 +866,6 @@ again:
#endif
} else
context_count++;
- }
break;
case H264_NAL_DPA:
case H264_NAL_DPB:
======================================================================
diff --cc libavcodec/h264_slice.c
index c2490cb,4910396..c6f40e5
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@@ -1738,62 -1565,30 +1738,66 @@@ int ff_h264_decode_slice_header(H264Con
if (ret < 0)
return ret;
+ // discard redundant pictures
+ if (sl->redundant_pic_count > 0)
+ return 0;
+
- if (!h->setup_finished) {
- if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
- if (h->current_slice && h->cur_pic_ptr && FIELD_PICTURE(h)) {
- ff_h264_field_end(h, sl, 1);
- }
+ if (sl->first_mb_addr == 0 || !h->current_slice) {
+ if (h->setup_finished) {
+ av_log(h->avctx, AV_LOG_ERROR, "Too many fields\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
- h->current_slice = 0;
- if (!h->first_field) {
- if (h->cur_pic_ptr && !h->droppable) {
- ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
- h->picture_structure == PICT_BOTTOM_FIELD);
+ if (sl->first_mb_addr == 0) { // FIXME better field boundary detection
+ if (h->current_slice) {
+ if (h->max_contexts > 1) {
+ if (!h->single_decode_warning) {
+ av_log(h->avctx, AV_LOG_WARNING, "Cannot decode multiple access units as slice threads\n");
+ h->single_decode_warning = 1;
}
+ h->max_contexts = 1;
+ return SLICE_SINGLETHREAD;
+ }
+
+ if (h->cur_pic_ptr && FIELD_PICTURE(h) && h->first_field) {
+ ret = ff_h264_field_end(h, h->slice_ctx, 1);
+ h->current_slice = 0;
+ if (ret < 0)
+ return ret;
+ } else if (h->cur_pic_ptr && !FIELD_PICTURE(h) && !h->first_field && h->nal_unit_type == H264_NAL_IDR_SLICE) {
+ av_log(h, AV_LOG_WARNING, "Broken frame packetizing\n");
+ ret = ff_h264_field_end(h, h->slice_ctx, 1);
+ h->current_slice = 0;
+ ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 0);
+ ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX, 1);
h->cur_pic_ptr = NULL;
+ if (ret < 0)
+ return ret;
+ } else
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!h->first_field) {
+ if (h->cur_pic_ptr && !h->droppable) {
+ ff_thread_report_progress(&h->cur_pic_ptr->tf, INT_MAX,
+ h->picture_structure == PICT_BOTTOM_FIELD);
}
+ h->cur_pic_ptr = NULL;
}
+ }
- if (h->current_slice == 0) {
- ret = h264_field_start(h, sl, nal);
- if (ret < 0)
- return ret;
+ if (!h->current_slice)
+ av_assert0(sl == h->slice_ctx);
+
+ if (h->current_slice == 0 && !h->first_field) {
+ if (
+ (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) ||
+ (h->avctx->skip_frame >= AVDISCARD_BIDIR && sl->slice_type_nos == AV_PICTURE_TYPE_B) ||
+ (h->avctx->skip_frame >= AVDISCARD_NONINTRA && sl->slice_type_nos != AV_PICTURE_TYPE_I) ||
+ (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != H264_NAL_IDR_SLICE && h->sei.recovery_point.recovery_frame_cnt < 0) ||
+ h->avctx->skip_frame >= AVDISCARD_ALL) {
+ return SLICE_SKIPED;
}
}
diff --cc libavcodec/h264dec.c
index 9779774,38ecc94..c72a7fc
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@@ -799,25 -701,18 +799,28 @@@ again
if ((err = ff_h264_decode_slice_header(h, sl, nal)))
break;
+ if (sl->redundant_pic_count > 0)
+ break;
+
- if (h->sei.recovery_point.recovery_frame_cnt >= 0 && h->recovery_frame < 0) {
- h->recovery_frame = (h->poc.frame_num + h->sei.recovery_point.recovery_frame_cnt) &
- ((1 << h->ps.sps->log2_max_frame_num) - 1);
+ if (h->sei.recovery_point.recovery_frame_cnt >= 0) {
+ const int sei_recovery_frame_cnt = h->sei.recovery_point.recovery_frame_cnt;
+
+ if (h->poc.frame_num != sei_recovery_frame_cnt || sl->slice_type_nos != AV_PICTURE_TYPE_I)
+ h->valid_recovery_point = 1;
+
+ if ( h->recovery_frame < 0
+ || av_mod_uintp2(h->recovery_frame - h->poc.frame_num, h->ps.sps->log2_max_frame_num) > sei_recovery_frame_cnt) {
+ h->recovery_frame = av_mod_uintp2(h->poc.frame_num + sei_recovery_frame_cnt, h->ps.sps->log2_max_frame_num);
+
+ if (!h->valid_recovery_point)
+ h->recovery_frame = h->poc.frame_num;
+ }
}
- h->cur_pic_ptr->f->key_frame |=
- (nal->type == H264_NAL_IDR_SLICE) || (h->sei.recovery_point.recovery_frame_cnt >= 0);
+ h->cur_pic_ptr->f->key_frame |= (nal->type == H264_NAL_IDR_SLICE);
- if (nal->type == H264_NAL_IDR_SLICE || h->recovery_frame == h->poc.frame_num) {
+ if (nal->type == H264_NAL_IDR_SLICE ||
+ (h->recovery_frame == h->poc.frame_num && nal->ref_idc)) {
h->recovery_frame = -1;
h->cur_pic_ptr->recovered = 1;
}
@@@ -834,37 -725,21 +837,35 @@@
if (h->current_slice == 1) {
if (!(avctx->flags2 & AV_CODEC_FLAG2_CHUNKS))
decode_postinit(h, i >= nals_needed);
+
+ if (h->avctx->hwaccel &&
+ (ret = h->avctx->hwaccel->start_frame(h->avctx, buf, buf_size)) < 0)
+ goto end;
+#if FF_API_CAP_VDPAU
+ if (CONFIG_H264_VDPAU_DECODER &&
+ h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU)
+ ff_vdpau_h264_picture_start(h);
+#endif
}
- if (sl->redundant_pic_count == 0) {
- if ((avctx->skip_frame < AVDISCARD_NONREF || nal->ref_idc) &&
- (avctx->skip_frame < AVDISCARD_BIDIR ||
- sl->slice_type_nos != AV_PICTURE_TYPE_B) &&
- (avctx->skip_frame < AVDISCARD_NONKEY ||
- h->cur_pic_ptr->f->key_frame) &&
- avctx->skip_frame < AVDISCARD_ALL) {
if (avctx->hwaccel) {
- ret = avctx->hwaccel->decode_slice(avctx, nal->raw_data, nal->raw_size);
+ ret = avctx->hwaccel->decode_slice(avctx,
+ nal->raw_data,
+ nal->raw_size);
if (ret < 0)
- return ret;
+ goto end;
+#if FF_API_CAP_VDPAU
+ } else if (CONFIG_H264_VDPAU_DECODER &&
+ h->avctx->codec->capabilities & AV_CODEC_CAP_HWACCEL_VDPAU) {
+ ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0],
+ start_code,
+ sizeof(start_code));
+ ff_vdpau_add_data_chunk(h->cur_pic_ptr->f->data[0],
+ nal->raw_data,
+ nal->raw_size);
+#endif
} else
context_count++;
-- }
break;
case H264_NAL_DPA:
case H264_NAL_DPB:
More information about the ffmpeg-cvslog
mailing list