shithub: dav1d

Download patch

ref: 9a9c0c7e78c3c277ebf5f8d10bef9bc81604c7a9
parent: 857232e44513ba2cbbb352a0f68d440c0ecd673e
author: James Almer <jamrial@gmail.com>
date: Tue Aug 6 10:59:40 EDT 2019

Export frame ITU-T T.35 Metadata

Based on a patch by Renato Cassaca.

--- a/include/dav1d/headers.h
+++ b/include/dav1d/headers.h
@@ -28,6 +28,8 @@
 #ifndef DAV1D_HEADERS_H
 #define DAV1D_HEADERS_H
 
+#include <stddef.h>
+
 // Constants from Section 3. "Symbols and abbreviated terms"
 #define DAV1D_MAX_CDEF_STRENGTHS 8
 #define DAV1D_MAX_OPERATING_POINTS 32
@@ -175,6 +177,13 @@
     ///< 18.14 fixed point
     uint32_t min_luminance;
 } Dav1dMasteringDisplay;
+
+typedef struct Dav1dITUTT35 {
+    uint8_t  country_code;
+    uint8_t  country_code_extension_byte;
+    size_t   payload_size;
+    uint8_t *payload;
+} Dav1dITUTT35;
 
 typedef struct Dav1dSequenceHeader {
     /**
--- a/include/dav1d/picture.h
+++ b/include/dav1d/picture.h
@@ -77,9 +77,16 @@
      * this picture, as defined in section 5.8.4 and 6.7.4
      */
     Dav1dMasteringDisplay *mastering_display;
+    /**
+     * ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
+     */
+    Dav1dITUTT35 *itut_t35;
 
+    uintptr_t reserved[4]; ///< reserved for future use
+
     struct Dav1dRef *frame_hdr_ref, *seq_hdr_ref; ///< Frame parameter allocation origins
-    struct Dav1dRef *content_light_ref, *mastering_display_ref; ///< Metadata allocation origins
+    struct Dav1dRef *content_light_ref, *mastering_display_ref, *itut_t35_ref; ///< Metadata allocation origins
+    uintptr_t reserved_ref[4]; ///< reserved for future use
     struct Dav1dRef *ref; ///< Frame data allocation origin
 
     void *allocator_data; ///< pointer managed by the allocator
--- a/meson.build
+++ b/meson.build
@@ -30,7 +30,7 @@
                       'b_ndebug=if-release'],
     meson_version: '>= 0.47.0')
 
-dav1d_soname_version       = '2.0.0'
+dav1d_soname_version       = '3.0.0'
 dav1d_api_version_array    = dav1d_soname_version.split('.')
 dav1d_api_version_major    = dav1d_api_version_array[0]
 dav1d_api_version_minor    = dav1d_api_version_array[1]
--- a/src/internal.h
+++ b/src/internal.h
@@ -89,6 +89,8 @@
     Dav1dContentLightLevel *content_light;
     Dav1dRef *mastering_display_ref;
     Dav1dMasteringDisplay *mastering_display;
+    Dav1dRef *itut_t35_ref;
+    Dav1dITUTT35 *itut_t35;
 
     // decoded output picture queue
     Dav1dData in;
--- a/src/lib.c
+++ b/src/lib.c
@@ -409,8 +409,10 @@
 
     c->mastering_display = NULL;
     c->content_light = NULL;
+    c->itut_t35 = NULL;
     dav1d_ref_dec(&c->mastering_display_ref);
     dav1d_ref_dec(&c->content_light_ref);
+    dav1d_ref_dec(&c->itut_t35_ref);
 
     if (c->n_fc == 1) return;
 
@@ -535,6 +537,7 @@
 
     dav1d_ref_dec(&c->mastering_display_ref);
     dav1d_ref_dec(&c->content_light_ref);
+    dav1d_ref_dec(&c->itut_t35_ref);
 
     dav1d_freep_aligned(c_out);
 }
--- a/src/obu.c
+++ b/src/obu.c
@@ -1364,10 +1364,12 @@
     case OBU_METADATA: {
         // obu metadta type field
         const enum ObuMetaType meta_type = dav1d_get_uleb128(&gb);
+        const int meta_type_len = (dav1d_get_bits_pos(&gb) - init_bit_pos) >> 3;
         if (gb.error) goto error;
         Dav1dRef *ref;
         Dav1dContentLightLevel *content_light;
         Dav1dMasteringDisplay *mastering_display;
+        Dav1dITUTT35 *itut_t35_metadata;
 
         switch (meta_type) {
         case OBU_META_HDR_CLL:
@@ -1420,7 +1422,47 @@
             c->mastering_display_ref = ref;
             break;
         }
-        case OBU_META_ITUT_T35:
+        case OBU_META_ITUT_T35: {
+            int payload_size = len;
+            // Don't take into account all the trailing bits for payload_size
+            while (payload_size > 0 && !in->data[init_byte_pos + payload_size - 1])
+                payload_size--; // trailing_zero_bit x 8
+            payload_size--; // trailing_one_bit + trailing_zero_bit x 7
+
+            // Don't take into account meta_type bytes
+            payload_size -= meta_type_len;
+
+            int country_code_extension_byte = 0;
+            int country_code = dav1d_get_bits(&gb, 8);
+            payload_size--;
+            if (country_code == 0xFF) {
+                country_code_extension_byte = dav1d_get_bits(&gb, 8);
+                payload_size--;
+            }
+
+            if (payload_size <= 0) {
+                dav1d_log(c, "Malformed ITU-T T.35 metadata message format\n");
+                goto error;
+            }
+
+            ref = dav1d_ref_create(sizeof(Dav1dITUTT35) + payload_size * sizeof(uint8_t));
+            if (!ref) return DAV1D_ERR(ENOMEM);
+            itut_t35_metadata = ref->data;
+
+            // We need our public headers to be C++ compatible, so payload can't be
+            // a flexible array member
+            itut_t35_metadata->payload = (uint8_t *) &itut_t35_metadata[1];
+            itut_t35_metadata->country_code = country_code;
+            itut_t35_metadata->country_code_extension_byte = country_code_extension_byte;
+            for (int i = 0; i < payload_size; i++)
+                itut_t35_metadata->payload[i] = dav1d_get_bits(&gb, 8);
+            itut_t35_metadata->payload_size = payload_size;
+
+            dav1d_ref_dec(&c->itut_t35_ref);
+            c->itut_t35 = itut_t35_metadata;
+            c->itut_t35_ref = ref;
+            break;
+        }
         case OBU_META_SCALABILITY:
         case OBU_META_TIMECODE:
             // ignore metadata OBUs we don't care about
--- a/src/picture.c
+++ b/src/picture.c
@@ -104,6 +104,7 @@
                                     Dav1dFrameHeader *frame_hdr,  Dav1dRef *frame_hdr_ref,
                                     Dav1dContentLightLevel *content_light, Dav1dRef *content_light_ref,
                                     Dav1dMasteringDisplay *mastering_display, Dav1dRef *mastering_display_ref,
+                                    Dav1dITUTT35 *itut_t35, Dav1dRef *itut_t35_ref,
                                     const int bpc, const Dav1dDataProps *props,
                                     Dav1dPicAllocator *const p_allocator,
                                     const size_t extra, void **const extra_ptr)
@@ -125,6 +126,7 @@
     p->frame_hdr = frame_hdr;
     p->content_light = content_light;
     p->mastering_display = mastering_display;
+    p->itut_t35 = itut_t35;
     p->p.layout = seq_hdr->layout;
     p->p.bpc = bpc;
     dav1d_data_props_set_defaults(&p->m);
@@ -161,6 +163,9 @@
     p->mastering_display_ref = mastering_display_ref;
     if (mastering_display_ref) dav1d_ref_inc(mastering_display_ref);
 
+    p->itut_t35_ref = itut_t35_ref;
+    if (itut_t35_ref) dav1d_ref_inc(itut_t35_ref);
+
     return 0;
 }
 
@@ -176,11 +181,16 @@
                                  f->frame_hdr, f->frame_hdr_ref,
                                  c->content_light, c->content_light_ref,
                                  c->mastering_display, c->mastering_display_ref,
+                                 c->itut_t35, c->itut_t35_ref,
                                  bpc, &f->tile[0].data.m, &c->allocator,
                                  p->t != NULL ? sizeof(atomic_int) * 2 : 0,
                                  (void **) &p->progress);
     if (res) return res;
 
+    // Must be removed from the context after being attached to the frame
+    dav1d_ref_dec(&c->itut_t35_ref);
+    c->itut_t35 = NULL;
+
     p->visible = f->frame_hdr->show_frame;
     if (p->t) {
         atomic_init(&p->progress[0], 0);
@@ -198,6 +208,7 @@
                                              src->frame_hdr, src->frame_hdr_ref,
                                              src->content_light, src->content_light_ref,
                                              src->mastering_display, src->mastering_display_ref,
+                                             src->itut_t35, src->itut_t35_ref,
                                              src->p.bpc, &src->m, &pic_ctx->allocator,
                                              0, NULL);
     return res;
@@ -216,6 +227,7 @@
         if (src->m.user_data.ref) dav1d_ref_inc(src->m.user_data.ref);
         if (src->content_light_ref) dav1d_ref_inc(src->content_light_ref);
         if (src->mastering_display_ref) dav1d_ref_inc(src->mastering_display_ref);
+        if (src->itut_t35_ref) dav1d_ref_inc(src->itut_t35_ref);
     }
     *dst = *src;
 }
@@ -252,6 +264,7 @@
         dav1d_ref_dec(&p->m.user_data.ref);
         dav1d_ref_dec(&p->content_light_ref);
         dav1d_ref_dec(&p->mastering_display_ref);
+        dav1d_ref_dec(&p->itut_t35_ref);
     }
     memset(p, 0, sizeof(*p));
 }