From patchwork Mon Dec 6 18:37:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 32072 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp5050365iog; Mon, 6 Dec 2021 10:38:07 -0800 (PST) X-Google-Smtp-Source: ABdhPJyFFvV9iFujjtqqbC/ETM1XoJdYPHmgE6Vi6HKU088WH+hHUXLfRlsZfxWAgFpK4hGPq+04 X-Received: by 2002:a17:906:2844:: with SMTP id s4mr47009533ejc.66.1638815887663; Mon, 06 Dec 2021 10:38:07 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1638815887; cv=none; d=google.com; s=arc-20160816; b=z1AoPR21UUSlB38+SYqALeIEk4grBX6jczI12qYLGgFn5pQarCo6nVuPgTnXXag9/r jARvHyjhi0On2yJma6R4oeA5KMlGHRkbCda+aQIpUO2mZ+ZH0govUveYZIuUZeLY1yaP aKE5WRBtaztLLJTkTjPhmdP5j2wS+/Mu0RUk14Yt1FjD2zLiTrXgKFNsZcWyoKM4LCgg hPl0bcheCe0qWBTESSOCd2W4Mn6bZVzuvbo3pPaqpN8RI/rEeBpBjH1ywTZUU/wl7jTG UUJ2ryoyFjKIGKbneRnJMJ8it6qj2YF6H+k9/Amrs6M++6+ahNXYuloTvKpoYdi/I6zF Kopg== 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:references:in-reply-to:message-id :date:to:from:delivered-to; bh=Pp+j4j8GOCYV5Pn/lF5I0Oiocx2oIdduP/xTe2hIZTY=; b=WW2P5Y3ohMlvCOu8TVQ2BPbqAHi4ROF/Lpz50zr108clKjNyILndMwDrIrriLbTwPO Mw21vi5Q+agBzSPhzJLAHTqmkcw/GCCSy1rw/th7g/usAWvnPSNoOuzgifwnue/YFYgZ 3VK70mdcQ72HXhIBFV+hWZRYRNtAc/fkaX8q35PIv2Tm49Cg1uZ1b6Oru47ezfdZ+GQw a4Xlx5t+OdVmWle60M9As2qjM7+O41iikdqg+QtE5LzLbb4SYypZ3QVd5V+DPdlhepA3 bL5wpZnINIo0J6XNbBZv+GgVDGkushe9cQM0YNG7xzvd3t9+jz2CxTgLom/F8z6XzkBF 7NcQ== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id t5si23656409edd.553.2021.12.06.10.38.02; Mon, 06 Dec 2021 10:38:07 -0800 (PST) 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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0616068AE83; Mon, 6 Dec 2021 20:37:59 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail0.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3A7A168AE83 for ; Mon, 6 Dec 2021 20:37:52 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id 9867924017A for ; Mon, 6 Dec 2021 19:37:51 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id hAyHlcghoN9V for ; Mon, 6 Dec 2021 19:37:50 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:2a00:c500:561:201::7]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "libav.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail0.khirnov.net (Postfix) with ESMTPS id E3599240179 for ; Mon, 6 Dec 2021 19:37:50 +0100 (CET) Received: by libav.khirnov.net (Postfix, from userid 1000) id 39D2F3A0631; Mon, 6 Dec 2021 19:37:50 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 6 Dec 2021 19:37:47 +0100 Message-Id: <20211206183747.21571-1-anton@khirnov.net> X-Mailer: git-send-email 2.33.0 In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avutil/frame: Add av_frame_transfer_side_data() function 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: 64YuqzwlBBlQ From: Soft Works Signed-off-by: softworkz Signed-off-by: Anton Khirnov --- doc/APIchanges | 4 +++ libavutil/frame.c | 63 ++++++++++++++++++++++++++------------------- libavutil/frame.h | 20 ++++++++++++++ libavutil/version.h | 4 +-- 4 files changed, 63 insertions(+), 28 deletions(-) - renamed the function to av_frame_transfer_side_data(), since actually copying side data is only one of the two possible modes of behavior (and not even the default one) - renamed flags accordingly - added the AV_FRAME_TRANSFER_SD_FILTER flags as discussed diff --git a/doc/APIchanges b/doc/APIchanges index 2914ad6734..79cfea00b8 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,10 @@ libavutil: 2021-04-27 API changes, most recent first: +2021-12-02 - xxxxxxxxxx - lavu 57.11.100 - frame.h + Add av_frame_transfer_side_data(), AV_FRAME_TRANSFER_SD_COPY, and + AV_FRAME_TRANSFER_SD_FILTER. + 2021-11-xx - xxxxxxxxxx - lavfi 8.19.100 - avfilter.h Add AVFILTER_FLAG_METADATA_ONLY. diff --git a/libavutil/frame.c b/libavutil/frame.c index 0912ad9131..0b087cc4c9 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -253,9 +253,40 @@ int av_frame_get_buffer(AVFrame *frame, int align) return AVERROR(EINVAL); } +int av_frame_transfer_side_data(AVFrame *dst, const AVFrame *src, int flags) +{ + for (unsigned i = 0; i < src->nb_side_data; i++) { + const AVFrameSideData *sd_src = src->side_data[i]; + AVFrameSideData *sd_dst; + if ((flags & AV_FRAME_TRANSFER_SD_FILTER) && + sd_src->type == AV_FRAME_DATA_PANSCAN && + (src->width != dst->width || src->height != dst->height)) + continue; + if (flags & AV_FRAME_TRANSFER_SD_COPY) { + sd_dst = av_frame_new_side_data(dst, sd_src->type, + sd_src->size); + if (!sd_dst) { + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + memcpy(sd_dst->data, sd_src->data, sd_src->size); + } else { + AVBufferRef *ref = av_buffer_ref(sd_src->buf); + sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); + if (!sd_dst) { + av_buffer_unref(&ref); + wipe_side_data(dst); + return AVERROR(ENOMEM); + } + } + av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); + } + return 0; +} + static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) { - int ret, i; + int ret; dst->key_frame = src->key_frame; dst->pict_type = src->pict_type; @@ -291,31 +322,11 @@ static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) av_dict_copy(&dst->metadata, src->metadata, 0); - for (i = 0; i < src->nb_side_data; i++) { - const AVFrameSideData *sd_src = src->side_data[i]; - AVFrameSideData *sd_dst; - if ( sd_src->type == AV_FRAME_DATA_PANSCAN - && (src->width != dst->width || src->height != dst->height)) - continue; - if (force_copy) { - sd_dst = av_frame_new_side_data(dst, sd_src->type, - sd_src->size); - if (!sd_dst) { - wipe_side_data(dst); - return AVERROR(ENOMEM); - } - memcpy(sd_dst->data, sd_src->data, sd_src->size); - } else { - AVBufferRef *ref = av_buffer_ref(sd_src->buf); - sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref); - if (!sd_dst) { - av_buffer_unref(&ref); - wipe_side_data(dst); - return AVERROR(ENOMEM); - } - } - av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); - } + ret = av_frame_transfer_side_data(dst, src, + (force_copy ? AV_FRAME_TRANSFER_SD_COPY : 0) | + AV_FRAME_TRANSFER_SD_FILTER); + if (ret < 0) + return ret; ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref); ret |= av_buffer_replace(&dst->private_ref, src->private_ref); diff --git a/libavutil/frame.h b/libavutil/frame.h index 3f295f6b9e..deb399f1da 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -873,6 +873,26 @@ AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, */ void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type); +/** + * Copy side data, rather than creating new references. + */ +#define AV_FRAME_TRANSFER_SD_COPY (1 << 0) +/** + * Filter out side data that does not match dst properties. + */ +#define AV_FRAME_TRANSFER_SD_FILTER (1 << 1) + +/** + * Transfer all side-data from src to dst. + * + * @param flags a combination of AV_FRAME_TRANSFER_SD_* + * + * @return >= 0 on success, a negative AVERROR on error. + * + * @note This function will create new references to side data buffers in src, + * unless the AV_FRAME_TRANSFER_SD_COPY flag is passed. + */ +int av_frame_transfer_side_data(AVFrame *dst, const AVFrame *src, int flags); /** * Flags for frame cropping. diff --git a/libavutil/version.h b/libavutil/version.h index 017fc277a6..0e7b36865a 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,8 +79,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 57 -#define LIBAVUTIL_VERSION_MINOR 10 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 11 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \