From patchwork Tue Jan 31 11:38:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 40191 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3ca3:b0:b9:1511:ac2c with SMTP id b35csp4166774pzj; Tue, 31 Jan 2023 03:39:47 -0800 (PST) X-Google-Smtp-Source: AMrXdXvN19/zwIKDKQC31F9PJBtVrUZpsRMi2rpRBQqJRbIo12agaVrCOyBmUOyL0Yfotu5VTGC4 X-Received: by 2002:a17:906:2ed1:b0:877:7113:71f3 with SMTP id s17-20020a1709062ed100b00877711371f3mr43474667eji.25.1675165186783; Tue, 31 Jan 2023 03:39:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1675165186; cv=none; d=google.com; s=arc-20160816; b=BqM8fbbu+PaZvYQLvkm6IAs3QJpNjpsTLeqxrjTG4YCwJxfa3plpV3tPhhVkzFHcmw i3srWx/eWs5yZJAnjtGZWjlOIvuEo6bnVer7H0fWOlK8eIIXbVN+chgomfDrfbJMH2lN NeC0jlLtvahJeYkHseXi1Hz+hKL8g+rnn6aCJ3IhuK+alWZP1077ljOYtzZiWOy01Yi5 +kAHLWZnj06R8NlP6rTzwhwA0HFfbShH5N/9eM0Uaq2KdaGSzzogp2Gtj78nqrnJlD49 nhK9cM37B5Yt7/9H10UNDWO29ZYfhTkrGvaNJIal7iZbtG+SSCa5ZwDOQy6EWgqGb6ml VBQA== 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 :delivered-to; bh=5mQtyI1i5NmPV9iZ/yfxTGDPcpFelF2TxqBiKZy7SAM=; b=Eq8eKa0RqPkZczH4K0mX6n4gWmWXHT0sB2ddOPxojbPM98+a6O+Ao2/lx/I0OgSWQR ah0fCxHD3/4pPrRHvI1yZo3QPfRF8h7UKMOiCRPp8FyFgsP+sbxkkgAyGZqlYVh4R3nY vOAgto8flhY7UGohw3aL0s7j2wBNwucYo4IkLu71jZLXImbv5SU7fii2GWs4HXPsi6/5 1/v9+CxP7JeQUXgnfnSdNfF8UFqH5mzQ9Ro+INRl/wK+kk2iTdJ2++b67zvQqTTfyPMx LNkqnRvgnAVJr8IEI6LMwOC6X7fOLscE2ACBfm34x3V2Fv/lg29toTNxn/s3isVnz7cI mD0w== 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 mi10-20020a1709071a8a00b008861cf89683si8930880ejc.833.2023.01.31.03.39.23; Tue, 31 Jan 2023 03:39:46 -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 8638068BE0D; Tue, 31 Jan 2023 13:39:20 +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 0A96968BBF4 for ; Tue, 31 Jan 2023 13:39:14 +0200 (EET) Received: from localhost (localhost [IPv6:::1]) by mail0.khirnov.net (Postfix) with ESMTP id C07542404EE for ; Tue, 31 Jan 2023 12:39:13 +0100 (CET) Received: from mail0.khirnov.net ([IPv6:::1]) by localhost (mail0.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id M6TBBUOxIKLU for ; Tue, 31 Jan 2023 12:39:13 +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 DE5CB2404EC for ; Tue, 31 Jan 2023 12:39:12 +0100 (CET) Received: from libav.khirnov.net (libav.khirnov.net [IPv6:::1]) by libav.khirnov.net (Postfix) with ESMTP id 8A20B3A0191 for ; Tue, 31 Jan 2023 12:39:06 +0100 (CET) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Tue, 31 Jan 2023 12:38:59 +0100 Message-Id: <20230131113900.5266-1-anton@khirnov.net> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] lavc/decode: allow using AV_CODEC_FLAG_COPY_OPAQUE for decoding 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: cnh6M1f7MFfu Use it to propagate AVPacket.opaque[_ref] to corresponding AVFrame fields. This is a more convenient alternative to reordered_opaque. --- doc/APIchanges | 3 +++ libavcodec/avcodec.h | 9 +++++++++ libavcodec/decode.c | 12 ++++++++++-- libavcodec/decode.h | 3 ++- libavcodec/libdav1d.c | 31 +++++++++++++++++++++++-------- libavcodec/version.h | 2 +- 6 files changed, 48 insertions(+), 12 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index bc52a07964..4b3934b82c 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,9 @@ libavutil: 2021-04-27 API changes, most recent first: +2023-0x-xx - xxxxxxxxxx - lavc 59.60.100 + Allow AV_CODEC_FLAG_COPY_OPAQUE to be used with decoders. + 2023-01-29 - xxxxxxxxxx - lavc 59.59.100 - avcodec.h Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION. diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 90b437ccbe..eba9ea73d7 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -242,9 +242,15 @@ typedef struct RcOverride{ */ #define AV_CODEC_FLAG_RECON_FRAME (1 << 6) /** + * @par decoding + * Request the decoder to propagate each packets AVPacket.opaque and + * AVPacket.opaque_ref to its corresponding output AVFrame. + * + * @par encoding: * Request the encoder to propagate each frame's AVFrame.opaque and * AVFrame.opaque_ref values to its corresponding output AVPacket. * + * @par * May only be set on encoders that have the * @ref AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE capability flag. * @@ -265,6 +271,9 @@ typedef struct RcOverride{ * . * When an output packet contains multiple frames, the opaque values will be * taken from the first of those. + * + * @note + * The converse holds for decoders, with frames and packets switched. */ #define AV_CODEC_FLAG_COPY_OPAQUE (1 << 7) /** diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 0abc88737b..17b398e933 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1291,7 +1291,8 @@ static int add_metadata_from_side_data(const AVPacket *avpkt, AVFrame *frame) return av_packet_unpack_dictionary(side_metadata, size, frame_md); } -int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt) +int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx, + AVFrame *frame, const AVPacket *pkt) { static const struct { enum AVPacketSideDataType packet; @@ -1336,6 +1337,13 @@ int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt) frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); } + if (avctx->flags & AV_CODEC_FLAG_COPY_OPAQUE) { + int ret = av_buffer_replace(&frame->opaque_ref, pkt->opaque_ref); + if (ret < 0) + return ret; + frame->opaque = pkt->opaque; + } + return 0; } @@ -1344,7 +1352,7 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) const AVPacket *pkt = avctx->internal->last_pkt_props; if (!(ffcodec(avctx->codec)->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { - int ret = ff_decode_frame_props_from_pkt(frame, pkt); + int ret = ff_decode_frame_props_from_pkt(avctx, frame, pkt); if (ret < 0) return ret; frame->pkt_size = (int)(intptr_t)pkt->opaque; diff --git a/libavcodec/decode.h b/libavcodec/decode.h index 906122b4a7..8430ffbd66 100644 --- a/libavcodec/decode.h +++ b/libavcodec/decode.h @@ -72,7 +72,8 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt); /** * Set various frame properties from the provided packet. */ -int ff_decode_frame_props_from_pkt(AVFrame *frame, const AVPacket *pkt); +int ff_decode_frame_props_from_pkt(const AVCodecContext *avctx, + AVFrame *frame, const AVPacket *pkt); /** * Set various frame properties from the codec context / packet data. diff --git a/libavcodec/libdav1d.c b/libavcodec/libdav1d.c index b43af03732..f7d75f9439 100644 --- a/libavcodec/libdav1d.c +++ b/libavcodec/libdav1d.c @@ -288,6 +288,11 @@ static void libdav1d_flush(AVCodecContext *c) dav1d_flush(dav1d->c); } +typedef struct OpaqueData { + void *pkt_orig_opaque; + int64_t reordered_opaque; +} OpaqueData; + static void libdav1d_data_free(const uint8_t *data, void *opaque) { AVBufferRef *buf = opaque; @@ -307,6 +312,7 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) Dav1dData *data = &dav1d->data; Dav1dPicture pic = { 0 }, *p = &pic; AVPacket *pkt; + OpaqueData *od = NULL; #if FF_DAV1D_VERSION_AT_LEAST(5,1) enum Dav1dEventFlags event_flags = 0; #endif @@ -333,17 +339,19 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) } pkt->buf = NULL; - pkt->opaque = NULL; - if (c->reordered_opaque != AV_NOPTS_VALUE) { - pkt->opaque = av_memdup(&c->reordered_opaque, - sizeof(c->reordered_opaque)); - if (!pkt->opaque) { + if (c->reordered_opaque != AV_NOPTS_VALUE || + (pkt->opaque && (c->flags & AV_CODEC_FLAG_COPY_OPAQUE))) { + od = av_mallocz(sizeof(*od)); + if (!od) { av_packet_free(&pkt); dav1d_data_unref(data); return AVERROR(ENOMEM); } + od->pkt_orig_opaque = pkt->opaque; + od->reordered_opaque = c->reordered_opaque; } + pkt->opaque = od; res = dav1d_data_wrap_user_data(data, (const uint8_t *)pkt, libdav1d_user_data_free, pkt); @@ -423,13 +431,20 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) ff_set_sar(c, frame->sample_aspect_ratio); pkt = (AVPacket *)p->m.user_data.data; - if (pkt->opaque) - memcpy(&frame->reordered_opaque, pkt->opaque, sizeof(frame->reordered_opaque)); + od = pkt->opaque; + if (od && od->reordered_opaque != AV_NOPTS_VALUE) + frame->reordered_opaque = od->reordered_opaque; else frame->reordered_opaque = AV_NOPTS_VALUE; + // restore the original user opaque value for + // ff_decode_frame_props_from_pkt() + pkt->opaque = od ? od->pkt_orig_opaque : NULL; + av_freep(&od); + // match timestamps and packet size - res = ff_decode_frame_props_from_pkt(frame, pkt); + res = ff_decode_frame_props_from_pkt(c, frame, pkt); + pkt->opaque = NULL; if (res < 0) goto fail; diff --git a/libavcodec/version.h b/libavcodec/version.h index 2ed4ef5547..499c6bb175 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 60 +#define LIBAVCODEC_VERSION_MINOR 61 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \