[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