[FFmpeg-devel] [PATCH 4/4] avcodec/h264: fix frame skip code

Michael Niedermayer michaelni at gmx.at
Sat Jun 7 20:56:20 CEST 2014


Fixes Ticket3475

Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
 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 49e512d..a266718 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 c057c97..da74241 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 5112053..13b1da7 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;
 
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list