From patchwork Mon Sep 6 02:27:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 30023 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6602:2a4a:0:0:0:0 with SMTP id k10csp3373174iov; Sun, 5 Sep 2021 19:28:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw3mPba//+es2oa+X7QAucXo6pY08lQ2fATe1/hdPHBceKUu8xHVvch/pzi5CypuIc8DYHI X-Received: by 2002:a17:906:2ac1:: with SMTP id m1mr11203384eje.518.1630895307291; Sun, 05 Sep 2021 19:28:27 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id m9si6506833edc.501.2021.09.05.19.28.26; Sun, 05 Sep 2021 19:28:27 -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=@outlook.com header.s=selector1 header.b=kwOHXQQZ; arc=fail (body hash mismatch); 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=outlook.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 704F468A6F4; Mon, 6 Sep 2021 05:28:22 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-VE1-obe.outbound.protection.outlook.com (mail-oln040092066075.outbound.protection.outlook.com [40.92.66.75]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 05B7168A62A for ; Mon, 6 Sep 2021 05:28:15 +0300 (EEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=OwdSWSmapoW+EF+z+P7ni316c31ZsqvNUgCTxA1zwtoH3DwkCcWKhHqQMuXA0/2kkonhgGmO0g5BEUxL+7Ru1qkrBpv+amXplZy6CCF9bQDBQpFIAZcynl+AF7p4ykDku0sX03ZqeWGWHy2+OaAoWjIB7k5mpolQtNfu0FEqgM/R8L+Po0vLUzqO2xTUM7ymf7wLHjDWL8Rrf7VvmEC4WqrWTBBLXNSk1IsNw2dnnCYyAzxrfhg1LZ5t8FQrrTLBfPeQGMTkvUX5u+f5pZQXvXWUUZ5OsF901+z8kdbEebkZouip/909uK/zaFoAbtcz9OUNvSA29hocTaWmWBwh4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=Rt8JDhWuZa2T5NG5nqocFjn7HsR1XA/jpb3q9KFzF0U=; b=SKsSnBoLT5UqcYBjR7Jqpf3as/gIs/W743loPhGLNQzswvUFlT8MQ9kfIO42cpaf1sYXqYE7CilKeGcnbyiYLy5ssyk4PJ61eoX1rb2Iy5Imd4COZ6DB6o16Z7VbN+XWjEU/xIMdNaKSr5mYsKsY+rn1kQEEmbL1kKDnOBpzIrJsKVR4eb493RheJcE3ILry2TjgeNitezIlZ5aH/wkSHsCerUQ0/P5s0XBYRrP/rvDKID6cXHeL7730Hg5eVxIxHnrqJ9l/lUbeHRdt22VFYOaWEn+PSJwFjhfSCmxhOmwPnwBymMA5fHLCOaISfNDJgNfokfdO94TH+DNNtW61pg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Rt8JDhWuZa2T5NG5nqocFjn7HsR1XA/jpb3q9KFzF0U=; b=kwOHXQQZw7US3KRPk7++U619rigePyWdQYusQaiCm4KHBLD2QY9ANXno7DIUQ8ookm0bf5v7Zgcdy75cyJxrRJcDbFFznh47xd94loJihYVLEYhL9cz3a+uVpuprHRuzL1HbQ/ia8vjbfOFFPNlKgAyY2cwjUfQq04wO8q+nhPzZSOqQ1x8QGcU/iJoMuUA9P0yIE13g3X7KwcNR5fFef2NVBPcoUcQXlGIuOu+mcTpiH/JMM37qImJ19X4m2RXQOD3A5UTrSjjTpvqUG3usuIW5PPik1I/4lyq9AZIAKCDSh2FRt/c/xJx5O6wkF8N14DmCPm42a+gXzp38GeNnyA== Received: from AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) by AM5PR03MB2850.eurprd03.prod.outlook.com (2603:10a6:206:20::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4478.24; Mon, 6 Sep 2021 02:28:14 +0000 Received: from AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::787b:2156:ca99:fe00]) by AM7PR03MB6660.eurprd03.prod.outlook.com ([fe80::787b:2156:ca99:fe00%3]) with mapi id 15.20.4478.025; Mon, 6 Sep 2021 02:28:14 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Mon, 6 Sep 2021 04:27:40 +0200 Message-ID: X-Mailer: git-send-email 2.30.2 In-Reply-To: References: X-TMN: [qBr70g3eqxXrxzl9FGOplJ7WKP7gYNie] X-ClientProxiedBy: PR1PR01CA0033.eurprd01.prod.exchangelabs.com (2603:10a6:102::46) To AM7PR03MB6660.eurprd03.prod.outlook.com (2603:10a6:20b:1c1::22) X-Microsoft-Original-Message-ID: <20210906022802.4072793-1-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from sblaptop.fritz.box (188.192.142.38) by PR1PR01CA0033.eurprd01.prod.exchangelabs.com (2603:10a6:102::46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4478.19 via Frontend Transport; Mon, 6 Sep 2021 02:28:13 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7716493a-a13c-42a4-1d40-08d970ddfa5f X-MS-Exchange-SLBlob-MailProps: EpEO96k6WomN+6scf6kWJwiB5ULWQzCZb7AFnZzxkN6f0+Kfp5aicT2WC2llf5sYvGHVA3vowZSuOEoI4RR7HW2jzYoZawQ3O46t+tpcyo206J4clvpqV29PqYGvO6gUTOvyWWpNpyMjm1xorc8xsBFQds4r5A788Rbmg3S1aqQ2cUscHAJVivnM4MKJm60qBw4+RE+R71YYu0t12VxX4snlifSG8URVykeTlpBxuZvawOXZSRTH4PZjG+oyyNhs4kqXNR6/fK4Znls8BEkZ/9LPRZdbrP/l5vngNDWxNUojI9NDn8CkGlUB0dR9nysl1MuvAh1RgE4LjjNXJ9z5oIjgObcT76gwaopNMl5dkrCpat/ooSRnsNsTY16Wxh7F5kBTkfKeICMSz395bMMPZifvYM8+j2/uti9aRKyAMWnHQfj9TR6e8wED2/aas1nPL6cCYpHwlV8m/TZsQuJgqKLpNyR/vKU+KlKJ3zZfTKJcpxAR0QTADJvfMOivOF37LLkV/f7OWly83ZyOPvEHpyG7Vk+ye8GATeT3Ep7Sz8QQnrBp4LcYpKxZ6obmLfXAieKlt7O+wVcGJp0SRU8V0yS1fjEcJC/TP/IvprXN3JVhFhQnBXzbt/8cn1rRZmGIuL8nMUyo75zVdOS9k7xnz06akTrvOcBHIia0E3Pl64ix/SaGJOuje2LYibEIKzyaidZEsjfQiyoi4bWRzLXdaKt6Td+HwK4/t4JS11bmgcq+3+9jpX4u/KM4ZhIpOTMkXmkpYicgH7Y= X-MS-TrafficTypeDiagnostic: AM5PR03MB2850: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +O+HHfBf/atHCDJQlhZWYTfAvH2tOO9G8gdUnPaFKtVXKaCJxHd/EjHAAt9r4dp0drjGtfnCHwA+ozhI2ZMtF+itkaLCXO6kRoHmnqOksvOrwBYBkYKL+1RP9/srXmmhJkpd712f81Wjauu7kqdAFqe1pazn8p1M1928hgmvuVuHsg4NoCW5fBZ+vrELw/OkHweX6e/7waleYuE7QVU1EFPMnF2F684DvS5cpiptRlfm2NlZkTjJlBeoNFnLcRJ2uYCA2QM2NySNaew8A5eAZw6+ECMZiIIp32OHKFiifsJhZYKqLZwPUv3UUKzFmjqxwhZnhKHRmaH+GYbMnDEPJxjeDERAcg1GAF1qVekYicar78sAXt43rvqUeA5csczoRMuMSY31O5pZaIqf3LDNp1NhFDind+q1BE6E9mD3F/HM41BCznjXUMSv7fmGYx/k X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: W0EbTWW7S0OrQPs7ux7J+uDjdTdRYKUeLoCD+AlVYTIELXWb/bf7VzE96Fy3D5Ir3hRq7bCaJmVM6MDMf+WZVdUnDRip709PainZr6DR6P07ZSWvaSG9g5q5nBmcO57zJInw7EyjkAk3iWZQUIFaug== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7716493a-a13c-42a4-1d40-08d970ddfa5f X-MS-Exchange-CrossTenant-AuthSource: AM7PR03MB6660.eurprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 06 Sep 2021 02:28:14.3601 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR03MB2850 Subject: [FFmpeg-devel] [PATCH 12/34] avformat/mux: Don't use stack packet when writing interleaved packets 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 Cc: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 6KTofYpVlATA Currently the interleave_packet functions use a packet for a new packet to be interleaved (may be NULL if there is none) and a packet for output; said packet is always a stack packet in interleaved_write_packet(). But all the interleave_packet functions in use first move the packet to the packet list and then check whether a packet can be returned, i.e. the effective lifetime of the new packet ends before the packet for output is touched. So one can use one packet both for input and output by adding a new parameter that indicates whether there is a packet to add to the packet list; there is just one complication: In case the muxer is flushed, there is no packet available. This can be solved by reusing one of the packets from AVFormatInternal. They are currently unused when flushing in av_interleaved_write_frame(). Signed-off-by: Andreas Rheinhardt --- libavformat/avformat.h | 18 ++++++++++++++--- libavformat/gxfenc.c | 7 ++++--- libavformat/internal.h | 19 ++++++----------- libavformat/mux.c | 46 ++++++++++++++++++------------------------ libavformat/mxfenc.c | 9 +++++---- 5 files changed, 50 insertions(+), 49 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 9b560c15be..7262ce8c5b 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -553,9 +553,21 @@ typedef struct AVOutputFormat { /** * A format-specific function for interleavement. * If unset, packets will be interleaved by dts. - */ - int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, - AVPacket *in, int flush); + * + * @param s An AVFormatContext for output. pkt will be added to + * resp. taken from its packet buffer. + * @param[in,out] pkt A packet to be interleaved if has_packet is set; + * also used to return packets. If no packet is returned + * (e.g. on error), pkt is blank on return. + * @param flush 1 if no further packets are available as input and + * all remaining packets should be output. + * @param has_packet If set, pkt contains a packet to be interleaved + * on input; otherwise pkt is blank on input. + * @return 1 if a packet was output, 0 if no packet could be output, + * < 0 if an error occurred + */ + int (*interleave_packet)(struct AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet); /** * Test if the given codec can be stored in this container. * diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c index 1a80ecb603..70a911673f 100644 --- a/libavformat/gxfenc.c +++ b/libavformat/gxfenc.c @@ -1008,10 +1008,11 @@ static int gxf_compare_field_nb(AVFormatContext *s, const AVPacket *next, (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order); } -static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) +static int gxf_interleave_packet(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet) { int ret; - if (pkt) { + if (has_packet) { AVStream *st = s->streams[pkt->stream_index]; GXFStreamContext *sc = st->priv_data; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) @@ -1022,7 +1023,7 @@ static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pk if ((ret = ff_interleave_add_packet(s, pkt, gxf_compare_field_nb)) < 0) return ret; } - return ff_interleave_packet_per_dts(s, out, NULL, flush); + return ff_interleave_packet_per_dts(s, pkt, flush, 0); } const AVOutputFormat ff_gxf_muxer = { diff --git a/libavformat/internal.h b/libavformat/internal.h index 9d7312c0e2..c3d0ff6b88 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -102,7 +102,8 @@ struct AVFormatInternal { struct PacketList *parse_queue_end; /** * The generic code uses this as a temporary packet - * to parse packets; it may also be used for other means + * to parse packets or for muxing, especially flushing. + * For demuxers, it may also be used for other means * for short periods that are guaranteed not to overlap * with calls to av_read_frame() (or ff_read_packet()) * or with each other. @@ -701,18 +702,10 @@ int ff_add_attached_pic(AVFormatContext *s, AVStream *st, AVIOContext *pb, /** * Interleave an AVPacket per dts so it can be muxed. - * - * @param s an AVFormatContext for output. pkt resp. out will be added to - * resp. taken from its packet buffer. - * @param out the interleaved packet will be output here - * @param pkt the input packet; will be blank on return if not NULL - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output - * (in which case out may be uninitialized), < 0 if an error occurred - */ -int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush); + * See the documentation of AVOutputFormat.interleave_packet for details. + */ +int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet); void ff_free_stream(AVFormatContext *s, AVStream *st); diff --git a/libavformat/mux.c b/libavformat/mux.c index dbcd3835c2..ea298c1221 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -898,8 +898,8 @@ static int interleave_compare_dts(AVFormatContext *s, const AVPacket *next, return comp > 0; } -int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush) +int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet) { PacketList *pktl; int stream_count = 0; @@ -907,7 +907,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, int i, ret; int eof = flush; - if (pkt) { + if (has_packet) { if ((ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts)) < 0) return ret; } @@ -999,8 +999,8 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, if (stream_count && flush) { AVStream *st; pktl = s->internal->packet_buffer; - *out = pktl->pkt; - st = s->streams[out->stream_index]; + *pkt = pktl->pkt; + st = s->streams[pkt->stream_index]; s->internal->packet_buffer = pktl->next; if (!s->internal->packet_buffer) @@ -1045,20 +1045,16 @@ const AVPacket *ff_interleaved_peek(AVFormatContext *s, int stream) } /** - * Interleave an AVPacket correctly so it can be muxed. - * @param out the interleaved packet will be output here - * @param in the input packet; will always be blank on return if not NULL - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred + * A wrapper around AVOutputFormat.interleave_packet. + * See its documentation for details. */ -static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush) +static int interleave_packet(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet) { if (s->oformat->interleave_packet) { - return s->oformat->interleave_packet(s, out, in, flush); + return s->oformat->interleave_packet(s, pkt, flush, has_packet); } else - return ff_interleave_packet_per_dts(s, out, in, flush); + return ff_interleave_packet_per_dts(s, pkt, flush, has_packet); } static int check_bitstream(AVFormatContext *s, AVStream *st, AVPacket *pkt) @@ -1080,20 +1076,18 @@ static int check_bitstream(AVFormatContext *s, AVStream *st, AVPacket *pkt) return 1; } -static int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt, int flush) +static int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet) { for (;; ) { - AVPacket opkt; - int ret = interleave_packet(s, &opkt, pkt, flush); + int ret = interleave_packet(s, pkt, flush, has_packet); if (ret <= 0) return ret; - pkt = NULL; - - ret = write_packet(s, &opkt); - - av_packet_unref(&opkt); + has_packet = 0; + ret = write_packet(s, pkt); + av_packet_unref(pkt); if (ret < 0) return ret; } @@ -1117,7 +1111,7 @@ static int write_packet_common(AVFormatContext *s, AVStream *st, AVPacket *pkt, if (interleaved) { if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) return AVERROR(EINVAL); - return interleaved_write_packet(s, pkt, 0); + return interleaved_write_packet(s, pkt, 0, 1); } else { return write_packet(s, pkt); } @@ -1237,7 +1231,7 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) return ret; } else { av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n"); - return interleaved_write_packet(s, NULL, 1/*flush*/); + return interleaved_write_packet(s, s->internal->parse_pkt, 1/*flush*/, 0); } } @@ -1256,7 +1250,7 @@ int av_write_trailer(AVFormatContext *s) ret = ret1; } } - ret1 = interleaved_write_packet(s, NULL, 1); + ret1 = interleaved_write_packet(s, pkt, 1, 0); if (ret >= 0) ret = ret1; diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 229817dba6..dd7b6314bc 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -3098,7 +3098,7 @@ static void mxf_deinit(AVFormatContext *s) } } -static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) +static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, int flush) { int i, stream_count = 0; @@ -3162,16 +3162,17 @@ static int mxf_compare_timestamps(AVFormatContext *s, const AVPacket *next, (next->dts == pkt->dts && sc->order < sc2->order); } -static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) +static int mxf_interleave(AVFormatContext *s, AVPacket *pkt, + int flush, int has_packet) { int ret; - if (pkt) { + if (has_packet) { MXFStreamContext *sc = s->streams[pkt->stream_index]->priv_data; pkt->pts = pkt->dts = sc->pkt_cnt++; if ((ret = ff_interleave_add_packet(s, pkt, mxf_compare_timestamps)) < 0) return ret; } - return mxf_interleave_get_packet(s, out, NULL, flush); + return mxf_interleave_get_packet(s, pkt, flush); } #define MXF_COMMON_OPTIONS \