summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorNiklas Haas <git@haasn.dev>2024-02-23 21:06:20 +0100
committerNiklas Haas <git@haasn.dev>2024-03-11 11:40:09 +0100
commit9aecd717ab9fb45bf57329c5afeaf5e80d2a3004 (patch)
tree1242bc2a9c6f4740452688af26090b1890617a39 /libavcodec
parent3d1860ec8db7f9785bf1338e826138c0218dfb59 (diff)
avcodec/dovi_rpu: implement support for profile 10
Instead of the nal_prefix, this profile inside wraps the RPU inside an EMDF container, as specified in ETSI TS 102 366. However, this DV-specific EMDF container is restricted (by the specification) to a fixed set of hard-coded parameters, which we can effecitvely treat as a magic byte sequence. Validated and tested using official Dolby sample files, which I unfortunately cannot share. However, there are public sample files available at the merge request link below. Relevant links: - https://www.etsi.org/deliver/etsi_ts/102300_102399/102366/01.04.01_60/ts_102366v010401p.pdf - https://patentimages.storage.googleapis.com/8a/0b/da/28294acaed2182/EP3588964A1.pdf - https://www.etsi.org/deliver/etsi_ts/103500_103599/103572/01.03.01_60/ts_103572v010301p.pdf - https://gitlab.com/mbunkus/mkvtoolnix/-/merge_requests/2254
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/dovi_rpu.c45
1 files changed, 42 insertions, 3 deletions
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index a6b23f4dd1..529062be30 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -174,6 +174,18 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader *
return 0; /* unreachable */
}
+static inline unsigned get_variable_bits(GetBitContext *gb, int n)
+{
+ unsigned int value = get_bits(gb, n);
+ int read_more = get_bits1(gb);
+ while (read_more) {
+ value = (value + 1) << n;
+ value |= get_bits(gb, n);
+ read_more = get_bits1(gb);
+ }
+ return value;
+}
+
#define VALIDATE(VAR, MIN, MAX) \
do { \
if (VAR < MIN || VAR > MAX) { \
@@ -200,9 +212,36 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size)
if ((ret = init_get_bits8(gb, rpu, rpu_size)) < 0)
return ret;
- /* RPU header, common values */
- nal_prefix = get_bits(gb, 8);
- VALIDATE(nal_prefix, 25, 25);
+ /* Container header */
+ if (s->dv_profile == 10 /* dav1.10 */) {
+ /* DV inside AV1 re-uses an EMDF container skeleton, but with fixed
+ * values - so we can effectively treat this as a magic byte sequence.
+ *
+ * The exact fields are, as follows:
+ * emdf_version : f(2) = 0
+ * key_id : f(3) = 6
+ * emdf_payload_id : f(5) = 31
+ * emdf_payload_id_ext : var(5) = 225
+ * smploffste : f(1) = 0
+ * duratione : f(1) = 0
+ * groupide : f(1) = 0
+ * codecdatae : f(1) = 0
+ * discard_unknown_payload : f(1) = 1
+ */
+ const unsigned header_magic = 0x01be6841u;
+ unsigned header, emdf_payload_size;
+ header = get_bits_long(gb, 27);
+ VALIDATE(header, header_magic, header_magic);
+ emdf_payload_size = get_variable_bits(gb, 8);
+ VALIDATE(emdf_payload_size, 6, 512);
+ if (emdf_payload_size * 8 > get_bits_left(gb))
+ return AVERROR_INVALIDDATA;
+ } else {
+ nal_prefix = get_bits(gb, 8);
+ VALIDATE(nal_prefix, 25, 25);
+ }
+
+ /* RPU header */
rpu_type = get_bits(gb, 6);
if (rpu_type != 2) {
av_log(s->logctx, AV_LOG_WARNING, "Unrecognized RPU type "