From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 5098A49AA2 for ; Thu, 28 Mar 2024 16:53:45 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1196168D4EF; Thu, 28 Mar 2024 18:53:36 +0200 (EET) Received: from mail-pg1-f171.google.com (mail-pg1-f171.google.com [209.85.215.171]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E90B568B4F8 for ; Thu, 28 Mar 2024 18:53:29 +0200 (EET) Received: by mail-pg1-f171.google.com with SMTP id 41be03b00d2f7-5d8b70b39efso959025a12.0 for ; Thu, 28 Mar 2024 09:53:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711644807; x=1712249607; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=PYGcK2X2+108ks0lYZ6SjlMCgksB/cstNas62md7b7Y=; b=H+udyPwk/sOVkXxPp8UXM+pWa2XYk45CLMnsWTW0jMinaP15z5ixMTkPnAeSFuU4SJ wZ+/bQHmbBWA4vtq2anuv7TJSma24OiMXF4eBp8EX38SfLcVt44HWSi4iWvmsmXVWwA7 x4jeYkffFNc1+njEMbe6uaDEc0Niib5G1+4u0E83JJSyVnuyyO5qnkU5L0KkLJvBtHZz DTtn4rur0k9yUQf/v2zHC4IBiWsY0l5VdXIY36n7DAMoZT+q5gG1L7gFshgoQ8YqOPRT xX7Bg/vlmgC9KVvl/oCUethvtFXC2i9TueM/6gUhZnl9WGDIFceCh4qj6XcVb2cQjspk YvhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711644807; x=1712249607; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PYGcK2X2+108ks0lYZ6SjlMCgksB/cstNas62md7b7Y=; b=qc2PJCUu9qj9d/UkKlW+thuoVS1+WrrPvzME4zvD9MlCMjBTNJcXz6t/9hnuh7WwLE MBf8LrHOjmjVtQzwfb8N1AMIEj7YNkqNs/FBMjNNGBKPkAl69QwblGj7rD5SQdmnW7tc 2kQHKNiYdk/cbOreIm9IDoBCMZg/OUUhddCOE9VNbso/MVUX+rRvxbPEBsnlDbr49ipk qnDrodvcwE/KHnO6z35N36Qew9irKQQDTGV/8iALn+j+kJ5cIwYCOZRRvcFJkhHmaP8/ WUAEFFwvFTMdWbgv3C/MofGiHVmKKcdJykNw3B5wE5boenIgisdQBxIlvbxfkM2Sjo7b LFrA== X-Gm-Message-State: AOJu0YyJ9PMGqImN4P18fzfmvF0AwhjXNYGept+ooWS0nSHw6S29E+SE +gq08wyRnAN2zV/egnrv028F2va37MD/lwzPs9ZvOrn2Ivcj+xrxRWHzzxa/ X-Google-Smtp-Source: AGHT+IHXLSfboL0YGyXoEZzxL9p+kx0SvI2xSL4XdWAlcjQG3fzt0fbgHouQeWvg0zPRd02DVFl0mA== X-Received: by 2002:a05:6a20:6a2c:b0:1a5:6fbc:43ad with SMTP id p44-20020a056a206a2c00b001a56fbc43admr2189840pzk.57.1711644806838; Thu, 28 Mar 2024 09:53:26 -0700 (PDT) Received: from localhost.localdomain ([190.194.167.233]) by smtp.gmail.com with ESMTPSA id w4-20020a1709029a8400b001d8f111804asm1822860plp.113.2024.03.28.09.53.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Mar 2024 09:53:25 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 28 Mar 2024 13:52:45 -0300 Message-ID: <20240328165250.64259-2-jamrial@gmail.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240328165250.64259-1-jamrial@gmail.com> References: <20240328165250.64259-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: Enable it only for side data types that don't allow more than one entry. Signed-off-by: James Almer --- libavutil/frame.c | 59 +++++++++++++++++++++++++++++-- libavutil/frame.h | 30 +++++++++++----- libavutil/tests/side_data_array.c | 52 +++++++++++++++------------ tests/ref/fate/side_data_array | 22 ++++++------ 4 files changed, 119 insertions(+), 44 deletions(-) diff --git a/libavutil/frame.c b/libavutil/frame.c index 87cc8450c8..9c3569db0e 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -795,15 +795,36 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame, return ret; } +static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst, + AVBufferRef *buf, int flags) +{ + if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) + return NULL; + + av_dict_free(&dst->metadata); + dst->buf = buf; + dst->data = buf->data; + dst->size = buf->size; + return dst; +} + AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, enum AVFrameSideDataType type, size_t size, unsigned int flags) { + const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); AVBufferRef *buf = av_buffer_alloc(size); 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)) && + (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) { + ret = replace_side_data_from_buf(ret, buf, flags); + if (!ret) + av_buffer_unref(&buf); + return ret; + } ret = add_side_data_from_buf(sd, nb_sd, type, buf); if (!ret) @@ -822,6 +843,13 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd, if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) remove_side_data(sd, nb_sd, type); + if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) && + (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) { + sd_dst = replace_side_data_from_buf(sd_dst, buf, flags); + if (sd_dst) + *pbuf = NULL; + return sd_dst; + } sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf); if (!sd_dst) @@ -834,6 +862,7 @@ AVFrameSideData *av_frame_side_data_add(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; @@ -841,13 +870,37 @@ 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)) && + (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) { + AVDictionary *dict = NULL; + + 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(&sd_dst->buf, src->buf); + if (ret < 0) { + av_dict_free(&dict); + return ret; + } + + av_dict_free(&sd_dst->metadata); + sd_dst->metadata = dict; + sd_dst->data = src->data; + sd_dst->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 8d16924432..4885600dce 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -1040,7 +1040,15 @@ 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. + * Applies only for side data types without the AV_SIDE_DATA_PROP_MULTI prop. + */ +#define AV_FRAME_SIDE_DATA_FLAG_REPLACE (1 << 1) /** * Add new side data entry to an array. @@ -1053,10 +1061,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, @@ -1080,6 +1090,8 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, * @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_add(AVFrameSideData ***sd, int *nb_sd, @@ -1098,10 +1110,12 @@ AVFrameSideData *av_frame_side_data_add(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 #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 -- 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-request@ffmpeg.org with subject "unsubscribe".