[FFmpeg-devel] [PATCH 7/8] avcodec/dovi_rpudec: reject reserved_zero_3bits != 0

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

This is used by future versions of the spec to implement metadata
compression. Given that we don't yet implement that spec, validate that
this is equal to 0 for now.
---
 libavcodec/dovi_rpudec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 064d74575f..e947870d45 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -412,6 +412,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 int bl_bit_depth_minus8 = get_ue_golomb_31(gb);
 int el_bit_depth_minus8 = get_ue_golomb_31(gb);
 int vdr_bit_depth_minus8 = get_ue_golomb_31(gb);
+int reserved_zero_3bits;
 VALIDATE(bl_bit_depth_minus8, 0, 8);
 VALIDATE(el_bit_depth_minus8, 0, 8);
 VALIDATE(vdr_bit_depth_minus8, 0, 8);
@@ -419,7 +420,8 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 hdr->el_bit_depth = el_bit_depth_minus8 + 8;
 hdr->vdr_bit_depth = vdr_bit_depth_minus8 + 8;
 hdr->spatial_resampling_filter_flag = get_bits1(gb);
-skip_bits(gb, 3); /* reserved_zero_3bits */
+reserved_zero_3bits = get_bits(gb, 3);
+VALIDATE(reserved_zero_3bits, 0, 0);
 hdr->el_spatial_resampling_filter_flag = get_bits1(gb);
 hdr->disable_residual_flag = get_bits1(gb);
 }
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 6/8] avcodec/dovi_rpu: guard ext blocks by dm_metadata_present

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

In the spec, dm_metadata_present also toggles all extension blocks, so
we need to move them inside the branch.
---
 libavcodec/dovi_rpudec.c | 25 +
 libavcodec/dovi_rpuenc.c | 21 -
 2 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 51f824d126..064d74575f 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -613,22 +613,23 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 color->source_min_pq = get_bits(gb, 12);
 color->source_max_pq = get_bits(gb, 12);
 color->source_diagonal = get_bits(gb, 10);
-} else {
-s->color = _dovi_color_default;
-}
-
-/* Parse extension blocks */
-s->num_ext_blocks = 0;
-if ((ret = parse_ext_blocks(s, gb, 1)) < 0) {
-ff_dovi_ctx_unref(s);
-return ret;
-}
 
-if (get_bits_left(gb) > 48 /* padding + CRC32 + terminator */) {
-if ((ret = parse_ext_blocks(s, gb, 2)) < 0) {
+/* Parse extension blocks */
+s->num_ext_blocks = 0;
+if ((ret = parse_ext_blocks(s, gb, 1)) < 0) {
 ff_dovi_ctx_unref(s);
 return ret;
 }
+
+if (get_bits_left(gb) > 48 /* padding + CRC32 + terminator */) {
+if ((ret = parse_ext_blocks(s, gb, 2)) < 0) {
+ff_dovi_ctx_unref(s);
+return ret;
+}
+}
+} else {
+s->color = _dovi_color_default;
+s->num_ext_blocks = 0;
 }
 
 return 0;
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 8fceefe2c1..f7d11c9042 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -508,6 +508,8 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 
 vdr_dm_metadata_present = memcmp(color, _dovi_color_default, 
sizeof(*color));
 use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping));
+if (num_ext_blocks_v1 || num_ext_blocks_v2)
+vdr_dm_metadata_present = 1;
 
 if (vdr_dm_metadata_present && !s->dm) {
 s->dm = ff_refstruct_allocz(sizeof(AVDOVIColorMetadata));
@@ -657,18 +659,19 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 
 memcpy(s->dm, color, sizeof(*color));
 s->color = s->dm;
-}
-
-set_ue_golomb(pb, num_ext_blocks_v1);
-align_put_bits(pb);
-for (int i = 0; i < metadata->num_ext_blocks; i++)
-generate_ext_v1(pb, av_dovi_get_ext(metadata, i));
 
-if (num_ext_blocks_v2) {
-set_ue_golomb(pb, num_ext_blocks_v2);
+/* Extension blocks */
+set_ue_golomb(pb, num_ext_blocks_v1);
 align_put_bits(pb);
 for (int i = 0; i < metadata->num_ext_blocks; i++)
-generate_ext_v2(pb, av_dovi_get_ext(metadata, i));
+generate_ext_v1(pb, av_dovi_get_ext(metadata, i));
+
+if (num_ext_blocks_v2) {
+set_ue_golomb(pb, num_ext_blocks_v2);
+align_put_bits(pb);
+for (int i = 0; i < metadata->num_ext_blocks; i++)
+generate_ext_v2(pb, av_dovi_get_ext(metadata, i));
+}
 }
 
 flush_put_bits(pb);
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 8/8] avcodec/dovi_rpudec: handle errors consistently

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

Only flush state when we started parsing data, otherwise just error out.
Remove the 'fail' label to make this a bit less confusing to read.
---
 libavcodec/dovi_rpudec.c | 23 ---
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index e947870d45..72e4add618 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -123,7 +123,8 @@ static inline unsigned get_variable_bits(GetBitContext *gb, 
int n)
 if (VAR < MIN || VAR > MAX) {  
 \
 av_log(s->logctx, AV_LOG_ERROR, "RPU validation failed: "  
 \
#MIN" <= "#VAR" = %d <= "#MAX"\n", (int) VAR);  
 \
-goto fail; 
 \
+ff_dovi_ctx_unref(s);  
 \
+return AVERROR_INVALIDDATA;
 \
 }  
 \
 } while (0)
 
@@ -306,7 +307,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 uint8_t profile;
 
 if (rpu_size < 5)
-goto fail;
+return AVERROR_INVALIDDATA;
 
 /* Container */
 if (s->cfg.dv_profile == 10 /* dav1.10 */) {
@@ -360,7 +361,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 }
 
 if (!rpu_size || rpu[rpu_size - 1] != 0x80)
-goto fail;
+return AVERROR_INVALIDDATA;
 
 if (err_recognition & AV_EF_CRCCHECK) {
 uint32_t crc = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE),
@@ -368,7 +369,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 if (crc) {
 av_log(s->logctx, AV_LOG_ERROR, "RPU CRC mismatch: %X\n", crc);
 if (err_recognition & AV_EF_EXPLODE)
-goto fail;
+return AVERROR_INVALIDDATA;
 }
 }
 
@@ -439,7 +440,8 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 profile = s->cfg.dv_profile ? s->cfg.dv_profile : 
ff_dovi_guess_profile_hevc(hdr);
 if (profile == 5 && use_nlq) {
 av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
-goto fail;
+ff_dovi_ctx_unref(s);
+return AVERROR_INVALIDDATA;
 }
 
 if (use_prev_vdr_rpu) {
@@ -453,7 +455,8 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
  * out as this corner case is not hit in practice */
 av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU ID: %u\n",
prev_vdr_rpu_id);
-goto fail;
+ff_dovi_ctx_unref(s);
+return AVERROR_INVALIDDATA;
 }
 s->mapping = s->vdr[prev_vdr_rpu_id];
 } else {
@@ -462,8 +465,10 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 VALIDATE(vdr_rpu_id, 0, DOVI_MAX_DM_ID);
 if (!s->vdr[vdr_rpu_id]) {
 s->vdr[vdr_rpu_id] = 
ff_refstruct_allocz(sizeof(AVDOVIDataMapping));
-if (!s->vdr[vdr_rpu_id])
+if (!s->vdr[vdr_rpu_id]) {
+ff_dovi_ctx_unref(s);
 return AVERROR(ENOMEM);
+}
 }
 
 s->mapping = mapping = s->vdr[vdr_rpu_id];
@@ -635,8 +640,4 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 }
 
 return 0;
-
-fail:
-ff_dovi_ctx_unref(s); /* don't leak potentially invalid state */
-return AVERROR_INVALIDDATA;
 }
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/8] avcodec/dovi_rpu: fix dm_metadata_id handling

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

Despite the suggestive size limits, this metadata ID has nothing to do
with the VDR metadata ID used for the data mappings. Actually, the
specification leaves them wholly unexplained, other than acknowleding
their existence. Must be some secret dolby sauce. They're not even
involved in DM metadata compression, which is handled using an entirely
separate ID.

That leaves us with a lack of anything sensible to do with these IDs.
Since we unfortunately only expose one `dm_metadata_id` field to the
user, just ensure that they match; which appears to always be the case
in practice. If somebody ever hits this error, I would really much
rather like to see the triggering file.
---
 libavcodec/dovi_rpu.c|  3 +++
 libavcodec/dovi_rpu.h|  1 +
 libavcodec/dovi_rpudec.c | 30 +++---
 libavcodec/dovi_rpuenc.c | 16 
 4 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 91134e031d..5130a9598d 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -28,6 +28,7 @@
 
 void ff_dovi_ctx_unref(DOVIContext *s)
 {
+ff_refstruct_unref(>dm);
 for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr); i++)
 ff_refstruct_unref(>vdr[i]);
 ff_refstruct_unref(>ext_blocks);
@@ -40,6 +41,7 @@ void ff_dovi_ctx_unref(DOVIContext *s)
 
 void ff_dovi_ctx_flush(DOVIContext *s)
 {
+ff_refstruct_unref(>dm);
 for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr); i++)
 ff_refstruct_unref(>vdr[i]);
 ff_refstruct_unref(>ext_blocks);
@@ -60,6 +62,7 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0)
 s->header = s0->header;
 s->mapping = s0->mapping;
 s->color = s0->color;
+ff_refstruct_replace(>dm, s0->dm);
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
 ff_refstruct_replace(>vdr[i], s0->vdr[i]);
 ff_refstruct_replace(>ext_blocks, s0->ext_blocks);
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index c784afbe4b..da9bd67cde 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -74,6 +74,7 @@ typedef struct DOVIContext {
 /**
  * Private fields internal to dovi_rpu.c
  */
+AVDOVIColorMetadata *dm; ///< RefStruct
 struct DOVIVdr *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
 uint8_t *rpu_buf; ///< temporary buffer
 unsigned rpu_buf_sz;
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index cf2152988c..3e15453705 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -568,25 +568,25 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 int current_dm_id = get_ue_golomb_31(gb);
 VALIDATE(affected_dm_id, 0, DOVI_MAX_DM_ID);
 VALIDATE(current_dm_id, 0, DOVI_MAX_DM_ID);
-if (!s->vdr[affected_dm_id]) {
-s->vdr[affected_dm_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
-if (!s->vdr[affected_dm_id])
-return AVERROR(ENOMEM);
+if (affected_dm_id != current_dm_id) {
+/* The spec does not explain these fields at all, and there is
+ * a lack of samples to understand how they're supposed to work,
+ * so just assert them being equal for now */
+avpriv_request_sample(s->logctx, "affected/current_dm_metadata_id "
+"mismatch? %u != %u\n", affected_dm_id, current_dm_id);
+ff_dovi_ctx_unref(s);
+return AVERROR_PATCHWELCOME;
 }
 
-if (!s->vdr[current_dm_id]) {
-av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU DM ID: %u\n",
-   current_dm_id);
-goto fail;
+if (!s->dm) {
+s->dm = ff_refstruct_allocz(sizeof(AVDOVIColorMetadata));
+if (!s->dm) {
+ff_dovi_ctx_unref(s);
+return AVERROR(ENOMEM);
+}
 }
 
-/* Update current pointer based on current_dm_id */
-vdr = s->vdr[current_dm_id];
-s->color = >color;
-
-/* Update values of affected_dm_id */
-vdr = s->vdr[affected_dm_id];
-color = >color;
+s->color = color = s->dm;
 color->dm_metadata_id = affected_dm_id;
 color->scene_refresh_flag = get_ue_golomb_31(gb);
 for (int i = 0; i < 9; i++)
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 242cd76c58..59e8ed6e3e 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -479,12 +479,6 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 return AVERROR(ENOMEM);
 }
 
-if (!s->vdr[color->dm_metadata_id]) {
-s->vdr[color->dm_metadata_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
-if (!s->vdr[color->dm_metadata_id])

[FFmpeg-devel] [PATCH 2/8] avcodec/dovi_rpu: properly handle vdr_dm_metadata_present

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

When this is 0, the metadata is explicitly inferred to stated default
values from the spec, rather than inferred from the previous frame's
values.

Likewise, when encoding, instead of checking if the value changed since
the last frame, we need to check if it differs from the default.
---
 libavcodec/dovi_rpu.c| 43 
 libavcodec/dovi_rpu.h|  3 +++
 libavcodec/dovi_rpudec.c |  2 ++
 libavcodec/dovi_rpuenc.c | 10 +-
 4 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index b26c19dd5e..91134e031d 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -86,3 +86,46 @@ int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader 
*hdr)
 
 return 0; /* unknown */
 }
+
+const AVDOVIColorMetadata ff_dovi_color_default = {
+.dm_metadata_id = 0,
+.scene_refresh_flag = 0,
+.ycc_to_rgb_matrix = {
+{  9575, 8192 },
+{ 0, 8192 },
+{ 14742, 8192 },
+{  9575, 8192 },
+{  1754, 8192 },
+{  4383, 8192 },
+{  9575, 8192 },
+{ 17372, 8192 },
+{ 0, 8192 },
+},
+.ycc_to_rgb_offset = {
+{ 1, 4 },
+{ 2, 1 },
+{ 2, 1 },
+},
+.rgb_to_lms_matrix = {
+{  5845, 16384 },
+{  9702, 16384 },
+{   837, 16384 },
+{  2568, 16384 },
+{ 12256, 16384 },
+{  1561, 16384 },
+{ 0, 16384 },
+{   679, 16384 },
+{ 15705, 16384 },
+},
+.signal_eotf= 39322,
+.signal_eotf_param0 = 15867,
+.signal_eotf_param1 = 228,
+.signal_eotf_param2 = 1383604,
+.signal_bit_depth   = 14,
+.signal_color_space = 0,
+.signal_chroma_format   = 0,
+.signal_full_range_flag = 1,
+.source_min_pq  = 62,
+.source_max_pq  = 3696,
+.source_diagonal= 42,
+};
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 8ce0c88e9d..c784afbe4b 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -157,4 +157,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
  */
 int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr);
 
+/* Default values for AVDOVIColorMetadata */
+extern const AVDOVIColorMetadata ff_dovi_color_default;
+
 #endif /* AVCODEC_DOVI_RPU_H */
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index d1dcc3a262..cf2152988c 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -616,6 +616,8 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 color->source_min_pq = get_bits(gb, 12);
 color->source_max_pq = get_bits(gb, 12);
 color->source_diagonal = get_bits(gb, 10);
+} else {
+s->color = _dovi_color_default;
 }
 
 /* Parse extension blocks */
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 3c3e0f84c0..242cd76c58 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -441,7 +441,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 const AVDOVIRpuDataHeader *hdr;
 const AVDOVIDataMapping *mapping;
 const AVDOVIColorMetadata *color;
-int vdr_dm_metadata_changed, vdr_rpu_id, use_prev_vdr_rpu, profile,
+int vdr_dm_metadata_present, vdr_rpu_id, use_prev_vdr_rpu, profile,
 buffer_size, rpu_size, pad, zero_run;
 int num_ext_blocks_v1, num_ext_blocks_v2;
 uint32_t crc;
@@ -512,7 +512,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 }
 
-vdr_dm_metadata_changed = !s->color || memcmp(s->color, color, 
sizeof(*color));
+vdr_dm_metadata_present = memcmp(color, _dovi_color_default, 
sizeof(*color));
 use_prev_vdr_rpu = !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, 
sizeof(*mapping));
 
 buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
@@ -529,7 +529,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 }
 }
-if (vdr_dm_metadata_changed)
+if (vdr_dm_metadata_present)
 buffer_size += 67;
 
 av_fast_padded_malloc(>rpu_buf, >rpu_buf_sz, buffer_size);
@@ -560,7 +560,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 s->header = *hdr;
 
-put_bits(pb, 1, vdr_dm_metadata_changed);
+put_bits(pb, 1, vdr_dm_metadata_present);
 put_bits(pb, 1, use_prev_vdr_rpu);
 set_ue_golomb(pb, vdr_rpu_id);
 s->mapping = >vdr[vdr_rpu_id]->mapping;
@@ -632,7 +632,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 memcpy(>vdr[vdr_rpu_id]->mapping, mapping, sizeof(*mapping));
 }
 
-if (vdr_dm_metadata_changed) {
+if (vdr_dm_metadata_present) {
 const int denom = profile == 4 ? (1 << 30) : (1 &l

[FFmpeg-devel] [PATCH 1/8] avdovi/dovi_rpudec: handle prev_vdr_rpu_id failures

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

According to the spec, missing previous VDR RPU IDs do not constitute an
error, but we should instead fallback first to VDR RPU with ID 0, and
failing that, synthesize "neutral" metadata.

That's nontrivial though as the resulting metadata will be dependent on
other properties of the RPU, and this case is not hit in practice so
I'll defer it to a rainy day.
---
 libavcodec/dovi_rpudec.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 7c7eda9d09..d1dcc3a262 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -444,7 +444,12 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 if (use_prev_vdr_rpu) {
 int prev_vdr_rpu_id = get_ue_golomb_31(gb);
 VALIDATE(prev_vdr_rpu_id, 0, DOVI_MAX_DM_ID);
+if (!s->vdr[prev_vdr_rpu_id])
+prev_vdr_rpu_id = 0;
 if (!s->vdr[prev_vdr_rpu_id]) {
+/* FIXME: Technically, the spec says that in this case we should
+ * synthesize "neutral" vdr metadata, but easier to just error
+ * out as this corner case is not hit in practice */
 av_log(s->logctx, AV_LOG_ERROR, "Unknown previous RPU ID: %u\n",
prev_vdr_rpu_id);
 goto fail;
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/8] avcodec/dovi_rpu: simplify vdr type

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

Storing the color metadata alongside the data mapping is no longer
needed, so we can simplify this array's type.
---
 libavcodec/dovi_rpu.h|  7 +--
 libavcodec/dovi_rpudec.c |  6 +++---
 libavcodec/dovi_rpuenc.c | 10 +-
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index da9bd67cde..058d50c64f 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -75,7 +75,7 @@ typedef struct DOVIContext {
  * Private fields internal to dovi_rpu.c
  */
 AVDOVIColorMetadata *dm; ///< RefStruct
-struct DOVIVdr *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
+AVDOVIDataMapping *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
 uint8_t *rpu_buf; ///< temporary buffer
 unsigned rpu_buf_sz;
 
@@ -127,11 +127,6 @@ int ff_dovi_configure(DOVIContext *s, AVCodecContext 
*avctx);
  * The following section is for internal use only. *
  ***/
 
-typedef struct DOVIVdr {
-AVDOVIDataMapping mapping;
-AVDOVIColorMetadata color;
-} DOVIVdr;
-
 enum {
 RPU_COEFF_FIXED = 0,
 RPU_COEFF_FLOAT = 1,
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 753e402dc6..51f824d126 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -453,18 +453,18 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
prev_vdr_rpu_id);
 goto fail;
 }
-s->mapping = >vdr[prev_vdr_rpu_id]->mapping;
+s->mapping = s->vdr[prev_vdr_rpu_id];
 } else {
 AVDOVIDataMapping *mapping;
 int vdr_rpu_id = get_ue_golomb_31(gb);
 VALIDATE(vdr_rpu_id, 0, DOVI_MAX_DM_ID);
 if (!s->vdr[vdr_rpu_id]) {
-s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
+s->vdr[vdr_rpu_id] = 
ff_refstruct_allocz(sizeof(AVDOVIDataMapping));
 if (!s->vdr[vdr_rpu_id])
 return AVERROR(ENOMEM);
 }
 
-s->mapping = mapping = >vdr[vdr_rpu_id]->mapping;
+s->mapping = mapping = s->vdr[vdr_rpu_id];
 mapping->vdr_rpu_id = vdr_rpu_id;
 mapping->mapping_color_space = get_ue_golomb_31(gb);
 mapping->mapping_chroma_format_idc = get_ue_golomb_31(gb);
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 59e8ed6e3e..8fceefe2c1 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -465,7 +465,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 
 vdr_rpu_id = -1;
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++) {
-if (s->vdr[i] && !memcmp(>vdr[i]->mapping, mapping, 
sizeof(*mapping))) {
+if (s->vdr[i] && !memcmp(s->vdr[i], mapping, sizeof(*mapping))) {
 vdr_rpu_id = i;
 break;
 } else if (vdr_rpu_id < 0 && (!s->vdr[i] || i == DOVI_MAX_DM_ID)) {
@@ -474,7 +474,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 
 if (!s->vdr[vdr_rpu_id]) {
-s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(DOVIVdr));
+s->vdr[vdr_rpu_id] = ff_refstruct_allocz(sizeof(AVDOVIDataMapping));
 if (!s->vdr[vdr_rpu_id])
 return AVERROR(ENOMEM);
 }
@@ -507,7 +507,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 
 vdr_dm_metadata_present = memcmp(color, _dovi_color_default, 
sizeof(*color));
-use_prev_vdr_rpu = !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, 
sizeof(*mapping));
+use_prev_vdr_rpu = !memcmp(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping));
 
 if (vdr_dm_metadata_present && !s->dm) {
 s->dm = ff_refstruct_allocz(sizeof(AVDOVIColorMetadata));
@@ -563,7 +563,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 put_bits(pb, 1, vdr_dm_metadata_present);
 put_bits(pb, 1, use_prev_vdr_rpu);
 set_ue_golomb(pb, vdr_rpu_id);
-s->mapping = >vdr[vdr_rpu_id]->mapping;
+s->mapping = s->vdr[vdr_rpu_id];
 
 profile = s->cfg.dv_profile ? s->cfg.dv_profile : 
ff_dovi_guess_profile_hevc(hdr);
 
@@ -629,7 +629,7 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
AVDOVIMetadata *metadata,
 }
 }
 
-memcpy(>vdr[vdr_rpu_id]->mapping, mapping, sizeof(*mapping));
+memcpy(s->vdr[vdr_rpu_id], mapping, sizeof(*mapping));
 }
 
 if (vdr_dm_metadata_present) {
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/8] avcodec/dovi_rpudec: simplify vdr handling (cosmetic)

2024-06-09 Thread Niklas Haas
From: Niklas Haas 

Move `vdr` into local scope and point only to the field we actually care
about.
---
 libavcodec/dovi_rpudec.c | 35 ---
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 3e15453705..753e402dc6 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -296,7 +296,6 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 {
 AVDOVIRpuDataHeader *hdr = >header;
 GetBitContext *gb = &(GetBitContext){0};
-DOVIVdr *vdr;
 int ret;
 
 uint8_t rpu_type;
@@ -454,9 +453,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
prev_vdr_rpu_id);
 goto fail;
 }
-vdr = s->vdr[prev_vdr_rpu_id];
-s->mapping = >mapping;
+s->mapping = >vdr[prev_vdr_rpu_id]->mapping;
 } else {
+AVDOVIDataMapping *mapping;
 int vdr_rpu_id = get_ue_golomb_31(gb);
 VALIDATE(vdr_rpu_id, 0, DOVI_MAX_DM_ID);
 if (!s->vdr[vdr_rpu_id]) {
@@ -465,15 +464,13 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 return AVERROR(ENOMEM);
 }
 
-vdr = s->vdr[vdr_rpu_id];
-s->mapping = >mapping;
-
-vdr->mapping.vdr_rpu_id = vdr_rpu_id;
-vdr->mapping.mapping_color_space = get_ue_golomb_31(gb);
-vdr->mapping.mapping_chroma_format_idc = get_ue_golomb_31(gb);
+s->mapping = mapping = >vdr[vdr_rpu_id]->mapping;
+mapping->vdr_rpu_id = vdr_rpu_id;
+mapping->mapping_color_space = get_ue_golomb_31(gb);
+mapping->mapping_chroma_format_idc = get_ue_golomb_31(gb);
 
 for (int c = 0; c < 3; c++) {
-AVDOVIReshapingCurve *curve = >mapping.curves[c];
+AVDOVIReshapingCurve *curve = >curves[c];
 int num_pivots_minus_2 = get_ue_golomb_31(gb);
 int pivot = 0;
 
@@ -487,28 +484,28 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 
 if (use_nlq) {
 int nlq_pivot = 0;
-vdr->mapping.nlq_method_idc = get_bits(gb, 3);
+mapping->nlq_method_idc = get_bits(gb, 3);
 
 for (int i = 0; i < 2; i++) {
 nlq_pivot += get_bits(gb, hdr->bl_bit_depth);
-vdr->mapping.nlq_pivots[i] = av_clip_uint16(nlq_pivot);
+mapping->nlq_pivots[i] = av_clip_uint16(nlq_pivot);
 }
 
 /**
  * The patent mentions another legal value, NLQ_MU_LAW, but it's
  * not documented anywhere how to parse or apply that type of NLQ.
  */
-VALIDATE(vdr->mapping.nlq_method_idc, 0, AV_DOVI_NLQ_LINEAR_DZ);
+VALIDATE(mapping->nlq_method_idc, 0, AV_DOVI_NLQ_LINEAR_DZ);
 } else {
-vdr->mapping.nlq_method_idc = AV_DOVI_NLQ_NONE;
+mapping->nlq_method_idc = AV_DOVI_NLQ_NONE;
 }
 
-vdr->mapping.num_x_partitions = get_ue_golomb_long(gb) + 1;
-vdr->mapping.num_y_partitions = get_ue_golomb_long(gb) + 1;
+mapping->num_x_partitions = get_ue_golomb_long(gb) + 1;
+mapping->num_y_partitions = get_ue_golomb_long(gb) + 1;
 /* End of rpu_data_header(), start of vdr_rpu_data_payload() */
 
 for (int c = 0; c < 3; c++) {
-AVDOVIReshapingCurve *curve = >mapping.curves[c];
+AVDOVIReshapingCurve *curve = >curves[c];
 for (int i = 0; i < curve->num_pivots - 1; i++) {
 int mapping_idc = get_ue_golomb_31(gb);
 VALIDATE(mapping_idc, 0, 1);
@@ -549,10 +546,10 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 
 if (use_nlq) {
 for (int c = 0; c < 3; c++) {
-AVDOVINLQParams *nlq = >mapping.nlq[c];
+AVDOVINLQParams *nlq = >nlq[c];
 nlq->nlq_offset = get_bits(gb, hdr->el_bit_depth);
 nlq->vdr_in_max = get_ue_coef(gb, hdr);
-switch (vdr->mapping.nlq_method_idc) {
+switch (mapping->nlq_method_idc) {
 case AV_DOVI_NLQ_LINEAR_DZ:
 nlq->linear_deadzone_slope = get_ue_coef(gb, hdr);
 nlq->linear_deadzone_threshold = get_ue_coef(gb, hdr);
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/dovi_rpudec: replace brittle struct copying code

2024-06-05 Thread Niklas Haas
On Wed, 05 Jun 2024 12:07:08 +0200 Andreas Rheinhardt 
 wrote:
> Niklas Haas:
> > From: Niklas Haas 
> > 
> > This code was unnecessarily trying to be robust against downgrades of
> > libavutil (relative to the version libavcodec was compiled against), but
> > in the process, ended up with very brittle code that is easy to
> > accidentally forget to update when adding new fields.
> > 
> > Instead, do the obvious thing and just directly copy the parts of the
> > struct known at compile time. Since it is not generally supported to
> > link against a version of libavutil older than the version libavcodec
> > was compiled against, the struct shrinking externally is not a case we
> > need to be worrying about.
> 
> The exact opposite is true: The code is trying to be robust against
> upgrades of libavutil. The reason for this is potential trailing padding
> in the structures that are copied here. It may be used for actual stuff
> in a future libavutil and the approach you use here allows the compiler
> to clobber it.
> 
> (How would this code be robust against downgrades of libavutil at all?
> There is no check here that sizeof of the side data is big enough to
> contain everything we expect it to contain.)

I should clearly not write code immediately after waking up.

Yes, true, the only thing this logic is trying to accomplish is being
robust against the struct gaining extra padding in the future.

That said, I still think the code as written is brittle and I'm not sure
it's providing anything useful. What is the likelihood of this struct
being extended in a way that does not affect the encoder, vs. the
likelihood of this struct being extended but somebody forgetting to bump
the equivalent "last field" entry in this file?

Anecdotally, the latter has already happened once.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/dovi_rpudec: replace brittle struct copying code

2024-06-05 Thread Niklas Haas
From: Niklas Haas 

This code was unnecessarily trying to be robust against downgrades of
libavutil (relative to the version libavcodec was compiled against), but
in the process, ended up with very brittle code that is easy to
accidentally forget to update when adding new fields.

Instead, do the obvious thing and just directly copy the parts of the
struct known at compile time. Since it is not generally supported to
link against a version of libavutil older than the version libavcodec
was compiled against, the struct shrinking externally is not a case we
need to be worrying about.
---
 libavcodec/dovi_rpudec.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 7c7eda9d09..adf2c00cf5 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -56,14 +56,12 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 return AVERROR(ENOMEM);
 }
 
-/* Copy only the parts of these structs known to us at compiler-time. */
-#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
-COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), >header, 
disable_residual_flag);
-COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots);
-COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, 
source_diagonal);
-ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size);
+*av_dovi_get_header(dovi)  = s->header;
+*av_dovi_get_mapping(dovi) = *s->mapping;
+*av_dovi_get_color(dovi)   = *s->color;
+av_assert0(dovi->ext_block_size >= sizeof(AVDOVIDmData));
 for (int i = 0; i < s->num_ext_blocks; i++)
-memcpy(av_dovi_get_ext(dovi, i), >ext_blocks[i], ext_sz);
+*av_dovi_get_ext(dovi, i) = s->ext_blocks[i];
 dovi->num_ext_blocks = s->num_ext_blocks;
 return 0;
 }
-- 
2.45.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-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avdovi/dovi_rpu{enc, dec}: fix ms_weight handling

2024-05-25 Thread Niklas Haas
From: Niklas Haas 

The code as written was wrong. The l2.ms_weight value is coded as
a *signed* integer, rather than a shifted unsigned integer. (And even
so, the offset of 8192 would be too large, since 2^12 = 4096. Ditto for
l8.ms_weight, which should have an offset of 2048, not 8192)

In addition, because the l8.ms_weight struct member is unsigned, these
shifting semantics ended up overflowing the field, leading to undefined
behavior when transcoding. Fortunately, the damage was relatively
contained in practice, because it just corrupts the coding of this
field, which is ignored in practice in all implementations I have seen.

For some reason, Dolby decided to add a sign bit to l2.ms_weight but not
l3.ms_weight. In either case, it's quite probably that this is still
a shifted unsigned integer in disguise, since all samples seem to have
a value of 2048 for these fields. But without specs, that's guesswork,
and the official DV validator also reports these fields as unsigned
integers with a value of 2048.
---
 libavcodec/dovi_rpudec.c | 4 ++--
 libavcodec/dovi_rpuenc.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 7c7eda9d09..a477dbd4e3 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -142,7 +142,7 @@ static void parse_ext_v1(DOVIContext *s, GetBitContext *gb, 
AVDOVIDmData *dm)
 dm->l2.trim_power = get_bits(gb, 12);
 dm->l2.trim_chroma_weight = get_bits(gb, 12);
 dm->l2.trim_saturation_gain = get_bits(gb, 12);
-dm->l2.ms_weight = get_bits(gb, 13) - 8192;
+dm->l2.ms_weight = get_sbits(gb, 13);
 break;
 case 4:
 dm->l4.anchor_pq = get_bits(gb, 12);
@@ -197,7 +197,7 @@ static void parse_ext_v2(DOVIContext *s, GetBitContext *gb, 
AVDOVIDmData *dm,
 dm->l8.trim_power = get_bits(gb, 12);
 dm->l8.trim_chroma_weight = get_bits(gb, 12);
 dm->l8.trim_saturation_gain = get_bits(gb, 12);
-dm->l8.ms_weight = get_bits(gb, 12) - 8192;
+dm->l8.ms_weight = get_bits(gb, 12);
 if (ext_block_length < 12)
 break;
 dm->l8.target_mid_contrast = get_bits(gb, 12);
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 3c3e0f84c0..dacb8b54e7 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -276,7 +276,7 @@ static void generate_ext_v1(PutBitContext *pb, const 
AVDOVIDmData *dm)
 put_bits(pb, 12, dm->l2.trim_power);
 put_bits(pb, 12, dm->l2.trim_chroma_weight);
 put_bits(pb, 12, dm->l2.trim_saturation_gain);
-put_bits(pb, 13, dm->l2.ms_weight + 8192);
+put_sbits(pb, 13, dm->l2.ms_weight);
 break;
 case 4:
 put_bits(pb, 12, dm->l4.anchor_pq);
@@ -374,7 +374,7 @@ static void generate_ext_v2(PutBitContext *pb, const 
AVDOVIDmData *dm)
 put_bits(pb, 12, dm->l8.trim_power);
 put_bits(pb, 12, dm->l8.trim_chroma_weight);
 put_bits(pb, 12, dm->l8.trim_saturation_gain);
-put_bits(pb, 12, dm->l8.ms_weight + 8192);
+put_bits(pb, 12, dm->l8.ms_weight);
 if (ext_block_length < 12)
 break;
 put_bits(pb, 12, dm->l8.target_mid_contrast);
-- 
2.45.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avcodec/h2645_sei: loosen up min luminance requirements

2024-05-25 Thread Niklas Haas
From: Niklas Haas 

The H.265 specification is quite clear on this case:

> When min_display_mastering_luminance is not in the range of 1 to
> 5, the nominal maximum display luminance of the mastering display
> is unknown or unspecified or specified by other means not specified in
> this Specification.

And so the current code is correct in marking luminance data as invalid
if min luminance is set to 0. However, this breaks playback of at least
several real-world Blu-ray releases, for example La La Land, Planet of
the Apes, and quite possibly a lot more. These come with ostensibly
valid max_luminance tags (1000 nits), but min_luminance set to 0.

Loosen up this requirement by guarding it behind FF_COMPLIANCE_STRICT.
We still reject blatantly invalid metadata (wrong value range on
luminance, max set to 0, max below min, min above 50 nits etc.), so this
shouldn't cause any unintended regressions.

Fixes: https://github.com/mpv-player/mpv/issues/14177
---
 libavcodec/h2645_sei.c | 8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index 1deb76c765..7c83747cd0 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -619,11 +619,15 @@ static int h2645_sei_to_side_data(AVCodecContext *avctx, 
H2645SEI *sei,
 
 metadata->min_luminance.num = sei->mastering_display.min_luminance;
 metadata->min_luminance.den = luma_den;
-metadata->has_luminance &= sei->mastering_display.min_luminance >= 
1 &&
-   sei->mastering_display.min_luminance <= 
5 &&
+metadata->has_luminance &= sei->mastering_display.min_luminance <= 
5 &&
sei->mastering_display.min_luminance <
sei->mastering_display.max_luminance;
 
+/* Real (blu-ray) releases in the wild come with minimum luminance
+ * values of 0.000 cd/m2, so permit this edge case */
+if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT)
+metadata->has_luminance &= 
sei->mastering_display.min_luminance >= 1;
+
 if (metadata->has_luminance || metadata->has_primaries)
 av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
 if (metadata->has_primaries) {
-- 
2.45.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 1/2] lavu/dovi_meta - add fields for ext_mapping_idc

2024-05-23 Thread Niklas Haas
On Wed, 22 May 2024 15:50:43 + Cosmin Stejerean via ffmpeg-devel 
 wrote:
> From: Cosmin Stejerean 
> 
> ---
>  libavutil/dovi_meta.h | 2 ++
>  libavutil/version.h   | 2 +-
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/libavutil/dovi_meta.h b/libavutil/dovi_meta.h
> index e10332f8d7..e168075a24 100644
> --- a/libavutil/dovi_meta.h
> +++ b/libavutil/dovi_meta.h
> @@ -91,6 +91,8 @@ typedef struct AVDOVIRpuDataHeader {
>  uint8_t spatial_resampling_filter_flag;
>  uint8_t el_spatial_resampling_filter_flag;
>  uint8_t disable_residual_flag;
> +uint8_t ext_mapping_idc_0_4; /* extended base layer inverse mapping 
> indicator */
> +uint8_t ext_mapping_idc_5_7; /* reserved */
>  } AVDOVIRpuDataHeader;

What value ranges have you seen for this indicator? Is it possible that
some values would extend the RPU in other ways, adding more bits that we
need to parse?

Maybe we should enforce this to be a well-known value just to be on the
safe side, until we receive public documentation on its purpose.

>  
>  enum AVDOVIMappingMethod {
> diff --git a/libavutil/version.h b/libavutil/version.h
> index 3221c4c592..9c7146c228 100644
> --- a/libavutil/version.h
> +++ b/libavutil/version.h
> @@ -79,7 +79,7 @@
>   */
>  
>  #define LIBAVUTIL_VERSION_MAJOR  59
> -#define LIBAVUTIL_VERSION_MINOR  19
> +#define LIBAVUTIL_VERSION_MINOR  20
>  #define LIBAVUTIL_VERSION_MICRO 100
>  
>  #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
> -- 
> 2.42.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-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2] avcodec/dovi - disable metadata compression by default

2024-05-23 Thread Niklas Haas
On Thu, 23 May 2024 03:45:44 + Cosmin Stejerean via ffmpeg-devel 
 wrote:
> From: Cosmin Stejerean 
> 
> not all clients support metadata compression, output when 
> vdr_dm_metadata_changed fails the DV verifier.
> ---
>  libavcodec/dovi_rpu.h| 10 ++
>  libavcodec/dovi_rpuenc.c |  8 ++--
>  libavcodec/libaomenc.c   |  3 +--
>  libavcodec/libsvtav1.c   |  3 +--
>  libavcodec/libx265.c |  3 +--
>  5 files changed, 19 insertions(+), 8 deletions(-)
> 
> diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
> index 8ce0c88e9d..dee34165c9 100644
> --- a/libavcodec/dovi_rpu.h
> +++ b/libavcodec/dovi_rpu.h
> @@ -28,6 +28,11 @@
>  #include "libavutil/frame.h"
>  #include "avcodec.h"
>  
> +#define DOVI_ENCODING_OPTS \
> +{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
> AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" }, \
> +{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" }, \
> +{ "dv_enable_compression", "Enable Dolby Vision metadata compression", 
> OFFSET(dovi.enable_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
> +

Nit: I would probably parametrize the base struct location (what you
hard-coded as `dovi`), just to avoid leaking per-encoder implementation
specifics. (Maybe somebody will decide to rename or move this struct
down the line)

Introducing this macro could probably be a separate commit also.

>  #define DOVI_MAX_DM_ID 15
>  typedef struct DOVIContext {
>  void *logctx;
> @@ -71,6 +76,11 @@ typedef struct DOVIContext {
>  AVDOVIDmData *ext_blocks;
>  int num_ext_blocks;
>  
> +/**
> + * Enable metadata compression in the output. Currently this is 
> experimental.
> + */
> +int enable_compression;
> +
>  /**
>   * Private fields internal to dovi_rpu.c
>   */
> diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
> index 3c3e0f84c0..26ed25733a 100644
> --- a/libavcodec/dovi_rpuenc.c
> +++ b/libavcodec/dovi_rpuenc.c
> @@ -512,8 +512,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
> AVDOVIMetadata *metadata,
>  }
>  }
>  
> -vdr_dm_metadata_changed = !s->color || memcmp(s->color, color, 
> sizeof(*color));
> -use_prev_vdr_rpu = !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, 
> sizeof(*mapping));
> +// the output when vdr_dm_metadata_changed is 0 fails the DV verifier
> +// force it to 1 until we can get some samples or documentation on 
> correct syntax
> +vdr_dm_metadata_changed = 1; // !s->color || memcmp(s->color, color, 
> sizeof(*color));
> +
> +// not all clients support metadata compression
> +use_prev_vdr_rpu = s->enable_compression && 
> !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, sizeof(*mapping));
>  
>  buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
>  buffer_size += num_ext_blocks_v1 * 13;
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index dec74ebecd..3837eaaec2 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -1487,8 +1487,7 @@ static const AVOption options[] = {
>  { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
> AOM_TUNE_SSIM}, 0, 0, VE, .unit = "tune"},
>  FF_AV1_PROFILE_OPTS
>  { "still-picture", "Encode in single frame mode (typically used for 
> still AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, 
> -1, 1, VE },
> -{ "dolbyvision", "Enable Dolby Vision RPU coding", 
> OFFSET(dovi.enable), AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, 
> VE, .unit = "dovi" },
> -{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" },
> +DOVI_ENCODING_OPTS
>  { "enable-rect-partitions", "Enable rectangular partitions", 
> OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
>  { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", 
> OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
>  { "enable-ab-partitions",   "Enable ab shape partitions",
> OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
> diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
> index 2fef8c8971..d747c31824 100644
> --- a/libavcodec/libsvtav1.c
> +++ b/libavcodec/libsvtav1.c
> @@ -731,8 +731,7 @@ static const AVOption options[] = {
>AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
>  { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated 
> list of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 
> 0, 0, VE },
>  
> -{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
> AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
> -{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" },
> +DOVI_ENCODING_OPTS
>  
>  {NULL},
>  };
> diff --git 

Re: [FFmpeg-devel] [PATCH] avcodec/dovi_rpudec - correctly read el_bit_depth_minus8 when ext_mapping_idc is non-zero

2024-05-21 Thread Niklas Haas
On Tue, 21 May 2024 01:17:32 + Cosmin Stejerean via ffmpeg-devel 
 wrote:
> From: Cosmin Stejerean 
> 
> It looks like the el_bitdepth_minus8 value in the header can also encode
> ext_mapping_idc in the upper 8 bits.
> 
> Samples having a non-zero ext_mapping_idc fail validation currently because 
> the
> value returned is out of range. This bypasses this by currently ignoring the
> ext_mapping_idc and using only the lower 8 bits for el_bitdepth_minus8.

What is ext_mapping_idc? If it's signalled data that can't be
reconstructed, we need to store it somewhere into AVDOVIMetadata and
then re-synthesize it during encoding. Otherwise the RPU transcode will
be lossy.

> 
> ---
>  libavcodec/dovi_rpudec.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
> index 7c7eda9d09..1b11ad3640 100644
> --- a/libavcodec/dovi_rpudec.c
> +++ b/libavcodec/dovi_rpudec.c
> @@ -411,7 +411,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
> size_t rpu_size,
>  
>  if ((hdr->rpu_format & 0x700) == 0) {
>  int bl_bit_depth_minus8 = get_ue_golomb_31(gb);
> -int el_bit_depth_minus8 = get_ue_golomb_31(gb);
> +// this can encode a two byte value, with higher byte being 
> ext_mapping_idc
> +// use only the lower byte for el_bit_depth_minus8
> +uint8_t el_bit_depth_minus8 = get_ue_golomb_long(gb) & 0xFF;
>  int vdr_bit_depth_minus8 = get_ue_golomb_31(gb);
>  VALIDATE(bl_bit_depth_minus8, 0, 8);
>  VALIDATE(el_bit_depth_minus8, 0, 8);
> -- 
> 2.42.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-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/dovi - disable metadata compression by default

2024-05-21 Thread Niklas Haas
On Tue, 21 May 2024 04:03:43 + Cosmin Stejerean via ffmpeg-devel 
 wrote:
> From: Cosmin Stejerean 
> 
> not all clients support metadata compression, make this an option and off by
> default until we can verify output.
> 
> vdr_dm_metadata_changed = 0 case fails the DV verifier so force this to true
> for now until we can determine the correct output format for this case.

This approach seems reasonable to me, at least until we get those specs.

>
> 
> ---
>  libavcodec/dovi_rpu.h| 5 +
>  libavcodec/dovi_rpuenc.c | 8 ++--
>  libavcodec/libaomenc.c   | 1 +
>  libavcodec/libsvtav1.c   | 1 +
>  libavcodec/libx265.c | 1 +
>  5 files changed, 14 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
> index 8ce0c88e9d..fca30804ae 100644
> --- a/libavcodec/dovi_rpu.h
> +++ b/libavcodec/dovi_rpu.h
> @@ -71,6 +71,11 @@ typedef struct DOVIContext {
>  AVDOVIDmData *ext_blocks;
>  int num_ext_blocks;
>  
> +/**
> + * Enable metadata compression in the output. Currently this is 
> experimental.
> + */
> +int enable_compression;
> +
>  /**
>   * Private fields internal to dovi_rpu.c
>   */
> diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
> index 3c3e0f84c0..26ed25733a 100644
> --- a/libavcodec/dovi_rpuenc.c
> +++ b/libavcodec/dovi_rpuenc.c
> @@ -512,8 +512,12 @@ int ff_dovi_rpu_generate(DOVIContext *s, const 
> AVDOVIMetadata *metadata,
>  }
>  }
>  
> -vdr_dm_metadata_changed = !s->color || memcmp(s->color, color, 
> sizeof(*color));
> -use_prev_vdr_rpu = !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, 
> sizeof(*mapping));
> +// the output when vdr_dm_metadata_changed is 0 fails the DV verifier
> +// force it to 1 until we can get some samples or documentation on 
> correct syntax
> +vdr_dm_metadata_changed = 1; // !s->color || memcmp(s->color, color, 
> sizeof(*color));
> +
> +// not all clients support metadata compression
> +use_prev_vdr_rpu = s->enable_compression && 
> !memcmp(>vdr[vdr_rpu_id]->mapping, mapping, sizeof(*mapping));
>  
>  buffer_size = 12 /* vdr seq info */ + 5 /* CRC32 + terminator */;
>  buffer_size += num_ext_blocks_v1 * 13;
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index dec74ebecd..c6104f5522 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -1489,6 +1489,7 @@ static const AVOption options[] = {
>  { "still-picture", "Encode in single frame mode (typically used for 
> still AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, 
> -1, 1, VE },
>  { "dolbyvision", "Enable Dolby Vision RPU coding", 
> OFFSET(dovi.enable), AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, 
> VE, .unit = "dovi" },
>  {   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" },
> +{ "dv_enable_compression", "Enable Dolby Vision metadata compression", 
> OFFSET(dovi.enable_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
>  { "enable-rect-partitions", "Enable rectangular partitions", 
> OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
>  { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", 
> OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
>  { "enable-ab-partitions",   "Enable ab shape partitions",
> OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
> diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
> index 2fef8c8971..86bb6686dd 100644
> --- a/libavcodec/libsvtav1.c
> +++ b/libavcodec/libsvtav1.c
> @@ -733,6 +733,7 @@ static const AVOption options[] = {
>  
>  { "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
> AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
>  {   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" },
> +{ "dv_enable_compression", "Enable Dolby Vision metadata compression", 
> OFFSET(dovi.enable_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
>  
>  {NULL},
>  };
> diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
> index ac1dbc4f97..2a79a5e6da 100644
> --- a/libavcodec/libx265.c
> +++ b/libavcodec/libx265.c
> @@ -953,6 +953,7 @@ static const AVOption options[] = {
>  #if X265_BUILD >= 167
>  { "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
> AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
>  {   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, 
> .flags = VE, .unit = "dovi" },
> +{ "dv_enable_compression", "Enable Dolby Vision metadata compression", 
> OFFSET(dovi.enable_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, VE },
>  #endif

Setting up an extra AVClass here seems more hassle than it's worth, but
maybe we could at least hide these options behind a preprocessor
definition so that 

[FFmpeg-devel] [PATCH] avfilter/vf_scale: add missing filter flag

2024-05-03 Thread Niklas Haas
From: Niklas Haas 

Fixes: bb8044581366fe286e16b14515d873979133dbda
---
 libavfilter/vf_scale.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index bc53571c1c..696ee272ec 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -1261,6 +1261,7 @@ const AVFilter ff_vf_scale = {
 FILTER_QUERY_FUNC(query_formats),
 .activate= activate,
 .process_command = process_command,
+.flags   = AVFILTER_FLAG_DYNAMIC_INPUTS,
 };
 
 static const AVFilterPad avfilter_vf_scale2ref_inputs[] = {
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-05-02 Thread Niklas Haas
On Thu, 11 Apr 2024 00:09:05 +0200 Michael Niedermayer  
wrote:
> On Mon, Apr 08, 2024 at 11:55:02PM +0200, Niklas Haas wrote:
> > On Mon, 08 Apr 2024 22:18:33 +0200 Michael Niedermayer 
> >  wrote:
> > > On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> > > > From: Niklas Haas 
> > > > 
> > > > This replaces the myriad of existing lists in AVCodec by a unified API
> > > > call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> > > > substantially, while also making this more trivially extensible.
> > > > 
> > > > In addition to the already covered lists, add two new entries for color
> > > > space and color range, mirroring the newly added negotiable fields in
> > > > libavfilter.
> > > > 
> > > > I decided to drop the explicit length field from the API proposed by
> > > > Andreas Rheinhardt, because having it in place ended up complicating
> > > > both the codec side and the client side implementations, while also
> > > > being strictly less flexible (it's trivial to recover a length given
> > > > a terminator, but requires allocation to add a terminator given
> > > > a length). Using a terminator also presents less of a porting challenge
> > > > for existing users of the current API.
> > > > 
> > > > Once the deprecation period passes for the existing public fields, the
> > > > rough plan is to move the commonly used fields (such as
> > > > pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> > > > configuration types, and then implement the rarely used fields with
> > > > custom callbacks.
> > > > ---
> > > >  doc/APIchanges  |  5 
> > > >  libavcodec/avcodec.c| 51 +
> > > >  libavcodec/avcodec.h| 27 
> > > >  libavcodec/codec.h  | 19 +++---
> > > >  libavcodec/codec_internal.h | 21 +++
> > > >  libavcodec/version.h|  4 +--
> > > >  6 files changed, 121 insertions(+), 6 deletions(-)
> > > 
> > > This patchset seems to overlap a bit with AVOptionRanges
> > > 
> > > I think ideally the user should at some point be able to query using some
> > > API on a AVCodecContext/AVCodecParameters/AVFormatContex/AVStream
> > > what for that specific instance are supported settings for each field
> > > 
> > > The API here seems to use a enum, which can make sense but it differs from
> > > how AVOption works which doesnt use enums to identify fields
> > 
> > I didn't know AVOptionRanges exists; indeed it can be seen as somewhat
> > overlapping here. That said, there is a vital distinction here: 
> > AVOptionRanges
> > represents *static* limits on what options can be set (e.g. via
> > `av_opt_set_int`), whereas this API represents *dynamic* limits on what can 
> > be
> > coded.
> 
> AVOptionRanges where definitly not intended to be static
> 
> see the docs:
>  * The returned list may depend on other fields in obj like for example 
> profile.
> 
> that would not be static
> 
> 
> 
> > 
> > In particular, the list of supported colorspaces etc. can *depend* on the 
> > value
> > of other options. Currently, only strict_std_compliance, but I can easily 
> > see
> > this list growing in the future (e.g. for different profiles, dolbyvision,
> > ...).
> > 
> > That aside, I personally find an API based on strings and doubles rather
> > cumbersome to use, especially when downstream clients expect an enum list.
> 
> AVOption* is intended to be a generic API.
> For example something that an App can query to build a drop down menu in a GUI
> for each parameter
> 
> For this, it must be possible to iterate over all paremeters, then for each
> iterate over all possible settings if its a discrete type or range if its a
> continous type. And then present the user with the corresponding GUI elements
> 
> thx

Okay, then I do not present as strong an objection as I thought. That
said, I still think that downstream API users will be very thankful for
having a replacement API that's easy to migrate to, rather one that's
IMO rather difficult to use (and which requires both FPU and malloc to
access what used to be just a static list).

What do other people think? Should we introduce this new API as-is, or
should it be scrapped in favor of reusing AVOptionRanges?
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 0/5] replace scale2ref by scale=rw:rh

2024-05-02 Thread Niklas Haas
On Wed, 24 Apr 2024 12:51:55 +0200 Niklas Haas  wrote:
> As discussed in my previous series for fixing scale2ref[1], this filter
> is fundamentally broken, and the only real fix would be to switch to
> activate(), or ideally FFFrameSync.
> 
> [1] https://ffmpeg.org//pipermail/ffmpeg-devel/2024-March/323382.html
> 
> The main thing making this difficult is the fact that scale2ref also
> wants to output ref frames to its secondary output, which FFFrameSync
> does not support, and which is ultimately at least part of the root
> cause of trac #10795.
> 
> Since this is in principle completely unnecessary (users can just
> 'split' the ref input and have it be consumed by vf_scale), and to make
> the design of this filter a bit more robust and maintainable, switch to
> an approach where vf_scale itself gains the ability to reference
> a secondary input stream, using the "ref_*" series of variables.
> 
> This makes the current [i][ri]scale2ref[o][ro] equivalent to the only
> slightly more verbose [ri]split[t][ro]; [i][t]scale=rw:rh[o]. (And
> conversely, it is no longer necessary to use nullsink to consume an
> unused [ro])
> 
> Incidentally, I think it would be nice if lavfi could *automatically*
> split filter links referenced multiple times, so we could just write
> e.g. [i][ri]scale=rw:rh[o]; [ri][o]overlay[out] and have it work. Maybe
> I'll try getting that to work, next.
> 
> Either way, after the deprecation period has elapsed, we can delete
> scale2ref from the codebase in order to make vf_scale.c IMHO
> significantly simpler versus the status quo.
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Will merge in around 24h if there is no objection, as this is fixing
a bug marked important.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/6] avutil/frame: add av_frame_remove_side_data_changed

2024-05-02 Thread Niklas Haas
On Fri, 26 Apr 2024 16:29:03 -0300 James Almer  wrote:
> On 4/26/2024 9:27 AM, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > Many filters modify certain aspects of frame data, e.g. through resizing
> > (vf_*scale* family), color volume mapping (vf_lut*, vf_tonemap*), or
> > possibly others.
> > 
> > When this happens, we should strip all frame side data that will no
> > longer be correct/relevant after the operation. For example, changing
> > the image size should invalidate AV_FRAME_DATA_PANSCAN because the crop
> > window (given in pixels) no longer corresponds to the actual image size.
> > For another example, tone-mapping filters (e.g. from HDR to SDR) should
> > strip all of the dynamic HDR related metadata.
> > 
> > Since there are a lot of similar with basically similar operations, it
> > make sense to consolidate this stripping logic into a common helper
> > function. I decided to put it into libavutil as it may be useful for API
> > users as well, who often have their own internal processing and
> > filtering.
> 
> Maybe instead of "changed", which is a concept that doesn't belong to a 
> frame but to a process, use a name that references side data that 
> depends on specific properties (dimensions, color props, etc).
> 
> Also, don't make it depend on AVFrame, but AVFrameSideData instead, so 
> it can be reused in other contexts (Use the av_frame_side_data_* 
> namespace for it).

Do you have a proposed name?

I can think of:
- av_frame_side_data_remove_aspect()
- av_frame_side_data_remove_dependent()
- av_frame_side_data_remove_category()

Not sure if I like any more (which is why I went with _changed(), which
tells you exactly when this function was intended to be used).
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 1/6] avutil/frame: add av_frame_remove_side_data_changed

2024-04-26 Thread Niklas Haas
On Fri, 26 Apr 2024 14:27:58 +0200 Niklas Haas  wrote:
> From: Niklas Haas 
> 
> Many filters modify certain aspects of frame data, e.g. through resizing
> (vf_*scale* family), color volume mapping (vf_lut*, vf_tonemap*), or
> possibly others.
> 
> When this happens, we should strip all frame side data that will no
> longer be correct/relevant after the operation. For example, changing
> the image size should invalidate AV_FRAME_DATA_PANSCAN because the crop
> window (given in pixels) no longer corresponds to the actual image size.
> For another example, tone-mapping filters (e.g. from HDR to SDR) should
> strip all of the dynamic HDR related metadata.
> 
> Since there are a lot of similar with basically similar operations, it
> make sense to consolidate this stripping logic into a common helper
> function. I decided to put it into libavutil as it may be useful for API
> users as well, who often have their own internal processing and
> filtering.
> ---
>  doc/APIchanges  |  3 +++
>  libavutil/frame.c   | 31 +++
>  libavutil/frame.h   | 14 ++
>  libavutil/version.h |  2 +-
>  4 files changed, 49 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/APIchanges b/doc/APIchanges
> index 0566fcdcc5..26af725528 100644
> --- a/doc/APIchanges
> +++ b/doc/APIchanges
> @@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
>  
>  API changes, most recent first:
>  
> +2024-04-xx - xx - lavu 59.17.100 - frame.h
> +  Add av_frame_remove_side_data_changed().
> +
>  2024-04-24 - 8616cfe0890 - lavu 59.16.100 - opt.h
>Add AV_OPT_SERIALIZE_SEARCH_CHILDREN.
>  
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 0775e2abd9..d5482c258e 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -1015,6 +1015,37 @@ void av_frame_remove_side_data(AVFrame *frame, enum 
> AVFrameSideDataType type)
>  remove_side_data(>side_data, >nb_side_data, type);
>  }
>  
> +static const struct {
> +enum AVFrameSideDataType type;
> +int aspect;
> +} side_data_aspects[] = {
> +{ AV_FRAME_DATA_PANSCAN,AV_FRAME_CHANGED_SIZE },
> +{ AV_FRAME_DATA_MOTION_VECTORS, AV_FRAME_CHANGED_SIZE },
> +{ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, 
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +
> +{ AV_FRAME_DATA_SPHERICAL,  AV_FRAME_CHANGED_SIZE },
> +{ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_ICC_PROFILE,
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_DYNAMIC_HDR_PLUS,   
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_REGIONS_OF_INTEREST,AV_FRAME_CHANGED_SIZE },
> +{ AV_FRAME_DATA_DETECTION_BBOXES,   AV_FRAME_CHANGED_SIZE },
> +{ AV_FRAME_DATA_DOVI_RPU_BUFFER,
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_DOVI_METADATA,  
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_DYNAMIC_HDR_VIVID,  
> AV_FRAME_CHANGED_COLOR_VOLUME },
> +{ AV_FRAME_DATA_VIDEO_HINT, AV_FRAME_CHANGED_SIZE },
> +};
> +
> +void av_frame_remove_side_data_changed(AVFrame *frame, int changed_aspects)
> +{
> +if (!changed_aspects)
> +return;
> +
> +for (int i = 0; i < FF_ARRAY_ELEMS(side_data_aspects); i++) {
> +if (changed_aspects & side_data_aspects[i].aspect)
> +av_frame_remove_side_data(frame, side_data_aspects[i].type);
> +}
> +}
> +
>  const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType 
> type)
>  {
>  unsigned t = type;
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 60bb966f8b..7e07ecf91f 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -983,6 +983,20 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame 
> *frame,
>   */
>  void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType 
> type);
>  
> +/**
> + * Flags for stripping side data based on changed aspects.
> + */
> +enum {
> +/* Video only */
> +AV_FRAME_CHANGED_SIZE   = 1 << 0, ///< changed dimensions / crop
> +AV_FRAME_CHANGED_COLOR_VOLUME   = 1 << 1, ///< changed color volume
> +};

We almost surely also want to do something similar for audio-related
metadata. I'm not too familiar with audio, does something like this seem
right?

On changing channel layout:
- strip AV_FRAME_DATA_MATRIXENCODING
- strip AV_FRAME_DATA_DOWNMIX_INFO
- strip AV_FRAME_DATA_REPLAYGAIN (maybe?)

On changing sample rate:
- strip AV_FRAME_DATA_SKIP_SAMPLES

Anything else?

What about S12M_TIMECODE / GOP

[FFmpeg-devel] [PATCH 6/6] avfilter/vf_lut*: strip color volume metadata

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

These filters, in general, will apply some arbitrary color volume
transformation. Strip corresponding metadata to be conservative/safe.
---
 libavfilter/vf_lut.c   | 2 ++
 libavfilter/vf_lut2.c  | 1 +
 libavfilter/vf_lut3d.c | 2 ++
 3 files changed, 5 insertions(+)

diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c
index 01df8f287d..89884dd315 100644
--- a/libavfilter/vf_lut.c
+++ b/libavfilter/vf_lut.c
@@ -537,6 +537,8 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
 av_frame_copy_props(out, in);
 }
 
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_COLOR_VOLUME);
+
 if (s->is_rgb && s->is_16bit && !s->is_planar) {
 /* packed, 16-bit */
 PACKED_THREAD_DATA
diff --git a/libavfilter/vf_lut2.c b/libavfilter/vf_lut2.c
index 1f0661a0f5..123bfb2e17 100644
--- a/libavfilter/vf_lut2.c
+++ b/libavfilter/vf_lut2.c
@@ -610,6 +610,7 @@ static int tlut2_filter_frame(AVFilterLink *inlink, AVFrame 
*frame)
 }
 
 av_frame_copy_props(out, frame);
+av_frame_remove_side_data_changed(out, 
AV_FRAME_CHANGED_COLOR_VOLUME);
 
 td.out  = out;
 td.srcx = frame;
diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c
index b3ddd3e69f..84c1405b26 100644
--- a/libavfilter/vf_lut3d.c
+++ b/libavfilter/vf_lut3d.c
@@ -1175,6 +1175,8 @@ static AVFrame *apply_lut(AVFilterLink *inlink, AVFrame 
*in)
 av_frame_copy_props(out, in);
 }
 
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_COLOR_VOLUME);
+
 td.in  = in;
 td.out = out;
 ff_filter_execute(ctx, lut3d->interp, , NULL,
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/6] avfilter/vf_colorspace: strip color volume metadata

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

---
 libavfilter/vf_colorspace.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/libavfilter/vf_colorspace.c b/libavfilter/vf_colorspace.c
index 7bacd7892a..46c442f3fb 100644
--- a/libavfilter/vf_colorspace.c
+++ b/libavfilter/vf_colorspace.c
@@ -750,6 +750,10 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
 } else {
 out->color_trc   = s->user_trc;
 }
+
+if (out->color_primaries != in->color_primaries || out->color_trc != 
in->color_trc)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_COLOR_VOLUME);
+
 if (rgb_sz != s->rgb_sz) {
 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(out->format);
 int uvw = in->width >> desc->log2_chroma_w;
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/6] avfilter/vf_libplacebo: update metadata stripping logic

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

Switches to av_frame_remove_side_data_changed(), covering a number of
cases that we previously ignored. Additionally, stop stripping metadata
when merely changing colorspace or color range, since these do not
affect the actual color volume of the image data, only the encoding.
---
 libavfilter/vf_libplacebo.c | 23 ---
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/libavfilter/vf_libplacebo.c b/libavfilter/vf_libplacebo.c
index be9000aa8e..17da6fc71d 100644
--- a/libavfilter/vf_libplacebo.c
+++ b/libavfilter/vf_libplacebo.c
@@ -806,7 +806,7 @@ static void update_crops(AVFilterContext *ctx, 
LibplaceboInput *in,
 /* Construct and emit an output frame for a given timestamp */
 static int output_frame(AVFilterContext *ctx, int64_t pts)
 {
-int err = 0, ok, changed_csp;
+int err = 0, ok, changed;
 LibplaceboContext *s = ctx->priv;
 pl_options opts = s->opts;
 AVFilterLink *outlink = ctx->outputs[0];
@@ -842,6 +842,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
  * output colorspace defaults */
 out->color_primaries = AVCOL_PRI_BT2020;
 out->color_trc = AVCOL_TRC_SMPTE2084;
+changed |= AV_FRAME_CHANGED_COLOR_VOLUME;
 }
 
 if (s->color_trc >= 0)
@@ -849,21 +850,13 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
 if (s->color_primaries >= 0)
 out->color_primaries = s->color_primaries;
 
-changed_csp = ref->colorspace  != out->colorspace ||
-  ref->color_range != out->color_range||
-  ref->color_trc   != out->color_trc  ||
-  ref->color_primaries != out->color_primaries;
-
 /* Strip side data if no longer relevant */
-if (changed_csp) {
-av_frame_remove_side_data(out, 
AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
-av_frame_remove_side_data(out, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
-av_frame_remove_side_data(out, AV_FRAME_DATA_ICC_PROFILE);
-}
-if (s->apply_dovi || changed_csp) {
-av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_RPU_BUFFER);
-av_frame_remove_side_data(out, AV_FRAME_DATA_DOVI_METADATA);
-}
+if (out->width != ref->width || out->height != ref->height)
+changed |= AV_FRAME_CHANGED_SIZE;
+if (ref->color_trc != out->color_trc || ref->color_primaries != 
out->color_primaries)
+changed |= AV_FRAME_CHANGED_COLOR_VOLUME;
+av_frame_remove_side_data_changed(out, changed);
+
 if (s->apply_filmgrain)
 av_frame_remove_side_data(out, AV_FRAME_DATA_FILM_GRAIN_PARAMS);
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/6] avfilter/vf_zscale: strip metadata on change

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

Required for both size chnages and color volume changes (as a result of
changing primaries/transfer).
---
 libavfilter/vf_zscale.c | 8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libavfilter/vf_zscale.c b/libavfilter/vf_zscale.c
index 45f1bd25ce..c012464615 100644
--- a/libavfilter/vf_zscale.c
+++ b/libavfilter/vf_zscale.c
@@ -783,7 +783,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
 const AVPixFmtDescriptor *odesc = av_pix_fmt_desc_get(outlink->format);
 char buf[32];
-int ret = 0;
+int ret = 0, changed = 0;
 AVFrame *out = NULL;
 ThreadData td;
 
@@ -880,6 +880,12 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
   (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
   INT_MAX);
 
+if (out->width != in->width || out->height != in->height)
+changed |= AV_FRAME_CHANGED_SIZE;
+if (out->color_trc != in->color_trc || out->color_primaries != 
in->color_primaries)
+changed |= AV_FRAME_CHANGED_COLOR_VOLUME;
+av_frame_remove_side_data_changed(out, changed);
+
 td.in = in;
 td.out = out;
 td.desc = desc;
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 2/6] avfilter/vf_scale*: strip metadata on size change

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

---
 libavfilter/vf_scale.c| 2 ++
 libavfilter/vf_scale_cuda.c   | 3 +++
 libavfilter/vf_scale_npp.c| 3 +++
 libavfilter/vf_scale_vaapi.c  | 3 +++
 libavfilter/vf_scale_vt.c | 3 +++
 libavfilter/vf_scale_vulkan.c | 3 +++
 6 files changed, 17 insertions(+)

diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 1c07daeddf..7b9be039ad 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -870,6 +870,8 @@ scale:
 out->height = outlink->h;
 out->color_range = outlink->color_range;
 out->colorspace = outlink->colorspace;
+if (out->width != in->width || out->height != in->height)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_SIZE);
 
 if (scale->output_is_pal)
 avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == 
AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format);
diff --git a/libavfilter/vf_scale_cuda.c b/libavfilter/vf_scale_cuda.c
index 5571a52b1e..1e381d6e52 100644
--- a/libavfilter/vf_scale_cuda.c
+++ b/libavfilter/vf_scale_cuda.c
@@ -525,6 +525,9 @@ static int cudascale_scale(AVFilterContext *ctx, AVFrame 
*out, AVFrame *in)
 if (ret < 0)
 return ret;
 
+if (out->width != in->width || out->height != in->height)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_SIZE);
+
 return 0;
 }
 
diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c
index 27e5e584ae..ed09f4f301 100644
--- a/libavfilter/vf_scale_npp.c
+++ b/libavfilter/vf_scale_npp.c
@@ -892,6 +892,9 @@ scale:
 if (ret < 0)
 return ret;
 
+if (out->width != in->width || out->height != in->height)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_SIZE);
+
 return 0;
 }
 
diff --git a/libavfilter/vf_scale_vaapi.c b/libavfilter/vf_scale_vaapi.c
index 5f20b8a43c..cf7af5c68e 100644
--- a/libavfilter/vf_scale_vaapi.c
+++ b/libavfilter/vf_scale_vaapi.c
@@ -137,6 +137,9 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, 
AVFrame *input_frame)
 if (err < 0)
 goto fail;
 
+if (output_frame->width != input_frame->width || output_frame->height != 
input_frame->height)
+av_frame_remove_side_data_changed(output_frame, AV_FRAME_CHANGED_SIZE);
+
 if (ctx->colour_primaries != AVCOL_PRI_UNSPECIFIED)
 output_frame->color_primaries = ctx->colour_primaries;
 if (ctx->colour_transfer != AVCOL_TRC_UNSPECIFIED)
diff --git a/libavfilter/vf_scale_vt.c b/libavfilter/vf_scale_vt.c
index af4a8b32c6..085f14d5fe 100644
--- a/libavfilter/vf_scale_vt.c
+++ b/libavfilter/vf_scale_vt.c
@@ -141,6 +141,9 @@ static int scale_vt_filter_frame(AVFilterLink *link, 
AVFrame *in)
 if (ret < 0)
 goto fail;
 
+if (out->width != in->width || out->height != in->height)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_SIZE);
+
 av_reduce(>sample_aspect_ratio.num, >sample_aspect_ratio.den,
   (int64_t)in->sample_aspect_ratio.num * outlink->h * link->w,
   (int64_t)in->sample_aspect_ratio.den * outlink->w * link->h,
diff --git a/libavfilter/vf_scale_vulkan.c b/libavfilter/vf_scale_vulkan.c
index 7210509de3..957f99a4d5 100644
--- a/libavfilter/vf_scale_vulkan.c
+++ b/libavfilter/vf_scale_vulkan.c
@@ -288,6 +288,9 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, 
AVFrame *in)
 if (err < 0)
 goto fail;
 
+if (out->width != in->width || out->height != in->height)
+av_frame_remove_side_data_changed(out, AV_FRAME_CHANGED_SIZE);
+
 if (s->out_range != AVCOL_RANGE_UNSPECIFIED)
 out->color_range = s->out_range;
 if (s->vkctx.output_format != s->vkctx.input_format)
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 1/6] avutil/frame: add av_frame_remove_side_data_changed

2024-04-26 Thread Niklas Haas
From: Niklas Haas 

Many filters modify certain aspects of frame data, e.g. through resizing
(vf_*scale* family), color volume mapping (vf_lut*, vf_tonemap*), or
possibly others.

When this happens, we should strip all frame side data that will no
longer be correct/relevant after the operation. For example, changing
the image size should invalidate AV_FRAME_DATA_PANSCAN because the crop
window (given in pixels) no longer corresponds to the actual image size.
For another example, tone-mapping filters (e.g. from HDR to SDR) should
strip all of the dynamic HDR related metadata.

Since there are a lot of similar with basically similar operations, it
make sense to consolidate this stripping logic into a common helper
function. I decided to put it into libavutil as it may be useful for API
users as well, who often have their own internal processing and
filtering.
---
 doc/APIchanges  |  3 +++
 libavutil/frame.c   | 31 +++
 libavutil/frame.h   | 14 ++
 libavutil/version.h |  2 +-
 4 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 0566fcdcc5..26af725528 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2024-03-07
 
 API changes, most recent first:
 
+2024-04-xx - xx - lavu 59.17.100 - frame.h
+  Add av_frame_remove_side_data_changed().
+
 2024-04-24 - 8616cfe0890 - lavu 59.16.100 - opt.h
   Add AV_OPT_SERIALIZE_SEARCH_CHILDREN.
 
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 0775e2abd9..d5482c258e 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -1015,6 +1015,37 @@ void av_frame_remove_side_data(AVFrame *frame, enum 
AVFrameSideDataType type)
 remove_side_data(>side_data, >nb_side_data, type);
 }
 
+static const struct {
+enum AVFrameSideDataType type;
+int aspect;
+} side_data_aspects[] = {
+{ AV_FRAME_DATA_PANSCAN,AV_FRAME_CHANGED_SIZE },
+{ AV_FRAME_DATA_MOTION_VECTORS, AV_FRAME_CHANGED_SIZE },
+{ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA, AV_FRAME_CHANGED_COLOR_VOLUME 
},
+
+{ AV_FRAME_DATA_SPHERICAL,  AV_FRAME_CHANGED_SIZE },
+{ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_ICC_PROFILE,AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_DYNAMIC_HDR_PLUS,   AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_REGIONS_OF_INTEREST,AV_FRAME_CHANGED_SIZE },
+{ AV_FRAME_DATA_DETECTION_BBOXES,   AV_FRAME_CHANGED_SIZE },
+{ AV_FRAME_DATA_DOVI_RPU_BUFFER,AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_DOVI_METADATA,  AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_DYNAMIC_HDR_VIVID,  AV_FRAME_CHANGED_COLOR_VOLUME 
},
+{ AV_FRAME_DATA_VIDEO_HINT, AV_FRAME_CHANGED_SIZE },
+};
+
+void av_frame_remove_side_data_changed(AVFrame *frame, int changed_aspects)
+{
+if (!changed_aspects)
+return;
+
+for (int i = 0; i < FF_ARRAY_ELEMS(side_data_aspects); i++) {
+if (changed_aspects & side_data_aspects[i].aspect)
+av_frame_remove_side_data(frame, side_data_aspects[i].type);
+}
+}
+
 const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType 
type)
 {
 unsigned t = type;
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 60bb966f8b..7e07ecf91f 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -983,6 +983,20 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame 
*frame,
  */
 void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type);
 
+/**
+ * Flags for stripping side data based on changed aspects.
+ */
+enum {
+/* Video only */
+AV_FRAME_CHANGED_SIZE   = 1 << 0, ///< changed dimensions / crop
+AV_FRAME_CHANGED_COLOR_VOLUME   = 1 << 1, ///< changed color volume
+};
+
+/**
+ * Remove all relevant side data after a corresponding change to the frame
+ * data, based on the given bitset of frame aspects.
+ */
+void av_frame_remove_side_data_changed(AVFrame *frame, int changed_aspects);
 
 /**
  * Flags for frame cropping.
diff --git a/libavutil/version.h b/libavutil/version.h
index ea289c406f..3b5a2e7aaa 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -79,7 +79,7 @@
  */
 
 #define LIBAVUTIL_VERSION_MAJOR  59
-#define LIBAVUTIL_VERSION_MINOR  16
+#define LIBAVUTIL_VERSION_MINOR  17
 #define LIBAVUTIL_VERSION_MICRO 100
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 0/5] replace scale2ref by scale=rw:rh

2024-04-24 Thread Niklas Haas
On Wed, 24 Apr 2024 16:48:54 +0530 Gyan Doshi  wrote:
> 
> 
> On 2024-04-24 04:21 pm, Niklas Haas wrote:
> > As discussed in my previous series for fixing scale2ref[1], this filter
> > is fundamentally broken, and the only real fix would be to switch to
> > activate(), or ideally FFFrameSync.
> >
> > [1] https://ffmpeg.org//pipermail/ffmpeg-devel/2024-March/323382.html
> >
> > The main thing making this difficult is the fact that scale2ref also
> > wants to output ref frames to its secondary output, which FFFrameSync
> > does not support, and which is ultimately at least part of the root
> > cause of trac #10795.
> >
> > Since this is in principle completely unnecessary (users can just
> > 'split' the ref input and have it be consumed by vf_scale), and to make
> > the design of this filter a bit more robust and maintainable, switch to
> > an approach where vf_scale itself gains the ability to reference
> > a secondary input stream, using the "ref_*" series of variables.
> >
> > This makes the current [i][ri]scale2ref[o][ro] equivalent to the only
> > slightly more verbose [ri]split[t][ro]; [i][t]scale=rw:rh[o]. (And
> > conversely, it is no longer necessary to use nullsink to consume an
> > unused [ro])
> 
> In principle, a good idea, but how does this impact memory use and speed 
> in the not-so-uncommon scenario where multiple overlay targets are 
> scaled 2 ref and then overlaid
> e.g.
> 
> in current flow:
> 
> [a][base]scale2ref[a][ref];
> [b][ref]scale2ref[b][ref[;
> [c][ref]scale2ref[c][ref[;
> [d][ref]scale2ref[d][ref[;
> [ref][a]overlay[ref];
> [ref][b]overlay[ref];
> [ref][c]overlay[ref];
> [ref][d]overlay[ref];
> 
> in new flow:
> 
> [base]split=5[base][refa][refb][refc][refd];
> [a][refa]scale[a];
> [b][refb]scale[b];
> [c][refc]scale[c];
> [d][refd]scale[d];
> [base][a]overlay[outa];
> [outa][b]overlay[outb];
> [outb][c]overlay[outc];
> [outc][d]overlay[out];
> 
> 
> Regards,
> Gyan

I have not tested it exactly, but based on my understanding of
libavfilter it shouldn't affect memory usage at all. `split` does not
duplicate frame data, it merely creates more references. And since all
of the `overlay` filters are upstream of [out], they all consume both of
their inputs before any forward progress can be made. So there is no
filter in this graph that can buffer more than 1 frame.

Actually, I would suspect memory usage to be slightly *lower* on
average, because ff_filter_activate_default() first consumes all
possible frames from input 1, then all possible frames from input 2,
etc.; whereas FFFrameSync consumes from both inputs simultaneously.
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 5/5] avfilter/scale2ref: deprecate in favor of scale=rw:rh

2024-04-24 Thread Niklas Haas
From: Niklas Haas 

And remove it from the documentation.
---
 Changelog  |  1 +
 doc/filters.texi   | 73 --
 libavfilter/vf_scale.c |  3 ++
 3 files changed, 4 insertions(+), 73 deletions(-)

diff --git a/Changelog b/Changelog
index e821e5ac74..e827208439 100644
--- a/Changelog
+++ b/Changelog
@@ -8,6 +8,7 @@ version :
 - LC3/LC3plus demuxer and muxer
 - pad_vaapi, drawbox_vaapi filters
 - vf_scale supports secondary ref input and framesync options
+- vf_scale2ref deprecated
 
 
 version 7.0:
diff --git a/doc/filters.texi b/doc/filters.texi
index cf884568b0..5198f14f28 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21590,79 +21590,6 @@ Scale a logo to 1/10th the height of a video, while 
preserving its display aspec
 @end example
 @end itemize
 
-@section scale2ref
-
-Scale (resize) the input video, based on a reference video.
-
-See the scale filter for available options, scale2ref supports the same but
-uses the reference video instead of the main input as basis. scale2ref also
-supports the following additional constants for the @option{w} and
-@option{h} options:
-
-@table @var
-@item main_w
-@item main_h
-The main input video's width and height
-
-@item main_a
-The same as @var{main_w} / @var{main_h}
-
-@item main_sar
-The main input video's sample aspect ratio
-
-@item main_dar, mdar
-The main input video's display aspect ratio. Calculated from
-@code{(main_w / main_h) * main_sar}.
-
-@item main_hsub
-@item main_vsub
-The main input video's horizontal and vertical chroma subsample values.
-For example for the pixel format "yuv422p" @var{hsub} is 2 and @var{vsub}
-is 1.
-
-@item main_n
-The (sequential) number of the main input frame, starting from 0.
-Only available with @code{eval=frame}.
-
-@item main_t
-The presentation timestamp of the main input frame, expressed as a number of
-seconds. Only available with @code{eval=frame}.
-
-@item main_pos
-The position (byte offset) of the frame in the main input stream, or NaN if
-this information is unavailable and/or meaningless (for example in case of 
synthetic video).
-Only available with @code{eval=frame}.
-@end table
-
-@subsection Examples
-
-@itemize
-@item
-Scale a subtitle stream (b) to match the main video (a) in size before 
overlaying
-@example
-'scale2ref[b][a];[a][b]overlay'
-@end example
-
-@item
-Scale a logo to 1/10th the height of a video, while preserving its display 
aspect ratio.
-@example
-[logo-in][video-in]scale2ref=w=oh*mdar:h=ih/10[logo-out][video-out]
-@end example
-@end itemize
-
-@subsection Commands
-
-This filter supports the following commands:
-@table @option
-@item width, w
-@item height, h
-Set the output video dimension expression.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
-@end table
-
 @section scale2ref_npp
 
 Use the NVIDIA Performance Primitives (libnpp) to scale (resize) the input
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index f174651333..bc53571c1c 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -368,6 +368,9 @@ static av_cold int init(AVFilterContext *ctx)
 int64_t threads;
 int ret;
 
+if (ctx->filter == _vf_scale2ref)
+av_log(ctx, AV_LOG_WARNING, "scale2ref is deprecated, use scale=rw:rh 
instead\n");
+
 if (scale->size_str && (scale->w_expr || scale->h_expr)) {
 av_log(ctx, AV_LOG_ERROR,
"Size and width/height expressions cannot be set at the same 
time.\n");
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 4/5] fate/scale2ref_keep_aspect: switch to vf_scale ref_*

2024-04-24 Thread Niklas Haas
From: Niklas Haas 

---
 tests/filtergraphs/scale2ref_keep_aspect | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tests/filtergraphs/scale2ref_keep_aspect 
b/tests/filtergraphs/scale2ref_keep_aspect
index f407460ec7..00b04fc3d1 100644
--- a/tests/filtergraphs/scale2ref_keep_aspect
+++ b/tests/filtergraphs/scale2ref_keep_aspect
@@ -1,5 +1,4 @@
 sws_flags=+accurate_rnd+bitexact;
 testsrc=size=320x240 [main];
 testsrc=size=640x360 [ref];
-[main][ref] scale2ref=iw/4:ow/mdar [main][ref];
-[ref] nullsink
+[main][ref] scale=rw/4:ow/dar [main]
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 3/5] avfilter/vf_scale: add optional "ref" input

2024-04-24 Thread Niklas Haas
From: Niklas Haas 

This is automatically enabled if the width/height expressions reference
any ref_* variable. This will ultimately serve as a more principled
replacement for the fundamentally broken scale2ref.

See-Also: https://trac.ffmpeg.org/ticket/10795
---
 Changelog  |   1 +
 doc/filters.texi   |  26 
 libavfilter/vf_scale.c | 132 -
 3 files changed, 156 insertions(+), 3 deletions(-)

diff --git a/Changelog b/Changelog
index 8db14f02b4..e821e5ac74 100644
--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,7 @@ version :
 - ffmpeg CLI filtergraph chaining
 - LC3/LC3plus demuxer and muxer
 - pad_vaapi, drawbox_vaapi filters
+- vf_scale supports secondary ref input and framesync options
 
 
 version 7.0:
diff --git a/doc/filters.texi b/doc/filters.texi
index f20b72ab96..cf884568b0 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -21562,8 +21562,34 @@ The position (byte offset) of the frame in the input 
stream, or NaN if
 this information is unavailable and/or meaningless (for example in case of 
synthetic video).
 Only available with @code{eval=frame}.
 Deprecated, do not use.
+
+@item ref_w, rw
+@item ref_h, rh
+@item ref_a
+@item ref_dar, rdar
+@item ref_n
+@item ref_t
+@item ref_pos
+Eqvuialent to the above, but for a second reference input. If any of these
+variables are present, this filter accepts two inputs.
 @end table
 
+@subsection Examples
+
+@itemize
+@item
+Scale a subtitle stream (sub) to match the main video (main) in size before 
overlaying
+@example
+'[main]split[a][b]; [ref][a]scale=rw:rh[c]; [b][c]overlay'
+@end example
+
+@item
+Scale a logo to 1/10th the height of a video, while preserving its display 
aspect ratio.
+@example
+[logo-in][video-in]scale=w=oh*dar:h=rh/10[logo-out]
+@end example
+@end itemize
+
 @section scale2ref
 
 Scale (resize) the input video, based on a reference video.
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index a986dc97ae..f174651333 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -59,6 +59,17 @@ static const char *const var_names[] = {
 #if FF_API_FRAME_PKT
 "pos",
 #endif
+"ref_w", "rw",
+"ref_h", "rh",
+"ref_a",
+"ref_sar",
+"ref_dar", "rdar",
+"ref_hsub",
+"ref_vsub",
+"ref_n",
+"ref_t",
+"ref_pos",
+/* Legacy variables for scale2ref */
 "main_w",
 "main_h",
 "main_a",
@@ -89,6 +100,16 @@ enum var_name {
 #if FF_API_FRAME_PKT
 VAR_POS,
 #endif
+VAR_REF_W, VAR_RW,
+VAR_REF_H, VAR_RH,
+VAR_REF_A,
+VAR_REF_SAR,
+VAR_REF_DAR, VAR_RDAR,
+VAR_REF_HSUB,
+VAR_REF_VSUB,
+VAR_REF_N,
+VAR_REF_T,
+VAR_REF_POS,
 VAR_S2R_MAIN_W,
 VAR_S2R_MAIN_H,
 VAR_S2R_MAIN_A,
@@ -131,6 +152,7 @@ typedef struct ScaleContext {
 int input_is_pal;   ///< set to 1 if the input format is paletted
 int output_is_pal;  ///< set to 1 if the output format is paletted
 int interlaced;
+int uses_ref;
 
 char *w_expr;   ///< width  expression string
 char *h_expr;   ///< height expression string
@@ -190,6 +212,38 @@ static int check_exprs(AVFilterContext *ctx)
 av_log(ctx, AV_LOG_WARNING, "Circular references detected for width 
'%s' and height '%s' - possibly invalid.\n", scale->w_expr, scale->h_expr);
 }
 
+if (vars_w[VAR_REF_W]|| vars_h[VAR_REF_W]||
+vars_w[VAR_RW]   || vars_h[VAR_RW]   ||
+vars_w[VAR_REF_H]|| vars_h[VAR_REF_H]||
+vars_w[VAR_RH]   || vars_h[VAR_RH]   ||
+vars_w[VAR_REF_A]|| vars_h[VAR_REF_A]||
+vars_w[VAR_REF_SAR]  || vars_h[VAR_REF_SAR]  ||
+vars_w[VAR_REF_DAR]  || vars_h[VAR_REF_DAR]  ||
+vars_w[VAR_RDAR] || vars_h[VAR_RDAR] ||
+vars_w[VAR_REF_HSUB] || vars_h[VAR_REF_HSUB] ||
+vars_w[VAR_REF_VSUB] || vars_h[VAR_REF_VSUB] ||
+vars_w[VAR_REF_N]|| vars_h[VAR_REF_N]||
+vars_w[VAR_REF_T]|| vars_h[VAR_REF_T]||
+vars_w[VAR_REF_POS]  || vars_h[VAR_REF_POS]) {
+scale->uses_ref = 1;
+}
+
+if (ctx->filter != _vf_scale2ref &&
+(vars_w[VAR_S2R_MAIN_W]|| vars_h[VAR_S2R_MAIN_W]||
+ vars_w[VAR_S2R_MAIN_H]|| vars_h[VAR_S2R_MAIN_H]||
+ vars_w[VAR_S2R_MAIN_A]|| vars_h[VAR_S2R_MAIN_A]||
+ vars_w[VAR_S2R_MAIN_SAR]  || vars_h[VAR_S2R_MAIN_SAR]  ||
+ vars_w[VAR_S2R_MAIN_DAR]  || vars_h[VAR_S2R_MAIN_DAR]  ||
+ vars_w[VAR_S2R_MDAR]  || vars_h[VAR_S2R_MDAR]  ||
+ vars_w[VAR_S2R_MAIN_HSUB] || vars_h[VAR_S2R_MAIN_HSUB] ||
+ vars_w[VAR_S2R_MAIN_VSUB] || vars_h[VAR_S2R_MAIN_VSUB] ||
+ vars_w[VAR_S2R_MAIN_N]|| v

[FFmpeg-devel] [PATCH 2/5] avfilter/vf_scale: switch to FFFrameSync

2024-04-24 Thread Niklas Haas
From: Niklas Haas 

Preliminary commit, in anticipation of adding support for multiple
inputs (with proper synchronization and activate() callback).
---
 doc/filters.texi   |  4 +--
 libavfilter/vf_scale.c | 65 +++---
 2 files changed, 63 insertions(+), 6 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index fc813f12c1..f20b72ab96 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -20989,8 +20989,8 @@ the next filter, the scale filter will convert the 
input to the
 requested format.
 
 @subsection Options
-The filter accepts the following options, or any of the options
-supported by the libswscale scaler.
+The filter accepts the following options, any of the options supported
+by the libswscale scaler, as well as any of the @ref{framesync} options.
 
 See @ref{scaler_options,,the ffmpeg-scaler manual,ffmpeg-scaler} for
 the complete list of scaler options.
diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c
index 1c07daeddf..a986dc97ae 100644
--- a/libavfilter/vf_scale.c
+++ b/libavfilter/vf_scale.c
@@ -29,6 +29,7 @@
 
 #include "avfilter.h"
 #include "formats.h"
+#include "framesync.h"
 #include "internal.h"
 #include "scale_eval.h"
 #include "video.h"
@@ -113,6 +114,7 @@ typedef struct ScaleContext {
 struct SwsContext *isws[2]; ///< software scaler context for interlaced 
material
 // context used for forwarding options to sws
 struct SwsContext *sws_opts;
+FFFrameSync fs;
 
 /**
  * New dimensions. Special values are:
@@ -287,6 +289,8 @@ static av_cold int preinit(AVFilterContext *ctx)
 if (ret < 0)
 return ret;
 
+ff_framesync_preinit(>fs);
+
 return 0;
 }
 
@@ -302,6 +306,8 @@ static const int sws_colorspaces[] = {
 -1
 };
 
+static int do_scale(FFFrameSync *fs);
+
 static av_cold int init(AVFilterContext *ctx)
 {
 ScaleContext *scale = ctx->priv;
@@ -388,6 +394,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 av_expr_free(scale->w_pexpr);
 av_expr_free(scale->h_pexpr);
 scale->w_pexpr = scale->h_pexpr = NULL;
+ff_framesync_uninit(>fs);
 sws_freeContext(scale->sws_opts);
 sws_freeContext(scale->sws);
 sws_freeContext(scale->isws[0]);
@@ -677,6 +684,21 @@ static int config_props(AVFilterLink *outlink)
flags_val);
 av_freep(_val);
 
+if (ctx->filter != _vf_scale2ref) {
+ret = ff_framesync_init(>fs, ctx, ctx->nb_inputs);
+if (ret < 0)
+return ret;
+scale->fs.on_event= do_scale;
+scale->fs.in[0].time_base = ctx->inputs[0]->time_base;
+scale->fs.in[0].sync  = 1;
+scale->fs.in[0].before= EXT_STOP;
+scale->fs.in[0].after = EXT_STOP;
+
+ret = ff_framesync_configure(>fs);
+if (ret < 0)
+return ret;
+}
+
 return 0;
 
 fail:
@@ -894,6 +916,26 @@ scale:
 return ret;
 }
 
+static int do_scale(FFFrameSync *fs)
+{
+AVFilterContext *ctx = fs->parent;
+AVFilterLink *outlink = ctx->outputs[0];
+AVFrame *in, *out;
+int ret;
+
+ret = ff_framesync_get_frame(fs, 0, , 1);
+if (ret < 0)
+return ret;
+
+ret = scale_frame(ctx->inputs[0], in, );
+if (out) {
+out->pts = av_rescale_q(fs->pts, fs->time_base, outlink->time_base);
+return ff_filter_frame(outlink, out);
+}
+
+return ret;
+}
+
 static int filter_frame(AVFilterLink *link, AVFrame *in)
 {
 AVFilterContext *ctx = link->dst;
@@ -972,11 +1014,24 @@ static int process_command(AVFilterContext *ctx, const 
char *cmd, const char *ar
 return ret;
 }
 
+static int activate(AVFilterContext *ctx)
+{
+ScaleContext *scale = ctx->priv;
+return ff_framesync_activate(>fs);
+}
+
 static const AVClass *child_class_iterate(void **iter)
 {
-const AVClass *c = *iter ? NULL : sws_get_class();
-*iter = (void*)(uintptr_t)c;
-return c;
+switch ((uintptr_t) *iter) {
+case 0:
+*iter = (void*)(uintptr_t) 1;
+return sws_get_class();
+case 1:
+*iter = (void*)(uintptr_t) 2;
+return _framesync_class;
+}
+
+return NULL;
 }
 
 static void *child_next(void *obj, void *prev)
@@ -984,6 +1039,8 @@ static void *child_next(void *obj, void *prev)
 ScaleContext *s = obj;
 if (!prev)
 return s->sws_opts;
+if (prev == s->sws_opts)
+return >fs;
 return NULL;
 }
 
@@ -1051,7 +1108,6 @@ static const AVFilterPad avfilter_vf_scale_inputs[] = {
 {
 .name = "default",
 .type = AVMEDIA_TYPE_VIDEO,
-.filter_frame = filter_frame,
 },
 };
 
@@ -1074,6 +1130,7 @@ const AVFilter ff_vf_scale = {
 FILTER_INPUTS(avfilter_vf_scale_inputs),
 FILTER_OUTPUTS(avfilter_vf_scale_outputs),
 FILTER_QUERY_FUNC(query_fo

[FFmpeg-devel] [PATCH 1/5] avfilter/framesync: make framesync_class un-static

2024-04-24 Thread Niklas Haas
From: Niklas Haas 

And rename to ff_framesync_class. More convenient for downstream users.
---
 libavfilter/framesync.c | 6 +++---
 libavfilter/framesync.h | 1 +
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/libavfilter/framesync.c b/libavfilter/framesync.c
index 1afd70ab21..a691136f34 100644
--- a/libavfilter/framesync.c
+++ b/libavfilter/framesync.c
@@ -51,7 +51,7 @@ static const AVOption framesync_options[] = {
 0, AV_OPT_TYPE_CONST, { .i64 = TS_NEAREST }, .flags = FLAGS, .unit 
= "ts_sync_mode" },
 { NULL }
 };
-static const AVClass framesync_class = {
+const AVClass ff_framesync_class = {
 .version   = LIBAVUTIL_VERSION_INT,
 .class_name= "framesync",
 .item_name = framesync_name,
@@ -62,7 +62,7 @@ static const AVClass framesync_class = {
 
 const AVClass *ff_framesync_child_class_iterate(void **iter)
 {
-const AVClass *c = *iter ? NULL : _class;
+const AVClass *c = *iter ? NULL : _framesync_class;
 *iter = (void *)(uintptr_t)c;
 return c;
 }
@@ -79,7 +79,7 @@ void ff_framesync_preinit(FFFrameSync *fs)
 {
 if (fs->class)
 return;
-fs->class  = _class;
+fs->class  = _framesync_class;
 av_opt_set_defaults(fs);
 }
 
diff --git a/libavfilter/framesync.h b/libavfilter/framesync.h
index 233f50a0eb..130d067bae 100644
--- a/libavfilter/framesync.h
+++ b/libavfilter/framesync.h
@@ -316,6 +316,7 @@ int ff_framesync_dualinput_get(FFFrameSync *fs, AVFrame 
**f0, AVFrame **f1);
 int ff_framesync_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame 
**f1);
 
 const AVClass *ff_framesync_child_class_iterate(void **iter);
+extern const AVClass ff_framesync_class;
 
 #define FRAMESYNC_DEFINE_PURE_CLASS(name, desc, func_prefix, options) \
 static const AVClass name##_class = { \
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH 0/5] replace scale2ref by scale=rw:rh

2024-04-24 Thread Niklas Haas
As discussed in my previous series for fixing scale2ref[1], this filter
is fundamentally broken, and the only real fix would be to switch to
activate(), or ideally FFFrameSync.

[1] https://ffmpeg.org//pipermail/ffmpeg-devel/2024-March/323382.html

The main thing making this difficult is the fact that scale2ref also
wants to output ref frames to its secondary output, which FFFrameSync
does not support, and which is ultimately at least part of the root
cause of trac #10795.

Since this is in principle completely unnecessary (users can just
'split' the ref input and have it be consumed by vf_scale), and to make
the design of this filter a bit more robust and maintainable, switch to
an approach where vf_scale itself gains the ability to reference
a secondary input stream, using the "ref_*" series of variables.

This makes the current [i][ri]scale2ref[o][ro] equivalent to the only
slightly more verbose [ri]split[t][ro]; [i][t]scale=rw:rh[o]. (And
conversely, it is no longer necessary to use nullsink to consume an
unused [ro])

Incidentally, I think it would be nice if lavfi could *automatically*
split filter links referenced multiple times, so we could just write
e.g. [i][ri]scale=rw:rh[o]; [ri][o]overlay[out] and have it work. Maybe
I'll try getting that to work, next.

Either way, after the deprecation period has elapsed, we can delete
scale2ref from the codebase in order to make vf_scale.c IMHO
significantly simpler versus the status quo.

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH] avfilter/f_sidedata: synchronize with side data list

2024-04-23 Thread Niklas Haas
From: Niklas Haas 

Add all recently added frame data types, as well as the new name for
DETECTION_BBOXES as an alias to the older DETECTION_BOUNDING_BOXES.
---
 libavfilter/f_sidedata.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/libavfilter/f_sidedata.c b/libavfilter/f_sidedata.c
index fe9607ed52..616fd0750c 100644
--- a/libavfilter/f_sidedata.c
+++ b/libavfilter/f_sidedata.c
@@ -71,8 +71,16 @@ static const AVOption filt_name##_options[] = { \
 {   "S12M_TIMECOD",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_S12M_TIMECODE  }, 0, 0, FLAGS, .unit = "type" 
}, \
 {   "DYNAMIC_HDR_PLUS",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DYNAMIC_HDR_PLUS   }, 0, 0, FLAGS, .unit = "type" 
}, \
 {   "REGIONS_OF_INTEREST","", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_REGIONS_OF_INTEREST}, 0, 0, FLAGS, .unit = "type" 
}, \
-{   "DETECTION_BOUNDING_BOXES",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DETECTION_BBOXES   }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "VIDEO_ENC_PARAMS",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_VIDEO_ENC_PARAMS   }, 0, 0, FLAGS, .unit = "type" 
}, \
 {   "SEI_UNREGISTERED",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_SEI_UNREGISTERED   }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "FILM_GRAIN_PARAMS",  "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_FILM_GRAIN_PARAMS  }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "DETECTION_BOUNDING_BOXES",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DETECTION_BBOXES   }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "DETECTION_BBOXES",   "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DETECTION_BBOXES   }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "DOVI_RPU_BUFFER","", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DOVI_RPU_BUFFER}, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "DOVI_METADATA",  "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DOVI_METADATA  }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "DYNAMIC_HDR_VIVID",  "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_DYNAMIC_HDR_VIVID  }, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "AMBIENT_VIEWING_ENVIRONMENT","", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT}, 0, 0, FLAGS, .unit = "type" 
}, \
+{   "VIDEO_HINT", "", 0, AV_OPT_TYPE_CONST,  
{.i64 = AV_FRAME_DATA_VIDEO_HINT }, 0, 0, FLAGS, .unit = "type" 
}, \
 { NULL } \
 }
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [RFC] 5 year plan & Inovation

2024-04-19 Thread Niklas Haas
On Thu, 18 Apr 2024 22:53:51 +0200 Michael Niedermayer  
wrote:
> A plugin system moves this patch-management to people who actually
> care, that is the authors of the codecs and (de)muxers.

A plugin system will only solve this insomuch as plugin authors will
just host their plugin code on GitHub instead of bothering with the
mailing list.

I think it runs a good risk of basically killing the project.

> Our productivity as is, is not good, many patches are ignored.
> The people caring about these patches are their Authors and yet they
> are powerless as they must sometimes wait many months for reviews

So, rather than all of the above, what I think we should do is contract
somebody to set up, manage, host and maintain a GitLab instance for us.

This would probably be the single most cost effective boost to both
community growth and innovation I can think of, as it will remove
several of the major grievances and barriers to entry with the
ML+pingspam model.

We can use a system like VLC's auto-merge bot, where any MR that has at
least one developer approval, no unresolved issues, and no activity for
N days gets *automatically* merged.

I'm sure that if we try, we can find an interested party willing to fund
this. (Maybe SPI?)

> Besides that, developers are leaving for various reasons and they
> are forced to setup full forks not being able to maintain their
> code in any other way.
> IMO A plugin system would improve productivity as everyone could work
> on their own terms.
> No week or month long delays and weekly pinging patches
> No risk about patches being rejected or ignored
> No need to read every other discussion on the ML. One can just
> simply work on their own plugin looking just at the API documentation
> ...
> 
> 
> 
> > 
> > > * ffchat
> > > (expand into realtime chat / zoom) this would
> > > bring in more users and developers, and we basically have almost
> > > all parts for it already but some people where against it
> > 
> > This seems like a user application on top of FFmpeg, not something that
> > should be part of FFmpeg core. Can you explain what modifications in
> > FFmpeg would be necessary for something like this?
> 
> ffmpeg, ffplay, ffprobe are also user applications.
> 
> 
> > 
> > > * client side / in browser support
> > > (expand towards webapps, webpages using ffmpeg client side in the 
> > > browser)
> > > bring in more users and developers, and it will be costly for us
> > > if we let others take this area as its important and significant
> > 
> > I don't understand this point - don't all major browsers already vendor
> > FFmpeg for decoding?
> 
> FFmpeg does more than decoding.
> 
> 
> > 
> > > * AI / neural network filters and codecs
> > > The future seems to be AI based. Future Filters and Codecs will use
> > > neural networks. FFmpeg can be at the forefront, developing these
> > 
> > We already have TensorFlow support, no? (vf_sr etc.) What more is
> > needed?
> 
> more of that AND more convenience
> 
> lets pick a comparission
> to run fate
> you write "make fate"
> if you want to do it with the samples its
> make fate-rsync ; make fate
> 
> if you want to use vf_sr, its reading the docs, looking at some scripts 
> reading their docs
> and i presume selecting a training set ? creating a model ? 
> 
> how many people do that ?
> 
> thx
> 
> [...]
> 
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> I have often repented speaking, but never of holding my tongue.
> -- Xenocrates
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [RFC] 5 year plan & Inovation

2024-04-18 Thread Niklas Haas
On Wed, 17 Apr 2024 15:58:32 +0200 Michael Niedermayer  
wrote:
> Hi all
> 
> The pace of inovation in FFmpeg has been slowing down.
> Most work is concentarted nowadays on code refactoring, and adding
> support for new codecs and formats.
> 
> Should we
> * make a list of longer term goals
> * vote on them
> * and then together work towards implementing them
> ?
> 
> (The idea here is to increase the success of larger efforts
>  than adding codecs and refactoring code)
> It would then also not be possible for individuals to object
> to a previously agreed goal.
> And it would add ideas for which we can try to get funding/grants for
> 
> (larger scale changes need consensus first that we as a whole want
>  them before we would be able to ask for funding/grants for them)
> 
> Some ideas and why they would help FFmpeg:
> 
> * Switch to a plugin architecture
> (Increase the number of developers willing to contribute and reduce
>  friction as the team and community grows)

This would almost surely hurt productivity as it will require exposing,
versioning, documenting and maintaining a vast number of internal APIs
which we are currently at the liberty of modifying freely.

> * ffchat
> (expand into realtime chat / zoom) this would
> bring in more users and developers, and we basically have almost
> all parts for it already but some people where against it

This seems like a user application on top of FFmpeg, not something that
should be part of FFmpeg core. Can you explain what modifications in
FFmpeg would be necessary for something like this?

> * client side / in browser support
> (expand towards webapps, webpages using ffmpeg client side in the browser)
> bring in more users and developers, and it will be costly for us
> if we let others take this area as its important and significant

I don't understand this point - don't all major browsers already vendor
FFmpeg for decoding?

> * AI / neural network filters and codecs
> The future seems to be AI based. Future Filters and Codecs will use
> neural networks. FFmpeg can be at the forefront, developing these

We already have TensorFlow support, no? (vf_sr etc.) What more is
needed?

> * [your idea here]
> 
> thx
> 
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> It is what and why we do it that matters, not just one of them.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 08/13] avcodec/dovi_rpudec: make `enable` also affect decoding

2024-04-18 Thread Niklas Haas
On Thu, 18 Apr 2024 13:30:39 +0200 Andreas Rheinhardt 
 wrote:
> Niklas Haas:
> > From: Niklas Haas 
> > 
> > This could be used by codecs to selectively disable parsing Dolby Vision
> > RPUs, and is cheap to support.
> > ---
> >  libavcodec/av1dec.c  | 1 +
> >  libavcodec/dovi_rpu.h| 2 ++
> >  libavcodec/dovi_rpudec.c | 6 ++
> >  libavcodec/hevcdec.c | 1 +
> >  libavcodec/libdav1d.c| 1 +
> >  5 files changed, 11 insertions(+)
> > 
> > diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
> > index 4c1405df77..20865b4f12 100644
> > --- a/libavcodec/av1dec.c
> > +++ b/libavcodec/av1dec.c
> > @@ -1551,6 +1551,7 @@ static void av1_decode_flush(AVCodecContext *avctx)
> >  static const AVOption av1_options[] = {
> >  { "operating_point",  "Select an operating point of the scalable 
> > bitstream",
> >OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 
> > = 0 }, 0, AV1_MAX_OPERATING_POINTS - 1, VD },
> > +{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
> > AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
> >  { NULL }
> >  };
> >  
> > diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
> > index 3e80647422..8f8905b96b 100644
> > --- a/libavcodec/dovi_rpu.h
> > +++ b/libavcodec/dovi_rpu.h
> > @@ -37,6 +37,8 @@ typedef struct DOVIContext {
> >   *
> >   * For encoding, FF_DOVI_AUTOMATIC enables Dolby Vision only if
> >   * avctx->decoded_side_data contains an AVDOVIMetadata.
> > + *
> > + * For decoding, FF_DOVI_AUTOMATIC has the same meaning as 1.
> >   */
> >  #define FF_DOVI_AUTOMATIC -1
> >  int enable;
> > diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
> > index 7c7eda9d09..978d5dfc2b 100644
> > --- a/libavcodec/dovi_rpudec.c
> > +++ b/libavcodec/dovi_rpudec.c
> > @@ -37,6 +37,9 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame 
> > *frame)
> >  AVDOVIMetadata *dovi;
> >  size_t dovi_size, ext_sz;
> >  
> > +if (!s->enable)
> > +return 0;
> > +
> >  if (!s->mapping || !s->color)
> >  return 0; /* incomplete dovi metadata */
> >  
> > @@ -306,6 +309,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t 
> > *rpu, size_t rpu_size,
> >  uint8_t use_nlq;
> >  uint8_t profile;
> >  
> > +if (!s->enable)
> > +return 0;
> > +
> >  if (rpu_size < 5)
> >  goto fail;
> >  
> > diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
> > index 7825efe2e6..c622a48b94 100644
> > --- a/libavcodec/hevcdec.c
> > +++ b/libavcodec/hevcdec.c
> > @@ -3694,6 +3694,7 @@ static const AVOption options[] = {
> >  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
> >  { "strict-displaywin", "stricly apply default display window size", 
> > OFFSET(apply_defdispwin),
> >  AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
> > +{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi_ctx.enable), 
> > AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, PAR },
> >  { NULL },
> >  };
> >  
> > diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
> > index 09fe767fb8..f9e1a181fc 100644
> > --- a/libavcodec/libdav1d.c
> > +++ b/libavcodec/libdav1d.c
> > @@ -674,6 +674,7 @@ static const AVOption libdav1d_options[] = {
> >  { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), 
> > AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED },
> >  { "oppoint",  "Select an operating point of the scalable bitstream", 
> > OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
> >  { "alllayers", "Output all spatial layers", OFFSET(all_layers), 
> > AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
> > +{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
> > AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
> >  { NULL }
> >  };
> >  
> 
> Is parsing this stuff very expensive? If not, I don't really see a
> reason to add an option for it (we also do not add options for lots of
> other side data types).
> 
> - Andreas

It's not expensive, no. Well, having DV metadata present technically
alters the interpretation of the video quite substantially (e.g. SDR
streams now displaying as HDR), so users may want *some* way of
"globally" disabling it.

That said, it's probably better to relegate that to `vf_sidedata`.
I'll drop this commit from the series, then.

> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v4 0/1] avfilter/vf_colorspace: use colorspace negotiation API

2024-04-17 Thread Niklas Haas
On Thu, 04 Apr 2024 19:05:13 +0200 Nicolas Gaullier 
 wrote:
> v4:
> - remove dynamic color_range pass-through (which requires changing outlink 
> dynamically and is forbidden)
> - nits style
> - commit msg: simplified example (+ removed example for dynamic color_range 
> pass-through)
> 
> Nicolas Gaullier (1):
>   avfilter/vf_colorspace: use colorspace negotiation API
> 
>  libavfilter/vf_colorspace.c | 62 +
>  1 file changed, 36 insertions(+), 26 deletions(-)
> 
> -- 
> 2.30.2
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Pushed as 376b3d53c54791c1be58709df4303ba2b90851bc

Sorry for the delay; it is really not clear to me who has push rights
and who does not, and whose job it is to merge patches.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v3 00/13] avcodec: add Dolby Vision encoding

2024-04-17 Thread Niklas Haas
On Fri, 12 Apr 2024 13:35:14 +0200 Niklas Haas  wrote:
> Changes since v2:
> - Split up dovi_rpu.c into dovi_rpudec.c and dovi_rpueenc.
> - Added missing dependencies of encoders onto dovi_rpueenc
> - Clarified and documented semantics of guess_profile()
> - Changed misleading commit message
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Ping for review
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2] avcodec/libx264: bump minimum required version to 155

2024-04-15 Thread Niklas Haas
On Fri, 12 Apr 2024 12:45:44 +0200 Niklas Haas  wrote:
> On Tue, 09 Apr 2024 15:12:05 +0200 Niklas Haas  wrote:
> > From: Niklas Haas 
> > 
> > This version is seven years old, and present in Debian oldoldstable,
> > Ubuntu 20.04 and Leap 15.0.
> > 
> > Allows cleaning up the file substantially. In particular, this is
> > motivated by the desire to stop relying on init_static_data.
> > ---
> >  configure|  2 +-
> >  libavcodec/libx264.c | 52 ++--
> >  2 files changed, 8 insertions(+), 46 deletions(-)
> > 
> > diff --git a/configure b/configure
> > index f511fbae492..248ce2040d6 100755
> > --- a/configure
> > +++ b/configure
> > @@ -7007,7 +7007,7 @@ enabled libwebp   && {
> >  enabled libwebp_encoder  && require_pkg_config libwebp "libwebp >= 
> > 0.2.0" webp/encode.h WebPGetEncoderVersion
> >  enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder 
> > "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
> >  enabled libx264   && require_pkg_config libx264 x264 "stdint.h 
> > x264.h" x264_encoder_encode &&
> > - require_cpp_condition libx264 x264.h 
> > "X264_BUILD >= 122" && {
> > + require_cpp_condition libx264 x264.h 
> > "X264_BUILD >= 155" && {
> >   [ "$toolchain" != "msvc" ] ||
> >   require_cpp_condition libx264 x264.h 
> > "X264_BUILD >= 158"; } &&
> >   check_cpp_condition libx264_hdr10 x264.h 
> > "X264_BUILD >= 163" &&
> > diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> > index eadb20d2b39..2715f277f1f 100644
> > --- a/libavcodec/libx264.c
> > +++ b/libavcodec/libx264.c
> > @@ -270,11 +270,9 @@ static void reconfig_encoder(AVCodecContext *ctx, 
> > const AVFrame *frame)
> >  case AV_STEREO3D_FRAMESEQUENCE:
> >  fpa_type = 5;
> >  break;
> > -#if X264_BUILD >= 145
> >  case AV_STEREO3D_2D:
> >  fpa_type = 6;
> >  break;
> > -#endif
> >  default:
> >  fpa_type = -1;
> >  break;
> > @@ -394,14 +392,14 @@ static int setup_mb_info(AVCodecContext *ctx, 
> > x264_picture_t *pic,
> >  return 0;
> >  }
> >  
> > -static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int 
> > bit_depth,
> > +static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic,
> >   const AVFrame *frame, const uint8_t *data, size_t 
> > size)
> >  {
> >  X264Context *x4 = ctx->priv_data;
> >  
> >  int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
> >  int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
> > -int qp_range = 51 + 6 * (bit_depth - 8);
> > +int qp_range = 51 + 6 * (x4->params.i_bitdepth - 8);
> >  int nb_rois;
> >  const AVRegionOfInterest *roi;
> >  uint32_t roi_size;
> > @@ -476,7 +474,7 @@ static int setup_frame(AVCodecContext *ctx, const 
> > AVFrame *frame,
> >  x264_sei_t *sei = >extra_sei;
> >  unsigned int sei_data_size = 0;
> >  int64_t wallclock = 0;
> > -int bit_depth, ret;
> > +int ret;
> >  AVFrameSideData *sd;
> >  AVFrameSideData *mbinfo_sd;
> >  
> > @@ -486,12 +484,7 @@ static int setup_frame(AVCodecContext *ctx, const 
> > AVFrame *frame,
> >  
> >  x264_picture_init(pic);
> >  pic->img.i_csp   = x4->params.i_csp;
> > -#if X264_BUILD >= 153
> > -bit_depth = x4->params.i_bitdepth;
> > -#else
> > -bit_depth = x264_bit_depth;
> > -#endif
> > -if (bit_depth > 8)
> > +if (x4->params.i_bitdepth > 8)
> >  pic->img.i_csp |= X264_CSP_HIGH_DEPTH;
> >  pic->img.i_plane = av_pix_fmt_count_planes(ctx->pix_fmt);
> >  
> > @@ -564,7 +557,7 @@ static int setup_frame(AVCodecContext *ctx, const 
> > AVFrame *frame,
> >  
> >  sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
> >  if (sd) {
> > -ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
> > +ret = setup_roi(ctx, pic, frame, sd->data, sd->size);
> >  if (ret < 0)
&

Re: [FFmpeg-devel] [PATCH v5] avcodec/h2645_sei: validate Mastering Display Colour Volume SEI values

2024-04-13 Thread Niklas Haas
On Sat, 13 Apr 2024 17:21:08 +0200 Kacper Michajłow  wrote:
> As we can read in ST 2086:
> 
> Values outside the specified ranges of luminance and chromaticity values
> are not reserved by SMPTE, and can be used for purposes outside the
> scope of this standard.
> 
> This is further acknowledged by ITU-T H.264 and ITU-T H.265. Which says
> that values out of range are unknown or unspecified or specified by
> other means not specified in this Specification.
> 
> Signed-off-by: Kacper Michajłow 
> ---
>  libavcodec/h2645_sei.c | 55 ++
>  1 file changed, 39 insertions(+), 16 deletions(-)
> 
> diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
> index 933975f076..96a22e7cf6 100644
> --- a/libavcodec/h2645_sei.c
> +++ b/libavcodec/h2645_sei.c
> @@ -587,38 +587,61 @@ static int h2645_sei_to_side_data(AVCodecContext 
> *avctx, H2645SEI *sei,
>  return ret;
>  
>  if (metadata) {
> +metadata->has_luminance = 1;
> +metadata->has_primaries = 1;
> +
>  for (i = 0; i < 3; i++) {
>  const int j = mapping[i];
>  metadata->display_primaries[i][0].num = 
> sei->mastering_display.display_primaries[j][0];
>  metadata->display_primaries[i][0].den = chroma_den;
> +metadata->has_primaries &= 
> sei->mastering_display.display_primaries[j][0] >= 5 &&
> +   
> sei->mastering_display.display_primaries[j][0] <= 37000;
> +
>  metadata->display_primaries[i][1].num = 
> sei->mastering_display.display_primaries[j][1];
>  metadata->display_primaries[i][1].den = chroma_den;
> +metadata->has_primaries &= 
> sei->mastering_display.display_primaries[j][1] >= 5 &&
> +   
> sei->mastering_display.display_primaries[j][1] <= 42000;
>  }
>  metadata->white_point[0].num = 
> sei->mastering_display.white_point[0];
>  metadata->white_point[0].den = chroma_den;
> +metadata->has_primaries &= sei->mastering_display.white_point[0] 
> >= 5 &&
> +   sei->mastering_display.white_point[0] 
> <= 37000;
> +
>  metadata->white_point[1].num = 
> sei->mastering_display.white_point[1];
>  metadata->white_point[1].den = chroma_den;
> +metadata->has_primaries &= sei->mastering_display.white_point[1] 
> >= 5 &&
> +   sei->mastering_display.white_point[1] 
> <= 42000;
>  
>  metadata->max_luminance.num = 
> sei->mastering_display.max_luminance;
>  metadata->max_luminance.den = luma_den;
> +metadata->has_luminance &= sei->mastering_display.max_luminance 
> >= 5 &&
> +   sei->mastering_display.max_luminance 
> <= 1;
> +
>  metadata->min_luminance.num = 
> sei->mastering_display.min_luminance;
>  metadata->min_luminance.den = luma_den;
> -metadata->has_luminance = 1;
> -metadata->has_primaries = 1;
> -
> -av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
> -av_log(avctx, AV_LOG_DEBUG,
> -   "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, 
> %5.4f)\n",
> -   av_q2d(metadata->display_primaries[0][0]),
> -   av_q2d(metadata->display_primaries[0][1]),
> -   av_q2d(metadata->display_primaries[1][0]),
> -   av_q2d(metadata->display_primaries[1][1]),
> -   av_q2d(metadata->display_primaries[2][0]),
> -   av_q2d(metadata->display_primaries[2][1]),
> -   av_q2d(metadata->white_point[0]), 
> av_q2d(metadata->white_point[1]));
> -av_log(avctx, AV_LOG_DEBUG,
> -   "min_luminance=%f, max_luminance=%f\n",
> -   av_q2d(metadata->min_luminance), 
> av_q2d(metadata->max_luminance));
> +metadata->has_luminance &= sei->mastering_display.min_luminance 
> >= 1 &&
> +   sei->mastering_display.min_luminance 
> <= 5 &&
> +   sei->mastering_display.min_luminance <
> +   sei->mastering_display.max_luminance;
> +
> +if (metadata->has_luminance || metadata->has_primaries)
> +av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
> +if (metadata->has_primaries) {
> +av_log(avctx, AV_LOG_DEBUG,
> +   "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) 
> wp(%5.4f, %5.4f)\n",
> +   av_q2d(metadata->display_primaries[0][0]),
> +   av_q2d(metadata->display_primaries[0][1]),
> +   av_q2d(metadata->display_primaries[1][0]),
> +   

[FFmpeg-devel] [PATCH v3 07/13] avcodec/dovi_rpuenc: add ff_dovi_configure()

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

We need to set up the configuration struct appropriately based on the
codec type, colorspace metadata, and presence/absence of an EL (though,
we currently don't support an EL).

When present, we use the signalled RPU data header to help infer (and
validate) the right values.

Behavior can be controlled by a new DOVIContext.enable flag.
---
 configure|   2 +
 libavcodec/Makefile  |   1 +
 libavcodec/dovi_rpu.h|  24 -
 libavcodec/dovi_rpuenc.c | 203 +++
 4 files changed, 229 insertions(+), 1 deletion(-)
 create mode 100644 libavcodec/dovi_rpuenc.c

diff --git a/configure b/configure
index c1e1ece1e2..d25d0f6907 100755
--- a/configure
+++ b/configure
@@ -2551,6 +2551,7 @@ CONFIG_EXTRA="
 dirac_parse
 dnn
 dovi_rpudec
+dovi_rpuenc
 dvprofile
 evcparse
 exif
@@ -2842,6 +2843,7 @@ cbs_vp9_select="cbs"
 deflate_wrapper_deps="zlib"
 dirac_parse_select="golomb"
 dovi_rpudec_select="golomb"
+dovi_rpuenc_select="golomb"
 dnn_suggest="libtensorflow libopenvino libtorch"
 dnn_deps="avformat swscale"
 error_resilience_select="me_cmp"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 45058eb8d2..6bddb6fb5e 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -86,6 +86,7 @@ OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
 OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
 OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
 OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o dovi_rpudec.o
+OBJS-$(CONFIG_DOVI_RPUENC) += dovi_rpu.o dovi_rpuenc.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)+= error_resilience.o
 OBJS-$(CONFIG_EVCPARSE)+= evc_parse.o evc_ps.o
 OBJS-$(CONFIG_EXIF)+= exif.o tiff_common.o
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 0c12a3fee0..3e80647422 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -26,14 +26,25 @@
 
 #include "libavutil/dovi_meta.h"
 #include "libavutil/frame.h"
+#include "avcodec.h"
 
 #define DOVI_MAX_DM_ID 15
 typedef struct DOVIContext {
 void *logctx;
 
+/**
+ * Enable tri-state.
+ *
+ * For encoding, FF_DOVI_AUTOMATIC enables Dolby Vision only if
+ * avctx->decoded_side_data contains an AVDOVIMetadata.
+ */
+#define FF_DOVI_AUTOMATIC -1
+int enable;
+
 /**
  * Currently active dolby vision configuration, or {0} for none.
- * Set by the user when decoding.
+ * Set by the user when decoding. Generated by ff_dovi_configure()
+ * when encoding.
  *
  * Note: sizeof(cfg) is not part of the libavutil ABI, so users should
  * never pass  to any other library calls. This is included merely as
@@ -100,6 +111,17 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
  */
 int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame);
 
+/**
+ * Configure the encoder for Dolby Vision encoding. Generates a configuration
+ * record in s->cfg, and attaches it to avctx->coded_side_data. Sets the 
correct
+ * profile and compatibility ID based on the tagged AVCodecContext colorspace
+ * metadata, and the correct level based on the resolution and tagged 
framerate.
+ *
+ * Returns 0 or a negative error code.
+ */
+int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx);
+
+
 /***
  * The following section is for internal use only. *
  ***/
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
new file mode 100644
index 00..3ab4624a79
--- /dev/null
+++ b/libavcodec/dovi_rpuenc.c
@@ -0,0 +1,203 @@
+/*
+ * Dolby Vision RPU encoder
+ *
+ * Copyright (C) 2024 Niklas Haas
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/mem.h"
+
+#include "avcodec.h"
+#include "dovi_rpu.h"
+
+static struct {
+uint64_t pps; // maximum pixels per second
+int width; // maximum width
+int main; // maximum bitrate in main tier
+int high; // m

[FFmpeg-devel] [PATCH v3 08/13] avcodec/dovi_rpudec: make `enable` also affect decoding

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

This could be used by codecs to selectively disable parsing Dolby Vision
RPUs, and is cheap to support.
---
 libavcodec/av1dec.c  | 1 +
 libavcodec/dovi_rpu.h| 2 ++
 libavcodec/dovi_rpudec.c | 6 ++
 libavcodec/hevcdec.c | 1 +
 libavcodec/libdav1d.c| 1 +
 5 files changed, 11 insertions(+)

diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 4c1405df77..20865b4f12 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -1551,6 +1551,7 @@ static void av1_decode_flush(AVCodecContext *avctx)
 static const AVOption av1_options[] = {
 { "operating_point",  "Select an operating point of the scalable 
bitstream",
   OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 
}, 0, AV1_MAX_OPERATING_POINTS - 1, VD },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
 { NULL }
 };
 
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 3e80647422..8f8905b96b 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -37,6 +37,8 @@ typedef struct DOVIContext {
  *
  * For encoding, FF_DOVI_AUTOMATIC enables Dolby Vision only if
  * avctx->decoded_side_data contains an AVDOVIMetadata.
+ *
+ * For decoding, FF_DOVI_AUTOMATIC has the same meaning as 1.
  */
 #define FF_DOVI_AUTOMATIC -1
 int enable;
diff --git a/libavcodec/dovi_rpudec.c b/libavcodec/dovi_rpudec.c
index 7c7eda9d09..978d5dfc2b 100644
--- a/libavcodec/dovi_rpudec.c
+++ b/libavcodec/dovi_rpudec.c
@@ -37,6 +37,9 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 AVDOVIMetadata *dovi;
 size_t dovi_size, ext_sz;
 
+if (!s->enable)
+return 0;
+
 if (!s->mapping || !s->color)
 return 0; /* incomplete dovi metadata */
 
@@ -306,6 +309,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 uint8_t use_nlq;
 uint8_t profile;
 
+if (!s->enable)
+return 0;
+
 if (rpu_size < 5)
 goto fail;
 
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 7825efe2e6..c622a48b94 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3694,6 +3694,7 @@ static const AVOption options[] = {
 AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
 { "strict-displaywin", "stricly apply default display window size", 
OFFSET(apply_defdispwin),
 AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi_ctx.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, PAR },
 { NULL },
 };
 
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 09fe767fb8..f9e1a181fc 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -674,6 +674,7 @@ static const AVOption libdav1d_options[] = {
 { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, 
{ .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED },
 { "oppoint",  "Select an operating point of the scalable bitstream", 
OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
 { "alllayers", "Output all spatial layers", OFFSET(all_layers), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
 { NULL }
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 06/13] avcodec/dovi_rpu: split into dovi_rpu.c and dovi_rpudec.c

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

To allow compiling the decoding objects without the encoding objects and
vice versa. Common helpers that users of both APIs need are put into the
shared dovi_rpu.c.
---
 libavcodec/Makefile  |   2 +-
 libavcodec/dovi_rpu.c| 624 +-
 libavcodec/dovi_rpu.h|  14 +
 libavcodec/dovi_rpudec.c | 635 +++
 4 files changed, 651 insertions(+), 624 deletions(-)
 create mode 100644 libavcodec/dovi_rpudec.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 61d261d606..45058eb8d2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -85,7 +85,7 @@ OBJS-$(CONFIG_CBS_MPEG2)   += cbs_mpeg2.o
 OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
 OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
 OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
-OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o
+OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o dovi_rpudec.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)+= error_resilience.o
 OBJS-$(CONFIG_EVCPARSE)+= evc_parse.o evc_ps.o
 OBJS-$(CONFIG_EXIF)+= exif.o tiff_common.o
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 77fef8c496..b26c19dd5e 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -2,7 +2,7 @@
  * Dolby Vision RPU decoder
  *
  * Copyright (C) 2021 Jan Ekström
- * Copyright (C) 2021 Niklas Haas
+ * Copyright (C) 2021-2024 Niklas Haas
  *
  * This file is part of FFmpeg.
  *
@@ -21,29 +21,11 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include "libavutil/buffer.h"
 #include "libavutil/mem.h"
-#include "libavutil/crc.h"
 
-#include "avcodec.h"
 #include "dovi_rpu.h"
-#include "golomb.h"
-#include "get_bits.h"
 #include "refstruct.h"
 
-enum {
-RPU_COEFF_FIXED = 0,
-RPU_COEFF_FLOAT = 1,
-};
-
-/**
- * Private contents of vdr.
- */
-typedef struct DOVIVdr {
-AVDOVIDataMapping mapping;
-AVDOVIColorMetadata color;
-} DOVIVdr;
-
 void ff_dovi_ctx_unref(DOVIContext *s)
 {
 for (int i = 0; i < FF_ARRAY_ELEMS(s->vdr); i++)
@@ -83,44 +65,6 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0)
 ff_refstruct_replace(>ext_blocks, s0->ext_blocks);
 }
 
-int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
-{
-AVFrameSideData *sd;
-AVBufferRef *buf;
-AVDOVIMetadata *dovi;
-size_t dovi_size, ext_sz;
-
-if (!s->mapping || !s->color)
-return 0; /* incomplete dovi metadata */
-
-dovi = av_dovi_metadata_alloc(_size);
-if (!dovi)
-return AVERROR(ENOMEM);
-
-buf = av_buffer_create((uint8_t *) dovi, dovi_size, NULL, NULL, 0);
-if (!buf) {
-av_free(dovi);
-return AVERROR(ENOMEM);
-}
-
-sd = av_frame_new_side_data_from_buf(frame, AV_FRAME_DATA_DOVI_METADATA, 
buf);
-if (!sd) {
-av_buffer_unref();
-return AVERROR(ENOMEM);
-}
-
-/* Copy only the parts of these structs known to us at compiler-time. */
-#define COPY(t, a, b, last) memcpy(a, b, offsetof(t, last) + sizeof((b)->last))
-COPY(AVDOVIRpuDataHeader, av_dovi_get_header(dovi), >header, 
disable_residual_flag);
-COPY(AVDOVIDataMapping, av_dovi_get_mapping(dovi), s->mapping, nlq_pivots);
-COPY(AVDOVIColorMetadata, av_dovi_get_color(dovi), s->color, 
source_diagonal);
-ext_sz = FFMIN(sizeof(AVDOVIDmData), dovi->ext_block_size);
-for (int i = 0; i < s->num_ext_blocks; i++)
-memcpy(av_dovi_get_ext(dovi, i), >ext_blocks[i], ext_sz);
-dovi->num_ext_blocks = s->num_ext_blocks;
-return 0;
-}
-
 int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr)
 {
 switch (hdr->vdr_rpu_profile) {
@@ -142,569 +86,3 @@ int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader 
*hdr)
 
 return 0; /* unknown */
 }
-
-static inline uint64_t get_ue_coef(GetBitContext *gb, const 
AVDOVIRpuDataHeader *hdr)
-{
-uint64_t ipart;
-union { uint32_t u32; float f32; } fpart;
-
-switch (hdr->coef_data_type) {
-case RPU_COEFF_FIXED:
-ipart = get_ue_golomb_long(gb);
-fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
-return (ipart << hdr->coef_log2_denom) | fpart.u32;
-
-case RPU_COEFF_FLOAT:
-fpart.u32 = get_bits_long(gb, 32);
-return fpart.f32 * (1LL << hdr->coef_log2_denom);
-}
-
-return 0; /* unreachable */
-}
-
-static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader 
*hdr)
-{
-int64_t ipart;
-union { uint32_t u32; float f32; } fpart;
-
-switch (hdr->coef_data_type) {
-case RPU_COEFF_FIXED:
-ipart = get_se_golomb_long(gb);
-fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom);
-return ipart * (1LL << hdr->coef_log2_de

[FFmpeg-devel] [PATCH v3 05/13] configure: rename dovi_rpu subsystem to dovi_rpudec

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

To distinguish it from the to-be-added dovi_rpuenc.
---
 configure   | 10 +-
 libavcodec/Makefile |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/configure b/configure
index 55f1fc354d..c1e1ece1e2 100755
--- a/configure
+++ b/configure
@@ -2550,7 +2550,7 @@ CONFIG_EXTRA="
 deflate_wrapper
 dirac_parse
 dnn
-dovi_rpu
+dovi_rpudec
 dvprofile
 evcparse
 exif
@@ -2841,7 +2841,7 @@ cbs_vp8_select="cbs"
 cbs_vp9_select="cbs"
 deflate_wrapper_deps="zlib"
 dirac_parse_select="golomb"
-dovi_rpu_select="golomb"
+dovi_rpudec_select="golomb"
 dnn_suggest="libtensorflow libopenvino libtorch"
 dnn_deps="avformat swscale"
 error_resilience_select="me_cmp"
@@ -2901,7 +2901,7 @@ asv1_encoder_select="aandcttables bswapdsp fdctdsp 
pixblockdsp"
 asv2_decoder_select="blockdsp bswapdsp idctdsp"
 asv2_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp"
 atrac1_decoder_select="sinewin"
-av1_decoder_select="atsc_a53 cbs_av1 dovi_rpu"
+av1_decoder_select="atsc_a53 cbs_av1 dovi_rpudec"
 bink_decoder_select="blockdsp hpeldsp"
 binkaudio_dct_decoder_select="wma_freqs"
 binkaudio_rdft_decoder_select="wma_freqs"
@@ -2957,7 +2957,7 @@ h264_decoder_suggest="error_resilience"
 hap_decoder_select="snappy texturedsp"
 hap_encoder_deps="libsnappy"
 hap_encoder_select="texturedspenc"
-hevc_decoder_select="bswapdsp cabac dovi_rpu golomb hevcparse hevc_sei 
videodsp"
+hevc_decoder_select="bswapdsp cabac dovi_rpudec golomb hevcparse hevc_sei 
videodsp"
 huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
 huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
 hymt_decoder_select="huffyuv_decoder"
@@ -3490,7 +3490,7 @@ libcelt_decoder_deps="libcelt"
 libcodec2_decoder_deps="libcodec2"
 libcodec2_encoder_deps="libcodec2"
 libdav1d_decoder_deps="libdav1d"
-libdav1d_decoder_select="atsc_a53 dovi_rpu"
+libdav1d_decoder_select="atsc_a53 dovi_rpudec"
 libdavs2_decoder_deps="libdavs2"
 libdavs2_decoder_select="avs2_parser"
 libfdk_aac_decoder_deps="libfdk_aac"
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 7f6de4470e..61d261d606 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -85,7 +85,7 @@ OBJS-$(CONFIG_CBS_MPEG2)   += cbs_mpeg2.o
 OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
 OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
 OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
-OBJS-$(CONFIG_DOVI_RPU)+= dovi_rpu.o
+OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o
 OBJS-$(CONFIG_ERROR_RESILIENCE)+= error_resilience.o
 OBJS-$(CONFIG_EVCPARSE)+= evc_parse.o evc_ps.o
 OBJS-$(CONFIG_EXIF)+= exif.o tiff_common.o
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 11/13] avcodec/libaomenc: implement dolby vision coding

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

---
 configure  |  2 +-
 libavcodec/libaomenc.c | 28 
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index d25d0f6907..bf63c831af 100755
--- a/configure
+++ b/configure
@@ -3485,7 +3485,7 @@ prores_videotoolbox_encoder_deps="pthreads"
 prores_videotoolbox_encoder_select="videotoolbox_encoder"
 libaom_av1_decoder_deps="libaom"
 libaom_av1_encoder_deps="libaom"
-libaom_av1_encoder_select="extract_extradata_bsf"
+libaom_av1_encoder_select="extract_extradata_bsf dovi_rpuenc"
 libaribb24_decoder_deps="libaribb24"
 libaribcaption_decoder_deps="libaribcaption"
 libcelt_decoder_deps="libcelt"
diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 4a71bba9c9..b43a902a38 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -43,6 +43,7 @@
 #include "avcodec.h"
 #include "bsf.h"
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "internal.h"
 #include "libaom.h"
@@ -70,6 +71,7 @@ struct FrameListData {
 typedef struct AOMEncoderContext {
 AVClass *class;
 AVBSFContext *bsf;
+DOVIContext dovi;
 struct aom_codec_ctx encoder;
 struct aom_image rawimg;
 struct aom_fixed_buf twopass_stats;
@@ -421,6 +423,7 @@ static av_cold int aom_free(AVCodecContext *avctx)
 av_freep(>stats_out);
 free_frame_list(ctx->coded_frame_list);
 av_bsf_free(>bsf);
+ff_dovi_ctx_unref(>dovi);
 return 0;
 }
 
@@ -989,6 +992,10 @@ static av_cold int aom_init(AVCodecContext *avctx,
 if (!cpb_props)
 return AVERROR(ENOMEM);
 
+ctx->dovi.logctx = avctx;
+if ((res = ff_dovi_configure(>dovi, avctx)) < 0)
+return res;
+
 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
 const AVBitStreamFilter *filter = 
av_bsf_get_by_name("extract_extradata");
 int ret;
@@ -1242,6 +1249,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 unsigned long duration = 0;
 int res, coded_size;
 aom_enc_frame_flags_t flags = 0;
+AVFrameSideData *sd;
 
 if (frame) {
 rawimg  = >rawimg;
@@ -1279,6 +1287,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
 break;
 }
 
+sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOVI_METADATA);
+if (ctx->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+uint8_t *t35;
+int size;
+if ((res = ff_dovi_rpu_generate(>dovi, metadata, , 
)) < 0)
+return res;
+res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35,
+   t35, size, AOM_MIF_ANY_FRAME);
+av_free(t35);
+if (res != AOM_CODEC_OK)
+return AVERROR(ENOMEM);
+} else if (ctx->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received 
frame "
+   "without AV_FRAME_DATA_DOVI_METADATA\n");
+return AVERROR_INVALIDDATA;
+}
+
 if (frame->pict_type == AV_PICTURE_TYPE_I)
 flags |= AOM_EFLAG_FORCE_KF;
 }
@@ -1459,6 +1485,8 @@ static const AVOption options[] = {
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, .unit = "tune"},
 FF_AV1_PROFILE_OPTS
 { "still-picture", "Encode in single frame mode (typically used for still 
AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, VE 
},
+{ "dolbyvision", "Enable Dolby Vision RPU coding", 
OFFSET(dovi.enable), AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, 
.unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
 { "enable-rect-partitions", "Enable rectangular partitions", 
OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", 
OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-ab-partitions",   "Enable ab shape partitions",
OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 04/13] avcodec/dovi_rpu: expose guess_profile(), clarify semantics

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

To allow internally re-using it for both the encoder and decoder.

This is based on HEVC only, H.264/AV1 use their own (hopefully correctly
signalled) profiles (and in particular, the AV1 decoders implicitly
default the correct profile in the absence of a configuration record).
---
 libavcodec/dovi_rpu.c |  4 ++--
 libavcodec/dovi_rpu.h | 11 +++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 267e52ceb6..77fef8c496 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -121,7 +121,7 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 return 0;
 }
 
-static int guess_profile(const AVDOVIRpuDataHeader *hdr)
+int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr)
 {
 switch (hdr->vdr_rpu_profile) {
 case 0:
@@ -510,7 +510,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 use_prev_vdr_rpu = get_bits1(gb);
 use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
 
-profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
+profile = s->cfg.dv_profile ? s->cfg.dv_profile : 
ff_dovi_guess_profile_hevc(hdr);
 if (profile == 5 && use_nlq) {
 av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
 goto fail;
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 9a68e45bf1..a866bbfebe 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -87,6 +87,10 @@ void ff_dovi_ctx_flush(DOVIContext *s);
  * DOVIContext struct.
  *
  * Returns 0 or an error code.
+ *
+ * Note: `DOVIContext.cfg` should be initialized before calling into this
+ * function. If not done, the profile will be guessed according to HEVC
+ * semantics.
  */
 int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, size_t rpu_size,
   int err_recognition);
@@ -96,4 +100,11 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
  */
 int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame);
 
+/**
+ * Internal helper function to guess the correct DV profile for HEVC.
+ *
+ * Returns the profile number or 0 if unknown.
+ */
+int ff_dovi_guess_profile_hevc(const AVDOVIRpuDataHeader *hdr);
+
 #endif /* AVCODEC_DOVI_RPU_H */
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 13/13] avcodec/libsvtav1: implement dolby vision coding

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

---
 configure  |  1 +
 libavcodec/libsvtav1.c | 34 ++
 2 files changed, 35 insertions(+)

diff --git a/configure b/configure
index cce37bb32e..6fbd0e44ff 100755
--- a/configure
+++ b/configure
@@ -3534,6 +3534,7 @@ libspeex_decoder_deps="libspeex"
 libspeex_encoder_deps="libspeex"
 libspeex_encoder_select="audio_frame_queue"
 libsvtav1_encoder_deps="libsvtav1"
+libsvtav1_encoder_select="dovi_rpueenc"
 libtheora_encoder_deps="libtheora"
 libtwolame_encoder_deps="libtwolame"
 libuavs3d_decoder_deps="libuavs3d"
diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 6ff893cf10..9bc165f0cf 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "libavutil/common.h"
 #include "libavutil/frame.h"
@@ -35,6 +36,7 @@
 #include "libavutil/avassert.h"
 
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "packet_internal.h"
 #include "avcodec.h"
@@ -62,6 +64,8 @@ typedef struct SvtContext {
 
 EOS_STATUS eos_flag;
 
+DOVIContext dovi;
+
 // User options.
 AVDictionary *svtav1_opts;
 int enc_mode;
@@ -418,6 +422,7 @@ static int read_in_data(EbSvtAv1EncConfiguration *param, 
const AVFrame *frame,
 in_data->cr_stride = AV_CEIL_RSHIFT(frame->linesize[2], bytes_shift);
 
 header_ptr->n_filled_len = frame_size;
+svt_metadata_array_free(_ptr->metadata);
 
 return 0;
 }
@@ -451,6 +456,11 @@ static av_cold int eb_enc_init(AVCodecContext *avctx)
 return svt_print_error(avctx, svt_ret, "Error initializing encoder");
 }
 
+svt_enc->dovi.logctx = avctx;
+ret = ff_dovi_configure(_enc->dovi, avctx);
+if (ret < 0)
+return ret;
+
 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
 EbBufferHeaderType *headerPtr = NULL;
 
@@ -486,6 +496,7 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 {
 SvtContext   *svt_enc = avctx->priv_data;
 EbBufferHeaderType  *headerPtr = svt_enc->in_buf;
+AVFrameSideData *sd;
 EbErrorType svt_ret;
 int ret;
 
@@ -525,6 +536,24 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 if (avctx->gop_size == 1)
 headerPtr->pic_type = EB_AV1_KEY_PICTURE;
 
+sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOVI_METADATA);
+if (svt_enc->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+uint8_t *t35;
+int size;
+if ((ret = ff_dovi_rpu_generate(_enc->dovi, metadata, , 
)) < 0)
+return ret;
+ret = svt_add_metadata(headerPtr, EB_AV1_METADATA_TYPE_ITUT_T35, t35, 
size);
+av_free(t35);
+if (ret < 0)
+return AVERROR(ENOMEM);
+} else if (svt_enc->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received frame "
+   "without AV_FRAME_DATA_DOVI_METADATA\n");
+return AVERROR_INVALIDDATA;
+}
+
+
 svt_ret = svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
 if (svt_ret != EB_ErrorNone)
 return svt_print_error(avctx, svt_ret, "Error sending a frame to 
encoder");
@@ -649,11 +678,13 @@ static av_cold int eb_enc_close(AVCodecContext *avctx)
 }
 if (svt_enc->in_buf) {
 av_free(svt_enc->in_buf->p_buffer);
+svt_metadata_array_free(_enc->in_buf->metadata);
 av_freep(_enc->in_buf);
 }
 
 av_buffer_pool_uninit(_enc->pool);
 av_frame_free(_enc->frame);
+ff_dovi_ctx_unref(_enc->dovi);
 
 return 0;
 }
@@ -700,6 +731,9 @@ static const AVOption options[] = {
   AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
 { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list 
of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, 
VE },
 
+{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
+
 {NULL},
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 03/13] avcodec/dovi_rpu: clarify error on missing RPU VDR

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

The code was written under the misguided assumption that these fields
would only be present when the value changes, however this does not
match the actual patent specification, which says that streams are
required to either always signal this metadata, or never signal it.

That said, the specification does not really clarify what the defaults
of these fields should be in the event that this metadata is missing, so
without any sample file or other reference I don't wish to hazard
a guess at how to interpret these fields.

Fix the current behavior by making sure we always throw this error, even
for files that have the vdr sequence info in one frame but are missing
it in the next frame.
---
 libavcodec/dovi_rpu.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index bfb7b9fe66..267e52ceb6 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -499,11 +499,11 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 hdr->el_spatial_resampling_filter_flag = get_bits1(gb);
 hdr->disable_residual_flag = get_bits1(gb);
 }
-}
-
-if (!hdr->bl_bit_depth) {
-av_log(s->logctx, AV_LOG_ERROR, "Missing RPU VDR sequence info?\n");
-goto fail;
+} else {
+/* lack of documentation/samples */
+avpriv_request_sample(s->logctx, "Missing RPU VDR sequence info\n");
+ff_dovi_ctx_unref(s);
+return AVERROR_PATCHWELCOME;
 }
 
 vdr_dm_metadata_present = get_bits1(gb);
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 12/13] avcodec/libx265: implement dolby vision coding

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

libx265 supports these natively, we just need to attach the generated
NALs to the x265picture, as well as setting the appropriate DV profile.
---
 configure|  2 +-
 libavcodec/libx265.c | 40 
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index bf63c831af..cce37bb32e 100755
--- a/configure
+++ b/configure
@@ -3553,7 +3553,7 @@ libx264_encoder_select="atsc_a53 golomb"
 libx264rgb_encoder_deps="libx264"
 libx264rgb_encoder_select="libx264_encoder"
 libx265_encoder_deps="libx265"
-libx265_encoder_select="atsc_a53"
+libx265_encoder_select="atsc_a53 dovi_rpueenc"
 libxavs_encoder_deps="libxavs"
 libxavs2_encoder_deps="libxavs2"
 libxevd_decoder_deps="libxevd"
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 0645cd2045..c4ce5d 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -36,6 +36,7 @@
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "packet_internal.h"
 #include "atsc_a53.h"
@@ -78,6 +79,8 @@ typedef struct libx265Context {
  * encounter a frame with ROI side data.
  */
 int roi_warned;
+
+DOVIContext dovi;
 } libx265Context;
 
 static int is_keyframe(NalUnitType naltype)
@@ -143,6 +146,8 @@ static av_cold int libx265_encode_close(AVCodecContext 
*avctx)
 if (ctx->encoder)
 ctx->api->encoder_close(ctx->encoder);
 
+ff_dovi_ctx_unref(>dovi);
+
 return 0;
 }
 
@@ -526,6 +531,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
 }
 }
 
+#if X265_BUILD >= 167
+ctx->dovi.logctx = avctx;
+if ((ret = ff_dovi_configure(>dovi, avctx)) < 0)
+return ret;
+ctx->params->dolbyProfile = ctx->dovi.cfg.dv_profile * 10 +
+ctx->dovi.cfg.dv_bl_signal_compatibility_id;
+#endif
+
 ctx->encoder = ctx->api->encoder_open(ctx->params);
 if (!ctx->encoder) {
 av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");
@@ -629,6 +642,10 @@ static void free_picture(libx265Context *ctx, x265_picture 
*pic)
 for (int i = 0; i < sei->numPayloads; i++)
 av_free(sei->payloads[i].payload);
 
+#if X265_BUILD >= 167
+av_free(pic->rpu.payload);
+#endif
+
 if (pic->userData) {
 int idx = (int)(intptr_t)pic->userData - 1;
 rd_release(ctx, idx);
@@ -660,6 +677,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 sei->numPayloads = 0;
 
 if (pic) {
+AVFrameSideData *sd;
 ReorderedData *rd;
 int rd_idx;
 
@@ -760,6 +778,24 @@ static int libx265_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 sei->numPayloads++;
 }
 }
+
+#if X265_BUILD >= 167
+sd = av_frame_get_side_data(pic, AV_FRAME_DATA_DOVI_METADATA);
+if (ctx->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+ret = ff_dovi_rpu_generate(>dovi, metadata, 
,
+   );
+if (ret < 0) {
+free_picture(ctx, );
+return ret;
+}
+} else if (ctx->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received 
frame "
+   "without AV_FRAME_DATA_DOVI_METADATA");
+free_picture(ctx, );
+return AVERROR_INVALIDDATA;
+}
+#endif
 }
 
 ret = ctx->api->encoder_encode(ctx->encoder, , ,
@@ -914,6 +950,10 @@ static const AVOption options[] = {
 { "udu_sei", "Use user data unregistered SEI if available",
 OFFSET(udu_sei),   AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, 
VE },
 { "a53cc",   "Use A53 Closed Captions (if available)", 
 OFFSET(a53_cc),AV_OPT_TYPE_BOOL,   { .i64 = 1 }, 0, 1, 
VE },
 { "x265-params", "set the x265 configuration using a :-separated list of 
key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT,   { 0 }, 0, 0, VE },
+#if X265_BUILD >= 167
+{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
+#endif
 { NULL }
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 10/13] avformat/movenc: warn if dovi cfg ignored

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

Since this is guarded behind strict unofficial, we should warn if the
user feeds a dolby vision stream to this muxer, as it will otherwise
result in a broken file.
---
 libavformat/movenc.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 6ede5119f0..1a0502bbb1 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2526,16 +2526,21 @@ static int mov_write_video_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContex
 const AVPacketSideData *spherical_mapping = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
 
track->st->codecpar->nb_coded_side_data,
 
AV_PKT_DATA_SPHERICAL);
-const AVPacketSideData *dovi = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
-   
track->st->codecpar->nb_coded_side_data,
-   
AV_PKT_DATA_DOVI_CONF);
-
 if (stereo_3d)
 mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
 if (spherical_mapping)
 mov_write_sv3d_tag(mov->fc, pb, 
(AVSphericalMapping*)spherical_mapping->data);
-if (dovi)
+}
+
+if (track->mode == MODE_MP4) {
+const AVPacketSideData *dovi = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
+   
track->st->codecpar->nb_coded_side_data,
+   
AV_PKT_DATA_DOVI_CONF);
+if (dovi && mov->fc->strict_std_compliance <= 
FF_COMPLIANCE_UNOFFICIAL) {
 mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord 
*)dovi->data);
+} else if (dovi) {
+av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. 
Requires -strict unofficial.\n");
+}
 }
 
 if (track->par->sample_aspect_ratio.den && 
track->par->sample_aspect_ratio.num) {
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 09/13] avcodec/dovi_rpuenc: add ff_dovi_rpu_generate()

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

This function takes a decoded AVDOVIMetadata struct and turns it back
into a binary RPU. Verified using existing tools, and matches the
bitstream in official reference files.

I decided to just roll the EMDF and NAL encapsulation into this function
because the end user will need to do it otherwise anyways.
---
 libavcodec/dovi_rpu.h|  20 +-
 libavcodec/dovi_rpuenc.c | 544 +++
 2 files changed, 562 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 8f8905b96b..1b74548e89 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -55,20 +55,22 @@ typedef struct DOVIContext {
 AVDOVIDecoderConfigurationRecord cfg;
 
 /**
- * Currently active RPU data header, updates on every dovi_rpu_parse().
+ * Currently active RPU data header, updates on every ff_dovi_rpu_parse()
+ * or ff_dovi_rpu_generate().
  */
 AVDOVIRpuDataHeader header;
 
 /**
  * Currently active data mappings, or NULL. Points into memory owned by the
  * corresponding rpu/vdr_ref, which becomes invalid on the next call to
- * dovi_rpu_parse.
+ * ff_dovi_rpu_parse() or ff_dovi_rpu_generate().
  */
 const AVDOVIDataMapping *mapping;
 const AVDOVIColorMetadata *color;
 
 /**
  * Currently active extension blocks, updates on every ff_dovi_rpu_parse()
+ * or ff_dovi_rpu_generate().
  */
 AVDOVIDmData *ext_blocks;
 int num_ext_blocks;
@@ -138,6 +140,20 @@ enum {
 RPU_COEFF_FLOAT = 1,
 };
 
+/**
+ * Synthesize a Dolby Vision RPU reflecting the current state. Note that this
+ * assumes all previous calls to `ff_dovi_rpu_generate` have been appropriately
+ * signalled, i.e. it will not re-send already transmitted redundant data.
+ *
+ * Mutates the internal state of DOVIContext to reflect the change.
+ * Returns 0 or a negative error code.
+ *
+ * This generates a fully formed RPU ready for inclusion in the bitstream,
+ * including the EMDF header (profile 10) or NAL encapsulation (otherwise).
+ */
+int ff_dovi_rpu_generate(DOVIContext *s, const AVDOVIMetadata *metadata,
+ uint8_t **out_rpu, int *out_size);
+
 /**
  * Internal helper function to guess the correct DV profile for HEVC.
  *
diff --git a/libavcodec/dovi_rpuenc.c b/libavcodec/dovi_rpuenc.c
index 3ab4624a79..8b99bf12d9 100644
--- a/libavcodec/dovi_rpuenc.c
+++ b/libavcodec/dovi_rpuenc.c
@@ -21,10 +21,15 @@
  */
 
 #include "libavutil/avassert.h"
+#include "libavutil/crc.h"
 #include "libavutil/mem.h"
 
 #include "avcodec.h"
 #include "dovi_rpu.h"
+#include "itut35.h"
+#include "put_bits.h"
+#include "put_golomb.h"
+#include "refstruct.h"
 
 static struct {
 uint64_t pps; // maximum pixels per second
@@ -201,3 +206,542 @@ skip:
 s->cfg = (AVDOVIDecoderConfigurationRecord) {0};
 return 0;
 }
+
+static inline void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader 
*hdr,
+   uint64_t coef)
+{
+union { uint32_t u32; float f32; } fpart;
+
+switch (hdr->coef_data_type) {
+case RPU_COEFF_FIXED:
+set_ue_golomb(pb, coef >> hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom,
+   coef & ((1LL << hdr->coef_log2_denom) - 1));
+break;
+case RPU_COEFF_FLOAT:
+fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom, fpart.u32);
+break;
+}
+}
+
+static inline void put_se_coef(PutBitContext *pb, const AVDOVIRpuDataHeader 
*hdr,
+   uint64_t coef)
+{
+union { uint32_t u32; float f32; } fpart;
+
+switch (hdr->coef_data_type) {
+case RPU_COEFF_FIXED:
+set_se_golomb(pb, coef >> hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom,
+   coef & ((1LL << hdr->coef_log2_denom) - 1));
+break;
+case RPU_COEFF_FLOAT:
+fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom, fpart.u32);
+break;
+}
+}
+
+static int av_q2den(AVRational q, int den)
+{
+if (q.den == den)
+return q.num;
+q = av_mul_q(q, av_make_q(den, 1));
+return (q.num + (q.den >> 1)) / q.den;
+}
+
+static void generate_ext_v1(PutBitContext *pb, const AVDOVIDmData *dm)
+{
+int ext_block_length, start_pos, pad_bits;
+
+switch (dm->level) {
+case 1:   ext_block_length = 5;  break;
+case 2:   ext_block_length = 11; break;
+case 4:   ext_block_length = 3;  break;
+case 5:   ext_block_length = 7;  break;
+case 6:   ext_block_length = 8;  break;
+case 255: ext_block_length = 6;  break;
+default: return;
+}
+
+set_ue_golomb(pb, ext_block_length);
+put_bits(pb, 8, dm->le

[FFmpeg-devel] [PATCH v3 02/13] avcodec/dovi_rpu: properly replace context header

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

This was never set in ff_dovi_ctx_replace(), leading to possibly
out-of-date when copying from one thread to another.
---
 libavcodec/dovi_rpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index d95c7e03af..bfb7b9fe66 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -75,6 +75,7 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0)
 {
 s->logctx = s0->logctx;
 s->cfg = s0->cfg;
+s->header = s0->header;
 s->mapping = s0->mapping;
 s->color = s0->color;
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v3 01/13] avcodec/dovi_rpu: store entire config record

2024-04-12 Thread Niklas Haas
From: Niklas Haas 

And make it public.

For encoding, users may also be interested in the configured level and
compatibility ID. So generalize the dv_profile field and just expose the
whole configuration record.

This makes the already rather reductive ff_dovi_update_cfg() function
almost wholly redundant, since users can just directly assign
DOVIContext.cfg.
---
 libavcodec/av1dec.c   |  6 +++---
 libavcodec/dovi_rpu.c | 16 
 libavcodec/dovi_rpu.h | 21 -
 libavcodec/hevcdec.c  | 13 ++---
 libavcodec/libdav1d.c |  6 +++---
 5 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 824725c031..4c1405df77 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -888,10 +888,10 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
 }
 
 s->dovi.logctx = avctx;
-s->dovi.dv_profile = 10; // default for AV1
+s->dovi.cfg.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(>dovi, (AVDOVIDecoderConfigurationRecord *) 
sd->data);
+if (sd && sd->size >= sizeof(s->dovi.cfg))
+s->dovi.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
 
 return ret;
 }
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 9f7a6b0066..d95c7e03af 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -64,7 +64,7 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 
 *s = (DOVIContext) {
 .logctx = s->logctx,
-.dv_profile = s->dv_profile,
+.cfg = s->cfg,
 /* preserve temporary buffer */
 .rpu_buf = s->rpu_buf,
 .rpu_buf_sz = s->rpu_buf_sz,
@@ -74,22 +74,14 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
 {
 s->logctx = s0->logctx;
+s->cfg = s0->cfg;
 s->mapping = s0->mapping;
 s->color = s0->color;
-s->dv_profile = s0->dv_profile;
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
 ff_refstruct_replace(>vdr[i], s0->vdr[i]);
 ff_refstruct_replace(>ext_blocks, s0->ext_blocks);
 }
 
-void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord 
*cfg)
-{
-if (!cfg)
-return;
-
-s->dv_profile = cfg->dv_profile;
-}
-
 int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 {
 AVFrameSideData *sd;
@@ -392,7 +384,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 goto fail;
 
 /* Container */
-if (s->dv_profile == 10 /* dav1.10 */) {
+if (s->cfg.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.
  *
@@ -517,7 +509,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 use_prev_vdr_rpu = get_bits1(gb);
 use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
 
-profile = s->dv_profile ? s->dv_profile : guess_profile(hdr);
+profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
 if (profile == 5 && use_nlq) {
 av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
 goto fail;
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 9f26f332ce..9a68e45bf1 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -31,6 +31,16 @@
 typedef struct DOVIContext {
 void *logctx;
 
+/**
+ * Currently active dolby vision configuration, or {0} for none.
+ * Set by the user when decoding.
+ *
+ * Note: sizeof(cfg) is not part of the libavutil ABI, so users should
+ * never pass  to any other library calls. This is included merely as
+ * a way to look up the values of fields known at compile time.
+ */
+AVDOVIDecoderConfigurationRecord cfg;
+
 /**
  * Currently active RPU data header, updates on every dovi_rpu_parse().
  */
@@ -56,7 +66,6 @@ typedef struct DOVIContext {
 struct DOVIVdr *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
 uint8_t *rpu_buf; ///< temporary buffer
 unsigned rpu_buf_sz;
-uint8_t dv_profile;
 
 } DOVIContext;
 
@@ -68,17 +77,11 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0);
 void ff_dovi_ctx_unref(DOVIContext *s);
 
 /**
- * Partially reset the internal state. Resets per-frame state while preserving
- * fields parsed from the configuration record.
+ * Partially reset the internal state. Resets per-frame state, but preserves
+ * the stream-wide configuration record.
  */
 void ff_dovi_ctx_flush(DOVIContext *s);
 
-/**
- * Read the contents of an AVDOVIDecoderConfigurationRecord (usually provided
- * by stream s

[FFmpeg-devel] [PATCH v3 00/13] avcodec: add Dolby Vision encoding

2024-04-12 Thread Niklas Haas
Changes since v2:
- Split up dovi_rpu.c into dovi_rpudec.c and dovi_rpueenc.
- Added missing dependencies of encoders onto dovi_rpueenc
- Clarified and documented semantics of guess_profile()
- Changed misleading commit message

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2] avcodec/libx264: bump minimum required version to 155

2024-04-12 Thread Niklas Haas
On Tue, 09 Apr 2024 15:12:05 +0200 Niklas Haas  wrote:
> From: Niklas Haas 
> 
> This version is seven years old, and present in Debian oldoldstable,
> Ubuntu 20.04 and Leap 15.0.
> 
> Allows cleaning up the file substantially. In particular, this is
> motivated by the desire to stop relying on init_static_data.
> ---
>  configure|  2 +-
>  libavcodec/libx264.c | 52 ++--
>  2 files changed, 8 insertions(+), 46 deletions(-)
> 
> diff --git a/configure b/configure
> index f511fbae492..248ce2040d6 100755
> --- a/configure
> +++ b/configure
> @@ -7007,7 +7007,7 @@ enabled libwebp   && {
>  enabled libwebp_encoder  && require_pkg_config libwebp "libwebp >= 
> 0.2.0" webp/encode.h WebPGetEncoderVersion
>  enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder 
> "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
>  enabled libx264   && require_pkg_config libx264 x264 "stdint.h 
> x264.h" x264_encoder_encode &&
> - require_cpp_condition libx264 x264.h 
> "X264_BUILD >= 122" && {
> + require_cpp_condition libx264 x264.h 
> "X264_BUILD >= 155" && {
>   [ "$toolchain" != "msvc" ] ||
>   require_cpp_condition libx264 x264.h 
> "X264_BUILD >= 158"; } &&
>   check_cpp_condition libx264_hdr10 x264.h 
> "X264_BUILD >= 163" &&
> diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
> index eadb20d2b39..2715f277f1f 100644
> --- a/libavcodec/libx264.c
> +++ b/libavcodec/libx264.c
> @@ -270,11 +270,9 @@ static void reconfig_encoder(AVCodecContext *ctx, const 
> AVFrame *frame)
>  case AV_STEREO3D_FRAMESEQUENCE:
>  fpa_type = 5;
>  break;
> -#if X264_BUILD >= 145
>  case AV_STEREO3D_2D:
>  fpa_type = 6;
>  break;
> -#endif
>  default:
>  fpa_type = -1;
>  break;
> @@ -394,14 +392,14 @@ static int setup_mb_info(AVCodecContext *ctx, 
> x264_picture_t *pic,
>  return 0;
>  }
>  
> -static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
> +static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic,
>   const AVFrame *frame, const uint8_t *data, size_t size)
>  {
>  X264Context *x4 = ctx->priv_data;
>  
>  int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
>  int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
> -int qp_range = 51 + 6 * (bit_depth - 8);
> +int qp_range = 51 + 6 * (x4->params.i_bitdepth - 8);
>  int nb_rois;
>  const AVRegionOfInterest *roi;
>  uint32_t roi_size;
> @@ -476,7 +474,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame 
> *frame,
>  x264_sei_t *sei = >extra_sei;
>  unsigned int sei_data_size = 0;
>  int64_t wallclock = 0;
> -int bit_depth, ret;
> +int ret;
>  AVFrameSideData *sd;
>  AVFrameSideData *mbinfo_sd;
>  
> @@ -486,12 +484,7 @@ static int setup_frame(AVCodecContext *ctx, const 
> AVFrame *frame,
>  
>  x264_picture_init(pic);
>  pic->img.i_csp   = x4->params.i_csp;
> -#if X264_BUILD >= 153
> -bit_depth = x4->params.i_bitdepth;
> -#else
> -bit_depth = x264_bit_depth;
> -#endif
> -if (bit_depth > 8)
> +if (x4->params.i_bitdepth > 8)
>  pic->img.i_csp |= X264_CSP_HIGH_DEPTH;
>  pic->img.i_plane = av_pix_fmt_count_planes(ctx->pix_fmt);
>  
> @@ -564,7 +557,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame 
> *frame,
>  
>  sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
>  if (sd) {
> -ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
> +ret = setup_roi(ctx, pic, frame, sd->data, sd->size);
>  if (ret < 0)
>  goto fail;
>  }
> @@ -1109,9 +1102,7 @@ static av_cold int X264_init(AVCodecContext *avctx)
>  x4->params.p_log_private= avctx;
>  x4->params.i_log_level  = X264_LOG_DEBUG;
>  x4->params.i_csp= convert_pix_fmt(avctx->pix_fmt);
> -#if X264_BUILD >= 153
>  x4->params.i_bitdepth   = 
> av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth;
> -#endif
>  
>  PARSE_X264_OPT("weightp", wpredp);
>  
> @@ -1180,11 +1171,10 @@ static av_cold in

[FFmpeg-devel] [TC] Technical decision on S302M non-PCM decoding

2024-04-12 Thread Niklas Haas
39.html
> 

Hi,

This is in regards to the patch "avcodec/s302m: enable non-PCM decoding"
by Gyan Doshi.
https://patchwork.ffmpeg.org/project/ffmpeg/patch/20240127103854.9971-1-ffm...@gyani.pro/

The TC has voted on the matter, with all 5 voting members unanimously
voting against the patch.

The opposition to the patch was based on the opinion that this
implementation of S302M should be handled by libavformat, not
libavcodec. The central argument focused on the ways in which these
formats can interact. In particular, S302M is always tied to MPEG-TS,
but Dolby E can also exist in other containers, so exposing Dolby E as
the the intermediary (AV_CODEC_ID) unlocks the full range of possible
operations (e.g. S302M -> Dolby E -> MXF remux).

Regarding Gyan Doshi's main objection that doing so would possibly
delete S302M metadata (e.g. S-ADM), it was observed that if the need for
such metadata truly arises, it should either be parsed by FFmpeg or
attached as an opaque side data blob (only if the former is impossible).

Therefore, the matter has been decided, rejecting the patch at hand.

Regards,
The FFmpeg Technical Committee
- Jan Ekström
- Niklas Haas
- Anton Khirnov
- Michael Niedermayer
- Martin Storsjö
- Mark Thompson
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/libx264: bump minimum required version to 160

2024-04-10 Thread Niklas Haas
On Wed, 10 Apr 2024 15:18:52 +0200 Michael Niedermayer  
wrote:
> On Tue, Apr 09, 2024 at 02:53:28PM +0200, Niklas Haas wrote:
> > On Sat, 06 Apr 2024 22:28:26 +0200 Michael Niedermayer 
> >  wrote:
> > > On Fri, Apr 05, 2024 at 07:44:52PM +0200, Niklas Haas wrote:
> > > > From: Niklas Haas 
> > > > 
> > > > This version is four years old, and present in Debian oldstable, Ubuntu
> > > > 22.04 and Leap 15.1.
> > > 
> > > Ubuntu 20.04 has general support till 2025-05-29
> > > Ubuntu 18.04 has security support (ESM) till 2028-04
> > 
> > I'll relax it from 160 back down to version 155 then. That covers Ubuntu
> > 20.04 and Debian oldoldstable.
> 
> 18.04 has 152
> 
> libx264-dev/bionic,now 2:0.152.2854+gite9a5903-2 amd64 [installed]
> 
> Ubuntu 18.04 still has security support in ESM and ubuntu pro IIUC till 
> 2028-04

Do you think FFmpeg 7.1 will be back-ported to Ubuntu 18.04 for security
reasons?

> 
> thx
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Those who are best at talking, realize last or never when they are wrong.
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

2024-04-10 Thread Niklas Haas
On Wed, 10 Apr 2024 14:59:15 +0200 Michael Niedermayer  
wrote:
> On Wed, Apr 10, 2024 at 12:29:06PM +0200, Niklas Haas wrote:
> > On Wed, 10 Apr 2024 03:25:45 +0200 Michael Niedermayer 
> >  wrote:
> > > On Mon, Apr 08, 2024 at 02:57:20PM +0200, Niklas Haas wrote:
> > > > From: Niklas Haas 
> > > > 
> > > > To convert between color spaces/ranges, if needed by the codec
> > > > properties.
> > > > ---
> > > >  fftools/ffmpeg_filter.c | 34 ++
> > > >  1 file changed, 34 insertions(+)
> > > 
> > > I presume this is intended to change some cases
> > > iam asking because it does
> > > for example, this one
> > > -i aletrek.mkv -t 1 -bitexact  /tmp/file-aletrek-palette.mkv
> > > has the output file change slightly
> > > 
> > > https://trac.ffmpeg.org/attachment/ticket/5071/aletrek.mkv
> > > 
> > > also given fate does not change, it would make sense to add a testcase
> > > to fate that does cover this
> > 
> > Two notes:
> > 
> > 1. The only difference between the `master` behavior and the new
> >behavior is that the file is marked as limited range instead of as
> >unspecified. However, this is the correct tagging, as the actual
> >output *is* limited range.
> > 
> > 2. While not *broken* per se, this is actually still a bug - in this
> >case, since the input is basically full range, we should actually try
> >and output full range by default.
> > 
> > The reason it doesn't output full range here is because a consequence of
> > the fact that format reduction happens *before* the logic in
> > pick_format() fixes all non-YUV links to be tagged as PC/RGB-only. So
> > the format reduction logic just sees that vf_scale can output any range
> > in this scenario (true) and picks TV range output as the default,
> > resulting in a conversion from the PC range input to a TV range output.
> > 
> > The easiest solution would be to not blindly pick the first here, but to
> > instead try and pick a colorspace and range matching the input (if one
> > exists). But this may still break in more complicated scenarios where
> > the dependence on the forced format spans several filters.
> > 
> > The more correct solution would probably be to explicitly reduce only
> > the format first (going through all the steps) and then negotiate
> > everything that depends on the format in an entirely separate step.
> > 
> > I'll see if I can do something about this situation, though it's
> > ultimately not a high priority as it's not a regression compared to the
> > status quo - just something that we could definitely improve.
> 
> I have the feeling the colorspace negotiation has become a bit messy
> IIRC The way it was intended to work originally was to have a
> arbitrary filtergraph and then randomly simplify/merge bits of the
> filtergraph before picking "colorspaces" for each part.
> Then repeat this whole process a few times starting from the unsimplified
> graph. Then pick the best and that would be within a constant factor
> of the optimal solution for any arbitrary complex graph.
> 
> Somehow this was never implemented as things worked okesich with just
> doing a single pass instead of multiple and then picking the best.
> 
> I dont know how much this applies here now but i thought bringing
> up the original intended design was a good idea. Because it seems
> every problem in the negotiation is solved by adjusting the single pass
> steps or its orders while really it should have been multiple randomized
> passes.
> Maybe we never have to deal with complex enough filtergraphs where a single
> pass cant be made to work well and surely this here is not a complex one
> at all.
> But wanted to bring this up anyway because i think many people forgot
> or didnt even know the original idea was to do multiple passes so as to
> handle any arbitrary complex graph well.

I think a greedy algorithm (not requiring juggling multiple random
passes) can still work, just that we need to change the logic from:

  do
  // step 1
  while (progress)
  
  do
  // step 2
  while (progress)

  ...

to:

  do {
  // step 1
  // step 2
  ...
  } while (any_progress)

In any case, the realization is clear that we can no longer rely on
negotiating everything at the same time, as we now have a fundamental
interdependency of one negotiated component on another. (And I can
easily see more such dependencies being added in the future)

> 
> thx
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730B

Re: [FFmpeg-devel] [PATCH v2 14/17] fftools/ffmpeg_filter: simplify choose_pix_fmts

2024-04-10 Thread Niklas Haas
On Wed, 10 Apr 2024 03:13:02 +0200 Michael Niedermayer  
wrote:
> On Mon, Apr 08, 2024 at 02:57:18PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > The only meaningful difference between choose_pix_fmts and the default
> > code was the inclusion of an extra branch for `keep_pix_fmt` being true.
> > 
> > However, in this case, we either:
> > 1. Force the specific `ofp->format` that we inherited from
> >ofilter_bind_ost, or if no format was set:
> > 2. Print an empty format list
> > 
> > Both of these goals can be accomplished by simply moving the decision
> > logic to ofilter_bind_ost, to avoid setting any format list when
> > keep_pix_fmt is enabled. This is arguably cleaner as it moves format
> > selection logic to a single function. In the case of branch 1, nothing
> > else needs to be done as we already force the format provided in
> > ofp->format, if any is set. Add an assertion to verify this assumption
> > just in case.
> > 
> > (Side note: The "choose_*" family of functions are arguably misnomers,
> > as they should really be called "print_*" - their current behavior is to
> > print the relevant format lists to the `vf/af_format` filter arguments)
> > ---
> >  fftools/ffmpeg_filter.c | 49 -
> >  1 file changed, 9 insertions(+), 40 deletions(-)
> 
> breaks:
> ./ffmpeg -y -i fate-suite/lena.pnm -pix_fmt +yuv444p -vf scale -strict -1 
> -bitexact -threads 2 -thread_type slice /tmp/file-2s-444.jpg
> 
> Press [q] to stop, [?] for help
> Assertion !ost->keep_pix_fmt || (!ofp->format && !ofp->formats) failed at 
> fftools/ffmpeg_filter.c:1314
> Aborted (core dumped)

My bad, I cherry-picked the wrong version of this commit.

> 
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> The real ebay dictionary, page 2
> "100% positive feedback" - "All either got their money back or didnt complain"
> "Best seller ever, very honest" - "Seller refunded buyer after failed scam"
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

2024-04-10 Thread Niklas Haas
On Wed, 10 Apr 2024 12:29:06 +0200 Niklas Haas  wrote:
> On Wed, 10 Apr 2024 03:25:45 +0200 Michael Niedermayer 
>  wrote:
> > On Mon, Apr 08, 2024 at 02:57:20PM +0200, Niklas Haas wrote:
> > > From: Niklas Haas 
> > > 
> > > To convert between color spaces/ranges, if needed by the codec
> > > properties.
> > > ---
> > >  fftools/ffmpeg_filter.c | 34 ++
> > >  1 file changed, 34 insertions(+)
> > 
> > I presume this is intended to change some cases
> > iam asking because it does
> > for example, this one
> > -i aletrek.mkv -t 1 -bitexact  /tmp/file-aletrek-palette.mkv
> > has the output file change slightly
> > 
> > https://trac.ffmpeg.org/attachment/ticket/5071/aletrek.mkv
> > 
> > also given fate does not change, it would make sense to add a testcase
> > to fate that does cover this
> 
> Two notes:
> 
> 1. The only difference between the `master` behavior and the new
>behavior is that the file is marked as limited range instead of as
>unspecified. However, this is the correct tagging, as the actual
>output *is* limited range.
> 
> 2. While not *broken* per se, this is actually still a bug - in this
>case, since the input is basically full range, we should actually try
>and output full range by default.
> 
> The reason it doesn't output full range here is because a consequence of
> the fact that format reduction happens *before* the logic in
> pick_format() fixes all non-YUV links to be tagged as PC/RGB-only. So
> the format reduction logic just sees that vf_scale can output any range
> in this scenario (true) and picks TV range output as the default,
> resulting in a conversion from the PC range input to a TV range output.
> 
> The easiest solution would be to not blindly pick the first here, but to
> instead try and pick a colorspace and range matching the input (if one
> exists). But this may still break in more complicated scenarios where
> the dependence on the forced format spans several filters.
> 
> The more correct solution would probably be to explicitly reduce only
> the format first (going through all the steps) and then negotiate
> everything that depends on the format in an entirely separate step.
> 
> I'll see if I can do something about this situation, though it's
> ultimately not a high priority as it's not a regression compared to the
> status quo - just something that we could definitely improve.

Alternatively, a third simple fix would be to make buffersrc explicitly
request PC range in this scenario (e.g. RGB/PAL8 input), but that feels
like a sort of a hack.

> 
> > 
> > thx
> > 
> > [...]
> > -- 
> > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> > 
> > What does censorship reveal? It reveals fear. -- Julian Assange
> > ___
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> > 
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

2024-04-10 Thread Niklas Haas
On Wed, 10 Apr 2024 03:25:45 +0200 Michael Niedermayer  
wrote:
> On Mon, Apr 08, 2024 at 02:57:20PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > To convert between color spaces/ranges, if needed by the codec
> > properties.
> > ---
> >  fftools/ffmpeg_filter.c | 34 ++
> >  1 file changed, 34 insertions(+)
> 
> I presume this is intended to change some cases
> iam asking because it does
> for example, this one
> -i aletrek.mkv -t 1 -bitexact  /tmp/file-aletrek-palette.mkv
> has the output file change slightly
> 
> https://trac.ffmpeg.org/attachment/ticket/5071/aletrek.mkv
> 
> also given fate does not change, it would make sense to add a testcase
> to fate that does cover this

Two notes:

1. The only difference between the `master` behavior and the new
   behavior is that the file is marked as limited range instead of as
   unspecified. However, this is the correct tagging, as the actual
   output *is* limited range.

2. While not *broken* per se, this is actually still a bug - in this
   case, since the input is basically full range, we should actually try
   and output full range by default.

The reason it doesn't output full range here is because a consequence of
the fact that format reduction happens *before* the logic in
pick_format() fixes all non-YUV links to be tagged as PC/RGB-only. So
the format reduction logic just sees that vf_scale can output any range
in this scenario (true) and picks TV range output as the default,
resulting in a conversion from the PC range input to a TV range output.

The easiest solution would be to not blindly pick the first here, but to
instead try and pick a colorspace and range matching the input (if one
exists). But this may still break in more complicated scenarios where
the dependence on the forced format spans several filters.

The more correct solution would probably be to explicitly reduce only
the format first (going through all the steps) and then negotiate
everything that depends on the format in an entirely separate step.

I'll see if I can do something about this situation, though it's
ultimately not a high priority as it's not a regression compared to the
status quo - just something that we could definitely improve.

> 
> thx
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> What does censorship reveal? It reveals fear. -- Julian Assange
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 02/11] avcodec/dovi_rpu: properly replace context header

2024-04-09 Thread Niklas Haas
On Tue, 09 Apr 2024 17:36:30 +0200 Andreas Rheinhardt 
 wrote:
> Niklas Haas:
> > From: Niklas Haas 
> > 
> > This was never set in ff_dovi_ctx_replace(), leading to possibly
> > out-of-date when copying from a sub-thread to the main thread.
> > ---
> 
> Sub-thread to the main thread? update_thread_context is not called with
> the main (user-facing) AVCodecContext.

Changed to "from one thread to another".

> 
> >  libavcodec/dovi_rpu.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
> > index d95c7e03af9..bfb7b9fe661 100644
> > --- a/libavcodec/dovi_rpu.c
> > +++ b/libavcodec/dovi_rpu.c
> > @@ -75,6 +75,7 @@ void ff_dovi_ctx_replace(DOVIContext *s, const 
> > DOVIContext *s0)
> >  {
> >  s->logctx = s0->logctx;
> >  s->cfg = s0->cfg;
> > +s->header = s0->header;
> >  s->mapping = s0->mapping;
> >  s->color = s0->color;
> >  for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 04/11] avcodec/dovi_rpu: clarify semantics of guess_profile()

2024-04-09 Thread Niklas Haas
On Tue, 09 Apr 2024 17:37:32 +0200 Andreas Rheinhardt 
 wrote:
> Niklas Haas:
> > From: Niklas Haas 
> > 
> > This is based on HEVC only, H.264/AV1 use their own (hopefully correctly
> > signalled) profiles.
> > ---
> >  libavcodec/dovi_rpu.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
> > index 267e52ceb66..4da711d763e 100644
> > --- a/libavcodec/dovi_rpu.c
> > +++ b/libavcodec/dovi_rpu.c
> > @@ -121,7 +121,8 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame 
> > *frame)
> >  return 0;
> >  }
> >  
> > -static int guess_profile(const AVDOVIRpuDataHeader *hdr)
> > +/* Note: Only works for HEVC */
> > +static int guess_hevc_profile(const AVDOVIRpuDataHeader *hdr)
> >  {
> >  switch (hdr->vdr_rpu_profile) {
> >  case 0:
> > @@ -510,7 +511,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t 
> > *rpu, size_t rpu_size,
> >  use_prev_vdr_rpu = get_bits1(gb);
> >  use_nlq = (hdr->rpu_format & 0x700) == 0 && 
> > !hdr->disable_residual_flag;
> >  
> > -profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
> > +profile = s->cfg.dv_profile ? s->cfg.dv_profile : 
> > guess_hevc_profile(hdr);
> >  if (profile == 5 && use_nlq) {
> >  av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use 
> > NLQ\n");
> >  goto fail;
> 
> Is guess_hevc_profile only called for HEVC?

Yes. All non-HEVC codecs explicitly override s->cfg.dv_profile before
calling into this function.

But probably we should document that more clearly somewhere.

> 
> - Andreas
> 
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2] avcodec/libx264: bump minimum required version to 155

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

This version is seven years old, and present in Debian oldoldstable,
Ubuntu 20.04 and Leap 15.0.

Allows cleaning up the file substantially. In particular, this is
motivated by the desire to stop relying on init_static_data.
---
 configure|  2 +-
 libavcodec/libx264.c | 52 ++--
 2 files changed, 8 insertions(+), 46 deletions(-)

diff --git a/configure b/configure
index f511fbae492..248ce2040d6 100755
--- a/configure
+++ b/configure
@@ -7007,7 +7007,7 @@ enabled libwebp   && {
 enabled libwebp_encoder  && require_pkg_config libwebp "libwebp >= 
0.2.0" webp/encode.h WebPGetEncoderVersion
 enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder 
"libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
 enabled libx264   && require_pkg_config libx264 x264 "stdint.h x264.h" 
x264_encoder_encode &&
- require_cpp_condition libx264 x264.h "X264_BUILD 
>= 122" && {
+ require_cpp_condition libx264 x264.h "X264_BUILD 
>= 155" && {
  [ "$toolchain" != "msvc" ] ||
  require_cpp_condition libx264 x264.h "X264_BUILD 
>= 158"; } &&
  check_cpp_condition libx264_hdr10 x264.h 
"X264_BUILD >= 163" &&
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index eadb20d2b39..2715f277f1f 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -270,11 +270,9 @@ static void reconfig_encoder(AVCodecContext *ctx, const 
AVFrame *frame)
 case AV_STEREO3D_FRAMESEQUENCE:
 fpa_type = 5;
 break;
-#if X264_BUILD >= 145
 case AV_STEREO3D_2D:
 fpa_type = 6;
 break;
-#endif
 default:
 fpa_type = -1;
 break;
@@ -394,14 +392,14 @@ static int setup_mb_info(AVCodecContext *ctx, 
x264_picture_t *pic,
 return 0;
 }
 
-static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic, int bit_depth,
+static int setup_roi(AVCodecContext *ctx, x264_picture_t *pic,
  const AVFrame *frame, const uint8_t *data, size_t size)
 {
 X264Context *x4 = ctx->priv_data;
 
 int mbx = (frame->width + MB_SIZE - 1) / MB_SIZE;
 int mby = (frame->height + MB_SIZE - 1) / MB_SIZE;
-int qp_range = 51 + 6 * (bit_depth - 8);
+int qp_range = 51 + 6 * (x4->params.i_bitdepth - 8);
 int nb_rois;
 const AVRegionOfInterest *roi;
 uint32_t roi_size;
@@ -476,7 +474,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame 
*frame,
 x264_sei_t *sei = >extra_sei;
 unsigned int sei_data_size = 0;
 int64_t wallclock = 0;
-int bit_depth, ret;
+int ret;
 AVFrameSideData *sd;
 AVFrameSideData *mbinfo_sd;
 
@@ -486,12 +484,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame 
*frame,
 
 x264_picture_init(pic);
 pic->img.i_csp   = x4->params.i_csp;
-#if X264_BUILD >= 153
-bit_depth = x4->params.i_bitdepth;
-#else
-bit_depth = x264_bit_depth;
-#endif
-if (bit_depth > 8)
+if (x4->params.i_bitdepth > 8)
 pic->img.i_csp |= X264_CSP_HIGH_DEPTH;
 pic->img.i_plane = av_pix_fmt_count_planes(ctx->pix_fmt);
 
@@ -564,7 +557,7 @@ static int setup_frame(AVCodecContext *ctx, const AVFrame 
*frame,
 
 sd = av_frame_get_side_data(frame, AV_FRAME_DATA_REGIONS_OF_INTEREST);
 if (sd) {
-ret = setup_roi(ctx, pic, bit_depth, frame, sd->data, sd->size);
+ret = setup_roi(ctx, pic, frame, sd->data, sd->size);
 if (ret < 0)
 goto fail;
 }
@@ -1109,9 +1102,7 @@ static av_cold int X264_init(AVCodecContext *avctx)
 x4->params.p_log_private= avctx;
 x4->params.i_log_level  = X264_LOG_DEBUG;
 x4->params.i_csp= convert_pix_fmt(avctx->pix_fmt);
-#if X264_BUILD >= 153
 x4->params.i_bitdepth   = 
av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth;
-#endif
 
 PARSE_X264_OPT("weightp", wpredp);
 
@@ -1180,11 +1171,10 @@ static av_cold int X264_init(AVCodecContext *avctx)
 else if (x4->params.i_level_idc > 0) {
 int i;
 int mbn = AV_CEIL_RSHIFT(avctx->width, 4) * 
AV_CEIL_RSHIFT(avctx->height, 4);
-int scale = X264_BUILD < 129 ? 384 : 1;
 
 for (i = 0; iparams.i_level_idc)
-x4->params.i_frame_reference = av_clip(x264_levels[i].dpb / 
mbn / scale, 1, x4->params.i_frame_reference);
+x4->params.i_frame_reference = av_clip(x264_levels[i].dpb / 
mbn, 1, x4->params.i_frame_reference);
 }
 
 if (avctx->trellis >= 0)
@@ -1228,12 +1218,7 @@ static av_c

Re: [FFmpeg-devel] [PATCH v2 13/17] fftools/ffmpeg_filter: set strict_std_compliance

2024-04-09 Thread Niklas Haas
On Mon, 08 Apr 2024 14:57:17 +0200 Niklas Haas  wrote:
> From: Niklas Haas 
> 
> For avcodec_get_supported_config(), which requires this value be set on
> the actual ost->enc_ctx being queried.
> ---
>  fftools/ffmpeg_filter.c | 16 ++--
>  1 file changed, 6 insertions(+), 10 deletions(-)
> 
> diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
> index ac04841a16c..9ff064f5f68 100644
> --- a/fftools/ffmpeg_filter.c
> +++ b/fftools/ffmpeg_filter.c
> @@ -770,6 +770,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
> *ost,
>  FilterGraph  *fg = ofilter->graph;
>  FilterGraphPriv *fgp = fgp_from_fg(fg);
>  const AVCodec *c = ost->enc_ctx->codec;
> +const AVDictionaryEntry *strict = av_dict_get(ost->encoder_opts, 
> "strict", NULL, 0);
>  int ret;
>  
>  av_assert0(!ofilter->ost);
> @@ -780,6 +781,10 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
> *ost,
>  ofp->ts_offset = of->start_time == AV_NOPTS_VALUE ? 0 : 
> of->start_time;
>  ofp->enc_timebase = ost->enc_timebase;
>  
> +/* Ensure this is up-to-date for avcodefc_get_supported_config() */
> +if (strict)
> +av_opt_set(ost->enc_ctx, strict->key, strict->value, 0);
> +
>  switch (ost->enc_ctx->codec_type) {
>  case AVMEDIA_TYPE_VIDEO:
>  ofp->width  = ost->enc_ctx->width;
> @@ -800,16 +805,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
> *ost,
>  { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
> AV_PIX_FMT_YUVJ444P,
>AV_PIX_FMT_NONE };
>  
> -const AVDictionaryEntry *strict = 
> av_dict_get(ost->encoder_opts, "strict", NULL, 0);
> -int strict_val = ost->enc_ctx->strict_std_compliance;
> -
> -if (strict) {
> -const AVOption *o = av_opt_find(ost->enc_ctx, 
> strict->key, NULL, 0, 0);
> -av_assert0(o);
> -av_opt_eval_int(ost->enc_ctx, o, strict->value, 
> _val);
> -}
> -
> -if (strict_val > FF_COMPLIANCE_UNOFFICIAL)
> +if (ost->enc_ctx->strict_std_compliance > 
> FF_COMPLIANCE_UNOFFICIAL)
>  ofp->formats = mjpeg_formats;
>  }
>  }
> -- 
> 2.44.0
> 

Note: Will be no longer needed if elenril's encoder_opts series is
merged first, so that would be preferred as this is sort of a hack.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH v2 09/17] avcodec/codec_internal: nuke init_static_data()

2024-04-09 Thread Niklas Haas
On Mon, 08 Apr 2024 14:57:13 +0200 Niklas Haas  wrote:
> From: Niklas Haas 
> 
> All hail get_supported_config()
> ---
>  libavcodec/allcodecs.c  | 7 +--
>  libavcodec/codec_internal.h | 8 
>  2 files changed, 1 insertion(+), 14 deletions(-)
> 
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index a9f1797930a..1f22e06e710 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -916,13 +916,8 @@ static AVOnce av_codec_static_init = AV_ONCE_INIT;
>  static void av_codec_init_static(void)
>  {
>  for (int i = 0; codec_list[i]; i++) {
> -const FFCodec *codec = codec_list[i];
> -if (codec->init_static_data) {
> -codec->init_static_data((FFCodec*) codec);
> -continue;
> -}
> -
>  /* Backward compatibility with deprecated public fields */
> +const FFCodec *codec = codec_list[i];
>  if (!codec->get_supported_config)
>  continue;
>  
> diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
> index bac3e30ba2c..d3033db3375 100644
> --- a/libavcodec/codec_internal.h
> +++ b/libavcodec/codec_internal.h
> @@ -174,14 +174,6 @@ typedef struct FFCodec {
>   */
>  const FFCodecDefault *defaults;
>  
> -/**
> - * Initialize codec static data, called from av_codec_iterate().
> - *
> - * This is not intended for time consuming operations as it is
> - * run for every codec regardless of that codec being used.
> - */
> -void (*init_static_data)(struct FFCodec *codec);
> -
>  int (*init)(struct AVCodecContext *);
>  
>  union {
> -- 
> 2.44.0
> 

Note: This depends on my other series for dropping init_static_data from
libx264.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 10/11] avcodec/libx265: implement dolby vision coding

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

libx265 supports these natively, we just need to attach the generated
NALs to the x265picture, as well as setting the appropriate DV profile.
---
 libavcodec/libx265.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 0645cd20457..c4ce5d3 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -36,6 +36,7 @@
 #include "libavutil/pixdesc.h"
 #include "avcodec.h"
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "packet_internal.h"
 #include "atsc_a53.h"
@@ -78,6 +79,8 @@ typedef struct libx265Context {
  * encounter a frame with ROI side data.
  */
 int roi_warned;
+
+DOVIContext dovi;
 } libx265Context;
 
 static int is_keyframe(NalUnitType naltype)
@@ -143,6 +146,8 @@ static av_cold int libx265_encode_close(AVCodecContext 
*avctx)
 if (ctx->encoder)
 ctx->api->encoder_close(ctx->encoder);
 
+ff_dovi_ctx_unref(>dovi);
+
 return 0;
 }
 
@@ -526,6 +531,14 @@ FF_ENABLE_DEPRECATION_WARNINGS
 }
 }
 
+#if X265_BUILD >= 167
+ctx->dovi.logctx = avctx;
+if ((ret = ff_dovi_configure(>dovi, avctx)) < 0)
+return ret;
+ctx->params->dolbyProfile = ctx->dovi.cfg.dv_profile * 10 +
+ctx->dovi.cfg.dv_bl_signal_compatibility_id;
+#endif
+
 ctx->encoder = ctx->api->encoder_open(ctx->params);
 if (!ctx->encoder) {
 av_log(avctx, AV_LOG_ERROR, "Cannot open libx265 encoder.\n");
@@ -629,6 +642,10 @@ static void free_picture(libx265Context *ctx, x265_picture 
*pic)
 for (int i = 0; i < sei->numPayloads; i++)
 av_free(sei->payloads[i].payload);
 
+#if X265_BUILD >= 167
+av_free(pic->rpu.payload);
+#endif
+
 if (pic->userData) {
 int idx = (int)(intptr_t)pic->userData - 1;
 rd_release(ctx, idx);
@@ -660,6 +677,7 @@ static int libx265_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 sei->numPayloads = 0;
 
 if (pic) {
+AVFrameSideData *sd;
 ReorderedData *rd;
 int rd_idx;
 
@@ -760,6 +778,24 @@ static int libx265_encode_frame(AVCodecContext *avctx, 
AVPacket *pkt,
 sei->numPayloads++;
 }
 }
+
+#if X265_BUILD >= 167
+sd = av_frame_get_side_data(pic, AV_FRAME_DATA_DOVI_METADATA);
+if (ctx->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+ret = ff_dovi_rpu_generate(>dovi, metadata, 
,
+   );
+if (ret < 0) {
+free_picture(ctx, );
+return ret;
+}
+} else if (ctx->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received 
frame "
+   "without AV_FRAME_DATA_DOVI_METADATA");
+free_picture(ctx, );
+return AVERROR_INVALIDDATA;
+}
+#endif
 }
 
 ret = ctx->api->encoder_encode(ctx->encoder, , ,
@@ -914,6 +950,10 @@ static const AVOption options[] = {
 { "udu_sei", "Use user data unregistered SEI if available",
 OFFSET(udu_sei),   AV_OPT_TYPE_BOOL,   { .i64 = 0 }, 0, 1, 
VE },
 { "a53cc",   "Use A53 Closed Captions (if available)", 
 OFFSET(a53_cc),AV_OPT_TYPE_BOOL,   { .i64 = 1 }, 0, 1, 
VE },
 { "x265-params", "set the x265 configuration using a :-separated list of 
key=value parameters", OFFSET(x265_opts), AV_OPT_TYPE_DICT,   { 0 }, 0, 0, VE },
+#if X265_BUILD >= 167
+{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
+#endif
 { NULL }
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 09/11] avcodec/libaomenc: implement dolby vision coding

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libaomenc.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 4a71bba9c9c..b43a902a384 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -43,6 +43,7 @@
 #include "avcodec.h"
 #include "bsf.h"
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "internal.h"
 #include "libaom.h"
@@ -70,6 +71,7 @@ struct FrameListData {
 typedef struct AOMEncoderContext {
 AVClass *class;
 AVBSFContext *bsf;
+DOVIContext dovi;
 struct aom_codec_ctx encoder;
 struct aom_image rawimg;
 struct aom_fixed_buf twopass_stats;
@@ -421,6 +423,7 @@ static av_cold int aom_free(AVCodecContext *avctx)
 av_freep(>stats_out);
 free_frame_list(ctx->coded_frame_list);
 av_bsf_free(>bsf);
+ff_dovi_ctx_unref(>dovi);
 return 0;
 }
 
@@ -989,6 +992,10 @@ static av_cold int aom_init(AVCodecContext *avctx,
 if (!cpb_props)
 return AVERROR(ENOMEM);
 
+ctx->dovi.logctx = avctx;
+if ((res = ff_dovi_configure(>dovi, avctx)) < 0)
+return res;
+
 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
 const AVBitStreamFilter *filter = 
av_bsf_get_by_name("extract_extradata");
 int ret;
@@ -1242,6 +1249,7 @@ static int aom_encode(AVCodecContext *avctx, AVPacket 
*pkt,
 unsigned long duration = 0;
 int res, coded_size;
 aom_enc_frame_flags_t flags = 0;
+AVFrameSideData *sd;
 
 if (frame) {
 rawimg  = >rawimg;
@@ -1279,6 +1287,24 @@ FF_ENABLE_DEPRECATION_WARNINGS
 break;
 }
 
+sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOVI_METADATA);
+if (ctx->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+uint8_t *t35;
+int size;
+if ((res = ff_dovi_rpu_generate(>dovi, metadata, , 
)) < 0)
+return res;
+res = aom_img_add_metadata(rawimg, OBU_METADATA_TYPE_ITUT_T35,
+   t35, size, AOM_MIF_ANY_FRAME);
+av_free(t35);
+if (res != AOM_CODEC_OK)
+return AVERROR(ENOMEM);
+} else if (ctx->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received 
frame "
+   "without AV_FRAME_DATA_DOVI_METADATA\n");
+return AVERROR_INVALIDDATA;
+}
+
 if (frame->pict_type == AV_PICTURE_TYPE_I)
 flags |= AOM_EFLAG_FORCE_KF;
 }
@@ -1459,6 +1485,8 @@ static const AVOption options[] = {
 { "ssim",NULL, 0, AV_OPT_TYPE_CONST, {.i64 = 
AOM_TUNE_SSIM}, 0, 0, VE, .unit = "tune"},
 FF_AV1_PROFILE_OPTS
 { "still-picture", "Encode in single frame mode (typically used for still 
AVIF images).", OFFSET(still_picture), AV_OPT_TYPE_BOOL, {.i64 = 0}, -1, 1, VE 
},
+{ "dolbyvision", "Enable Dolby Vision RPU coding", 
OFFSET(dovi.enable), AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, 
.unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
 { "enable-rect-partitions", "Enable rectangular partitions", 
OFFSET(enable_rect_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-1to4-partitions", "Enable 1:4/4:1 partitions", 
OFFSET(enable_1to4_partitions), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
 { "enable-ab-partitions",   "Enable ab shape partitions",
OFFSET(enable_ab_partitions),   AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, VE},
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 08/11] avformat/movenc: warn if dovi cfg ignored

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

Since this is guarded behind strict unofficial, we should warn if the
user feeds a dolby vision stream to this muxer, as it will otherwise
result in a broken file.
---
 libavformat/movenc.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 15b65dcf96d..0f819214be9 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2528,16 +2528,21 @@ static int mov_write_video_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContex
 const AVPacketSideData *spherical_mapping = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
 
track->st->codecpar->nb_coded_side_data,
 
AV_PKT_DATA_SPHERICAL);
-const AVPacketSideData *dovi = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
-   
track->st->codecpar->nb_coded_side_data,
-   
AV_PKT_DATA_DOVI_CONF);
-
 if (stereo_3d)
 mov_write_st3d_tag(s, pb, (AVStereo3D*)stereo_3d->data);
 if (spherical_mapping)
 mov_write_sv3d_tag(mov->fc, pb, 
(AVSphericalMapping*)spherical_mapping->data);
-if (dovi)
+}
+
+if (track->mode == MODE_MP4) {
+const AVPacketSideData *dovi = 
av_packet_side_data_get(track->st->codecpar->coded_side_data,
+   
track->st->codecpar->nb_coded_side_data,
+   
AV_PKT_DATA_DOVI_CONF);
+if (dovi && mov->fc->strict_std_compliance <= 
FF_COMPLIANCE_UNOFFICIAL) {
 mov_write_dvcc_dvvc_tag(s, pb, (AVDOVIDecoderConfigurationRecord 
*)dovi->data);
+} else if (dovi) {
+av_log(mov->fc, AV_LOG_WARNING, "Not writing 'dvcC'/'dvvC' box. 
Requires -strict unofficial.\n");
+}
 }
 
 if (track->par->sample_aspect_ratio.den && 
track->par->sample_aspect_ratio.num) {
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 07/11] avcodec/dovi_rpu: add ff_dovi_rpu_generate()

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

This function takes a decoded AVDOVIMetadata struct and turns it back
into a binary RPU. Verified using existing tools, and matches the
bitstream in official reference files.

I decided to just roll the EMDF and NAL encapsulation into this function
because the end user will need to do it otherwise anyways.
---
 libavcodec/dovi_rpu.c | 542 ++
 libavcodec/dovi_rpu.h |  20 +-
 2 files changed, 560 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 54994188a96..272a5125b65 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -29,6 +29,9 @@
 #include "dovi_rpu.h"
 #include "golomb.h"
 #include "get_bits.h"
+#include "itut35.h"
+#include "put_bits.h"
+#include "put_golomb.h"
 #include "refstruct.h"
 
 enum {
@@ -361,6 +364,42 @@ static inline int64_t get_se_coef(GetBitContext *gb, const 
AVDOVIRpuDataHeader *
 return 0; /* unreachable */
 }
 
+static inline void put_ue_coef(PutBitContext *pb, const AVDOVIRpuDataHeader 
*hdr,
+   uint64_t coef)
+{
+union { uint32_t u32; float f32; } fpart;
+
+switch (hdr->coef_data_type) {
+case RPU_COEFF_FIXED:
+set_ue_golomb(pb, coef >> hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom,
+   coef & ((1LL << hdr->coef_log2_denom) - 1));
+break;
+case RPU_COEFF_FLOAT:
+fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom, fpart.u32);
+break;
+}
+}
+
+static inline void put_se_coef(PutBitContext *pb, const AVDOVIRpuDataHeader 
*hdr,
+   uint64_t coef)
+{
+union { uint32_t u32; float f32; } fpart;
+
+switch (hdr->coef_data_type) {
+case RPU_COEFF_FIXED:
+set_se_golomb(pb, coef >> hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom,
+   coef & ((1LL << hdr->coef_log2_denom) - 1));
+break;
+case RPU_COEFF_FLOAT:
+fpart.f32 = coef / (float) (1LL << hdr->coef_log2_denom);
+put_bits64(pb, hdr->coef_log2_denom, fpart.u32);
+break;
+}
+}
+
 static inline unsigned get_variable_bits(GetBitContext *gb, int n)
 {
 unsigned int value = get_bits(gb, n);
@@ -891,3 +930,506 @@ fail:
 ff_dovi_ctx_unref(s); /* don't leak potentially invalid state */
 return AVERROR_INVALIDDATA;
 }
+
+static int av_q2den(AVRational q, int den)
+{
+if (q.den == den)
+return q.num;
+q = av_mul_q(q, av_make_q(den, 1));
+return (q.num + (q.den >> 1)) / q.den;
+}
+
+static void generate_ext_v1(PutBitContext *pb, const AVDOVIDmData *dm)
+{
+int ext_block_length, start_pos, pad_bits;
+
+switch (dm->level) {
+case 1:   ext_block_length = 5;  break;
+case 2:   ext_block_length = 11; break;
+case 4:   ext_block_length = 3;  break;
+case 5:   ext_block_length = 7;  break;
+case 6:   ext_block_length = 8;  break;
+case 255: ext_block_length = 6;  break;
+default: return;
+}
+
+set_ue_golomb(pb, ext_block_length);
+put_bits(pb, 8, dm->level);
+start_pos = put_bits_count(pb);
+
+switch (dm->level) {
+case 1:
+put_bits(pb, 12, dm->l1.min_pq);
+put_bits(pb, 12, dm->l1.max_pq);
+put_bits(pb, 12, dm->l1.avg_pq);
+break;
+case 2:
+put_bits(pb, 12, dm->l2.target_max_pq);
+put_bits(pb, 12, dm->l2.trim_slope);
+put_bits(pb, 12, dm->l2.trim_offset);
+put_bits(pb, 12, dm->l2.trim_power);
+put_bits(pb, 12, dm->l2.trim_chroma_weight);
+put_bits(pb, 12, dm->l2.trim_saturation_gain);
+put_bits(pb, 13, dm->l2.ms_weight + 8192);
+break;
+case 4:
+put_bits(pb, 12, dm->l4.anchor_pq);
+put_bits(pb, 12, dm->l4.anchor_power);
+break;
+case 5:
+put_bits(pb, 13, dm->l5.left_offset);
+put_bits(pb, 13, dm->l5.right_offset);
+put_bits(pb, 13, dm->l5.top_offset);
+put_bits(pb, 13, dm->l5.bottom_offset);
+break;
+case 6:
+put_bits(pb, 16, dm->l6.max_luminance);
+put_bits(pb, 16, dm->l6.min_luminance);
+put_bits(pb, 16, dm->l6.max_cll);
+put_bits(pb, 16, dm->l6.max_fall);
+break;
+case 255:
+put_bits(pb, 8, dm->l255.dm_run_mode);
+put_bits(pb, 8, dm->l255.dm_run_version);
+for (int i = 0; i < 4; i++)
+put_bits(pb, 8, dm->l255.dm_debug[i]);
+break;
+}
+
+pad_bits = ext_block_length * 8 - (put_bits_count(pb) - start_pos);
+av_assert1(pad_bits >= 0);
+put_bits(pb, pad_bits, 0);
+}
+
+static void put_cie_xy(PutBitContext *pb, AVCIExy xy)
+{
+const int den

[FFmpeg-devel] [PATCH v2 05/11] avcodec/dovi_rpu: add ff_dovi_configure()

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

We need to set up the configuration struct appropriately based on the
codec type, colorspace metadata, and presence/absence of an EL (though,
we currently don't support an EL).

When present, we use the signalled RPU data header to help infer (and
validate) the right values.

Behavior can be controlled by a new DOVIContext.enable flag.
---
 libavcodec/dovi_rpu.c | 176 ++
 libavcodec/dovi_rpu.h |  23 +-
 2 files changed, 198 insertions(+), 1 deletion(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 4da711d763e..d3a284c150d 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -144,6 +144,182 @@ static int guess_hevc_profile(const AVDOVIRpuDataHeader 
*hdr)
 return 0; /* unknown */
 }
 
+static struct {
+uint64_t pps; // maximum pixels per second
+int width; // maximum width
+int main; // maximum bitrate in main tier
+int high; // maximum bitrate in high tier
+} dv_levels[] = {
+ [1] = {1280*720*24,1280,  20,  50},
+ [2] = {1280*720*30,1280,  20,  50},
+ [3] = {1920*1080*24,   1920,  20,  70},
+ [4] = {1920*1080*30,   2560,  20,  70},
+ [5] = {1920*1080*60,   3840,  20,  70},
+ [6] = {3840*2160*24,   3840,  25, 130},
+ [7] = {3840*2160*30,   3840,  25, 130},
+ [8] = {3840*2160*48,   3840,  40, 130},
+ [9] = {3840*2160*60,   3840,  40, 130},
+[10] = {3840*2160*120,  3840,  60, 240},
+[11] = {3840*2160*120,  7680,  60, 240},
+[12] = {7680*4320*60,   7680, 120, 450},
+[13] = {7680*4320*120u, 7680, 240, 800},
+};
+
+int ff_dovi_configure(DOVIContext *s, AVCodecContext *avctx)
+{
+AVDOVIDecoderConfigurationRecord *cfg;
+const AVDOVIRpuDataHeader *hdr = NULL;
+const AVFrameSideData *sd;
+int dv_profile, dv_level, bl_compat_id;
+size_t cfg_size;
+uint64_t pps;
+
+if (!s->enable)
+goto skip;
+
+sd = av_frame_side_data_get(avctx->decoded_side_data,
+avctx->nb_decoded_side_data, 
AV_FRAME_DATA_DOVI_METADATA);
+
+if (sd)
+hdr = av_dovi_get_header((const AVDOVIMetadata *) sd->data);
+
+if (s->enable == FF_DOVI_AUTOMATIC && !hdr)
+goto skip;
+
+switch (avctx->codec_id) {
+case AV_CODEC_ID_AV1:  dv_profile = 10; break;
+case AV_CODEC_ID_H264: dv_profile = 9;  break;
+case AV_CODEC_ID_HEVC: dv_profile = hdr ? guess_hevc_profile(hdr) : 8; 
break;
+default:
+/* No other encoder should be calling this! */
+av_assert0(0);
+return AVERROR_BUG;
+}
+
+if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
+if (dv_profile == 9) {
+if (avctx->pix_fmt != AV_PIX_FMT_YUV420P)
+dv_profile = 0;
+} else {
+if (avctx->pix_fmt != AV_PIX_FMT_YUV420P10)
+dv_profile = 0;
+}
+}
+
+switch (dv_profile) {
+case 0: /* None */
+bl_compat_id = -1;
+break;
+case 4: /* HEVC with enhancement layer */
+case 7:
+if (s->enable > 0) {
+av_log(s->logctx, AV_LOG_ERROR, "Coding of Dolby Vision 
enhancement "
+   "layers is currently unsupported.");
+return AVERROR_PATCHWELCOME;
+} else {
+goto skip;
+}
+case 5: /* HEVC with proprietary IPTPQc2 */
+bl_compat_id = 0;
+break;
+case 10:
+/* FIXME: check for proper H.273 tags once those are added */
+if (hdr && hdr->bl_video_full_range_flag) {
+/* AV1 with proprietary IPTPQc2 */
+bl_compat_id = 0;
+break;
+}
+/* fall through */
+case 8: /* HEVC (or AV1) with BL compatibility */
+if (avctx->colorspace == AVCOL_SPC_BT2020_NCL &&
+avctx->color_primaries == AVCOL_PRI_BT2020 &&
+avctx->color_trc == AVCOL_TRC_SMPTE2084) {
+bl_compat_id = 1;
+} else if (avctx->colorspace == AVCOL_SPC_BT2020_NCL &&
+   avctx->color_primaries == AVCOL_PRI_BT2020 &&
+   avctx->color_trc == AVCOL_TRC_ARIB_STD_B67) {
+bl_compat_id = 4;
+} else if (avctx->colorspace == AVCOL_SPC_BT709 &&
+   avctx->color_primaries == AVCOL_PRI_BT709 &&
+   avctx->color_trc == AVCOL_TRC_BT709) {
+bl_compat_id = 2;
+} else {
+/* Not a valid colorspace combination */
+bl_compat_id = -1;
+}
+}
+
+if (!dv_profile || bl_compat_id < 0) {
+if (s->enable > 0) {
+av_log(s->logctx, AV_LOG_ERROR, "Dolby Vision enabled, but could "
+   "not determine profile and compaatibility mode. 
Double-check "
+   "colorspace and format settin

[FFmpeg-devel] [PATCH v2 06/11] avcodec/dovi_rpu: make `enable` also affect decoding

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

This could be used by codecs to selectively disable parsing Dolby Vision
RPUs, and is cheap to support.
---
 libavcodec/av1dec.c   | 1 +
 libavcodec/dovi_rpu.c | 6 ++
 libavcodec/dovi_rpu.h | 2 ++
 libavcodec/hevcdec.c  | 1 +
 libavcodec/libdav1d.c | 1 +
 5 files changed, 11 insertions(+)

diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 4c1405df779..20865b4f129 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -1551,6 +1551,7 @@ static void av1_decode_flush(AVCodecContext *avctx)
 static const AVOption av1_options[] = {
 { "operating_point",  "Select an operating point of the scalable 
bitstream",
   OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = 0 
}, 0, AV1_MAX_OPERATING_POINTS - 1, VD },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
 { NULL }
 };
 
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index d3a284c150d..54994188a96 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -90,6 +90,9 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 AVDOVIMetadata *dovi;
 size_t dovi_size, ext_sz;
 
+if (!s->enable)
+return 0;
+
 if (!s->mapping || !s->color)
 return 0; /* incomplete dovi metadata */
 
@@ -558,6 +561,9 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 uint8_t use_nlq;
 uint8_t profile;
 
+if (!s->enable)
+return 0;
+
 if (rpu_size < 5)
 goto fail;
 
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 56395707369..8dc69a2733d 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -37,6 +37,8 @@ typedef struct DOVIContext {
  *
  * For encoding, FF_DOVI_AUTOMATIC enables Dolby Vision only if
  * avctx->decoded_side_data contains an AVDOVIMetadata.
+ *
+ * For decoding, FF_DOVI_AUTOMATIC has the same meaning as 1.
  */
 #define FF_DOVI_AUTOMATIC -1
 int enable;
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 4bc9e2afc1d..651773260e3 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3689,6 +3689,7 @@ static const AVOption options[] = {
 AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
 { "strict-displaywin", "stricly apply default display window size", 
OFFSET(apply_defdispwin),
 AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, PAR },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi_ctx.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, PAR },
 { NULL },
 };
 
diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c
index 09fe767fb86..f9e1a181fc3 100644
--- a/libavcodec/libdav1d.c
+++ b/libavcodec/libdav1d.c
@@ -674,6 +674,7 @@ static const AVOption libdav1d_options[] = {
 { "filmgrain", "Apply Film Grain", OFFSET(apply_grain), AV_OPT_TYPE_BOOL, 
{ .i64 = -1 }, -1, 1, VD | AV_OPT_FLAG_DEPRECATED },
 { "oppoint",  "Select an operating point of the scalable bitstream", 
OFFSET(operating_point), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 31, VD },
 { "alllayers", "Output all spatial layers", OFFSET(all_layers), 
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
+{ "dolbyvision", "Decode Dolby Vision RPUs", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = 1 }, 0, 1, VD },
 { NULL }
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 11/11] avcodec/libsvtav1: implement dolby vision coding

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libsvtav1.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 105c3369c0f..cd62103dba4 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "libavutil/common.h"
 #include "libavutil/frame.h"
@@ -35,6 +36,7 @@
 #include "libavutil/avassert.h"
 
 #include "codec_internal.h"
+#include "dovi_rpu.h"
 #include "encode.h"
 #include "packet_internal.h"
 #include "avcodec.h"
@@ -62,6 +64,8 @@ typedef struct SvtContext {
 
 EOS_STATUS eos_flag;
 
+DOVIContext dovi;
+
 // User options.
 AVDictionary *svtav1_opts;
 int enc_mode;
@@ -418,6 +422,7 @@ static int read_in_data(EbSvtAv1EncConfiguration *param, 
const AVFrame *frame,
 in_data->cr_stride = AV_CEIL_RSHIFT(frame->linesize[2], bytes_shift);
 
 header_ptr->n_filled_len = frame_size;
+svt_metadata_array_free(_ptr->metadata);
 
 return 0;
 }
@@ -451,6 +456,11 @@ static av_cold int eb_enc_init(AVCodecContext *avctx)
 return svt_print_error(avctx, svt_ret, "Error initializing encoder");
 }
 
+svt_enc->dovi.logctx = avctx;
+ret = ff_dovi_configure(_enc->dovi, avctx);
+if (ret < 0)
+return ret;
+
 if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
 EbBufferHeaderType *headerPtr = NULL;
 
@@ -486,6 +496,7 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 {
 SvtContext   *svt_enc = avctx->priv_data;
 EbBufferHeaderType  *headerPtr = svt_enc->in_buf;
+AVFrameSideData *sd;
 int ret;
 
 if (!frame) {
@@ -524,6 +535,24 @@ static int eb_send_frame(AVCodecContext *avctx, const 
AVFrame *frame)
 if (avctx->gop_size == 1)
 headerPtr->pic_type = EB_AV1_KEY_PICTURE;
 
+sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DOVI_METADATA);
+if (svt_enc->dovi.cfg.dv_profile && sd) {
+const AVDOVIMetadata *metadata = (const AVDOVIMetadata *)sd->data;
+uint8_t *t35;
+int size;
+if ((ret = ff_dovi_rpu_generate(_enc->dovi, metadata, , 
)) < 0)
+return ret;
+ret = svt_add_metadata(headerPtr, EB_AV1_METADATA_TYPE_ITUT_T35, t35, 
size);
+av_free(t35);
+if (ret < 0)
+return AVERROR(ENOMEM);
+} else if (svt_enc->dovi.cfg.dv_profile) {
+av_log(avctx, AV_LOG_ERROR, "Dolby Vision enabled, but received frame "
+   "without AV_FRAME_DATA_DOVI_METADATA\n");
+return AVERROR_INVALIDDATA;
+}
+
+
 svt_av1_enc_send_picture(svt_enc->svt_handle, headerPtr);
 
 return 0;
@@ -644,11 +673,13 @@ static av_cold int eb_enc_close(AVCodecContext *avctx)
 }
 if (svt_enc->in_buf) {
 av_free(svt_enc->in_buf->p_buffer);
+svt_metadata_array_free(_enc->in_buf->metadata);
 av_freep(_enc->in_buf);
 }
 
 av_buffer_pool_uninit(_enc->pool);
 av_frame_free(_enc->frame);
+ff_dovi_ctx_unref(_enc->dovi);
 
 return 0;
 }
@@ -695,6 +726,9 @@ static const AVOption options[] = {
   AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 63, VE },
 { "svtav1-params", "Set the SVT-AV1 configuration using a :-separated list 
of key=value parameters", OFFSET(svtav1_opts), AV_OPT_TYPE_DICT, { 0 }, 0, 0, 
VE },
 
+{ "dolbyvision", "Enable Dolby Vision RPU coding", OFFSET(dovi.enable), 
AV_OPT_TYPE_BOOL, {.i64 = FF_DOVI_AUTOMATIC }, -1, 1, VE, .unit = "dovi" },
+{   "auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_DOVI_AUTOMATIC}, .flags 
= VE, .unit = "dovi" },
+
 {NULL},
 };
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 04/11] avcodec/dovi_rpu: clarify semantics of guess_profile()

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

This is based on HEVC only, H.264/AV1 use their own (hopefully correctly
signalled) profiles.
---
 libavcodec/dovi_rpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 267e52ceb66..4da711d763e 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -121,7 +121,8 @@ int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 return 0;
 }
 
-static int guess_profile(const AVDOVIRpuDataHeader *hdr)
+/* Note: Only works for HEVC */
+static int guess_hevc_profile(const AVDOVIRpuDataHeader *hdr)
 {
 switch (hdr->vdr_rpu_profile) {
 case 0:
@@ -510,7 +511,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 use_prev_vdr_rpu = get_bits1(gb);
 use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
 
-profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
+profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_hevc_profile(hdr);
 if (profile == 5 && use_nlq) {
 av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
 goto fail;
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 03/11] avcodec/dovi_rpu: clarify error on missing RPU VDR

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

The code was written under the misguided assumption that these fields
would only be present when the value changes, however this does not
match the actual patent specification, which says that streams are
required to either always signal this metadata, or never signal it.

That said, the specification does not really clarify what the defaults
of these fields should be in the event that this metadata is missing, so
without any sample file or other reference I don't wish to hazard
a guess at how to interpret these fields.

Fix the current behavior by making sure we always throw this error, even
for files that have the vdr sequence info in one frame but are missing
it in the next frame.
---
 libavcodec/dovi_rpu.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index bfb7b9fe661..267e52ceb66 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -499,11 +499,11 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 hdr->el_spatial_resampling_filter_flag = get_bits1(gb);
 hdr->disable_residual_flag = get_bits1(gb);
 }
-}
-
-if (!hdr->bl_bit_depth) {
-av_log(s->logctx, AV_LOG_ERROR, "Missing RPU VDR sequence info?\n");
-goto fail;
+} else {
+/* lack of documentation/samples */
+avpriv_request_sample(s->logctx, "Missing RPU VDR sequence info\n");
+ff_dovi_ctx_unref(s);
+return AVERROR_PATCHWELCOME;
 }
 
 vdr_dm_metadata_present = get_bits1(gb);
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 02/11] avcodec/dovi_rpu: properly replace context header

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

This was never set in ff_dovi_ctx_replace(), leading to possibly
out-of-date when copying from a sub-thread to the main thread.
---
 libavcodec/dovi_rpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index d95c7e03af9..bfb7b9fe661 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -75,6 +75,7 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0)
 {
 s->logctx = s0->logctx;
 s->cfg = s0->cfg;
+s->header = s0->header;
 s->mapping = s0->mapping;
 s->color = s0->color;
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 01/11] avcodec/dovi_rpu: store entire config record

2024-04-09 Thread Niklas Haas
From: Niklas Haas 

And make it public.

For encoding, users may also be interested in the configured level and
compatibility ID. So generalize the dv_profile field and just expose the
whole configuration record.

This makes the already rather reductive ff_dovi_update_cfg() function
almost wholly redundant, since users can just directly assign
DOVIContext.cfg.
---
 libavcodec/av1dec.c   |  6 +++---
 libavcodec/dovi_rpu.c | 16 
 libavcodec/dovi_rpu.h | 21 -
 libavcodec/hevcdec.c  | 13 ++---
 libavcodec/libdav1d.c |  6 +++---
 5 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c
index 824725c031f..4c1405df779 100644
--- a/libavcodec/av1dec.c
+++ b/libavcodec/av1dec.c
@@ -888,10 +888,10 @@ static av_cold int av1_decode_init(AVCodecContext *avctx)
 }
 
 s->dovi.logctx = avctx;
-s->dovi.dv_profile = 10; // default for AV1
+s->dovi.cfg.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(>dovi, (AVDOVIDecoderConfigurationRecord *) 
sd->data);
+if (sd && sd->size >= sizeof(s->dovi.cfg))
+s->dovi.cfg = *(AVDOVIDecoderConfigurationRecord *) sd->data;
 
 return ret;
 }
diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c
index 9f7a6b00664..d95c7e03af9 100644
--- a/libavcodec/dovi_rpu.c
+++ b/libavcodec/dovi_rpu.c
@@ -64,7 +64,7 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 
 *s = (DOVIContext) {
 .logctx = s->logctx,
-.dv_profile = s->dv_profile,
+.cfg = s->cfg,
 /* preserve temporary buffer */
 .rpu_buf = s->rpu_buf,
 .rpu_buf_sz = s->rpu_buf_sz,
@@ -74,22 +74,14 @@ void ff_dovi_ctx_flush(DOVIContext *s)
 void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext *s0)
 {
 s->logctx = s0->logctx;
+s->cfg = s0->cfg;
 s->mapping = s0->mapping;
 s->color = s0->color;
-s->dv_profile = s0->dv_profile;
 for (int i = 0; i <= DOVI_MAX_DM_ID; i++)
 ff_refstruct_replace(>vdr[i], s0->vdr[i]);
 ff_refstruct_replace(>ext_blocks, s0->ext_blocks);
 }
 
-void ff_dovi_update_cfg(DOVIContext *s, const AVDOVIDecoderConfigurationRecord 
*cfg)
-{
-if (!cfg)
-return;
-
-s->dv_profile = cfg->dv_profile;
-}
-
 int ff_dovi_attach_side_data(DOVIContext *s, AVFrame *frame)
 {
 AVFrameSideData *sd;
@@ -392,7 +384,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 goto fail;
 
 /* Container */
-if (s->dv_profile == 10 /* dav1.10 */) {
+if (s->cfg.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.
  *
@@ -517,7 +509,7 @@ int ff_dovi_rpu_parse(DOVIContext *s, const uint8_t *rpu, 
size_t rpu_size,
 use_prev_vdr_rpu = get_bits1(gb);
 use_nlq = (hdr->rpu_format & 0x700) == 0 && !hdr->disable_residual_flag;
 
-profile = s->dv_profile ? s->dv_profile : guess_profile(hdr);
+profile = s->cfg.dv_profile ? s->cfg.dv_profile : guess_profile(hdr);
 if (profile == 5 && use_nlq) {
 av_log(s->logctx, AV_LOG_ERROR, "Profile 5 RPUs should not use NLQ\n");
 goto fail;
diff --git a/libavcodec/dovi_rpu.h b/libavcodec/dovi_rpu.h
index 9f26f332ceb..9a68e45bf1b 100644
--- a/libavcodec/dovi_rpu.h
+++ b/libavcodec/dovi_rpu.h
@@ -31,6 +31,16 @@
 typedef struct DOVIContext {
 void *logctx;
 
+/**
+ * Currently active dolby vision configuration, or {0} for none.
+ * Set by the user when decoding.
+ *
+ * Note: sizeof(cfg) is not part of the libavutil ABI, so users should
+ * never pass  to any other library calls. This is included merely as
+ * a way to look up the values of fields known at compile time.
+ */
+AVDOVIDecoderConfigurationRecord cfg;
+
 /**
  * Currently active RPU data header, updates on every dovi_rpu_parse().
  */
@@ -56,7 +66,6 @@ typedef struct DOVIContext {
 struct DOVIVdr *vdr[DOVI_MAX_DM_ID+1]; ///< RefStruct references
 uint8_t *rpu_buf; ///< temporary buffer
 unsigned rpu_buf_sz;
-uint8_t dv_profile;
 
 } DOVIContext;
 
@@ -68,17 +77,11 @@ void ff_dovi_ctx_replace(DOVIContext *s, const DOVIContext 
*s0);
 void ff_dovi_ctx_unref(DOVIContext *s);
 
 /**
- * Partially reset the internal state. Resets per-frame state while preserving
- * fields parsed from the configuration record.
+ * Partially reset the internal state. Resets per-frame state, but preserves
+ * the stream-wide configuration record.
  */
 void ff_dovi_ctx_flush(DOVIContext *s);
 
-/**
- * Read the contents of an AVDOVIDecoderConfigurationRecord (usually provided
- * b

[FFmpeg-devel] [PATCH v2 00/11] avcodec: add Dolby Vision encoding

2024-04-09 Thread Niklas Haas
Changes since v1:

- Moved dolbyvision option from AVCodecContext to DOVIContext, and
  add an explicit option only to codecs that use it
- Changed its type to AV_OPT_TYPE_BOOL
- Made it control decoding as well as encoding, so you can use
  `-dolbyvision off` as an input option to suppress it
- Added support for libsvtav1 encoding as well

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] avcodec/libx264: bump minimum required version to 160

2024-04-09 Thread Niklas Haas
On Sat, 06 Apr 2024 22:28:26 +0200 Michael Niedermayer  
wrote:
> On Fri, Apr 05, 2024 at 07:44:52PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > This version is four years old, and present in Debian oldstable, Ubuntu
> > 22.04 and Leap 15.1.
> 
> Ubuntu 20.04 has general support till 2025-05-29
> Ubuntu 18.04 has security support (ESM) till 2028-04

I'll relax it from 160 back down to version 155 then. That covers Ubuntu
20.04 and Debian oldoldstable.

> 
> thx
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Nations do behave wisely once they have exhausted all other alternatives. 
> -- Abba Eban
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH 01/11] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
On Mon, 08 Apr 2024 22:18:33 +0200 Michael Niedermayer  
wrote:
> On Fri, Apr 05, 2024 at 08:57:11PM +0200, Niklas Haas wrote:
> > From: Niklas Haas 
> > 
> > This replaces the myriad of existing lists in AVCodec by a unified API
> > call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
> > substantially, while also making this more trivially extensible.
> > 
> > In addition to the already covered lists, add two new entries for color
> > space and color range, mirroring the newly added negotiable fields in
> > libavfilter.
> > 
> > I decided to drop the explicit length field from the API proposed by
> > Andreas Rheinhardt, because having it in place ended up complicating
> > both the codec side and the client side implementations, while also
> > being strictly less flexible (it's trivial to recover a length given
> > a terminator, but requires allocation to add a terminator given
> > a length). Using a terminator also presents less of a porting challenge
> > for existing users of the current API.
> > 
> > Once the deprecation period passes for the existing public fields, the
> > rough plan is to move the commonly used fields (such as
> > pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
> > configuration types, and then implement the rarely used fields with
> > custom callbacks.
> > ---
> >  doc/APIchanges  |  5 
> >  libavcodec/avcodec.c| 51 +
> >  libavcodec/avcodec.h| 27 
> >  libavcodec/codec.h  | 19 +++---
> >  libavcodec/codec_internal.h | 21 +++
> >  libavcodec/version.h|  4 +--
> >  6 files changed, 121 insertions(+), 6 deletions(-)
> 
> This patchset seems to overlap a bit with AVOptionRanges
> 
> I think ideally the user should at some point be able to query using some
> API on a AVCodecContext/AVCodecParameters/AVFormatContex/AVStream
> what for that specific instance are supported settings for each field
> 
> The API here seems to use a enum, which can make sense but it differs from
> how AVOption works which doesnt use enums to identify fields

I didn't know AVOptionRanges exists; indeed it can be seen as somewhat
overlapping here. That said, there is a vital distinction here: AVOptionRanges
represents *static* limits on what options can be set (e.g. via
`av_opt_set_int`), whereas this API represents *dynamic* limits on what can be
coded.

In particular, the list of supported colorspaces etc. can *depend* on the value
of other options. Currently, only strict_std_compliance, but I can easily see
this list growing in the future (e.g. for different profiles, dolbyvision,
...).

That aside, I personally find an API based on strings and doubles rather
cumbersome to use, especially when downstream clients expect an enum list.

> 
> 
> [...]
> -- 
> Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> Never trust a computer, one day, it may think you are the virus. -- Compn
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 11/17] fftools: drop unused/hacky macros

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

Having macros initialize local variables seems strange to me, and there
are no more current users of these macros. (The one that was commented
out was incorrect anyway, since the macro has changed in the meantime)
---
 fftools/cmdutils.h  | 13 -
 fftools/ffmpeg_filter.c |  2 +-
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index d0c773663ba..940541b9eaf 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -465,19 +465,6 @@ void *allocate_array_elem(void *array, size_t elem_size, 
int *nb_elems);
 #define GROW_ARRAY(array, nb_elems)\
 grow_array((void**), sizeof(*array), _elems, nb_elems + 1)
 
-#define GET_PIX_FMT_NAME(pix_fmt)\
-const char *name = av_get_pix_fmt_name(pix_fmt);
-
-#define GET_CODEC_NAME(id)\
-const char *name = avcodec_descriptor_get(id)->name;
-
-#define GET_SAMPLE_FMT_NAME(sample_fmt)\
-const char *name = av_get_sample_fmt_name(sample_fmt)
-
-#define GET_SAMPLE_RATE_NAME(rate)\
-char name[16];\
-snprintf(name, sizeof(name), "%d", rate);
-
 double get_rotation(const int32_t *displaymatrix);
 
 /* read file contents into a string */
diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 2308abf82af..ac04841a16c 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -401,7 +401,7 @@ static void choose_ ## name (OutputFilterPriv *ofp, 
AVBPrint *bprint)  \
 }
 
 //DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, 
AV_PIX_FMT_NONE,
-//  GET_PIX_FMT_NAME)
+//  av_get_pix_fmt_name)
 
 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
   AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 10/17] fftools/opt_common: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

While rewriting this macro, I decided to make it a bit more flexible so
it can work for all of the fields (including future fields) in a more
generic way, and to also print the channel layout using an AVBPrint to
avoid hard-coding the assumption that the length is less than 128
characters.
---
 fftools/opt_common.c | 92 +++-
 1 file changed, 49 insertions(+), 43 deletions(-)

diff --git a/fftools/opt_common.c b/fftools/opt_common.c
index 947a226d8d1..c4d71fbe3c7 100644
--- a/fftools/opt_common.c
+++ b/fftools/opt_common.c
@@ -262,22 +262,35 @@ int show_buildconf(void *optctx, const char *opt, const 
char *arg)
 return 0;
 }
 
-#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
-if (codec->field) {  \
-const type *p = codec->field;\
- \
-printf("Supported " list_name ":");  \
-while (*p != term) { \
-get_name(*p);\
-printf(" %s", name); \
-p++; \
-}\
-printf("\n");\
-}\
+#define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, cond, fmt, ...) 
 \
+do {   
 \
+const type *elem = NULL;   
 \
+avcodec_get_supported_config(NULL, codec, config, 0,   
 \
+ (const void **) );   
 \
+if (elem) {
 \
+printf("Supported " name ":"); 
 \
+while (cond) { 
 \
+printf(" " fmt, __VA_ARGS__);  
 \
+elem++;
 \
+}  
 \
+printf("\n");  
 \
+}  
 \
+} while (0)
+
+static const char *get_channel_layout_desc(const AVChannelLayout *layout, 
AVBPrint *bp)
+{
+int ret;
+av_bprint_clear(bp);
+ret = av_channel_layout_describe_bprint(layout, bp);
+if (!av_bprint_is_complete(bp) || ret < 0)
+return "unknown/invalid";
+return bp->str;
+}
 
 static void print_codec(const AVCodec *c)
 {
 int encoder = av_codec_is_encoder(c);
+AVBPrint desc;
 
 printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
c->long_name ? c->long_name : "");
@@ -343,35 +356,22 @@ static void print_codec(const AVCodec *c)
 printf("\n");
 }
 
-if (c->supported_framerates) {
-const AVRational *fps = c->supported_framerates;
-
-printf("Supported framerates:");
-while (fps->num) {
-printf(" %d/%d", fps->num, fps->den);
-fps++;
-}
-printf("\n");
-}
-PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
-  AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
-PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
-  GET_SAMPLE_RATE_NAME);
-PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample 
formats",
-  AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
-
-if (c->ch_layouts) {
-const AVChannelLayout *p = c->ch_layouts;
-
-printf("Supported channel layouts:");
-while (p->nb_channels) {
-char name[128];
-av_channel_layout_describe(p, name, sizeof(name));
-printf(" %s", name);
-p++;
-}
-printf("\n");
-}
+PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_FRAME_RATE, AVRational, 
"framerates",
+  fps, fps->num, "%d/%d", fps->num, fps->den);
+PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_PIX_FORMAT, enum AVPixelFormat

[FFmpeg-devel] [PATCH v2 09/17] avcodec/codec_internal: nuke init_static_data()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

All hail get_supported_config()
---
 libavcodec/allcodecs.c  | 7 +--
 libavcodec/codec_internal.h | 8 
 2 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index a9f1797930a..1f22e06e710 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -916,13 +916,8 @@ static AVOnce av_codec_static_init = AV_ONCE_INIT;
 static void av_codec_init_static(void)
 {
 for (int i = 0; codec_list[i]; i++) {
-const FFCodec *codec = codec_list[i];
-if (codec->init_static_data) {
-codec->init_static_data((FFCodec*) codec);
-continue;
-}
-
 /* Backward compatibility with deprecated public fields */
+const FFCodec *codec = codec_list[i];
 if (!codec->get_supported_config)
 continue;
 
diff --git a/libavcodec/codec_internal.h b/libavcodec/codec_internal.h
index bac3e30ba2c..d3033db3375 100644
--- a/libavcodec/codec_internal.h
+++ b/libavcodec/codec_internal.h
@@ -174,14 +174,6 @@ typedef struct FFCodec {
  */
 const FFCodecDefault *defaults;
 
-/**
- * Initialize codec static data, called from av_codec_iterate().
- *
- * This is not intended for time consuming operations as it is
- * run for every codec regardless of that codec being used.
- */
-void (*init_static_data)(struct FFCodec *codec);
-
 int (*init)(struct AVCodecContext *);
 
 union {
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 08/17] avcodec/mjpegenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This codec's capabilities should be set dynamically based on the value
of strict_std_compliance, when available. This will allow us to finally
get rid of the strictness hack in ffmpeg_filter.c.
---
 libavcodec/mjpegenc.c | 21 +++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c
index 137b68a98db..0473ad132ba 100644
--- a/libavcodec/mjpegenc.c
+++ b/libavcodec/mjpegenc.c
@@ -640,7 +640,24 @@ static const AVClass mjpeg_class = {
 .version= LIBAVUTIL_VERSION_INT,
 };
 
-const FFCodec ff_mjpeg_encoder = {
+static int mjpeg_get_supported_config(const AVCodecContext *avctx,
+  const AVCodec *codec,
+  enum AVCodecConfig config,
+  unsigned flags, const void **out)
+{
+if (config == AV_CODEC_CONFIG_COLOR_RANGE) {
+static const enum AVColorRange mjpeg_ranges[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED,
+};
+int strict = avctx ? avctx->strict_std_compliance : 0;
+*out = _ranges[strict > FF_COMPLIANCE_UNOFFICIAL ? 1 : 0];
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
+}
+
+FFCodec ff_mjpeg_encoder = {
 .p.name = "mjpeg",
 CODEC_LONG_NAME("MJPEG (Motion JPEG)"),
 .p.type = AVMEDIA_TYPE_VIDEO,
@@ -657,9 +674,9 @@ const FFCodec ff_mjpeg_encoder = {
 AV_PIX_FMT_YUV420P,  AV_PIX_FMT_YUV422P,  AV_PIX_FMT_YUV444P,
 AV_PIX_FMT_NONE
 },
-.color_ranges   = AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG,
 .p.priv_class   = _class,
 .p.profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles),
+.get_supported_config = mjpeg_get_supported_config,
 };
 #endif
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 07/17] avcodec/libaomenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libaomenc.c | 28 ++--
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 5023d2fda42..0488e5c3c9a 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -1398,16 +1398,24 @@ static const enum AVPixelFormat 
av1_pix_fmts_highbd_with_gray[] = {
 AV_PIX_FMT_NONE
 };
 
-static av_cold void av1_init_static(FFCodec *codec)
+static int av1_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-int supports_monochrome = aom_codec_version() >= 20001;
-aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
-if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
-codec->p.pix_fmts = supports_monochrome ? 
av1_pix_fmts_highbd_with_gray :
-  av1_pix_fmts_highbd;
-else
-codec->p.pix_fmts = supports_monochrome ? av1_pix_fmts_with_gray :
-  av1_pix_fmts;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+int supports_monochrome = aom_codec_version() >= 20001;
+aom_codec_caps_t codec_caps = aom_codec_get_caps(aom_codec_av1_cx());
+if (codec_caps & AOM_CODEC_CAP_HIGHBITDEPTH)
+*out = supports_monochrome ? av1_pix_fmts_highbd_with_gray :
+ av1_pix_fmts_highbd;
+else
+*out = supports_monochrome ? av1_pix_fmts_with_gray :
+ av1_pix_fmts;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 static av_cold int av1_init(AVCodecContext *avctx)
@@ -1529,5 +1537,5 @@ FFCodec ff_libaom_av1_encoder = {
   FF_CODEC_CAP_INIT_CLEANUP |
   FF_CODEC_CAP_AUTO_THREADS,
 .defaults   = defaults,
-.init_static_data = av1_init_static,
+.get_supported_config = av1_get_supported_config,
 };
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 06/17] avcodec/libvpxenc: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libvpxenc.c | 22 +++---
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c
index cdb83312614..64dc69f8547 100644
--- a/libavcodec/libvpxenc.c
+++ b/libavcodec/libvpxenc.c
@@ -2087,13 +2087,21 @@ static const enum AVPixelFormat vp9_pix_fmts_highbd[] = 
{
 AV_PIX_FMT_NONE
 };
 
-static av_cold void vp9_init_static(FFCodec *codec)
+static int vp9_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
-if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH)
-codec->p.pix_fmts = vp9_pix_fmts_highbd;
-else
-codec->p.pix_fmts = vp9_pix_fmts_highcol;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+vpx_codec_caps_t codec_caps = vpx_codec_get_caps(vpx_codec_vp9_cx());
+if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH)
+*out = vp9_pix_fmts_highbd;
+else
+*out = vp9_pix_fmts_highcol;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 static const AVClass class_vp9 = {
@@ -2122,6 +2130,6 @@ FFCodec ff_libvpx_vp9_encoder = {
 .caps_internal  = FF_CODEC_CAP_NOT_INIT_THREADSAFE |
   FF_CODEC_CAP_AUTO_THREADS,
 .defaults   = defaults,
-.init_static_data = vp9_init_static,
+.get_supported_config = vp9_get_supported_config,
 };
 #endif /* CONFIG_LIBVPX_VP9_ENCODER */
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 05/17] avcodec/libx265: switch to get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/libx265.c | 26 ++
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 3533ac5cc1f..e36a1eb9505 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -892,14 +892,24 @@ static const enum AVPixelFormat x265_csp_twelve[] = {
 AV_PIX_FMT_NONE
 };
 
-static av_cold void libx265_encode_init_csp(FFCodec *codec)
+static int libx265_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags, const void **out)
 {
-if (x265_api_get(12))
-codec->p.pix_fmts = x265_csp_twelve;
-else if (x265_api_get(10))
-codec->p.pix_fmts = x265_csp_ten;
-else if (x265_api_get(8))
-codec->p.pix_fmts = x265_csp_eight;
+if (config == AV_CODEC_CONFIG_PIX_FORMAT) {
+if (x265_api_get(12))
+*out = x265_csp_twelve;
+else if (x265_api_get(10))
+*out = x265_csp_ten;
+else if (x265_api_get(8))
+*out = x265_csp_eight;
+else
+return AVERROR_EXTERNAL;
+return 0;
+}
+
+return ff_default_get_supported_config(avctx, codec, config, flags, out);
 }
 
 #define OFFSET(x) offsetof(libx265Context, x)
@@ -952,7 +962,7 @@ FFCodec ff_libx265_encoder = {
 .p.priv_class = ,
 .p.wrapper_name   = "libx265",
 .init = libx265_encode_init,
-.init_static_data = libx265_encode_init_csp,
+.get_supported_config = libx265_get_supported_config,
 FF_CODEC_ENCODE_CB(libx265_encode_frame),
 .close= libx265_encode_close,
 .priv_data_size   = sizeof(libx265Context),
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 16/17] fftools/ffmpeg_filter: propagate codec yuv metadata to filters

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

To convert between color spaces/ranges, if needed by the codec
properties.
---
 fftools/ffmpeg_filter.c | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 83259416a68..a40c6f381f2 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -193,6 +193,8 @@ typedef struct OutputFilterPriv {
 int width, height;
 int sample_rate;
 AVChannelLayout ch_layout;
+enum AVColorSpace   color_space;
+enum AVColorRange   color_range;
 
 // time base in which the output is sent to our downstream
 // does not need to match the filtersink's timebase
@@ -208,6 +210,8 @@ typedef struct OutputFilterPriv {
 const int  *formats;
 const AVChannelLayout  *ch_layouts;
 const int  *sample_rates;
+const enum AVColorSpace *color_spaces;
+const enum AVColorRange *color_ranges;
 
 AVRational  enc_timebase;
 // offset for output timestamps, in AV_TIME_BASE_Q
@@ -379,6 +383,12 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, 
format, formats,
 DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
   "%d", )
 
+DEF_CHOOSE_FORMAT(color_spaces, enum AVColorSpace, color_space, color_spaces,
+  AVCOL_SPC_UNSPECIFIED, "%s", av_color_space_name);
+
+DEF_CHOOSE_FORMAT(color_ranges, enum AVColorRange, color_range, color_ranges,
+  AVCOL_RANGE_UNSPECIFIED, "%s", av_color_range_name);
+
 static void choose_channel_layouts(OutputFilterPriv *ofp, AVBPrint *bprint)
 {
 if (av_channel_layout_check(>ch_layout)) {
@@ -607,6 +617,8 @@ static OutputFilter *ofilter_alloc(FilterGraph *fg)
 ofilter->graph= fg;
 ofp->format   = -1;
 ofp->index= fg->nb_outputs - 1;
+ofp->color_space  = AVCOL_SPC_UNSPECIFIED;
+ofp->color_range  = AVCOL_RANGE_UNSPECIFIED;
 
 return ofilter;
 }
@@ -789,6 +801,24 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->formats = mjpeg_formats;
 }
 }
+if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
+ofp->color_space = ost->enc_ctx->colorspace;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_COLOR_SPACE, 0,
+   (const void **) 
>color_spaces);
+if (ret < 0)
+return ret;
+}
+if (ost->enc_ctx->color_range != AVCOL_RANGE_UNSPECIFIED) {
+ofp->color_range = ost->enc_ctx->color_range;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_COLOR_RANGE, 0,
+   (const void **) 
>color_ranges);
+if (ret < 0)
+return ret;
+}
 
 fgp->disable_conversions |= ost->keep_pix_fmt;
 
@@ -1347,6 +1377,8 @@ static int configure_output_video_filter(FilterGraph *fg, 
AVFilterGraph *graph,
 av_assert0(!ost->keep_pix_fmt || (!ofp->format && !ofp->formats));
 av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
 choose_pix_fmts(ofp, );
+choose_color_spaces(ofp, );
+choose_color_ranges(ofp, );
 if (!av_bprint_is_complete())
 return AVERROR(ENOMEM);
 if (bprint.len) {
@@ -1777,6 +1809,8 @@ static int configure_filtergraph(FilterGraph *fg, 
FilterGraphThread *fgt)
 
 ofp->width  = av_buffersink_get_w(sink);
 ofp->height = av_buffersink_get_h(sink);
+ofp->color_space = av_buffersink_get_colorspace(sink);
+ofp->color_range = av_buffersink_get_color_range(sink);
 
 // If the timing parameters are not locked yet, get the tentative 
values
 // here but don't lock them. They will only be used if no output frames
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 14/17] fftools/ffmpeg_filter: simplify choose_pix_fmts

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

The only meaningful difference between choose_pix_fmts and the default
code was the inclusion of an extra branch for `keep_pix_fmt` being true.

However, in this case, we either:
1. Force the specific `ofp->format` that we inherited from
   ofilter_bind_ost, or if no format was set:
2. Print an empty format list

Both of these goals can be accomplished by simply moving the decision
logic to ofilter_bind_ost, to avoid setting any format list when
keep_pix_fmt is enabled. This is arguably cleaner as it moves format
selection logic to a single function. In the case of branch 1, nothing
else needs to be done as we already force the format provided in
ofp->format, if any is set. Add an assertion to verify this assumption
just in case.

(Side note: The "choose_*" family of functions are arguably misnomers,
as they should really be called "print_*" - their current behavior is to
print the relevant format lists to the `vf/af_format` filter arguments)
---
 fftools/ffmpeg_filter.c | 49 -
 1 file changed, 9 insertions(+), 40 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 9ff064f5f68..945147d6ca1 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -348,36 +348,6 @@ static void sub2video_update(InputFilterPriv *ifp, int64_t 
heartbeat_pts,
 ifp->sub2video.initialize = 0;
 }
 
-/* *dst may return be set to NULL (no pixel format found), a static string or a
- * string backed by the bprint. Nothing has been written to the AVBPrint in 
case
- * NULL is returned. The AVBPrint provided should be clean. */
-static int choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint,
-   const char **dst)
-{
-OutputFilterPriv *ofp = ofp_from_ofilter(ofilter);
-OutputStream *ost = ofilter->ost;
-
-*dst = NULL;
-
-if (ost->keep_pix_fmt || ofp->format != AV_PIX_FMT_NONE) {
-*dst = ofp->format == AV_PIX_FMT_NONE ? NULL :
-   av_get_pix_fmt_name(ofp->format);
-} else if (ofp->formats) {
-const enum AVPixelFormat *p = ofp->formats;
-
-for (; *p != AV_PIX_FMT_NONE; p++) {
-const char *name = av_get_pix_fmt_name(*p);
-av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : 
'|');
-}
-if (!av_bprint_is_complete(bprint))
-return AVERROR(ENOMEM);
-
-*dst = bprint->str;
-}
-
-return 0;
-}
-
 /* Define a function for appending a list of allowed formats
  * to an AVBPrint. If nonempty, the list will have a header. */
 #define DEF_CHOOSE_FORMAT(name, type, var, supported_list, none, 
printf_format, get_name) \
@@ -400,8 +370,8 @@ static void choose_ ## name (OutputFilterPriv *ofp, 
AVBPrint *bprint)  \
 av_bprint_chars(bprint, ':', 1);   
\
 }
 
-//DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats, 
AV_PIX_FMT_NONE,
-//  av_get_pix_fmt_name)
+DEF_CHOOSE_FORMAT(pix_fmts, enum AVPixelFormat, format, formats,
+  AV_PIX_FMT_NONE, "%s", av_get_pix_fmt_name)
 
 DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
   AV_SAMPLE_FMT_NONE, "%s", av_get_sample_fmt_name)
@@ -791,7 +761,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->height = ost->enc_ctx->height;
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
-} else {
+} else if (!ost->keep_pix_fmt) {
 ofp->formats = c->pix_fmts;
 
 // MJPEG encoder exports a full list of supported pixel formats,
@@ -1307,7 +1277,6 @@ static int configure_output_video_filter(FilterGraph *fg, 
AVFilterGraph *graph,
 AVBPrint bprint;
 int pad_idx = out->pad_idx;
 int ret;
-const char *pix_fmts;
 char name[255];
 
 snprintf(name, sizeof(name), "out_%d_%d", ost->file->index, ost->index);
@@ -1342,17 +1311,17 @@ static int configure_output_video_filter(FilterGraph 
*fg, AVFilterGraph *graph,
 pad_idx = 0;
 }
 
+av_assert0(!ost->keep_pix_fmt || (!ofp->format && !ofp->formats));
 av_bprint_init(, 0, AV_BPRINT_SIZE_UNLIMITED);
-ret = choose_pix_fmts(ofilter, , _fmts);
-if (ret < 0)
-return ret;
-
-if (pix_fmts) {
+choose_pix_fmts(ofp, );
+if (!av_bprint_is_complete())
+return AVERROR(ENOMEM);
+if (bprint.len) {
 AVFilterContext *filter;
 
 ret = avfilter_graph_create_filter(,
avfilter_get_by_name("format"),
-   "format", pix_fmts, NULL, graph);
+   "format", bprint.str, NULL, graph);
 av

[FFmpeg-devel] [PATCH v2 17/17] fftools/ffmpeg_filter: remove YUVJ hack

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This is no longer needed, since we now correctly negotiate the required
range from the mjpeg encoder via avcodec_get_supported_config().
---
 fftools/ffmpeg_filter.c | 15 ---
 1 file changed, 15 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index a40c6f381f2..461f2b86065 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -785,21 +785,6 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
(const void **) >formats);
 if (ret < 0)
 return ret;
-
-// MJPEG encoder exports a full list of supported pixel formats,
-// but the full-range ones are experimental-only.
-// Restrict the auto-conversion list unless -strict experimental
-// has been specified.
-if (!strcmp(c->name, "mjpeg")) {
-// FIXME: YUV420P etc. are actually supported with full color 
range,
-// yet the latter information isn't available here.
-static const enum AVPixelFormat mjpeg_formats[] =
-{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
AV_PIX_FMT_YUVJ444P,
-  AV_PIX_FMT_NONE };
-
-if (ost->enc_ctx->strict_std_compliance > 
FF_COMPLIANCE_UNOFFICIAL)
-ofp->formats = mjpeg_formats;
-}
 }
 if (ost->enc_ctx->colorspace != AVCOL_SPC_UNSPECIFIED) {
 ofp->color_space = ost->enc_ctx->colorspace;
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 13/17] fftools/ffmpeg_filter: set strict_std_compliance

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

For avcodec_get_supported_config(), which requires this value be set on
the actual ost->enc_ctx being queried.
---
 fftools/ffmpeg_filter.c | 16 ++--
 1 file changed, 6 insertions(+), 10 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index ac04841a16c..9ff064f5f68 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -770,6 +770,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 FilterGraph  *fg = ofilter->graph;
 FilterGraphPriv *fgp = fgp_from_fg(fg);
 const AVCodec *c = ost->enc_ctx->codec;
+const AVDictionaryEntry *strict = av_dict_get(ost->encoder_opts, "strict", 
NULL, 0);
 int ret;
 
 av_assert0(!ofilter->ost);
@@ -780,6 +781,10 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 ofp->ts_offset = of->start_time == AV_NOPTS_VALUE ? 0 : of->start_time;
 ofp->enc_timebase = ost->enc_timebase;
 
+/* Ensure this is up-to-date for avcodefc_get_supported_config() */
+if (strict)
+av_opt_set(ost->enc_ctx, strict->key, strict->value, 0);
+
 switch (ost->enc_ctx->codec_type) {
 case AVMEDIA_TYPE_VIDEO:
 ofp->width  = ost->enc_ctx->width;
@@ -800,16 +805,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, 
AV_PIX_FMT_YUVJ444P,
   AV_PIX_FMT_NONE };
 
-const AVDictionaryEntry *strict = 
av_dict_get(ost->encoder_opts, "strict", NULL, 0);
-int strict_val = ost->enc_ctx->strict_std_compliance;
-
-if (strict) {
-const AVOption *o = av_opt_find(ost->enc_ctx, strict->key, 
NULL, 0, 0);
-av_assert0(o);
-av_opt_eval_int(ost->enc_ctx, o, strict->value, 
_val);
-}
-
-if (strict_val > FF_COMPLIANCE_UNOFFICIAL)
+if (ost->enc_ctx->strict_std_compliance > 
FF_COMPLIANCE_UNOFFICIAL)
 ofp->formats = mjpeg_formats;
 }
 }
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 15/17] fftools/ffmpeg_filter: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

I preserved the no-op condition on `!ch_layouts`, even though I suspect
it's not actually needed.
---
 fftools/ffmpeg_filter.c | 59 -
 1 file changed, 46 insertions(+), 13 deletions(-)

diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c
index 945147d6ca1..83259416a68 100644
--- a/fftools/ffmpeg_filter.c
+++ b/fftools/ffmpeg_filter.c
@@ -694,7 +694,7 @@ static int ifilter_bind_dec(InputFilterPriv *ifp, Decoder 
*dec)
 
 static int set_channel_layout(OutputFilterPriv *f, OutputStream *ost)
 {
-const AVCodec *c = ost->enc_ctx->codec;
+const AVChannelLayout *ch_layouts;
 int i, err;
 
 if (ost->enc_ctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
@@ -705,8 +705,14 @@ static int set_channel_layout(OutputFilterPriv *f, 
OutputStream *ost)
 return 0;
 }
 
+err = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0,
+   (const void **) _layouts);
+if (err < 0)
+return err;
+
 /* Requested layout is of order UNSPEC */
-if (!c->ch_layouts) {
+if (!ch_layouts) {
 /* Use the default native layout for the requested amount of channels 
when the
encoder doesn't have a list of supported layouts */
 av_channel_layout_default(>ch_layout, 
ost->enc_ctx->ch_layout.nb_channels);
@@ -714,13 +720,13 @@ static int set_channel_layout(OutputFilterPriv *f, 
OutputStream *ost)
 }
 /* Encoder has a list of supported layouts. Pick the first layout in it 
with the
same amount of channels as the requested layout */
-for (i = 0; c->ch_layouts[i].nb_channels; i++) {
-if (c->ch_layouts[i].nb_channels == 
ost->enc_ctx->ch_layout.nb_channels)
+for (i = 0; ch_layouts[i].nb_channels; i++) {
+if (ch_layouts[i].nb_channels == ost->enc_ctx->ch_layout.nb_channels)
 break;
 }
-if (c->ch_layouts[i].nb_channels) {
+if (ch_layouts[i].nb_channels) {
 /* Use it if one is found */
-err = av_channel_layout_copy(>ch_layout, >ch_layouts[i]);
+err = av_channel_layout_copy(>ch_layout, _layouts[i]);
 if (err < 0)
 return err;
 return 0;
@@ -762,7 +768,11 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
 ofp->format = ost->enc_ctx->pix_fmt;
 } else if (!ost->keep_pix_fmt) {
-ofp->formats = c->pix_fmts;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_PIX_FORMAT, 0,
+   (const void **) >formats);
+if (ret < 0)
+return ret;
 
 // MJPEG encoder exports a full list of supported pixel formats,
 // but the full-range ones are experimental-only.
@@ -788,8 +798,16 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 
 ofp->fps.framerate   = ost->frame_rate;
 ofp->fps.framerate_max   = ost->max_frame_rate;
-ofp->fps.framerate_supported = ost->force_fps ?
-   NULL : c->supported_framerates;
+
+if (ost->force_fps) {
+ofp->fps.framerate_supported = NULL;
+} else {
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_FRAME_RATE, 0,
+   (const void **) 
>fps.framerate_supported);
+if (ret < 0)
+return ret;
+}
 
 // reduce frame rate for mpeg4 to be within the spec limits
 if (c->id == AV_CODEC_ID_MPEG4)
@@ -802,19 +820,34 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream 
*ost,
 if (ost->enc_ctx->sample_fmt != AV_SAMPLE_FMT_NONE) {
 ofp->format = ost->enc_ctx->sample_fmt;
 } else {
-ofp->formats = c->sample_fmts;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_SAMPLE_FORMAT, 
0,
+   (const void **) >formats);
+if (ret < 0)
+return ret;
 }
 if (ost->enc_ctx->sample_rate) {
 ofp->sample_rate = ost->enc_ctx->sample_rate;
 } else {
-ofp->sample_rates = c->supported_samplerates;
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL,
+   AV_CODEC_CONFIG_SAMPLE_RATE, 0,
+   (const void **) 
>sample_rates);

[FFmpeg-devel] [PATCH v2 12/17] fftools/ffmpeg_mux_init: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 fftools/ffmpeg_mux_init.c | 22 +-
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/fftools/ffmpeg_mux_init.c b/fftools/ffmpeg_mux_init.c
index d3d7d022ff6..4f8c81102d3 100644
--- a/fftools/ffmpeg_mux_init.c
+++ b/fftools/ffmpeg_mux_init.c
@@ -511,13 +511,19 @@ static int fmt_in_list(const int *formats, int format)
 }
 
 static enum AVPixelFormat
-choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat target)
+choose_pixel_fmt(const AVCodecContext *avctx, enum AVPixelFormat target)
 {
-const enum AVPixelFormat *p = codec->pix_fmts;
+const enum AVPixelFormat *p;
 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target);
 //FIXME: This should check for AV_PIX_FMT_FLAG_ALPHA after PAL8 pixel 
format without alpha is implemented
 int has_alpha = desc ? desc->nb_components % 2 == 0 : 0;
 enum AVPixelFormat best= AV_PIX_FMT_NONE;
+int ret;
+
+ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) );
+if (ret < 0)
+return AV_PIX_FMT_NONE;
 
 for (; *p != AV_PIX_FMT_NONE; p++) {
 best = av_find_best_pix_fmt_of_2(best, *p, target, has_alpha, NULL);
@@ -529,7 +535,7 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat 
target)
 av_log(NULL, AV_LOG_WARNING,
"Incompatible pixel format '%s' for codec '%s', 
auto-selecting format '%s'\n",
av_get_pix_fmt_name(target),
-   codec->name,
+   avctx->codec->name,
av_get_pix_fmt_name(best));
 return best;
 }
@@ -538,8 +544,9 @@ choose_pixel_fmt(const AVCodec *codec, enum AVPixelFormat 
target)
 
 static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, const char *name)
 {
-const enum AVPixelFormat *fmts = ost->enc_ctx->codec->pix_fmts;
+const enum AVPixelFormat *fmts;
 enum AVPixelFormat fmt;
+int ret;
 
 fmt = av_get_pix_fmt(name);
 if (fmt == AV_PIX_FMT_NONE) {
@@ -547,6 +554,11 @@ static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, 
const char *name)
 return AV_PIX_FMT_NONE;
 }
 
+ret = avcodec_get_supported_config(ost->enc_ctx, NULL, 
AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) );
+if (ret < 0)
+return AV_PIX_FMT_NONE;
+
 /* when the user specified-format is an alias for an endianness-specific
  * one (e.g. rgb48 -> rgb48be/le), it gets translated into the native
  * endianness by av_get_pix_fmt();
@@ -574,7 +586,7 @@ static enum AVPixelFormat pix_fmt_parse(OutputStream *ost, 
const char *name)
 }
 
 if (fmts && !fmt_in_list(fmts, fmt))
-fmt = choose_pixel_fmt(ost->enc_ctx->codec, fmt);
+fmt = choose_pixel_fmt(ost->enc_ctx, fmt);
 
 return fmt;
 }
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 04/17] avcodec/allcodecs: add backcompat for new config API

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

In order to avoid breaking older clients not yet using the new API, we
need to add backwards compatibility for codecs which have switched from
init_static() to get_supported_config().

This function can be removed entirely once the deprecated static fields
are removed.
---
 libavcodec/allcodecs.c | 37 +++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index f4705651fb8..a9f1797930a 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -916,8 +916,41 @@ static AVOnce av_codec_static_init = AV_ONCE_INIT;
 static void av_codec_init_static(void)
 {
 for (int i = 0; codec_list[i]; i++) {
-if (codec_list[i]->init_static_data)
-codec_list[i]->init_static_data((FFCodec*)codec_list[i]);
+const FFCodec *codec = codec_list[i];
+if (codec->init_static_data) {
+codec->init_static_data((FFCodec*) codec);
+continue;
+}
+
+/* Backward compatibility with deprecated public fields */
+if (!codec->get_supported_config)
+continue;
+
+FF_DISABLE_DEPRECATION_WARNINGS
+switch (codec->p.type) {
+case AVMEDIA_TYPE_VIDEO:
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_PIX_FORMAT, 0,
+(const void **) >p.pix_fmts);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_FRAME_RATE, 0,
+(const void **) 
>p.supported_framerates);
+break;
+case AVMEDIA_TYPE_AUDIO:
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_SAMPLE_FORMAT, 0,
+(const void **) >p.sample_fmts);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_SAMPLE_RATE, 0,
+(const void **) 
>p.supported_samplerates);
+codec->get_supported_config(NULL, >p,
+AV_CODEC_CONFIG_CHANNEL_LAYOUT, 0,
+(const void **) >p.ch_layouts);
+break;
+default:
+break;
+}
+FF_ENABLE_DEPRECATION_WARNINGS
 }
 }
 
-- 
2.44.0

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


[FFmpeg-devel] [PATCH v2 03/17] avcodec/encode: switch to avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

---
 libavcodec/encode.c | 88 -
 1 file changed, 55 insertions(+), 33 deletions(-)

diff --git a/libavcodec/encode.c b/libavcodec/encode.c
index 34658d13d0c..d0e79379048 100644
--- a/libavcodec/encode.c
+++ b/libavcodec/encode.c
@@ -563,7 +563,8 @@ static int encode_preinit_video(AVCodecContext *avctx)
 {
 const AVCodec *c = avctx->codec;
 const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(avctx->pix_fmt);
-int i;
+const enum AVPixelFormat *pix_fmts;
+int ret, i;
 
 if (!av_get_pix_fmt_name(avctx->pix_fmt)) {
 av_log(avctx, AV_LOG_ERROR, "Invalid video pixel format: %d\n",
@@ -571,28 +572,33 @@ static int encode_preinit_video(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (c->pix_fmts) {
-for (i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++)
-if (avctx->pix_fmt == c->pix_fmts[i])
+ret = avcodec_get_supported_config(avctx, NULL, AV_CODEC_CONFIG_PIX_FORMAT,
+   0, (const void **) _fmts);
+if (ret < 0)
+return ret;
+
+if (pix_fmts) {
+for (i = 0; pix_fmts[i] != AV_PIX_FMT_NONE; i++)
+if (avctx->pix_fmt == pix_fmts[i])
 break;
-if (c->pix_fmts[i] == AV_PIX_FMT_NONE) {
+if (pix_fmts[i] == AV_PIX_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR,
"Specified pixel format %s is not supported by the %s 
encoder.\n",
av_get_pix_fmt_name(avctx->pix_fmt), c->name);
 
 av_log(avctx, AV_LOG_ERROR, "Supported pixel formats:\n");
-for (int p = 0; c->pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
+for (int p = 0; pix_fmts[p] != AV_PIX_FMT_NONE; p++) {
 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-   av_get_pix_fmt_name(c->pix_fmts[p]));
+   av_get_pix_fmt_name(pix_fmts[p]));
 }
 
 return AVERROR(EINVAL);
 }
-if (c->pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
-c->pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
+if (pix_fmts[i] == AV_PIX_FMT_YUVJ420P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ411P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ422P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ440P ||
+pix_fmts[i] == AV_PIX_FMT_YUVJ444P)
 avctx->color_range = AVCOL_RANGE_JPEG;
 }
 
@@ -646,7 +652,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
 static int encode_preinit_audio(AVCodecContext *avctx)
 {
 const AVCodec *c = avctx->codec;
-int i;
+const enum AVSampleFormat *sample_fmts;
+const int *supported_samplerates;
+const AVChannelLayout *ch_layouts;
+int ret, i;
 
 if (!av_get_sample_fmt_name(avctx->sample_fmt)) {
 av_log(avctx, AV_LOG_ERROR, "Invalid audio sample format: %d\n",
@@ -659,53 +668,66 @@ static int encode_preinit_audio(AVCodecContext *avctx)
 return AVERROR(EINVAL);
 }
 
-if (c->sample_fmts) {
-for (i = 0; c->sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
-if (avctx->sample_fmt == c->sample_fmts[i])
+ret = avcodec_get_supported_config(avctx, NULL, 
AV_CODEC_CONFIG_SAMPLE_FORMAT,
+   0, (const void **) _fmts);
+if (ret < 0)
+return ret;
+if (sample_fmts) {
+for (i = 0; sample_fmts[i] != AV_SAMPLE_FMT_NONE; i++) {
+if (avctx->sample_fmt == sample_fmts[i])
 break;
 if (avctx->ch_layout.nb_channels == 1 &&
 av_get_planar_sample_fmt(avctx->sample_fmt) ==
-av_get_planar_sample_fmt(c->sample_fmts[i])) {
-avctx->sample_fmt = c->sample_fmts[i];
+av_get_planar_sample_fmt(sample_fmts[i])) {
+avctx->sample_fmt = sample_fmts[i];
 break;
 }
 }
-if (c->sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
+if (sample_fmts[i] == AV_SAMPLE_FMT_NONE) {
 av_log(avctx, AV_LOG_ERROR,
"Specified sample format %s is not supported by the %s 
encoder\n",
av_get_sample_fmt_name(avctx->sample_fmt), c->name);
 
 av_log(avctx, AV_LOG_ERROR, "Supported sample formats:\n");
-for (int p = 0; c->sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
+for (int p = 0; sample_fmts[p] != AV_SAMPLE_FMT_NONE; p++) {
 av_log(avctx, AV_LOG_ERROR, "  %s\n",
-   av_get_sample_fmt_name(c->sample_fmts[p]));
+   av_get_sample_fmt_name(samp

[FFmpeg-devel] [PATCH v2 02/17] avcodec: add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

This replaces the myriad of existing lists in AVCodec by a unified API
call, allowing us to (ultimately) trim down the sizeof(AVCodec) quite
substantially, while also making this more trivially extensible.

In addition to the already covered lists, add two new entries for color
space and color range, mirroring the newly added negotiable fields in
libavfilter.

I decided to drop the explicit length field from the API proposed by
Andreas Rheinhardt, because having it in place ended up complicating
both the codec side and the client side implementations, while also
being strictly less flexible (it's trivial to recover a length given
a terminator, but requires allocation to add a terminator given
a length). Using a terminator also presents less of a porting challenge
for existing users of the current API.

Once the deprecation period passes for the existing public fields, the
rough plan is to move the commonly used fields (such as
pix_fmt/sample_fmt) into FFCodec, possibly as a union of audio and video
configuration types, and then implement the rarely used fields with
custom callbacks.
---
 doc/APIchanges  |  5 +++
 libavcodec/avcodec.c| 75 +
 libavcodec/avcodec.h| 27 +
 libavcodec/codec.h  | 19 --
 libavcodec/codec_internal.h | 24 
 libavcodec/version.h|  4 +-
 6 files changed, 148 insertions(+), 6 deletions(-)

diff --git a/doc/APIchanges b/doc/APIchanges
index 0a39b6d7ab8..fdeae67159d 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07
 
 API changes, most recent first:
 
+2024-04-xx - xx - lavc 59.6.100 - avcodec.h
+  Add avcodec_get_supported_config() and enum AVCodecConfig; deprecate
+  AVCodec.pix_fmts, AVCodec.sample_fmts, AVCodec.supported_framerates,
+  AVCodec.supported_samplerates and AVCodec.ch_layouts.
+
 2024-04-03 - xx - lavu 59.13.100 - pixfmt.h
   Add AVCOL_SPC_IPT_C2, AVCOL_SPC_YCGCO_RE and AVCOL_SPC_YCGCO_RO
   to map new matrix coefficients defined by H.273 v3.
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index 525fe516bd2..96728546d6c 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -700,3 +700,78 @@ int attribute_align_arg 
avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
 return ff_decode_receive_frame(avctx, frame);
 return ff_encode_receive_frame(avctx, frame);
 }
+
+#define WRAP_CONFIG(allowed_type, field)\
+do {\
+if (codec->type != (allowed_type))  \
+return AVERROR(EINVAL); \
+*out_configs = (field); \
+return 0;   \
+} while (0)
+
+static const enum AVColorRange color_range_jpeg[] = {
+AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange color_range_mpeg[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange color_range_all[] = {
+AVCOL_RANGE_MPEG, AVCOL_RANGE_JPEG, AVCOL_RANGE_UNSPECIFIED
+};
+
+static const enum AVColorRange *color_range_table[] = {
+[AVCOL_RANGE_MPEG] = color_range_mpeg,
+[AVCOL_RANGE_JPEG] = color_range_jpeg,
+[AVCOL_RANGE_MPEG | AVCOL_RANGE_JPEG] = color_range_all,
+};
+
+int ff_default_get_supported_config(const AVCodecContext *avctx,
+const AVCodec *codec,
+enum AVCodecConfig config,
+unsigned flags,
+const void **out_configs)
+{
+switch (config) {
+FF_DISABLE_DEPRECATION_WARNINGS
+case AV_CODEC_CONFIG_PIX_FORMAT:
+WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->pix_fmts);
+case AV_CODEC_CONFIG_FRAME_RATE:
+WRAP_CONFIG(AVMEDIA_TYPE_VIDEO, codec->supported_framerates);
+case AV_CODEC_CONFIG_SAMPLE_RATE:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->supported_samplerates);
+case AV_CODEC_CONFIG_SAMPLE_FORMAT:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->sample_fmts);
+case AV_CODEC_CONFIG_CHANNEL_LAYOUT:
+WRAP_CONFIG(AVMEDIA_TYPE_AUDIO, codec->ch_layouts);
+FF_ENABLE_DEPRECATION_WARNINGS
+
+case AV_CODEC_CONFIG_COLOR_RANGE:
+if (codec->type != AVMEDIA_TYPE_VIDEO)
+return AVERROR(EINVAL);
+*out_configs = color_range_table[ffcodec(codec)->color_ranges];
+return 0;
+
+case AV_CODEC_CONFIG_COLOR_SPACE:
+*out_configs = NULL;
+return 0;
+default:
+return AVERROR(EINVAL);
+}
+}
+
+int avcodec_get_supported_config(const AVCodecContext *avctx, const AVCodec 
*codec,
+ enum AVCodecConfig config, unsigned flags,
+ const void **out)
+{
+const FFCodec *codec2;
+if (!codec)
+codec = avctx->codec;
+codec2 = ffco

[FFmpeg-devel] [PATCH v2 01/17] avcodec/internal: add FFCodec.color_ranges

2024-04-08 Thread Niklas Haas
From: Niklas Haas 

I went through all codecs and put them into five basic categories:

1. JPEG range only
2. MPEG range only
3. Explicitly tagged
4. Broken (codec supports both but encoder ignores tags)
5. N/A (headerless or pseudo-formats)

Filters in category 5 remain untouched. The rest gain an explicit
assignment of their supported color ranges, with codecs in category
4 being set to MPEG-only for safety.

It might be considered redundant to distinguish between 0 (category 5)
and MPEG+JPEG (category 3), but in doing so we effectively communicate
that we can guarantee that these tags will be encoded, which is distinct
from the situation where there are some codecs that simply don't have
tagging or implied semantics (e.g. rawvideo).

A full list of codecs follows:

JPEG range only:
 - amv
 - roqvideo

MPEG range only:
 - asv1, asv2
 - avui
 - cfhd
 - cljr
 - dnxhd
 - dvvideo
 - ffv1
 - flv
 - h261, h263, h263p
 - {h263,vp8}_v4l2m2m
 - huffyuv, ffvhuff
 - jpeg2000
 - libopenjpeg
 - libtheora
 - libwebp, libwebp_anim
 - libx262
 - libxavs, libxavs2
 - libxvid
 - mpeg1video, mpeg2video
 - mpeg2_qsv
 - mpeg2_vaapi
 - mpeg4, msmpeg4, msmpeg4v2, wmv1, wmv2
 - mpeg4_omx
 - rv10, rv20
 - snow
 - speedhq
 - svq1
 - tiff
 - utvideo

Explicitly tagged (MPEG/JPEG):
 - {av1,h264,hevc}_nvenc
 - {av1,h264,hevc}_vaapi
 - {av1,h264,hevc,vp8,vp9,mpeg4}_mediacodec
 - {av1,h264,hevc,vp9}_qsv
 - h264_amf
 - {h264,hevc,prores}_videotoolbox
 - libaom-av1
 - libkvazaar
 - libopenh264
 - librav1e
 - libsvtav1
 - libvpx, libvpx-vp9
 - libx264
 - libx265
 - ljpeg
 - mjpeg
 - vc2

Broken (encoder ignores tags):
 - {av1,hevc}_amf
 - {h264,hevc,mpeg4}_v4l2m2m
 - h264_omx
 - libxeve
 - magicyuv
 - {vp8,vp9,mjpeg}_vaapi

N/A:
 - ayuv, yuv4, y41p, v308, v210, v410, v408 (headerless)
 - pgmyuv (headerless)
 - prores, prores_aw, prores_ks (?)
 - rawvideo, bitpacked (headerless)
 - vnull, wrapped_avframe (pseudocodecs)
---
 libavcodec/amfenc_av1.c | 1 +
 libavcodec/amfenc_h264.c| 1 +
 libavcodec/amfenc_hevc.c| 1 +
 libavcodec/asvenc.c | 2 ++
 libavcodec/avuienc.c| 1 +
 libavcodec/cfhdenc.c| 1 +
 libavcodec/cljrenc.c| 1 +
 libavcodec/codec_internal.h | 8 +++-
 libavcodec/dnxhdenc.c   | 1 +
 libavcodec/dvenc.c  | 1 +
 libavcodec/ffv1enc.c| 1 +
 libavcodec/flvenc.c | 1 +
 libavcodec/h261enc.c| 1 +
 libavcodec/huffyuvenc.c | 2 ++
 libavcodec/ituh263enc.c | 2 ++
 libavcodec/j2kenc.c | 1 +
 libavcodec/libaomenc.c  | 1 +
 libavcodec/libkvazaar.c | 1 +
 libavcodec/libopenh264enc.c | 1 +
 libavcodec/libopenjpegenc.c | 1 +
 libavcodec/librav1e.c   | 1 +
 libavcodec/libsvtav1.c  | 1 +
 libavcodec/libtheoraenc.c   | 1 +
 libavcodec/libvpxenc.c  | 2 ++
 libavcodec/libwebpenc.c | 1 +
 libavcodec/libwebpenc_animencoder.c | 1 +
 libavcodec/libx264.c| 2 ++
 libavcodec/libx265.c| 1 +
 libavcodec/libxavs.c| 1 +
 libavcodec/libxavs2.c   | 1 +
 libavcodec/libxeve.c| 1 +
 libavcodec/libxvid.c| 1 +
 libavcodec/ljpegenc.c   | 1 +
 libavcodec/magicyuvenc.c| 1 +
 libavcodec/mediacodecenc.c  | 1 +
 libavcodec/mjpegenc.c   | 2 ++
 libavcodec/mpeg12enc.c  | 2 ++
 libavcodec/mpeg4videoenc.c  | 1 +
 libavcodec/msmpeg4enc.c | 3 +++
 libavcodec/nvenc_av1.c  | 1 +
 libavcodec/nvenc_h264.c | 1 +
 libavcodec/nvenc_hevc.c | 1 +
 libavcodec/omx.c| 2 ++
 libavcodec/qsvenc_av1.c | 1 +
 libavcodec/qsvenc_h264.c| 1 +
 libavcodec/qsvenc_hevc.c| 1 +
 libavcodec/qsvenc_jpeg.c| 1 +
 libavcodec/qsvenc_mpeg2.c   | 1 +
 libavcodec/qsvenc_vp9.c | 1 +
 libavcodec/roqvideoenc.c| 1 +
 libavcodec/rv10enc.c| 1 +
 libavcodec/rv20enc.c| 1 +
 libavcodec/snowenc.c| 1 +
 libavcodec/speedhqenc.c | 1 +
 libavcodec/svq1enc.c| 1 +
 libavcodec/tiffenc.c| 1 +
 libavcodec/utvideoenc.c | 1 +
 libavcodec/v4l2_m2m_enc.c   | 1 +
 libavcodec/vaapi_encode_av1.c   | 1 +
 libavcodec/vaapi_encode_h264.c  | 1 +
 libavcodec/vaapi_encode_h265.c  | 1 +
 libavcodec/vaapi_encode_mjpeg.c | 1 +
 libavcodec/vaapi_encode_mpeg2.c | 1 +
 libavcodec/vaapi_encode_vp8.c   | 1 +
 libavcodec/vaapi_encode_vp9.c   | 1 +
 libavcodec/vc2enc.c | 3 ++-
 libavcodec/videotoolboxenc.c| 2 ++
 libavcodec/wmv2enc.c| 1 +
 68 files changed, 86 insertions(+), 2 deletions(-)

diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c
index

[FFmpeg-devel] [PATCH v2 00/17] Add avcodec_get_supported_config()

2024-04-08 Thread Niklas Haas
Changes since v1:
- Add implementation of AV_CODEC_CONFIG_COLOR_RANGE for all codecs
- Use AVBPrint instead of char desc[128] for printing channel
  descriptions
- Implement new constraints inside fftools/ffmpeg_filter.c
- Remove old YUVJ/MJPEG strictness hack

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


  1   2   3   4   5   6   7   8   >