* [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10
@ 2024-02-25 11:44 Niklas Haas
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU Niklas Haas
` (4 more replies)
0 siblings, 5 replies; 8+ messages in thread
From: Niklas Haas @ 2024-02-25 11:44 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
From: Niklas Haas <git@haasn.dev>
Instead of the nal_prefix, this profile inside wraps the RPU inside an
EMDF header, as specified in ETSI TS 102 366. This particular usage is
supposedly specified in ETSI TS 103 572, at least according to European
Patent EP 3 588 964 A1, but I could not find any references to DV RPUs
in the former.
It's worth pointing out that the EMDF container is not byte-aligned,
meaning that payloads are delivered at arbitrary byte boundaries. Hence
the reason for doing it inside ff_dovi_rpu_parse, which already uses
a bitstream reader, rather than splitting off the container in
a separate stage. (Plus, we hard-code the DV-specific payload ID)
Magic values were taken from a combination of the sources below, all of
which agree about what the specific EMDF header should look like. In
fact, they all hard-code a very *specific* header sequence, but I wanted
to go the extra mile and at least properly skip the variable fields
- even though the non-existent Dolby Vision specification probably
specifies that they all must be 0. This is probably overkill.
Validated and tested using sample files from the merge request linked
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://github.com/rockchip-linux/mpp/blob/fdeb8c378b79d4b4ef80457e4431815de89dc417/mpp/codec/dec/av1/av1d_cbs.c#L2378
- https://github.com/elginsk8r/android_kernel_amlogic_linux-4.9/blob/23a4c38bf06ef34821e476a8edddbf9213712c8a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c#L5638
- https://gitlab.com/mbunkus/mkvtoolnix/-/merge_requests/2254
---
libavcodec/dovi_rpu.c | 68 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 65 insertions(+), 3 deletions(-)
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index a6b23f4dd11..c7cdd65a2f2 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,59 @@ 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 EMDF container, parse header */
+ int emdf_version, key_id, emdf_payload_id, emdf_payload_size, smploffste;
+ emdf_version = get_bits(gb, 2);
+ if (emdf_version == 3)
+ emdf_version += get_variable_bits(gb, 2);
+ key_id = get_bits(gb, 3);
+ if (key_id == 7)
+ key_id += get_variable_bits(gb, 3);
+ emdf_payload_id = get_bits(gb, 5);
+ if (emdf_payload_id == 0x1F)
+ emdf_payload_id += get_variable_bits(gb, 5);
+
+ /* Magic values taken from amlogic and rockchip drivers, and also
+ * match values found in practice (and validated in hardware) */
+ VALIDATE(key_id, 6, 6);
+ VALIDATE(emdf_payload_id, 256, 256);
+
+ /* Note: In theory, there could be multiple payloads, and we should
+ * skip over the unused payloads until we find the one we're interested
+ * in. But this capability does not seem to be used in practice, so
+ * the DV-specific usage of EMDF probably requires only one payload
+ * per T.35 OBU */
+
+ /* Skip emdf_payload_config() */
+ if ((smploffste = get_bits1(gb)))
+ skip_bits(gb, 11 + 1);
+ if (get_bits1(gb)) /* duratione */
+ get_variable_bits(gb, 11);
+ if (get_bits1(gb)) /* groupide */
+ get_variable_bits(gb, 2);
+ if (get_bits1(gb)) /* codecdatae */
+ skip_bits(gb, 8);
+ if (!get_bits1(gb)) { /* discard_unknown_payload */
+ int payload_frame_aligned;
+ if (!smploffste) {
+ if ((payload_frame_aligned = get_bits1(gb)))
+ skip_bits(gb, 1 + 1);
+ }
+ if (smploffste || payload_frame_aligned)
+ skip_bits(gb, 5 + 2);
+ }
+
+ emdf_payload_size = get_variable_bits(gb, 8);
+ 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 "
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
@ 2024-02-25 11:44 ` Niklas Haas
2024-03-04 12:50 ` James Almer
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/av1dec: " Niklas Haas
` (3 subsequent siblings)
4 siblings, 1 reply; 8+ messages in thread
From: Niklas Haas @ 2024-02-25 11:44 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
From: Niklas Haas <git@haasn.dev>
This is thankfully passed through verbatim by libdav1d, so we can parse
it in our own code.
In theory, taking the DV profile from the packet-level configuration
struct is redundant since there is currently only one possible DV level
for AV1 (and all others would fail parsing), but this marginally
future-proofs it against possible new AV1-specific profiles being added
in the future.
---
libavcodec/libdav1d.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 78a5c63bf42..9bac4a9eb27 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -35,6 +35,7 @@
#include "bytestream.h"
#include "codec_internal.h"
#include "decode.h"
+#include "dovi_rpu.h"
#include "internal.h"
#define FF_DAV1D_VERSION_AT_LEAST(x,y) \
@@ -44,6 +45,7 @@ typedef struct Libdav1dContext {
AVClass *class;
Dav1dContext *c;
AVBufferPool *pool;
+ DOVIContext dovi;
int pool_size;
Dav1dData data;
@@ -213,6 +215,7 @@ static av_cold int libdav1d_init(AVCodecContext *c)
#else
int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2;
#endif
+ const AVPacketSideData *sd;
int res;
av_log(c, AV_LOG_VERBOSE, "libdav1d %s\n", dav1d_version());
@@ -285,6 +288,11 @@ static av_cold int libdav1d_init(AVCodecContext *c)
c->delay = res > 1 ? res : 0;
#endif
+ dav1d->dovi.logctx = c;
+ dav1d->dovi.dv_profile = 10; // default for AV1
+ sd = ff_get_coded_side_data(c, AV_PKT_DATA_DOVI_CONF);
+ if (sd && sd->size > 0)
+ ff_dovi_update_cfg(&dav1d->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
return 0;
}
@@ -593,6 +601,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
goto fail;
break;
}
+ case 0x3B: { // dolby_provider_code
+ int provider_oriented_code = bytestream2_get_be32(&gb);
+ if (itut_t35->country_code != 0xB5 || provider_oriented_code != 0x800)
+ break;
+
+ res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer);
+ if (res < 0) {
+ av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
+ break; // ignore
+ }
+
+ res = ff_dovi_attach_side_data(&dav1d->dovi, frame);
+ if (res < 0)
+ goto fail;
+ break;
+ }
default: // ignore unsupported provider codes
break;
}
@@ -652,6 +676,7 @@ static av_cold int libdav1d_close(AVCodecContext *c)
Libdav1dContext *dav1d = c->priv_data;
av_buffer_pool_uninit(&dav1d->pool);
+ ff_dovi_ctx_unref(&dav1d->dovi);
dav1d_data_unref(&dav1d->data);
dav1d_close(&dav1d->c);
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* [FFmpeg-devel] [PATCH 3/3] avcodec/av1dec: parse DV profile 10 T.35 OBU
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU Niklas Haas
@ 2024-02-25 11:44 ` Niklas Haas
2024-03-04 11:42 ` [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
` (2 subsequent siblings)
4 siblings, 0 replies; 8+ messages in thread
From: Niklas Haas @ 2024-02-25 11:44 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
From: Niklas Haas <git@haasn.dev>
See previous commit.
---
libavcodec/av1dec.c | 25 +++++++++++++++++++++++++
libavcodec/av1dec.h | 2 ++
2 files changed, 27 insertions(+)
diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 7debc4dedaa..f42dc77148f 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -727,6 +727,7 @@ static av_cold int av1_decode_free(AVCodecContext *avctx)
ff_cbs_fragment_free(&s->current_obu);
ff_cbs_close(&s->cbc);
+ ff_dovi_ctx_unref(&s->dovi);
return 0;
}
@@ -818,6 +819,7 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
{
AV1DecContext *s = avctx->priv_data;
AV1RawSequenceHeader *seq;
+ const AVPacketSideData *sd;
int ret;
s->avctx = avctx;
@@ -875,6 +877,12 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
ff_cbs_fragment_reset(&s->current_obu);
}
+ s->dovi.logctx = avctx;
+ s->dovi.dv_profile = 10; // default for AV1
+ sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
+ if (sd && sd->size > 0)
+ ff_dovi_update_cfg(&s->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
+
return ret;
}
@@ -928,6 +936,7 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
const AV1RawMetadataITUTT35 *itut_t35)
{
GetByteContext gb;
+ AV1DecContext *s = avctx->priv_data;
int ret, provider_code;
bytestream2_init(&gb, itut_t35->payload, itut_t35->payload_size);
@@ -976,6 +985,22 @@ static int export_itut_t35(AVCodecContext *avctx, AVFrame *frame,
return ret;
break;
}
+ case 0x3B: { // dolby_provider_code
+ int provider_oriented_code = bytestream2_get_be32(&gb);
+ if (itut_t35->itu_t_t35_country_code != 0xB5 || provider_oriented_code != 0x800)
+ break;
+
+ ret = ff_dovi_rpu_parse(&s->dovi, gb.buffer, gb.buffer_end - gb.buffer);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
+ break; // ignore
+ }
+
+ ret = ff_dovi_attach_side_data(&s->dovi, frame);
+ if (ret < 0)
+ return ret;
+ break;
+ }
default: // ignore unsupported provider codes
break;
}
diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h
index b6a0c08e488..f1d57b39f9a 100644
--- a/libavcodec/av1dec.h
+++ b/libavcodec/av1dec.h
@@ -30,6 +30,7 @@
#include "packet.h"
#include "cbs.h"
#include "cbs_av1.h"
+#include "dovi_rpu.h"
typedef struct AV1Frame {
AVFrame *f;
@@ -79,6 +80,7 @@ typedef struct AV1DecContext {
AV1RawMetadataHDRCLL *cll;
AV1RawOBU *mdcv_ref; ///< RefStruct reference backing mdcv
AV1RawMetadataHDRMDCV *mdcv;
+ DOVIContext dovi;
AVFifo *itut_t35_fifo;
uint16_t tile_num;
--
2.43.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU Niklas Haas
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/av1dec: " Niklas Haas
@ 2024-03-04 11:42 ` Niklas Haas
2024-03-04 13:06 ` Andreas Rheinhardt
2024-03-07 20:10 ` Niklas Haas
4 siblings, 0 replies; 8+ messages in thread
From: Niklas Haas @ 2024-03-04 11:42 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
On Sun, 25 Feb 2024 12:44:49 +0100 Niklas Haas <ffmpeg@haasn.xyz> wrote:
> From: Niklas Haas <git@haasn.dev>
>
> Instead of the nal_prefix, this profile inside wraps the RPU inside an
> EMDF header, as specified in ETSI TS 102 366. This particular usage is
> supposedly specified in ETSI TS 103 572, at least according to European
> Patent EP 3 588 964 A1, but I could not find any references to DV RPUs
> in the former.
>
> It's worth pointing out that the EMDF container is not byte-aligned,
> meaning that payloads are delivered at arbitrary byte boundaries. Hence
> the reason for doing it inside ff_dovi_rpu_parse, which already uses
> a bitstream reader, rather than splitting off the container in
> a separate stage. (Plus, we hard-code the DV-specific payload ID)
>
> Magic values were taken from a combination of the sources below, all of
> which agree about what the specific EMDF header should look like. In
> fact, they all hard-code a very *specific* header sequence, but I wanted
> to go the extra mile and at least properly skip the variable fields
> - even though the non-existent Dolby Vision specification probably
> specifies that they all must be 0. This is probably overkill.
>
> Validated and tested using sample files from the merge request linked
> 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://github.com/rockchip-linux/mpp/blob/fdeb8c378b79d4b4ef80457e4431815de89dc417/mpp/codec/dec/av1/av1d_cbs.c#L2378
> - https://github.com/elginsk8r/android_kernel_amlogic_linux-4.9/blob/23a4c38bf06ef34821e476a8edddbf9213712c8a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c#L5638
> - https://gitlab.com/mbunkus/mkvtoolnix/-/merge_requests/2254
Ping. Is there anybody who could kindly review this?
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU Niklas Haas
@ 2024-03-04 12:50 ` James Almer
0 siblings, 0 replies; 8+ messages in thread
From: James Almer @ 2024-03-04 12:50 UTC (permalink / raw)
To: ffmpeg-devel
On 2/25/2024 8:44 AM, Niklas Haas wrote:
> From: Niklas Haas <git@haasn.dev>
>
> This is thankfully passed through verbatim by libdav1d, so we can parse
> it in our own code.
>
> In theory, taking the DV profile from the packet-level configuration
> struct is redundant since there is currently only one possible DV level
> for AV1 (and all others would fail parsing), but this marginally
> future-proofs it against possible new AV1-specific profiles being added
> in the future.
> ---
> libavcodec/libdav1d.c | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
>
> diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
> index 78a5c63bf42..9bac4a9eb27 100644
> --- a/libavcodec/libdav1d.c
> +++ b/libavcodec/libdav1d.c
> @@ -35,6 +35,7 @@
> #include "bytestream.h"
> #include "codec_internal.h"
> #include "decode.h"
> +#include "dovi_rpu.h"
> #include "internal.h"
>
> #define FF_DAV1D_VERSION_AT_LEAST(x,y) \
> @@ -44,6 +45,7 @@ typedef struct Libdav1dContext {
> AVClass *class;
> Dav1dContext *c;
> AVBufferPool *pool;
> + DOVIContext dovi;
> int pool_size;
>
> Dav1dData data;
> @@ -213,6 +215,7 @@ static av_cold int libdav1d_init(AVCodecContext *c)
> #else
> int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2;
> #endif
> + const AVPacketSideData *sd;
> int res;
>
> av_log(c, AV_LOG_VERBOSE, "libdav1d %s\n", dav1d_version());
> @@ -285,6 +288,11 @@ static av_cold int libdav1d_init(AVCodecContext *c)
> c->delay = res > 1 ? res : 0;
> #endif
>
> + dav1d->dovi.logctx = c;
> + dav1d->dovi.dv_profile = 10; // default for AV1
> + sd = ff_get_coded_side_data(c, AV_PKT_DATA_DOVI_CONF);
> + if (sd && sd->size > 0)
> + ff_dovi_update_cfg(&dav1d->dovi, (AVDOVIDecoderConfigurationRecord *) sd->data);
> return 0;
> }
>
> @@ -593,6 +601,22 @@ FF_ENABLE_DEPRECATION_WARNINGS
> goto fail;
> break;
> }
> + case 0x3B: { // dolby_provider_code
> + int provider_oriented_code = bytestream2_get_be32(&gb);
> + if (itut_t35->country_code != 0xB5 || provider_oriented_code != 0x800)
> + break;
> +
> + res = ff_dovi_rpu_parse(&dav1d->dovi, gb.buffer, gb.buffer_end - gb.buffer);
> + if (res < 0) {
> + av_log(c, AV_LOG_WARNING, "Error parsing DOVI OBU.\n");
> + break; // ignore
> + }
> +
> + res = ff_dovi_attach_side_data(&dav1d->dovi, frame);
> + if (res < 0)
> + goto fail;
> + break;
> + }
> default: // ignore unsupported provider codes
> break;
> }
> @@ -652,6 +676,7 @@ static av_cold int libdav1d_close(AVCodecContext *c)
> Libdav1dContext *dav1d = c->priv_data;
>
> av_buffer_pool_uninit(&dav1d->pool);
> + ff_dovi_ctx_unref(&dav1d->dovi);
> dav1d_data_unref(&dav1d->data);
> dav1d_close(&dav1d->c);
>
This and patch 3/3 lgtm.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
` (2 preceding siblings ...)
2024-03-04 11:42 ` [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
@ 2024-03-04 13:06 ` Andreas Rheinhardt
2024-03-04 13:23 ` Niklas Haas
2024-03-07 20:10 ` Niklas Haas
4 siblings, 1 reply; 8+ messages in thread
From: Andreas Rheinhardt @ 2024-03-04 13:06 UTC (permalink / raw)
To: ffmpeg-devel
Niklas Haas:
> From: Niklas Haas <git@haasn.dev>
>
> Instead of the nal_prefix, this profile inside wraps the RPU inside an
> EMDF header, as specified in ETSI TS 102 366. This particular usage is
> supposedly specified in ETSI TS 103 572, at least according to European
> Patent EP 3 588 964 A1, but I could not find any references to DV RPUs
> in the former.
>
> It's worth pointing out that the EMDF container is not byte-aligned,
> meaning that payloads are delivered at arbitrary byte boundaries. Hence
> the reason for doing it inside ff_dovi_rpu_parse, which already uses
> a bitstream reader, rather than splitting off the container in
> a separate stage. (Plus, we hard-code the DV-specific payload ID)
>
> Magic values were taken from a combination of the sources below, all of
> which agree about what the specific EMDF header should look like. In
> fact, they all hard-code a very *specific* header sequence, but I wanted
> to go the extra mile and at least properly skip the variable fields
> - even though the non-existent Dolby Vision specification probably
> specifies that they all must be 0. This is probably overkill.
>
> Validated and tested using sample files from the merge request linked
> 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://github.com/rockchip-linux/mpp/blob/fdeb8c378b79d4b4ef80457e4431815de89dc417/mpp/codec/dec/av1/av1d_cbs.c#L2378
> - https://github.com/elginsk8r/android_kernel_amlogic_linux-4.9/blob/23a4c38bf06ef34821e476a8edddbf9213712c8a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c#L5638
> - https://gitlab.com/mbunkus/mkvtoolnix/-/merge_requests/2254
> ---
> libavcodec/dovi_rpu.c | 68 +++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 65 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
> index a6b23f4dd11..c7cdd65a2f2 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);
Using |= is more appropriate.
> + read_more = get_bits1(gb);
> + };
The ';' is a null statement.
> + return value;
> +}
> +
> #define VALIDATE(VAR, MIN, MAX) \
> do { \
> if (VAR < MIN || VAR > MAX) { \
> @@ -200,9 +212,59 @@ 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 EMDF container, parse header */
> + int emdf_version, key_id, emdf_payload_id, emdf_payload_size, smploffste;
> + emdf_version = get_bits(gb, 2);
> + if (emdf_version == 3)
> + emdf_version += get_variable_bits(gb, 2);
> + key_id = get_bits(gb, 3);
> + if (key_id == 7)
> + key_id += get_variable_bits(gb, 3);
> + emdf_payload_id = get_bits(gb, 5);
> + if (emdf_payload_id == 0x1F)
> + emdf_payload_id += get_variable_bits(gb, 5);
> +
> + /* Magic values taken from amlogic and rockchip drivers, and also
> + * match values found in practice (and validated in hardware) */
> + VALIDATE(key_id, 6, 6);
> + VALIDATE(emdf_payload_id, 256, 256);
> +
> + /* Note: In theory, there could be multiple payloads, and we should
> + * skip over the unused payloads until we find the one we're interested
> + * in. But this capability does not seem to be used in practice, so
> + * the DV-specific usage of EMDF probably requires only one payload
> + * per T.35 OBU */
> +
> + /* Skip emdf_payload_config() */
> + if ((smploffste = get_bits1(gb)))
> + skip_bits(gb, 11 + 1);
> + if (get_bits1(gb)) /* duratione */
> + get_variable_bits(gb, 11);
> + if (get_bits1(gb)) /* groupide */
> + get_variable_bits(gb, 2);
> + if (get_bits1(gb)) /* codecdatae */
> + skip_bits(gb, 8);
> + if (!get_bits1(gb)) { /* discard_unknown_payload */
> + int payload_frame_aligned;
> + if (!smploffste) {
> + if ((payload_frame_aligned = get_bits1(gb)))
> + skip_bits(gb, 1 + 1);
> + }
> + if (smploffste || payload_frame_aligned)
> + skip_bits(gb, 5 + 2);
> + }
> +
> + emdf_payload_size = get_variable_bits(gb, 8);
> + 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 "
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10
2024-03-04 13:06 ` Andreas Rheinhardt
@ 2024-03-04 13:23 ` Niklas Haas
0 siblings, 0 replies; 8+ messages in thread
From: Niklas Haas @ 2024-03-04 13:23 UTC (permalink / raw)
To: ffmpeg-devel
On Mon, 04 Mar 2024 14:06:51 +0100 Andreas Rheinhardt <andreas.rheinhardt@outlook.com> wrote:
> Niklas Haas:
> > From: Niklas Haas <git@haasn.dev>
> >
> > Instead of the nal_prefix, this profile inside wraps the RPU inside an
> > EMDF header, as specified in ETSI TS 102 366. This particular usage is
> > supposedly specified in ETSI TS 103 572, at least according to European
> > Patent EP 3 588 964 A1, but I could not find any references to DV RPUs
> > in the former.
> >
> > It's worth pointing out that the EMDF container is not byte-aligned,
> > meaning that payloads are delivered at arbitrary byte boundaries. Hence
> > the reason for doing it inside ff_dovi_rpu_parse, which already uses
> > a bitstream reader, rather than splitting off the container in
> > a separate stage. (Plus, we hard-code the DV-specific payload ID)
> >
> > Magic values were taken from a combination of the sources below, all of
> > which agree about what the specific EMDF header should look like. In
> > fact, they all hard-code a very *specific* header sequence, but I wanted
> > to go the extra mile and at least properly skip the variable fields
> > - even though the non-existent Dolby Vision specification probably
> > specifies that they all must be 0. This is probably overkill.
> >
> > Validated and tested using sample files from the merge request linked
> > 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://github.com/rockchip-linux/mpp/blob/fdeb8c378b79d4b4ef80457e4431815de89dc417/mpp/codec/dec/av1/av1d_cbs.c#L2378
> > - https://github.com/elginsk8r/android_kernel_amlogic_linux-4.9/blob/23a4c38bf06ef34821e476a8edddbf9213712c8a/drivers/amlogic/media/enhancement/amdolby_vision/amdolby_vision.c#L5638
> > - https://gitlab.com/mbunkus/mkvtoolnix/-/merge_requests/2254
> > ---
> > libavcodec/dovi_rpu.c | 68 +++++++++++++++++++++++++++++++++++++++++--
> > 1 file changed, 65 insertions(+), 3 deletions(-)
> >
> > diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
> > index a6b23f4dd11..c7cdd65a2f2 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);
>
> Using |= is more appropriate.
>
> > + read_more = get_bits1(gb);
> > + };
>
> The ';' is a null statement.
Fixed both, thanks.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
` (3 preceding siblings ...)
2024-03-04 13:06 ` Andreas Rheinhardt
@ 2024-03-07 20:10 ` Niklas Haas
4 siblings, 0 replies; 8+ messages in thread
From: Niklas Haas @ 2024-03-07 20:10 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Niklas Haas
Will merge tomorrow without further comments.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2024-03-07 20:10 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-25 11:44 [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 2/3] avcodec/libdav1d: parse DV profile 10 T.35 OBU Niklas Haas
2024-03-04 12:50 ` James Almer
2024-02-25 11:44 ` [FFmpeg-devel] [PATCH 3/3] avcodec/av1dec: " Niklas Haas
2024-03-04 11:42 ` [FFmpeg-devel] [PATCH 1/3] avcodec/dovi_rpu: implement support for profile 10 Niklas Haas
2024-03-04 13:06 ` Andreas Rheinhardt
2024-03-04 13:23 ` Niklas Haas
2024-03-07 20:10 ` Niklas Haas
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git