Skip to content

AV1 bitstream support: HDR10+ metadata in OBU_METADATA (T.35) #116

Closed as duplicate

Description

@sven-pke

Hi @quietvoid,

I wanted to share a fork I created that adds AV1 bitstream support to hdr10plus_tool:
👉 https://github.com/sven-pke/hdr10plus_tool

What was done:
The HEVC-based pipeline (hevc_parser) was replaced with a stateful AV1 OBU parser.
The tool can now extract, inject, and remove HDR10+ metadata from/into AV1 bitstreams —
both raw AV1 and IVF container format are supported.

How it works:

  • HDR10+ metadata is carried in OBU_METADATA with metadata_type=4 (ITU-T T.35),
    itu_t_t35_country_code=0xB5, and itu_t_t35_provider_code=0x003C
  • Temporal units are delimited by OBU_TEMPORAL_DELIMITER
  • IVF files (e.g. from libaom/SVT-AV1) are detected automatically via the DKIF magic
  • The .json metadata format and all non-bitstream commands (editor, plot) are unchanged

What was removed:

  • hevc_parser dependency
  • HEVC-specific SEI extraction/injection logic
  • hevc/ module in the hdr10plus sub-crate

This was motivated by the growing use of AV1 for HDR content delivery. If you're
interested in merging any of this upstream, I'm happy to split it into proper PRs.

Thanks for the great work on this toolchain!

Activity

  1. quietvoid commented on Mar 19, 2026

    @quietvoid
    Owner

    Please use #50 to track this.
    As it is the code is not in a mergeable state, the whole of AV1 parsing needs to be in a separate crate.
    And it's also that crate that should be responsible for the I/O.

  2. JORDZIE commented on Sep 20, 2026

    @JORDZIE

    Hi, I found a small AV1 HDR10+ injection bug.

    libdav1d reports:

    Malformed ITU-T T.35 metadata message format

    In hdr10plus/src/av1/mod.rs, encode_hdr10plus_obu() appends the T.35 payload but doesn't append AV1 trailing bits.

    Adding:

    obu_payload.push(0x80);

    immediately after:

    obu_payload.extend_from_slice(&t35_payload);

    fixes it.

    I rebuilt and tested it with two HDR10+ JSON files. FFmpeg/libdav1d then decodes cleanly, and HDR10+ playback works correctly after remuxing to MP4.

  3. sven-pke commented on Sep 23, 2026

    @sven-pke
    Author

    Thanks @JORDZIE — confirmed, and fixed in my fork (main and feat/av1-bitstream). The metadata OBU lacked trailing_bits(), and it sat ahead of the sequence header, where mkvmerge copies it into av1C; my dovi_tool fork had the same two problems with its RPU OBUs. FFmpeg's CBS parser (-bsf:v trace_headers) rejects the old output and accepts the new.

    Sorry for the noise here — this concerns my fork, not upstream.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions