[FFmpeg-cvslog] lavc/hevcdec: factor decoding a slice NALU out of decode_nal_unit()

Anton Khirnov git at videolan.org
Tue Jun 11 18:51:37 EEST 2024


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Jun  3 11:41:23 2024 +0200| [edb6a471c4b3b96845c84772393b74f52e970f45] | committer: Anton Khirnov

lavc/hevcdec: factor decoding a slice NALU out of decode_nal_unit()

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=edb6a471c4b3b96845c84772393b74f52e970f45
---

 libavcodec/hevc/hevcdec.c | 97 +++++++++++++++++++++++++----------------------
 1 file changed, 52 insertions(+), 45 deletions(-)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index b9aea45edb..7263b80a24 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -3065,10 +3065,60 @@ static int hevc_frame_end(HEVCContext *s)
     return 0;
 }
 
+static int decode_slice(HEVCContext *s, const H2645NAL *nal, GetBitContext *gb)
+{
+    int ret;
+
+    ret = hls_slice_header(&s->sh, s, gb);
+    if (ret < 0)
+        return ret;
+
+    if ((s->avctx->skip_frame >= AVDISCARD_BIDIR && s->sh.slice_type == HEVC_SLICE_B) ||
+        (s->avctx->skip_frame >= AVDISCARD_NONINTRA && s->sh.slice_type != HEVC_SLICE_I) ||
+        (s->avctx->skip_frame >= AVDISCARD_NONKEY && !IS_IRAP(s)) ||
+        ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) &&
+         s->no_rasl_output_flag)) {
+        return 0;
+    }
+
+    if (s->sh.first_slice_in_pic_flag) {
+        if (s->cur_frame) {
+            av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
+            return AVERROR_INVALIDDATA;
+        }
+
+        ret = hevc_frame_start(s);
+        if (ret < 0)
+            return ret;
+    } else if (!s->cur_frame) {
+        av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    if (s->nal_unit_type != s->first_nal_type) {
+        av_log(s->avctx, AV_LOG_ERROR,
+               "Non-matching NAL types of the VCL NALUs: %d %d\n",
+               s->first_nal_type, s->nal_unit_type);
+        return AVERROR_INVALIDDATA;
+    }
+
+    ret = decode_slice_data(s, nal, gb);
+    if (ret < 0)
+        return ret;
+    if (ret >= s->cur_frame->ctb_count) {
+        ret = hevc_frame_end(s);
+        if (ret < 0)
+            return ret;
+        s->is_decoded = 1;
+    }
+
+    return 0;
+}
+
 static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
 {
     GetBitContext     gb = nal->gb;
-    int ctb_addr_ts, ret;
+    int ret;
 
     s->nal_unit_type = nal->type;
     s->temporal_id   = nal->temporal_id;
@@ -3124,52 +3174,9 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
     case HEVC_NAL_RADL_R:
     case HEVC_NAL_RASL_N:
     case HEVC_NAL_RASL_R:
-        ret = hls_slice_header(&s->sh, s, &gb);
+        ret = decode_slice(s, nal, &gb);
         if (ret < 0)
-            return ret;
-
-        if ((s->avctx->skip_frame >= AVDISCARD_BIDIR && s->sh.slice_type == HEVC_SLICE_B) ||
-            (s->avctx->skip_frame >= AVDISCARD_NONINTRA && s->sh.slice_type != HEVC_SLICE_I) ||
-            (s->avctx->skip_frame >= AVDISCARD_NONKEY && !IS_IRAP(s)) ||
-            ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) &&
-             s->no_rasl_output_flag)) {
-            break;
-        }
-
-        if (s->sh.first_slice_in_pic_flag) {
-            if (s->cur_frame) {
-                av_log(s->avctx, AV_LOG_ERROR, "Two slices reporting being the first in the same frame.\n");
-                ret = AVERROR_INVALIDDATA;
-                goto fail;
-            }
-
-            ret = hevc_frame_start(s);
-            if (ret < 0)
-                return ret;
-        } else if (!s->cur_frame) {
-            av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
             goto fail;
-        }
-
-        if (s->nal_unit_type != s->first_nal_type) {
-            av_log(s->avctx, AV_LOG_ERROR,
-                   "Non-matching NAL types of the VCL NALUs: %d %d\n",
-                   s->first_nal_type, s->nal_unit_type);
-            return AVERROR_INVALIDDATA;
-        }
-
-        ctb_addr_ts = decode_slice_data(s, nal, &gb);
-        if (ctb_addr_ts >= s->cur_frame->ctb_count) {
-            ret = hevc_frame_end(s);
-            if (ret < 0)
-                goto fail;
-            s->is_decoded = 1;
-        }
-
-        if (ctb_addr_ts < 0) {
-            ret = ctb_addr_ts;
-            goto fail;
-        }
         break;
     case HEVC_NAL_EOS_NUT:
     case HEVC_NAL_EOB_NUT:



More information about the ffmpeg-cvslog mailing list