diff mbox series

[FFmpeg-devel,8/9] avcodec/dovi_rpu: add ff_dovi_get_metadata()

Message ID 20240624172044.101722-8-ffmpeg@haasn.xyz
State New
Headers show
Series [FFmpeg-devel,1/9] avcodec/dovi_rpudec: clarify semantics | 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

Niklas Haas June 24, 2024, 5:20 p.m. UTC
From: Niklas Haas <git@haasn.dev>

Provides direct access to the AVDOVIMetadata without having to attach it
to a frame.
---
 libavcodec/dovi_rpu.h    |  9 +++++++++
 libavcodec/dovi_rpudec.c | 40 +++++++++++++++++++++++++++-------------
 2 files changed, 36 insertions(+), 13 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index f0d9c24379..10d5c7f566 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -108,8 +108,17 @@  void ff_dovi_ctx_flush(DOVIContext *s);
 int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
                       int err_recognition);
 
+/**
+ * Get the decoded AVDOVIMetadata. Ownership passes to the caller.
+ *
+ * Returns the size of *out_metadata, a negative error code, or 0 if no
+ * metadata is available to return.
+ */
+int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata);
+
 /**
  * Attach the decoded AVDOVIMetadata as side data to an AVFrame.
+ * Returns 0 or a negative error code.
  */
 int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame);
 
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 375e6e560b..e8c25e9f3b 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -30,10 +30,8 @@ 
 #include "get_bits.h"
 #include "refstruct.h"
 
-int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
+int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata)
 {
-    AVFrameSideData *sd;
-    AVBufferRef *buf;
     AVDOVIMetadata *dovi;
     size_t dovi_size, ext_sz;
 
@@ -44,7 +42,32 @@  int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
     if (!dovi)
         return AVERROR(ENOMEM);
 
-    buf = av_buffer_create((uint8_t *) dovi, dovi_size, NULL, NULL, 0);
+    /* Copy only the parts of these structs known to us at compiler-time. */
+#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
+    COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7);
+    COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots);
+    COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal);
+    ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size);
+    for (int i = 0; i < s->num_ext_blocks; i++)
+        memcpy(av_dovi_get_ext(dovi, i), &s->ext_blocks[i], ext_sz);
+    dovi->num_ext_blocks = s->num_ext_blocks;
+
+    *out_metadata = dovi;
+    return dovi_size;
+}
+
+int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
+{
+    AVFrameSideData *sd;
+    AVDOVIMetadata *dovi;
+    AVBufferRef *buf;
+    int size;
+
+    size = ff_dovi_get_metadata(s, &dovi);
+    if (size <= 0)
+        return size;
+
+    buf = av_buffer_create((uint8_t *) dovi, size, NULL, NULL, 0);
     if (!buf) {
         av_free(dovi);
         return AVERROR(ENOMEM);
@@ -56,15 +79,6 @@  int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
         return AVERROR(ENOMEM);
     }
 
-    /* Copy only the parts of these structs known to us at compiler-time. */
-#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
-    COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), &s->header, ext_mapping_idc_5_7);
-    COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots);
-    COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, source_diagonal);
-    ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size);
-    for (int i = 0; i < s->num_ext_blocks; i++)
-        memcpy(av_dovi_get_ext(dovi, i), &s->ext_blocks[i], ext_sz);
-    dovi->num_ext_blocks = s->num_ext_blocks;
     return 0;
 }