mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
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
This commit is contained in:
parent
3d1860ec8d
commit
9aecd717ab
@ -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 "
|
||||
|
Loading…
Reference in New Issue
Block a user