From patchwork Thu Mar 28 03:12:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 47568 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:9f96:b0:1a3:b6bb:3029 with SMTP id mm22csp1048960pzb; Wed, 27 Mar 2024 20:12:51 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCX4TjOESJXV9J5EscHe5CPy+j/P2bcGwAI+kjPQhVqEi4ArLJLxnT7r1Jk8SG+FMUNc3sPXZ4guN/zGPNX08qB2jEwXmyUeA9DzzQ== X-Google-Smtp-Source: AGHT+IHzjX+hdbIJ3pxlaXMC/m6MzrhZ8jrGIQQPtwYvu8Vn6qTDge3prrgJYrbnmhX2QtgoGqUz X-Received: by 2002:a17:907:9408:b0:a47:366b:21da with SMTP id dk8-20020a170907940800b00a47366b21damr726915ejc.4.1711595570838; Wed, 27 Mar 2024 20:12:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711595570; cv=none; d=google.com; s=arc-20160816; b=G4m4MSbYWJETA/Ixxe3zwDNuZoELU9EA9hg5FrB0/vJu1usp712bwkUl+RZ7+ODpqm GHyb2PwOhhmwW0wAOehBBKymVAZ63/F2K4Fc+Q2GPfJNMUGm+zZ2cqnwrmyNwnFF/EJk UZWkSAQHdQANucQOOGBFC/ErgCCua+cOiecbhiBQVq0pTUHfariH6voY1Z3YgitakrIe BrXsoU/xIkWOutrsl93pDMjzymTKVTkO0hGWksJiMy4Ko9rZT3V9Dr1N671RTQkuoYew CTGREWRzCF6xz6vfXfRtY+ifpySI20RJrWBoQ262aLUuR1oTxEYPsykxlWPGd+lVO4Hc Q7qw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=xGQAFddigf3yav1Adc1blruyyO0djswYMmYKJaMiPLk=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=TofmSHqXrbON14g1TkbInIJ9wJOw0lw8QXDy14mX4SvN6aoIgYcGMhlw6Fv4QJ6FHc cz9JRKcSQcmkmVplxOHp53+YIPL5fbO4DBsb5S/PTjBySghKR7LZTqPewJQXzMG9BWsS Pkcv3p0BpblQAvxsoRLIDK7p1vpQMkMBrHsnIVn5z6LFJ+L/ECXTrhciwo+pxfxSRpv1 H86kNkC4IZ9OoDZ4kIZihiZYjP3YF8NAuZrTudmUwJTFuK5dNbw4p+Gq8GNKeh+C3gU3 i8fXHJ0uyyY0kiO5+eSSMXGXASIZjYUFO1v2qaXwtcdzraP3hIgn9eCB+az1yEcpsSSR 9vXA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=iDc1KqVT; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id d24-20020a1709067f1800b00a4e086884eesi221965ejr.850.2024.03.27.20.12.50; Wed, 27 Mar 2024 20:12:50 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=iDc1KqVT; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 53F8E68D644; Thu, 28 Mar 2024 05:12:46 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oo1-f41.google.com (mail-oo1-f41.google.com [209.85.161.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4CA3768D4AD for ; Thu, 28 Mar 2024 05:12:39 +0200 (EET) Received: by mail-oo1-f41.google.com with SMTP id 006d021491bc7-5a58009fe88so279138eaf.0 for ; Wed, 27 Mar 2024 20:12:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711595556; x=1712200356; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=S2R6YXUwNAAfQ2wLP9ufw/LYrOBF8/Ghnwk7KOdB/DM=; b=iDc1KqVTZCvq0e4PPgEaOWwrpWOG4UR/Zj1jGghjYBSYeQQ9WgLydautiBvG4YDqFM e1cjtE8qXu07IqvC6hJzcleABcY1kD7BwpHt0rMT5joPaFX4jsEOtvB/9FX8drZarIHB IkfB16r4fLotP6+bmzlWaNtmsK6cfgf0jbVn+Hw+6S45WCm1Zy41cU8Ku2Qy2opEk0+P o5z0HQkvFSNm5/UtvaFOphErp5ajGAZGEjmRIH8k4pDfAR47zeYgydjSvsyc0tNkE3ER jzH5ba98L3e1CZjXgSlPnWVpu1izA7asDZrpI/kqgcqgZXCYU5ZACUCqDCZfwjzTdPoi 1Mfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711595556; x=1712200356; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=S2R6YXUwNAAfQ2wLP9ufw/LYrOBF8/Ghnwk7KOdB/DM=; b=rmhkPCC4HuigO7+RN5P08S0ArzNugJnxGNNMbPYBZGe0vGxL8KMW3ZnccvH2TFOrH4 WrwzG8IVTNukkpQdFzaN1H/IhkjczGkM+lWlMOaqaI6ZASqnKJtAUeb6MfBhP8Gm6jp2 25itmpVHUVBMxAdDIM+8o99JOJn0RFq2gJsLddyv7imfgc5/hgIM5o8B88j2kUJizXEr WO35xsIUWXpEe+AO1q0wczDiVxK6x119aiezDLS0CfATYdhKBI0Lrv6ETkAd8hpBnC/9 zT5UCvoVj+tWQDtp5NXi/J/WB4/K8CkeWN5V7jTqztvHHn+qBHxAykDZDnS5BoxLZ3XU m1Yg== X-Gm-Message-State: AOJu0YxMVsgGZpFp0Hl6Z7E3bJBJmMFZ1r2Uflfn2hvfWE1OtobMGNnL cADmxe+FLgAqw0175KUjKjRBCcYWt/xuY666t72TOorRpLgyhjksEmicW9p0 X-Received: by 2002:a05:6358:e4a5:b0:17c:1e6c:14c0 with SMTP id by37-20020a056358e4a500b0017c1e6c14c0mr1367051rwb.16.1711595555713; Wed, 27 Mar 2024 20:12:35 -0700 (PDT) Received: from localhost.localdomain ([190.194.167.233]) by smtp.gmail.com with ESMTPSA id q20-20020a635054000000b005dc120fa3b2sm249964pgl.18.2024.03.27.20.12.34 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Mar 2024 20:12:35 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 28 Mar 2024 00:12:04 -0300 Message-ID: <20240328031210.21407-1-jamrial@gmail.com> X-Mailer: git-send-email 2.44.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/7 v4] 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: wgbbtKBeIAdA 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 | 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)) { + 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 #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