diff mbox series

[FFmpeg-devel,07/13] avcodec/hevcdec: export LCEVC metadata as frame side data

Message ID 20240831163114.4197-7-jamrial@gmail.com
State New
Headers show
Series [FFmpeg-devel,01/13,v3] avutil/frame: add an LCEVC enhancement data payload side data type | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

James Almer Aug. 31, 2024, 4:31 p.m. UTC
Signed-off-by: James Almer <jamrial@gmail.com>
---
 configure                 |  1 +
 libavcodec/hevc/hevcdec.c |  3 +++
 libavcodec/hevc/refs.c    | 15 ++++++++++++++-
 3 files changed, 18 insertions(+), 1 deletion(-)

Comments

Derek Buitenhuis Sept. 2, 2024, noon UTC | #1
On 8/31/2024 5:31 PM, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  configure                 |  1 +
>  libavcodec/hevc/hevcdec.c |  3 +++
>  libavcodec/hevc/refs.c    | 15 ++++++++++++++-
>  3 files changed, 18 insertions(+), 1 deletion(-)

Maybe I've misunderstood, but doesn't requiring every possible base layer
codec to explicitly support exporting LCEVC kind of defeat the point of
a 'generic' enhancement layer codec like LCEVC?

- Derek
James Almer Sept. 2, 2024, 4:40 p.m. UTC | #2
On 9/2/2024 9:00 AM, Derek Buitenhuis wrote:
> On 8/31/2024 5:31 PM, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>   configure                 |  1 +
>>   libavcodec/hevc/hevcdec.c |  3 +++
>>   libavcodec/hevc/refs.c    | 15 ++++++++++++++-
>>   3 files changed, 18 insertions(+), 1 deletion(-)
> 
> Maybe I've misunderstood, but doesn't requiring every possible base layer
> codec to explicitly support exporting LCEVC kind of defeat the point of
> a 'generic' enhancement layer codec like LCEVC?
We don't require that. Those codecs that have it embedded in the 
bitstream do it, like hevc here. Those who don't will require the caller 
to insert the lcevc payload (which most likely came from the container) 
into the base layer packets as side data, which decode.c will make sure 
makes it to the frame for decoding.
The last patch in this set makes ffmpeg.c (the aforementioned caller) do 
exactly that for split variants (exported by mov/mp4 for now).
diff mbox series

Patch

diff --git a/configure b/configure
index 84f63bbb87..3b7cf05bb5 100755
--- a/configure
+++ b/configure
@@ -2975,6 +2975,7 @@  hap_decoder_select="snappy texturedsp"
 hap_encoder_deps="libsnappy"
 hap_encoder_select="texturedspenc"
 hevc_decoder_select="bswapdsp cabac dovi_rpudec golomb hevcparse hevc_sei videodsp"
+hevc_decoder_suggest="liblcevc_dec"
 huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
 huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
 hymt_decoder_select="huffyuv_decoder"
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 4077ed3ac5..41bb7fdfe1 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -3459,6 +3459,9 @@  do_output:
     if (ff_container_fifo_read(s->output_fifo, frame) >= 0) {
         if (!(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN))
             av_frame_remove_side_data(frame, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
+        if (!CONFIG_LIBLCEVC_DEC &&
+            !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS))
+            av_frame_remove_side_data(frame, AV_FRAME_DATA_LCEVC);
 
         return 0;
     }
diff --git a/libavcodec/hevc/refs.c b/libavcodec/hevc/refs.c
index 65abd09a21..88c5c5ea52 100644
--- a/libavcodec/hevc/refs.c
+++ b/libavcodec/hevc/refs.c
@@ -83,10 +83,23 @@  static HEVCFrame *alloc_frame(HEVCContext *s)
         if (frame->f)
             continue;
 
+        ret = ff_progress_frame_alloc(s->avctx, &frame->tf);
+        if (ret < 0)
+            return NULL;
+
+        if (CONFIG_LIBLCEVC_DEC && s->sei.common.lcevc.info && !s->avctx->hwaccel &&
+            !(s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_ENHANCEMENTS)) {
+            HEVCSEILCEVC *lcevc = &s->sei.common.lcevc;
+            ret = ff_frame_new_side_data_from_buf(s->avctx, frame->tf.f,
+                                                  AV_FRAME_DATA_LCEVC, &lcevc->info);
+            if (ret < 0)
+                goto fail;
+        }
+
         ret = ff_progress_frame_get_buffer(s->avctx, &frame->tf,
                                            AV_GET_BUFFER_FLAG_REF);
         if (ret < 0)
-            return NULL;
+            goto fail;
 
         frame->rpl = ff_refstruct_allocz(s->pkt.nb_nals * sizeof(*frame->rpl));
         if (!frame->rpl)