[FFmpeg-cvslog] avcodec/dovi_rpu: separate static ext blocks
Niklas Haas
git at videolan.org
Fri Aug 16 12:52:11 EEST 2024
ffmpeg | branch: master | Niklas Haas <git at haasn.dev> | Wed Jul 10 14:47:40 2024 +0200| [a1f96ae157d80c6fd982c60b2e78a555aaa7e810] | committer: Niklas Haas
avcodec/dovi_rpu: separate static ext blocks
Static and dynamic extension blocks are handled differently by metadata
compression, so we need to separate the extension block array into two.
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a1f96ae157d80c6fd982c60b2e78a555aaa7e810
---
libavcodec/dovi_rpu.h | 20 ++++++++++++++++++--
libavcodec/dovi_rpudec.c | 31 +++++++++++++++++++++----------
libavcodec/dovi_rpuenc.c | 11 ++++++++---
3 files changed, 47 insertions(+), 15 deletions(-)
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index ed5bfa7b26..f3ccc27ae8 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -33,8 +33,10 @@
#define DOVI_MAX_DM_ID 15
typedef struct DOVIExt {
- AVDOVIDmData dm[AV_DOVI_MAX_EXT_BLOCKS];
- int num_dm;
+ AVDOVIDmData dm_static[7]; ///< static extension blocks
+ AVDOVIDmData dm_dynamic[25]; ///< dynamic extension blocks
+ int num_static;
+ int num_dynamic;
} DOVIExt;
typedef struct DOVIContext {
@@ -191,4 +193,18 @@ int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr);
/* Default values for AVDOVIColorMetadata */
extern const AVDOVIColorMetadata ff_dovi_color_default;
+static inline int ff_dovi_rpu_extension_is_static(int level)
+{
+ switch (level) {
+ case 6:
+ case 10:
+ case 32: /* reserved as static by spec */
+ case 254:
+ case 255:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
#endif /* AVCODEC_DOVI_RPU_H */
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 1650547c80..6ef7a88ffd 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -51,9 +51,10 @@ int ff_dovi_get_metadata(DOVIContext *s, AVDOVIMetadata **out_metadata)
if (s->ext_blocks) {
const DOVIExt *ext = s->ext_blocks;
size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size);
- for (int i = 0; i < ext->num_dm; i++)
- memcpy(av_dovi_get_ext(dovi, i), &ext->dm[i], ext_sz);
- dovi->num_ext_blocks = ext->num_dm;
+ for (int i = 0; i < ext->num_static; i++)
+ memcpy(av_dovi_get_ext(dovi, dovi->num_ext_blocks++), &ext->dm_static[i], ext_sz);
+ for (int i = 0; i < ext->num_dynamic; i++)
+ memcpy(av_dovi_get_ext(dovi, dovi->num_ext_blocks++), &ext->dm_dynamic[i], ext_sz);
}
*out_metadata = dovi;
@@ -296,15 +297,23 @@ static int parse_ext_blocks(DOVIContext *s, GetBitContext *gb, int ver)
while (num_ext_blocks--) {
AVDOVIDmData *dm;
-
- if (ext->num_dm >= FF_ARRAY_ELEMS(ext->dm))
- return AVERROR_INVALIDDATA;
- dm = &ext->dm[ext->num_dm++];
+ uint8_t level;
ext_block_length = get_ue_golomb_31(gb);
- dm->level = get_bits(gb, 8);
+ level = get_bits(gb, 8);
start_pos = get_bits_count(gb);
+ if (ff_dovi_rpu_extension_is_static(level)) {
+ if (ext->num_static >= FF_ARRAY_ELEMS(ext->dm_static))
+ return AVERROR_INVALIDDATA;
+ dm = &ext->dm_static[ext->num_static++];
+ } else {
+ if (ext->num_dynamic >= FF_ARRAY_ELEMS(ext->dm_dynamic))
+ return AVERROR_INVALIDDATA;
+ dm = &ext->dm_dynamic[ext->num_dynamic++];
+ }
+
+ dm->level = level;
switch (ver) {
case 1: ret = parse_ext_v1(s, gb, dm); break;
case 2: ret = parse_ext_v2(s, gb, dm, ext_block_length); break;
@@ -674,8 +683,10 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
color->source_diagonal = get_bits(gb, 10);
/* Parse extension blocks */
- if (s->ext_blocks)
- s->ext_blocks->num_dm = 0;
+ if (s->ext_blocks) {
+ DOVIExt *ext = s->ext_blocks;
+ ext->num_static = ext->num_dynamic = 0;
+ }
if ((ret = parse_ext_blocks(s, gb, 1)) < 0) {
ff_dovi_ctx_unref(s);
return ret;
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 667d681c25..7193e2d9c8 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -758,9 +758,14 @@ int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
if (ext) {
size_t ext_sz = FFMIN(sizeof(AVDOVIDmData), metadata->ext_block_size);
- for (int i = 0; i < metadata->num_ext_blocks; i++)
- memcpy(&ext->dm[i], av_dovi_get_ext(metadata, i), ext_sz);
- ext->num_dm = metadata->num_ext_blocks;
+ ext->num_static = ext->num_dynamic = 0;
+ for (int i = 0; i < metadata->num_ext_blocks; i++) {
+ const AVDOVIDmData *dm = av_dovi_get_ext(metadata, i);
+ if (ff_dovi_rpu_extension_is_static(dm->level))
+ memcpy(&ext->dm_static[ext->num_static++], dm, ext_sz);
+ else
+ memcpy(&ext->dm_dynamic[ext->num_dynamic++], dm, ext_sz);
+ }
}
} else {
s->color = &ff_dovi_color_default;
More information about the ffmpeg-cvslog
mailing list