From 7eae8cd87054713cbef51b22b93f3a0eb5036c90 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 7 Jun 2014 20:56:20 +0200 Subject: [PATCH] avcodec/h264: fix frame skip code Fixes Ticket3475 Signed-off-by: Michael Niedermayer --- libavcodec/h264.c | 16 +++++----------- libavcodec/h264.h | 2 ++ libavcodec/h264_slice.c | 9 +++++++++ 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 49e512de87..a266718ead 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1617,14 +1617,7 @@ again: ff_vdpau_h264_picture_start(h); } - if (hx->redundant_pic_count == 0 && - (avctx->skip_frame < AVDISCARD_NONREF || - hx->nal_ref_idc) && - (avctx->skip_frame < AVDISCARD_BIDIR || - hx->slice_type_nos != AV_PICTURE_TYPE_B) && - (avctx->skip_frame < AVDISCARD_NONINTRA || - hx->slice_type_nos == AV_PICTURE_TYPE_I) && - avctx->skip_frame < AVDISCARD_ALL) { + if (hx->redundant_pic_count == 0) { if (avctx->hwaccel) { ret = avctx->hwaccel->decode_slice(avctx, &buf[buf_index - consumed], @@ -1655,7 +1648,7 @@ again: hx->intra_gb_ptr = hx->inter_gb_ptr = NULL; - if ((err = ff_h264_decode_slice_header(hx, h)) < 0) { + if ((err = ff_h264_decode_slice_header(hx, h))) { /* make sure data_partitioning is cleared if it was set * before, so we don't try decoding a slice without a valid * slice header later */ @@ -1730,8 +1723,9 @@ again: context_count = 0; } - if (err < 0) { - av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); + if (err < 0 || err == SLICE_SKIPED) { + if (err < 0) + av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); h->ref_count[0] = h->ref_count[1] = h->list_count = 0; } else if (err == 1) { /* Slice could not be decoded in parallel mode, copy down diff --git a/libavcodec/h264.h b/libavcodec/h264.h index c057c9709d..da7424168a 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -1098,6 +1098,8 @@ int ff_pred_weight_table(H264Context *h); int ff_set_ref_count(H264Context *h); int ff_h264_decode_slice_header(H264Context *h, H264Context *h0); +#define SLICE_SKIPED 2 + int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count); int ff_h264_update_thread_context(AVCodecContext *dst, const AVCodecContext *src); diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 51120531df..13b1da7abc 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1321,6 +1321,15 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) return AVERROR_INVALIDDATA; } + if ( + (h->avctx->skip_frame >= AVDISCARD_NONREF && !h->nal_ref_idc) || + (h->avctx->skip_frame >= AVDISCARD_BIDIR && h->slice_type_nos == AV_PICTURE_TYPE_B) || + (h->avctx->skip_frame >= AVDISCARD_NONINTRA && h->slice_type_nos != AV_PICTURE_TYPE_I) || + (h->avctx->skip_frame >= AVDISCARD_NONKEY && h->nal_unit_type != NAL_IDR_SLICE) || + h->avctx->skip_frame >= AVDISCARD_ALL) { + return SLICE_SKIPED; + } + // to make a few old functions happy, it's wrong though h->pict_type = h->slice_type;