[FFmpeg-devel] [PATCH 2/2] cbs_av1: Don't reject unknown metadata

Mark Thompson sw at jkqxz.net
Wed Jan 18 00:23:22 EET 2023


Accept it and pass it through unchanged.

The standard requires that decoders ignore unknown metadata, and indeed
this is tested by some of the Argon coverage streams.
---
Artificial test example:

[trace_headers @ 0x5596dda6ed80] OBU header
[trace_headers @ 0x5596dda6ed80] 0           obu_forbidden_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 1           obu_type                                                 0101 = 5
[trace_headers @ 0x5596dda6ed80] 5           obu_extension_flag                                          0 = 0
[trace_headers @ 0x5596dda6ed80] 6           obu_has_size_field                                          1 = 1
[trace_headers @ 0x5596dda6ed80] 7           obu_reserved_1bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 8           leb128_byte[0]                                       00001101 = 13
[trace_headers @ 0x5596dda6ed80] 8           obu_size                                                      = 13
[trace_headers @ 0x5596dda6ed80] 16          leb128_byte[0]                                       00101010 = 42
[trace_headers @ 0x5596dda6ed80] 16          metadata_type                                                 = 42
[trace_headers @ 0x5596dda6ed80] Unknown Metadata
[trace_headers @ 0x5596dda6ed80] 24          payload[0]                                           00000000 = 0
[trace_headers @ 0x5596dda6ed80] 32          payload[1]                                           00000001 = 1
[trace_headers @ 0x5596dda6ed80] 40          payload[2]                                           00000010 = 2
[trace_headers @ 0x5596dda6ed80] 48          payload[3]                                           00000011 = 3
[trace_headers @ 0x5596dda6ed80] 56          payload[4]                                           00000100 = 4
[trace_headers @ 0x5596dda6ed80] 64          payload[5]                                           00000101 = 5
[trace_headers @ 0x5596dda6ed80] 72          payload[6]                                           00000110 = 6
[trace_headers @ 0x5596dda6ed80] 80          payload[7]                                           00000111 = 7
[trace_headers @ 0x5596dda6ed80] 88          payload[8]                                           00001000 = 8
[trace_headers @ 0x5596dda6ed80] 96          payload[9]                                           00001001 = 9
[trace_headers @ 0x5596dda6ed80] 104         payload[10]                                          00001010 = 10
[trace_headers @ 0x5596dda6ed80] 112         trailing_one_bit                                            1 = 1
[trace_headers @ 0x5596dda6ed80] 113         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 114         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 115         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 116         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 117         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 118         trailing_zero_bit                                           0 = 0
[trace_headers @ 0x5596dda6ed80] 119         trailing_zero_bit                                           0 = 0

  libavcodec/cbs_av1.c                 |  7 +++++++
  libavcodec/cbs_av1.h                 |  7 +++++++
  libavcodec/cbs_av1_syntax_template.c | 26 ++++++++++++++++++++++++--
  3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c
index 45e1288a51..8788fee099 100644
--- a/libavcodec/cbs_av1.c
+++ b/libavcodec/cbs_av1.c
@@ -1306,9 +1306,16 @@ static void cbs_av1_free_metadata(void *unit, uint8_t *content)
      md = &obu->obu.metadata;

      switch (md->metadata_type) {
+    case AV1_METADATA_TYPE_HDR_CLL:
+    case AV1_METADATA_TYPE_HDR_MDCV:
+    case AV1_METADATA_TYPE_SCALABILITY:
+    case AV1_METADATA_TYPE_TIMECODE:
+        break;
      case AV1_METADATA_TYPE_ITUT_T35:
          av_buffer_unref(&md->metadata.itut_t35.payload_ref);
          break;
+    default:
+        av_buffer_unref(&md->metadata.unknown.payload_ref);
      }
      av_free(content);
  }
diff --git a/libavcodec/cbs_av1.h b/libavcodec/cbs_av1.h
index 1fc80dcfa0..36848d4410 100644
--- a/libavcodec/cbs_av1.h
+++ b/libavcodec/cbs_av1.h
@@ -370,6 +370,12 @@ typedef struct AV1RawMetadataTimecode {
      uint32_t time_offset_value;
  } AV1RawMetadataTimecode;

+typedef struct AV1RawMetadataUnknown {
+    uint8_t     *payload;
+    AVBufferRef *payload_ref;
+    size_t       payload_size;
+} AV1RawMetadataUnknown;
+
  typedef struct AV1RawMetadata {
      uint64_t metadata_type;
      union {
@@ -378,6 +384,7 @@ typedef struct AV1RawMetadata {
          AV1RawMetadataScalability scalability;
          AV1RawMetadataITUTT35     itut_t35;
          AV1RawMetadataTimecode    timecode;
+        AV1RawMetadataUnknown     unknown;
      } metadata;
  } AV1RawMetadata;

diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c
index 46f4c5a6b8..3cab02bdd9 100644
--- a/libavcodec/cbs_av1_syntax_template.c
+++ b/libavcodec/cbs_av1_syntax_template.c
@@ -2007,6 +2007,29 @@ static int FUNC(metadata_timecode)(CodedBitstreamContext *ctx, RWContext *rw,
      return 0;
  }

+static int FUNC(metadata_unknown)(CodedBitstreamContext *ctx, RWContext *rw,
+                                  AV1RawMetadataUnknown *current)
+{
+    int err;
+    size_t i;
+
+    HEADER("Unknown Metadata");
+
+#ifdef READ
+    current->payload_size = cbs_av1_get_payload_bytes_left(rw);
+
+    current->payload_ref = av_buffer_alloc(current->payload_size);
+    if (!current->payload_ref)
+        return AVERROR(ENOMEM);
+    current->payload = current->payload_ref->data;
+#endif
+
+    for (i = 0; i < current->payload_size; i++)
+        fbs(8, payload[i], 1, i);
+
+    return 0;
+}
+
  static int FUNC(metadata_obu)(CodedBitstreamContext *ctx, RWContext *rw,
                                AV1RawMetadata *current)
  {
@@ -2031,8 +2054,7 @@ static int FUNC(metadata_obu)(CodedBitstreamContext *ctx, RWContext *rw,
          CHECK(FUNC(metadata_timecode)(ctx, rw, &current->metadata.timecode));
          break;
      default:
-        // Unknown metadata type.
-        return AVERROR_PATCHWELCOME;
+        CHECK(FUNC(metadata_unknown)(ctx, rw, &current->metadata.unknown));
      }

      return 0;
-- 
2.39.0


More information about the ffmpeg-devel mailing list