Message ID | 20240328031210.21407-1-jamrial@gmail.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/7,v4] avutil/frame: add a flag to allow overwritting existing entries | expand |
Context | Check | Description |
---|---|---|
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Quoting James Almer (2024-03-28 04:12:04) > Enable it only for side data types that don't allow more than one entry. > > Signed-off-by: James Almer <jamrial@gmail.com> > --- > libavutil/frame.c | 59 ++++++++++++++++++++++++++++--- > libavutil/frame.h | 27 +++++++++----- > libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ > tests/ref/fate/side_data_array | 22 ++++++------ > 4 files changed, 115 insertions(+), 45 deletions(-) > > diff --git a/libavutil/frame.c b/libavutil/frame.c > index ef1613c344..d9bd19b2aa 100644 > --- a/libavutil/frame.c > +++ b/libavutil/frame.c > @@ -799,12 +799,34 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, > enum AVFrameSideDataType type, > size_t size, unsigned int flags) > { > - AVBufferRef *buf = av_buffer_alloc(size); > + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); > + AVBufferRef *buf; > AVFrameSideData *ret = NULL; > > if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) > remove_side_data(sd, nb_sd, type); > + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { desc == NULL means type is invalid > + for (int i = 0; i < *nb_sd; i++) { > + AVFrameSideData *entry = ((*sd)[i]); > + if (entry->type != type) > + continue; Why are you not calling av_frame_side_data_get()? > @@ -822,13 +845,41 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, > if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) > return AVERROR(EINVAL); > > + desc = av_frame_side_data_desc(src->type); > + if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) > + remove_side_data(sd, nb_sd, src->type); > + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { > + for (int i = 0; i < *nb_sd; i++) { > + AVFrameSideData *entry = ((*sd)[i]); > + AVDictionary *dict = NULL; > + > + if (entry->type != src->type) > + continue; > + if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) > + return AVERROR(EEXIST); > + > + ret = av_dict_copy(&dict, src->metadata, 0); > + if (ret < 0) > + return ret; > + > + ret = av_buffer_replace(&entry->buf, src->buf); > + if (ret < 0) { > + av_dict_free(&dict); > + return ret; > + } > + > + av_dict_free(&entry->metadata); > + entry->metadata = dict; > + entry->data = src->data; > + entry->size = src->size; > + return 0; > + } This whole block looks very similar to the one you're adding to av_frame_side_data_new(). > + } > + > buf = av_buffer_ref(src->buf); > if (!buf) > return AVERROR(ENOMEM); > > - if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) > - remove_side_data(sd, nb_sd, src->type); > - > sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf); > if (!sd_dst) { > av_buffer_unref(&buf); > diff --git a/libavutil/frame.h b/libavutil/frame.h > index 3b6d746a16..2ea129888e 100644 > --- a/libavutil/frame.h > +++ b/libavutil/frame.h > @@ -1040,7 +1040,14 @@ const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType typ > */ > void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd); > > +/** > + * Remove existing entries before adding new ones. > + */ > #define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0) > +/** > + * Don't add a new entry if another of the same type exists. This should mention that it only applies to MULTI side data types.
On 3/28/2024 8:23 AM, Anton Khirnov wrote: > Quoting James Almer (2024-03-28 04:12:04) >> Enable it only for side data types that don't allow more than one entry. >> >> Signed-off-by: James Almer <jamrial@gmail.com> >> --- >> libavutil/frame.c | 59 ++++++++++++++++++++++++++++--- >> libavutil/frame.h | 27 +++++++++----- >> libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ >> tests/ref/fate/side_data_array | 22 ++++++------ >> 4 files changed, 115 insertions(+), 45 deletions(-) >> >> diff --git a/libavutil/frame.c b/libavutil/frame.c >> index ef1613c344..d9bd19b2aa 100644 >> --- a/libavutil/frame.c >> +++ b/libavutil/frame.c >> @@ -799,12 +799,34 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, >> enum AVFrameSideDataType type, >> size_t size, unsigned int flags) >> { >> - AVBufferRef *buf = av_buffer_alloc(size); >> + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); >> + AVBufferRef *buf; >> AVFrameSideData *ret = NULL; >> >> if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) >> remove_side_data(sd, nb_sd, type); >> + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { > > desc == NULL means type is invalid This being a generic alloc function, it should IMO not be limited to currently defined types. And I chose to treat them as non multi, as that's the most common scenario. > >> + for (int i = 0; i < *nb_sd; i++) { >> + AVFrameSideData *entry = ((*sd)[i]); >> + if (entry->type != type) >> + continue; > > Why are you not calling av_frame_side_data_get()? An oversight i guess :p > >> @@ -822,13 +845,41 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, >> if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) >> return AVERROR(EINVAL); >> >> + desc = av_frame_side_data_desc(src->type); >> + if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) >> + remove_side_data(sd, nb_sd, src->type); >> + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { >> + for (int i = 0; i < *nb_sd; i++) { >> + AVFrameSideData *entry = ((*sd)[i]); >> + AVDictionary *dict = NULL; >> + >> + if (entry->type != src->type) >> + continue; >> + if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) >> + return AVERROR(EEXIST); >> + >> + ret = av_dict_copy(&dict, src->metadata, 0); >> + if (ret < 0) >> + return ret; >> + >> + ret = av_buffer_replace(&entry->buf, src->buf); >> + if (ret < 0) { >> + av_dict_free(&dict); >> + return ret; >> + } >> + >> + av_dict_free(&entry->metadata); >> + entry->metadata = dict; >> + entry->data = src->data; >> + entry->size = src->size; >> + return 0; >> + } > > This whole block looks very similar to the one you're adding to > av_frame_side_data_new(). I can try to factorize it. > >> + } >> + >> buf = av_buffer_ref(src->buf); >> if (!buf) >> return AVERROR(ENOMEM); >> >> - if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) >> - remove_side_data(sd, nb_sd, src->type); >> - >> sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf); >> if (!sd_dst) { >> av_buffer_unref(&buf); >> diff --git a/libavutil/frame.h b/libavutil/frame.h >> index 3b6d746a16..2ea129888e 100644 >> --- a/libavutil/frame.h >> +++ b/libavutil/frame.h >> @@ -1040,7 +1040,14 @@ const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType typ >> */ >> void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd); >> >> +/** >> + * Remove existing entries before adding new ones. >> + */ >> #define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0) >> +/** >> + * Don't add a new entry if another of the same type exists. > > This should mention that it only applies to MULTI side data types. Ok.
Quoting James Almer (2024-03-28 12:41:40) > On 3/28/2024 8:23 AM, Anton Khirnov wrote: > > Quoting James Almer (2024-03-28 04:12:04) > >> Enable it only for side data types that don't allow more than one entry. > >> > >> Signed-off-by: James Almer <jamrial@gmail.com> > >> --- > >> libavutil/frame.c | 59 ++++++++++++++++++++++++++++--- > >> libavutil/frame.h | 27 +++++++++----- > >> libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ > >> tests/ref/fate/side_data_array | 22 ++++++------ > >> 4 files changed, 115 insertions(+), 45 deletions(-) > >> > >> diff --git a/libavutil/frame.c b/libavutil/frame.c > >> index ef1613c344..d9bd19b2aa 100644 > >> --- a/libavutil/frame.c > >> +++ b/libavutil/frame.c > >> @@ -799,12 +799,34 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, > >> enum AVFrameSideDataType type, > >> size_t size, unsigned int flags) > >> { > >> - AVBufferRef *buf = av_buffer_alloc(size); > >> + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); > >> + AVBufferRef *buf; > >> AVFrameSideData *ret = NULL; > >> > >> if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) > >> remove_side_data(sd, nb_sd, type); > >> + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { > > > > desc == NULL means type is invalid > > This being a generic alloc function, it should IMO not be limited to > currently defined types. And I chose to treat them as non multi, as > that's the most common scenario. Andreas argued in the thread adding descriptors that side data type without a descriptor is invalid and should explode. I tend to agree.
On 3/28/2024 9:21 AM, Anton Khirnov wrote: > Quoting James Almer (2024-03-28 12:41:40) >> On 3/28/2024 8:23 AM, Anton Khirnov wrote: >>> Quoting James Almer (2024-03-28 04:12:04) >>>> Enable it only for side data types that don't allow more than one entry. >>>> >>>> Signed-off-by: James Almer <jamrial@gmail.com> >>>> --- >>>> libavutil/frame.c | 59 ++++++++++++++++++++++++++++--- >>>> libavutil/frame.h | 27 +++++++++----- >>>> libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ >>>> tests/ref/fate/side_data_array | 22 ++++++------ >>>> 4 files changed, 115 insertions(+), 45 deletions(-) >>>> >>>> diff --git a/libavutil/frame.c b/libavutil/frame.c >>>> index ef1613c344..d9bd19b2aa 100644 >>>> --- a/libavutil/frame.c >>>> +++ b/libavutil/frame.c >>>> @@ -799,12 +799,34 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, >>>> enum AVFrameSideDataType type, >>>> size_t size, unsigned int flags) >>>> { >>>> - AVBufferRef *buf = av_buffer_alloc(size); >>>> + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); >>>> + AVBufferRef *buf; >>>> AVFrameSideData *ret = NULL; >>>> >>>> if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) >>>> remove_side_data(sd, nb_sd, type); >>>> + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { >>> >>> desc == NULL means type is invalid >> >> This being a generic alloc function, it should IMO not be limited to >> currently defined types. And I chose to treat them as non multi, as >> that's the most common scenario. > > Andreas argued in the thread adding descriptors that side data type > without a descriptor is invalid and should explode. I tend to agree. I agree with that when you're handling side data that comes from something like a filter or similar modules within our libraries, as that'd be a bug. But this is the public core API for side data, and i don't see a reason why we should fail if the caller does av_frame_side_data_new(&sd, &nd_sd, 1000, 1, 0);. We never did before, and doing it now feels wrong.
diff --git a/libavutil/frame.c b/libavutil/frame.c index ef1613c344..d9bd19b2aa 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -799,12 +799,34 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type, size_t size, unsigned int flags) { - AVBufferRef *buf = av_buffer_alloc(size); + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); + AVBufferRef *buf; AVFrameSideData *ret = NULL; if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) remove_side_data(sd, nb_sd, type); + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { + for (int i = 0; i < *nb_sd; i++) { + AVFrameSideData *entry = ((*sd)[i]); + if (entry->type != type) + continue; + if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) + return NULL; + + buf = av_buffer_alloc(size); + if (!buf) + return NULL; + + av_buffer_unref(&entry->buf); + av_dict_free(&entry->metadata); + entry->buf = buf; + entry->data = buf->data; + entry->size = buf->size; + return entry; + } + } + buf = av_buffer_alloc(size); ret = add_side_data_from_buf(sd, nb_sd, type, buf); if (!ret) av_buffer_unref(&buf); @@ -815,6 +837,7 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, const AVFrameSideData *src, unsigned int flags) { + const AVSideDataDescriptor *desc; AVBufferRef *buf = NULL; AVFrameSideData *sd_dst = NULL; int ret = AVERROR_BUG; @@ -822,13 +845,41 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) return AVERROR(EINVAL); + desc = av_frame_side_data_desc(src->type); + if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) + remove_side_data(sd, nb_sd, src->type); + if (!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) { + for (int i = 0; i < *nb_sd; i++) { + AVFrameSideData *entry = ((*sd)[i]); + AVDictionary *dict = NULL; + + if (entry->type != src->type) + continue; + if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) + return AVERROR(EEXIST); + + ret = av_dict_copy(&dict, src->metadata, 0); + if (ret < 0) + return ret; + + ret = av_buffer_replace(&entry->buf, src->buf); + if (ret < 0) { + av_dict_free(&dict); + return ret; + } + + av_dict_free(&entry->metadata); + entry->metadata = dict; + entry->data = src->data; + entry->size = src->size; + return 0; + } + } + buf = av_buffer_ref(src->buf); if (!buf) return AVERROR(ENOMEM); - if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) - remove_side_data(sd, nb_sd, src->type); - sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf); if (!sd_dst) { av_buffer_unref(&buf); diff --git a/libavutil/frame.h b/libavutil/frame.h index 3b6d746a16..2ea129888e 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -1040,7 +1040,14 @@ const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType typ */ void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd); +/** + * Remove existing entries before adding new ones. + */ #define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0) +/** + * Don't add a new entry if another of the same type exists. + */ +#define AV_FRAME_SIDE_DATA_FLAG_REPLACE (1 << 1) /** * Add new side data entry to an array. @@ -1053,10 +1060,12 @@ void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd); * @param size size of the side data * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0. * - * @return newly added side data on success, NULL on error. In case of - * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching - * AVFrameSideDataType will be removed before the addition is - * attempted. + * @return newly added side data on success, NULL on error. + * @note In case of AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of + * matching AVFrameSideDataType will be removed before the addition + * is attempted. + * @note In case of AV_FRAME_SIDE_DATA_FLAG_REPLACE being set, if an + * entry of the same type already exists, it will be replaced instead. */ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type, @@ -1074,10 +1083,12 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, * for the buffer. * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0. * - * @return negative error code on failure, >=0 on success. In case of - * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching - * AVFrameSideDataType will be removed before the addition is - * attempted. + * @return negative error code on failure, >=0 on success. + * @note In case of AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of + * matching AVFrameSideDataType will be removed before the addition + * is attempted. + * @note In case of AV_FRAME_SIDE_DATA_FLAG_REPLACE being set, if an + * entry of the same type already exists, it will be replaced instead. */ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, const AVFrameSideData *src, unsigned int flags); diff --git a/libavutil/tests/side_data_array.c b/libavutil/tests/side_data_array.c index 793a62c009..633e9ee681 100644 --- a/libavutil/tests/side_data_array.c +++ b/libavutil/tests/side_data_array.c @@ -20,23 +20,22 @@ #include <stdio.h> #include "libavutil/frame.c" -#include "libavutil/mastering_display_metadata.h" +#include "libavutil/internal.h" -static void print_clls(const AVFrameSideData **sd, const int nb_sd) +static void print_entries(const AVFrameSideData **sd, const int nb_sd) { for (int i = 0; i < nb_sd; i++) { const AVFrameSideData *entry = sd[i]; - printf("sd %d, %s", - i, av_frame_side_data_name(entry->type)); + printf("sd %d (size %"SIZE_SPECIFIER"), %s", + i, entry->size, av_frame_side_data_name(entry->type)); - if (entry->type != AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) { + if (entry->type != AV_FRAME_DATA_SEI_UNREGISTERED) { putchar('\n'); continue; } - printf(": MaxCLL: %u\n", - ((AVContentLightMetadata *)entry->data)->MaxCLL); + printf(": %d\n", *(int32_t *)entry->data); } } @@ -51,51 +50,60 @@ int main(void) av_assert0( av_frame_side_data_new(&set.sd, &set.nb_sd, - AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, - 0, 0)); + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + sizeof(int64_t), 0)); + av_assert0( + av_frame_side_data_new(&set.sd, &set.nb_sd, + AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, + sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_REPLACE)); // test entries in the middle for (int value = 1; value < 4; value++) { AVFrameSideData *sd = av_frame_side_data_new( - &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, - sizeof(AVContentLightMetadata), 0); + &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED, + sizeof(int32_t), 0); av_assert0(sd); - ((AVContentLightMetadata *)sd->data)->MaxCLL = value; + *(int32_t *)sd->data = value; } av_assert0( av_frame_side_data_new( - &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL, 0, 0)); + &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL, + sizeof(int64_t), 0)); + + av_assert0( + av_frame_side_data_new( + &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL, + sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_REPLACE)); // test entries at the end for (int value = 1; value < 4; value++) { AVFrameSideData *sd = av_frame_side_data_new( - &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, - sizeof(AVContentLightMetadata), 0); + &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED, + sizeof(int32_t), 0); av_assert0(sd); - ((AVContentLightMetadata *)sd->data)->MaxCLL = value + 3; + *(int32_t *)sd->data = value + 3; } puts("Initial addition results with duplicates:"); - print_clls((const AVFrameSideData **)set.sd, set.nb_sd); + print_entries((const AVFrameSideData **)set.sd, set.nb_sd); { AVFrameSideData *sd = av_frame_side_data_new( - &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL, - sizeof(AVContentLightMetadata), - AV_FRAME_SIDE_DATA_FLAG_UNIQUE); + &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED, + sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_UNIQUE); av_assert0(sd); - ((AVContentLightMetadata *)sd->data)->MaxCLL = 1337; + *(int32_t *)sd->data = 1337; } puts("\nFinal state after a single 'no-duplicates' addition:"); - print_clls((const AVFrameSideData **)set.sd, set.nb_sd); + print_entries((const AVFrameSideData **)set.sd, set.nb_sd); av_frame_side_data_free(&set.sd, &set.nb_sd); diff --git a/tests/ref/fate/side_data_array b/tests/ref/fate/side_data_array index 7d8c684d8f..c1d77b0445 100644 --- a/tests/ref/fate/side_data_array +++ b/tests/ref/fate/side_data_array @@ -1,14 +1,14 @@ Initial addition results with duplicates: -sd 0, Ambient viewing environment -sd 1, Content light level metadata: MaxCLL: 1 -sd 2, Content light level metadata: MaxCLL: 2 -sd 3, Content light level metadata: MaxCLL: 3 -sd 4, Spherical Mapping -sd 5, Content light level metadata: MaxCLL: 4 -sd 6, Content light level metadata: MaxCLL: 5 -sd 7, Content light level metadata: MaxCLL: 6 +sd 0 (size 4), Content light level metadata +sd 1 (size 4), H.26[45] User Data Unregistered SEI message: 1 +sd 2 (size 4), H.26[45] User Data Unregistered SEI message: 2 +sd 3 (size 4), H.26[45] User Data Unregistered SEI message: 3 +sd 4 (size 4), Spherical Mapping +sd 5 (size 4), H.26[45] User Data Unregistered SEI message: 4 +sd 6 (size 4), H.26[45] User Data Unregistered SEI message: 5 +sd 7 (size 4), H.26[45] User Data Unregistered SEI message: 6 Final state after a single 'no-duplicates' addition: -sd 0, Ambient viewing environment -sd 1, Spherical Mapping -sd 2, Content light level metadata: MaxCLL: 1337 +sd 0 (size 4), Content light level metadata +sd 1 (size 4), Spherical Mapping +sd 2 (size 4), H.26[45] User Data Unregistered SEI message: 1337
Enable it only for side data types that don't allow more than one entry. Signed-off-by: James Almer <jamrial@gmail.com> --- libavutil/frame.c | 59 ++++++++++++++++++++++++++++--- libavutil/frame.h | 27 +++++++++----- libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ tests/ref/fate/side_data_array | 22 ++++++------ 4 files changed, 115 insertions(+), 45 deletions(-)