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));
}