[FFmpeg-devel] [PATCH 21/39] lavc/hevcdec: output RASL frames based on the value of no_rasl_output_flag

Anton Khirnov anton at khirnov.net
Fri Jun 7 16:01:17 EEST 2024


Instead of an ad-hoc scheme. Also, combine skipping RASL frames with
skip_frame handling - current code seems flawed as it only executes for
the first slice of a RASL frame and unnecessarily unsets is_decoded,
which should not be set at this point anyway..

Some RASL frames in fate-hevc-afd-tc-sei that were previously discarded
are now output.
---
 libavcodec/hevc/hevcdec.c      | 33 ++++---------------------------
 libavcodec/hevc/hevcdec.h      |  1 -
 tests/ref/fate/hevc-afd-tc-sei | 36 ++++++++++++++++++++++++++++++++++
 3 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index d444ea93f7..a57fa4e539 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -605,7 +605,6 @@ static int hls_slice_header(HEVCContext *s, GetBitContext *gb)
 
     if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) {
         s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
-        s->max_ra     = INT_MAX;
         if (IS_IDR(s))
             ff_hevc_clear_refs(s);
     }
@@ -645,7 +644,6 @@ static int hls_slice_header(HEVCContext *s, GetBitContext *gb)
         s->avctx->pix_fmt = pix_fmt;
 
         s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
-        s->max_ra     = INT_MAX;
     }
 
     sh->dependent_slice_segment_flag = 0;
@@ -3106,32 +3104,15 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
         }
 
 
-        if (
-            (s->avctx->skip_frame >= AVDISCARD_BIDIR && s->sh.slice_type == HEVC_SLICE_B) ||
+        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->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->max_ra == INT_MAX) {
-                if (s->nal_unit_type == HEVC_NAL_CRA_NUT || IS_BLA(s)) {
-                    s->max_ra = s->poc;
-                } else {
-                    if (IS_IDR(s))
-                        s->max_ra = INT_MIN;
-                }
-            }
-
-            if ((s->nal_unit_type == HEVC_NAL_RASL_R || s->nal_unit_type == HEVC_NAL_RASL_N) &&
-                s->poc <= s->max_ra) {
-                s->is_decoded = 0;
-                break;
-            } else {
-                if (s->nal_unit_type == HEVC_NAL_RASL_R && s->poc > s->max_ra)
-                    s->max_ra = INT_MIN;
-            }
-
             s->overlap ++;
             ret = hevc_frame_start(s);
             if (ret < 0)
@@ -3196,7 +3177,6 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal)
     case HEVC_NAL_EOS_NUT:
     case HEVC_NAL_EOB_NUT:
         s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
-        s->max_ra     = INT_MAX;
         break;
     case HEVC_NAL_AUD:
     case HEVC_NAL_FD_NUT:
@@ -3572,8 +3552,6 @@ static av_cold int hevc_init_context(AVCodecContext *avctx)
             return AVERROR(ENOMEM);
     }
 
-    s->max_ra = INT_MAX;
-
     s->md5_ctx = av_md5_alloc();
     if (!s->md5_ctx)
         return AVERROR(ENOMEM);
@@ -3626,7 +3604,6 @@ static int hevc_update_thread_context(AVCodecContext *dst,
     s->seq_decode = s0->seq_decode;
     s->seq_output = s0->seq_output;
     s->poc_tid0   = s0->poc_tid0;
-    s->max_ra     = s0->max_ra;
     s->eos        = s0->eos;
     s->no_rasl_output_flag = s0->no_rasl_output_flag;
 
@@ -3640,7 +3617,6 @@ static int hevc_update_thread_context(AVCodecContext *dst,
 
     if (s0->eos) {
         s->seq_decode = (s->seq_decode + 1) & HEVC_SEQUENCE_COUNTER_MASK;
-        s->max_ra = INT_MAX;
     }
 
     ret = ff_h2645_sei_ctx_replace(&s->sei.common, &s0->sei.common);
@@ -3734,7 +3710,6 @@ static void hevc_decode_flush(AVCodecContext *avctx)
     ff_hevc_reset_sei(&s->sei);
     ff_dovi_ctx_flush(&s->dovi_ctx);
     av_buffer_unref(&s->rpu_buf);
-    s->max_ra = INT_MAX;
     s->eos = 1;
 
     if (FF_HW_HAS_CB(avctx, flush))
diff --git a/libavcodec/hevc/hevcdec.h b/libavcodec/hevc/hevcdec.h
index fa7caf9cf7..04eacca76d 100644
--- a/libavcodec/hevc/hevcdec.h
+++ b/libavcodec/hevc/hevcdec.h
@@ -487,7 +487,6 @@ typedef struct HEVCContext {
     int slice_idx; ///< number of the slice being currently decoded
     int eos;       ///< current packet contains an EOS/EOB NAL
     int last_eos;  ///< last packet contains an EOS/EOB NAL
-    int max_ra;
     int bs_width;
     int bs_height;
     int overlap;
diff --git a/tests/ref/fate/hevc-afd-tc-sei b/tests/ref/fate/hevc-afd-tc-sei
index 27eb3fc8d7..735226745b 100644
--- a/tests/ref/fate/hevc-afd-tc-sei
+++ b/tests/ref/fate/hevc-afd-tc-sei
@@ -202,3 +202,39 @@ value=00:00:00:00
 [/TIMECODE]
 [/SIDE_DATA]
 [/FRAME]
+[FRAME]
+[SIDE_DATA]
+side_data_type=Active format description
+active_format=8
+[/SIDE_DATA]
+[SIDE_DATA]
+side_data_type=SMPTE 12-1 timecode
+[TIMECODE]
+value=00:00:00:00
+[/TIMECODE]
+[/SIDE_DATA]
+[/FRAME]
+[FRAME]
+[SIDE_DATA]
+side_data_type=Active format description
+active_format=8
+[/SIDE_DATA]
+[SIDE_DATA]
+side_data_type=SMPTE 12-1 timecode
+[TIMECODE]
+value=00:00:00:00
+[/TIMECODE]
+[/SIDE_DATA]
+[/FRAME]
+[FRAME]
+[SIDE_DATA]
+side_data_type=Active format description
+active_format=8
+[/SIDE_DATA]
+[SIDE_DATA]
+side_data_type=SMPTE 12-1 timecode
+[TIMECODE]
+value=00:00:00:00
+[/TIMECODE]
+[/SIDE_DATA]
+[/FRAME]
-- 
2.43.0



More information about the ffmpeg-devel mailing list