diff options
author | Anton Khirnov <anton@khirnov.net> | 2016-05-20 12:30:42 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2016-06-21 11:20:26 +0200 |
commit | e26c64148be8a20ace7512d96503172fb5e9753b (patch) | |
tree | 57cfa88685fd2b448e462ba42ee515810e9c0f8e | |
parent | 6efc4638584e1e14d1a6152186ba28f5d48a80c0 (diff) | |
download | ffmpeg-e26c64148be8a20ace7512d96503172fb5e9753b.tar.gz |
h264: discard slices of redundant pictures right after parsing the slice header
Going through the whole decoder initialization process for a slice we
are not going to decode is unnecessary and potentially dangerous.
-rw-r--r-- | libavcodec/h264_slice.c | 4 | ||||
-rw-r--r-- | libavcodec/h264dec.c | 6 |
2 files changed, 8 insertions, 2 deletions
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index dbff1f3f8b..491039626e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1565,6 +1565,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 (!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)) { diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index b98d1416c1..38ecc9477f 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -701,6 +701,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) 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); @@ -724,8 +727,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) decode_postinit(h, i >= nals_needed); } - if (sl->redundant_pic_count == 0 && - (avctx->skip_frame < AVDISCARD_NONREF || nal->ref_idc) && + 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 || |