From patchwork Sun Jun 5 15:28:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 36076 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:6914:b0:82:6b11:2509 with SMTP id q20csp5750329pzj; Sun, 5 Jun 2022 08:28:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz/XdJ43V/GykSIvjEsPBuCLI0nsr8YCC5gXKOPV14hdkJUjT7op734zndjDrkreur92tIr X-Received: by 2002:a05:6402:5306:b0:430:97ab:51f with SMTP id eo6-20020a056402530600b0043097ab051fmr8549987edb.171.1654442920986; Sun, 05 Jun 2022 08:28:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654442920; cv=none; d=google.com; s=arc-20160816; b=Ghq6wesOWlI2sz55YpVi+ljkdgZtQn2Iwvra9vNkabapUHhcacCDDOn7Vodsl3onEC B8kI8N0TOe2Z/nZia2bw/yXjje2ISihvieIECmwbvvU22t9PQWWPEZES+OPtFoNT807m ca0H7t8CNTp4lvvKL8KEzbQgQbdomXKqQ0ICO/rHh7Vr7nhrrMAMX9u64K0cJL6ufwip QNQGOweS8JGXU3LFHOz/6/jaH9YPzdhhS0x7Dh0JLYPFwExcLUnpkrkZ+Wv1d2aCFCcA wSMhe56pkj4RJVX8TvWps1NR6dW28o0tP0vWuobwBg+3XROpxuNUx5b/hE5dbzVplqsQ Sy9A== 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=LUiVW/3R8D96dtNrEfMCx89W6qrsydjvR2ho938eLRg=; b=WnoS+lB6KKx7XKGFFeEwh3rfPh5c3SJU00dGd3cB4kaoGlIlFD4E4RsPTw7KECKsz1 u++aTJCcAUdAjSymionAr8cFJtCA5G6jnj9tXD+DhuamMCQjZioYYx4SUXicWKNtMxYw C0snTK7EU89tOZE1H0EDd4yfX2/YqMvZx+uk0UiZpOrnSmtAWON1X7uuS22YMtNWLJ5l w9RABmUbP8tb3fULCRfJY06+tvSPMQGodpVHfTns4+YU4mu7N/h5h1zQuLR4KCVBxmgR dinreDB1tr4NEO5UGVNz/pulRbD7yW0C+8Lyyb/pvZokfUawIGvP0vR5FXj6zM9ge/JB kLkw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=evcKkVFf; 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 du8-20020a17090772c800b007115a93d536si3805310ejc.598.2022.06.05.08.28.39; Sun, 05 Jun 2022 08:28:40 -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=20210112 header.b=evcKkVFf; 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 6196168B58F; Sun, 5 Jun 2022 18:28:35 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f172.google.com (mail-oi1-f172.google.com [209.85.167.172]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6D0A168B58F for ; Sun, 5 Jun 2022 18:28:28 +0300 (EEST) Received: by mail-oi1-f172.google.com with SMTP id k11so16689464oia.12 for ; Sun, 05 Jun 2022 08:28:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=P3gLBjfl4S+Lt+ChNMGLDhsApCRFkusxhffgrpHREUA=; b=evcKkVFfKgV3QIRL9ySYXerGrCOj2dPXrYvrkiaJ67eVOCwNbJYRA4gKsL3n1CMvvw 7K6pKDAbF9ZvZx27qntEIZCS0UoO3oOvUKJszWBipp+gdgtOTx9LVM5eB5LSxQUj48LY zv58CZB3zIMyeb7L5wP6zZ79qJ+iGd5VoSEReRBf2mxO0qq2amVpqTcAh3AGsJyUX66P mtVmwt0L9ncgRkzTEOOTFWvTOEfc6Pl2VbtB2AzOlsXA7G+D6ZB5yx6QGA95rM+b1JFn q4T9YAtngZZz9yENDFmVelFjVKGOhzpGzzgHJtcwj0lWoaoFlpRF2Sq6P2I5tJ/FIXsf N26w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=P3gLBjfl4S+Lt+ChNMGLDhsApCRFkusxhffgrpHREUA=; b=3FRSD3bw0M93e1Hwtji9hfq6yprgr7tgJQYOC4JtUsAY6PPIpnHdElTx0gh26xGSgu GSBzRTsTlI/Ahh4gRL9gwtjdhFayUpJNM1MYC6EqqFGsG98QP662q3hfKbu28moYgilR mhIgz/rz+BX/QYjn4nlR0NWSAekIKPmQhao4bkZu8Rhnq4fi0zc5Ritz5pg+2nm/vp5Y I4A8Igs0CGeR9BtxDxAZU+NbEgR45GdqRjy93FrxBz6cdRqqsuDs/KyHYyVayrajwkJv 9AQuN6TEl7aEyZa9XXxNARbN67ELz5NtDRfaTfH/ZYYmXD9R0NL1twRhDOITlPaQTY9C bbgg== X-Gm-Message-State: AOAM530hv67Z/v0zIdHb/dVvbG7idjui0B1ynY/rjVZD1Qh2v3ENQwwz kVpv2F76oE87rprjCroDnawhG0l6Ohw= X-Received: by 2002:a05:6808:1710:b0:32e:37f6:cbe1 with SMTP id bc16-20020a056808171000b0032e37f6cbe1mr10119528oib.114.1654442906667; Sun, 05 Jun 2022 08:28:26 -0700 (PDT) Received: from localhost.localdomain ([186.136.131.204]) by smtp.gmail.com with ESMTPSA id u20-20020a544394000000b0032e6b8e8aefsm2426067oiv.17.2022.06.05.08.28.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Jun 2022 08:28:26 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sun, 5 Jun 2022 12:28:13 -0300 Message-Id: <20220605152813.1888-1-jamrial@gmail.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avutil/frame: add av_frame_replace 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: yfqfHPMDdDy9 Signed-off-by: James Almer --- Now taking into account the new channel layout API fields, supporting non refcouted src, plus changing the documentation to state that the dst frame properties will be replaced by those from src even if the data described by both frames is the same. Still missing APIChanges entry and version bump. libavutil/frame.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++ libavutil/frame.h | 17 ++++++ 2 files changed, 161 insertions(+) diff --git a/libavutil/frame.c b/libavutil/frame.c index 4c16488c66..2a4a2c27ad 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -461,6 +461,150 @@ fail: return ret; } +int av_frame_replace(AVFrame *dst, const AVFrame *src) +{ + int i, ret = 0; + + dst->format = src->format; + dst->width = src->width; + dst->height = src->height; + dst->nb_samples = src->nb_samples; +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + dst->channels = src->channels; + dst->channel_layout = src->channel_layout; + if (!av_channel_layout_check(&src->ch_layout)) { + av_channel_layout_uninit(&dst->ch_layout); + if (src->channel_layout) + av_channel_layout_from_mask(&dst->ch_layout, src->channel_layout); + else { + dst->ch_layout.nb_channels = src->channels; + dst->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + } + } else { +#endif + ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout); + if (ret < 0) + goto fail; +#if FF_API_OLD_CHANNEL_LAYOUT + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + wipe_side_data(dst); + av_dict_free(&dst->metadata); + ret = frame_copy_props(dst, src, 0); + if (ret < 0) + goto fail; + + /* duplicate the frame data if it's not refcounted */ + if (!src->buf[0]) { + for (i = 0; i < FF_ARRAY_ELEMS(dst->buf); i++) + av_buffer_unref(&dst->buf[i]); + for (i = 0; i < dst->nb_extended_buf; i++) + av_buffer_unref(&dst->extended_buf[i]); + av_freep(&dst->extended_buf); + + memset(dst->data, 0, sizeof(dst->data)); + if (dst->extended_data != dst->data) + av_freep(&dst->extended_data); + + ret = av_frame_get_buffer(dst, 0); + if (ret < 0) + goto fail; + + ret = av_frame_copy(dst, src); + if (ret < 0) + goto fail; + + ret = av_buffer_replace(&dst->hw_frames_ctx, src->hw_frames_ctx); + if (ret < 0) + goto fail; + + return 0; + } + + /* replace the buffers */ + for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { + ret = av_buffer_replace(&dst->buf[i], src->buf[i]); + if (ret < 0) + goto fail; + } + + if (src->extended_buf) { + if (dst->nb_extended_buf != src->nb_extended_buf) { + int nb_extended_buf = FFMIN(dst->nb_extended_buf, src->nb_extended_buf); + void *tmp; + + for (i = nb_extended_buf; i < dst->nb_extended_buf; i++) + av_buffer_unref(&dst->extended_buf[i]); + + tmp = av_realloc_array(dst->extended_buf, sizeof(*dst->extended_buf), + src->nb_extended_buf); + if (!tmp) { + ret = AVERROR(ENOMEM); + goto fail; + } + dst->extended_buf = tmp; + dst->nb_extended_buf = src->nb_extended_buf; + + memset(&dst->extended_buf[nb_extended_buf], 0, + (src->nb_extended_buf - nb_extended_buf) * sizeof(*dst->extended_buf)); + } + + for (i = 0; i < src->nb_extended_buf; i++) { + ret = av_buffer_replace(&dst->extended_buf[i], src->extended_buf[i]); + if (ret < 0) + goto fail; + } + } else if (dst->extended_buf) { + for (i = 0; i < dst->nb_extended_buf; i++) + av_buffer_unref(&dst->extended_buf[i]); + av_freep(&dst->extended_buf); + } + + ret = av_buffer_replace(&dst->hw_frames_ctx, src->hw_frames_ctx); + if (ret < 0) + goto fail; + + if (dst->extended_data != dst->data) + av_freep(&dst->extended_data); + + if (src->extended_data != src->data) { + int ch = src->ch_layout.nb_channels; + +#if FF_API_OLD_CHANNEL_LAYOUT +FF_DISABLE_DEPRECATION_WARNINGS + if (!ch) { + ch = src->channels; + CHECK_CHANNELS_CONSISTENCY(src); + } +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (!ch) { + ret = AVERROR(EINVAL); + goto fail; + } + + dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); + if (!dst->extended_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch); + } else + dst->extended_data = dst->data; + + memcpy(dst->data, src->data, sizeof(src->data)); + memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); + + return 0; + +fail: + av_frame_unref(dst); + return ret; +} + AVFrame *av_frame_clone(const AVFrame *src) { AVFrame *ret = av_frame_alloc(); diff --git a/libavutil/frame.h b/libavutil/frame.h index 33fac2054c..a971b1655e 100644 --- a/libavutil/frame.h +++ b/libavutil/frame.h @@ -752,6 +752,23 @@ void av_frame_free(AVFrame **frame); */ int av_frame_ref(AVFrame *dst, const AVFrame *src); +/** + * Ensure the destination frame refers to the same data described by the source + * frame by creating a new reference for each AVBufferRef from src if they + * differ from those in dst, or if src is not reference counted, by allocating + * new buffers and copying data. + * + * Frame properties on dst will be replaced by those from src. + * + * @param src The source frame. If there's data described in it, it must be + * reference counted. + * @param dst The destination frame. + * + * @return 0 on success, a negative AVERROR on error. On error, dst is + * unreferenced. + */ +int av_frame_replace(AVFrame *dst, const AVFrame *src); + /** * Create a new frame that references the same data as src. *