From patchwork Fri Nov 3 16:11:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 44497 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:671c:b0:181:818d:5e7f with SMTP id q28csp661724pzh; Fri, 3 Nov 2023 09:10:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG3a5xt1YPA2zThm7G5pTUW2o/dAcjA7b/sxrebH+rmLm7vXsmJ7kpdY8aFB9BlCN5znRHd X-Received: by 2002:a50:9b5e:0:b0:542:fe59:2234 with SMTP id a30-20020a509b5e000000b00542fe592234mr3361427edj.6.1699027807452; Fri, 03 Nov 2023 09:10:07 -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 d21-20020a056402079500b005401adf8d10si1054623edy.684.2023.11.03.09.10.07; Fri, 03 Nov 2023 09:10:07 -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="Fz0jglS/"; 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 1EF0B68C8C6; Fri, 3 Nov 2023 18:09:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01olkn2042.outbound.protection.outlook.com [40.92.65.42]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E235B68CBE7 for ; Fri, 3 Nov 2023 18:09:53 +0200 (EET) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oPtAS8EE3rTx0Z1cfSOgsBqhsAmelGoEQXsjKpmwmYWRtcwjnTGIwA8qO2ackbBfdurYwTrnx0ECX7lU61Ggdiac4cmjE462PcOzjMlp6fjAssXHGjcKIFeOKw6PU2zOKwdApvbMm7YA9WpyfRWzL1Bv0gAg9QYLNYCnPwGCMk0RbmUY8kHEFi/9B1F5YFxIuvNjY857yFSrS1yOCjRQB5ZnfLGUp/gUe6Mg98eaTMmYBzcaaL6MMZM40ZDe17yNwct+KpghdgosQ69nRthSIcPzzYkG9C1nxqDI5xVEyryLWztj07ahU8xc2bPEdCFKAIpU9KKNHZmPYZDzV+gO+w== 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:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=FUMYXZpLNmrLJSqzeJRfvcMlRMMd1wSeL/86SI8gM1o=; b=lVLBWj0V9iezItEG1IBRAihzFyWqYdquQX5Eay3UJx1LUELnnlmZtqgS5C/3CvC2bmwZrR15WGCh/iO/1eEQyG3nMoQAPymmnaXHprBtba1Ou2LW4TyLBziHOxZTvjwEpLurldAv0dfkn5wMxxQuUCG6IZ1zJBEv6YT5Nx45N1/AMxrxfClKuqReg5J3cgEFunlAOqLKx6N/3JB03wJJ1DmFgpIWSqMKSF0ynkBi/dTrDDAnaGfA9aNh8Vsfif0Rfx5EbocUGOFurrbdGvSE8sPdrRaDkkWJJZrT1s/1xHg1F14XpRLkZN+9OVDsnuqD2XPslyq09o+l7K20SqQHCg== 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=FUMYXZpLNmrLJSqzeJRfvcMlRMMd1wSeL/86SI8gM1o=; b=Fz0jglS/vq+QafXC0Hk5hGMlbkh7kOGf+SXViFKiKbcv+CfgRBHuaQhjEOXdhqvBQtfLOIUCWtIhzEBqmkRCUCZojAuNf2AgWGQOJcNNFkseevwVeBuOShKjBBNOAX1b23ozQ7sqqlivbhLIQg9RACFUjdQTYllcCfoA2+JjcQpfi4cDcDEpY8uRkyod23nUvPwaRJPYQ0J5IibRGQve5kGU/i1v9EyTPKOopFCshXyGxomZiw0qgfRlLaNoVplC4tEnZTQrHmsHxzJAjGSztIZR2N5MKukqJMUlmOsP7lEQ7hb0Meck6zuPspChRT1hructX05YEaR6JBqT8wEdIQ== Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) by AS8P250MB0331.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:37e::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6954.21; Fri, 3 Nov 2023 16:09:48 +0000 Received: from AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::f59c:9cff:a42d:bde]) by AS8P250MB0744.EURP250.PROD.OUTLOOK.COM ([fe80::f59c:9cff:a42d:bde%3]) with mapi id 15.20.6954.020; Fri, 3 Nov 2023 16:09:48 +0000 From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Fri, 3 Nov 2023 17:11:01 +0100 Message-ID: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: X-TMN: [iHoMj9Bxx1MjMO6eSSZEDwoH4uiV2r9tuFffo23BuAA=] X-ClientProxiedBy: ZR0P278CA0104.CHEP278.PROD.OUTLOOK.COM (2603:10a6:910:23::19) To AS8P250MB0744.EURP250.PROD.OUTLOOK.COM (2603:10a6:20b:541::14) X-Microsoft-Original-Message-ID: <20231103161101.81135-2-andreas.rheinhardt@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: AS8P250MB0744:EE_|AS8P250MB0331:EE_ X-MS-Office365-Filtering-Correlation-Id: 5de03ef7-91a5-429f-72b5-08dbdc874daf X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: LD4DKLmdcE0KVOHu+9CDAgqWwKR+ltOFYhAWYkzh6nX5r7jJnooJHcvjrMEKhsyQSQUyfeJXj6Ao3h0LUXBgf060ZKNus544rNJgTzJMjYrcKiAhKUPGW3tEcFyA1A2DabRPlXHN8g1Qs4EncRujCSiJPQJc6eFieABQdQKR0/zfTVZKVdGMhYVC+zAk50YbWVx4SnctGrqPQXM29UgbDLYOOcseJBBmQTS20QKtwigWcvtd6G8iB5rFUluiuEE31PJ/VO9Ymc3gGRy7NXZas5auPrjI1Tliw6KdFN/4UhwSp2885TJEptVDuXpLSqwkF81+CoUtY2xlIUY31W+g2pzBnj2CKGdwzsUtAyIP2YfjCUXl8KZrxAxEjt5/ZYNGP6wEeXbNq/zfF+q7vCgAqOlgt5pZuz92o8b7jMsK4Nx9pN27EaD4QRnpZglvL5MI3r6LQUvfSIFdSV0h+VWMIazH4mE8WmHXOkGRbqrPnLIYAOOWUz1XCsJaTiVSAJL5SgCSvqOmC3GCFHJGyo7xTi1QQTr2jQVdEAaSwXD2K2eOLrR7ybLRDXGIeQ4IzQRy7iFcPrMy1yJNIyHqW1nG7dEKz1ixF45JQoQtouJhu4P508My/ISfm/Sb7y1BB0KR X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: m8W3RjGZmpcBx0E19X1/DM2T7BeOICHJQXHvoqQpE0dpHlvhB+WS5zPfIb7nLyIfoDMTEopPfSHJECbLzdSlXuY1wjxj1oVBtyKmUtsq7l8a9gndi1sV9TdLXNgtWpwJbItJKK9Uhkij1SjFE9AiHgTYCDN1ubtjfYXivRi9BnpQ+6t8P5Q0y8xzu+Dgpmu5261vJWqV0c6ZvdakquC5aTeuwlnHFLA056dnYeTgR1ptUVUf/QU2cq3wp7ks+p9pB4OVw3pwSllsAvSGBdlQrgCxdPwxXjFm3iLzosIiRDJc3L9vhEpDXeiIapAy/97cakA4d0Gnzogl16d9IsTRaeQV3OPqhsGPekPGngAoX91piETLw04DGdxTAdAPEb1RafnRdYekjiwRNrWGa2MrcUa2U+TzY0JgN+SJF4doXfQ6SyS7xJDkYH9eUQhshFD9h5qWpw5CfpclFgupW78ssFM6dIDjqlWJv2mgvHBcI5Z21CK55xv7r6NTv0vqT5e4c05alSewK6X4FJTQg6HYMC8IdPn2b7gHe+f+AQGxTsoj6Zv58pA+AaTD3utKqvhN+8Ha5eDho7Gi2k0Yd3tjLuq7uJlt9KRTt75gxqAtJkCytAd8W+MQZCwLML1TFrcuGXhYDTDpOEMx6bfBAEIti/hgyAKnJq7Xfu4ae5INvaSasVZWnjnKP/vPoPbkFb542AMpld3aMEVqzScYxs8NWBwkNrgvpNcvpkvffWQEXB5rKhAn0GU4ks1WE4e1xh4Gu7RrBSc9Ik6WZInJkgVwJCsl9ga1HHzi25xkFIo3YNTS3N0yDnXKTXjd6F7tn+5Ldg1jc4kQc1daCq+GWa7Yzy5j3fE+963zn/a+KymSI8uKLMloiVmFxi93wT8hU1l7PPxTfSdnhLD58iYus+0q+XdUpu2S3O7JrpjkRkUFqTn+7Ddbd1Niw4Elp2mjtlvOrgn2vTpnh1FWHN3YZtZ9MTTeYfrNm5QTvwCnAR/abg2e51jzPlNXuOZCt9E9KRfZ5c//zFpc5e0Rhkvl9pVm8idDMyyqV2Tz2O0Ld9QfbM8O+dThTbe8mscYl4KRunSNAou3jjG5IQp9Ty47B31j4L6SpSBcZ9vTQTgKqmkQdGHEEdVlTa66/c+G+hZfQS6wHqSDF8q3FVrLo7Zv+za6+n/fIys13B70I5w8w00ud6LlNi7asS3G3Ra1GL9V99driZ2wtoylcafTeydMkfYfhI2kb3BIjZX3g0XP2XNTudzrrDGwXH5jflOJ86ExF5xa X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5de03ef7-91a5-429f-72b5-08dbdc874daf X-MS-Exchange-CrossTenant-AuthSource: AS8P250MB0744.EURP250.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Nov 2023 16:09:48.7591 (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: AS8P250MB0331 Subject: [FFmpeg-devel] [PATCH 3/3] avformat/webpenc: Write correct size for single images when unseekable 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: L2R6XTcaZZ5F The earlier code writes the file and then tries to patch up the size later. This is avoidable for the common case of a single image because one can know the complete size in advance and write it. Fixes ticket #4609. Signed-off-by: Andreas Rheinhardt --- libavformat/webpenc.c | 68 ++++++++++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c index d4acea7ba6..ea7a321975 100644 --- a/libavformat/webpenc.c +++ b/libavformat/webpenc.c @@ -21,6 +21,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/opt.h" +#include "libavcodec/bytestream.h" #include "avformat.h" #include "internal.h" #include "mux.h" @@ -76,11 +77,16 @@ static int is_animated_webp_packet(AVPacket *pkt) return 0; } +/** + * Returns 1 if it has written a RIFF header with a correct length field + */ static int flush(AVFormatContext *s, int trailer, int64_t pts) { WebpContext *w = s->priv_data; AVStream *st = s->streams[0]; - int skip = 0; + uint8_t buf[12 /* RIFF+WEBP */ + 18 /* VP8X */ + + 14 /* ANIM */ + 24 /* ANMF */], *bufp = buf; + int writing_webp_header = 0, skip = 0; unsigned flags = 0; int vp8x = 0; @@ -97,7 +103,10 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) } if (!w->wrote_webp_header) { - avio_write(s->pb, "RIFF\0\0\0\0WEBP", 12); + bytestream_put_le32(&bufp, MKTAG('R', 'I', 'F', 'F')); + bytestream_put_le32(&bufp, 0); /* Size to be patched later */ + bytestream_put_le32(&bufp, MKTAG('W', 'E', 'B', 'P')); + writing_webp_header = 1; w->wrote_webp_header = 1; if (w->frame_count > 1) // first non-empty packet w->frame_count = 1; // so we don't count previous empty packets. @@ -110,38 +119,41 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) } if (vp8x) { - avio_write(s->pb, "VP8X", 4); - avio_wl32(s->pb, 10); - avio_w8(s->pb, flags); - avio_wl24(s->pb, 0); - avio_wl24(s->pb, st->codecpar->width - 1); - avio_wl24(s->pb, st->codecpar->height - 1); + bytestream_put_le32(&bufp, MKTAG('V', 'P', '8', 'X')); + bytestream_put_le32(&bufp, 10); + bytestream_put_byte(&bufp, flags); + bytestream_put_le24(&bufp, 0); + bytestream_put_le24(&bufp, st->codecpar->width - 1); + bytestream_put_le24(&bufp, st->codecpar->height - 1); } if (!trailer) { - avio_write(s->pb, "ANIM", 4); - avio_wl32(s->pb, 6); - avio_wl32(s->pb, 0xFFFFFFFF); - avio_wl16(s->pb, w->loop); + bytestream_put_le32(&bufp, MKTAG('A', 'N', 'I', 'M')); + bytestream_put_le32(&bufp, 6); + bytestream_put_le32(&bufp, 0xFFFFFFFF); + bytestream_put_le16(&bufp, w->loop); } } if (w->frame_count > trailer) { - avio_write(s->pb, "ANMF", 4); - avio_wl32(s->pb, 16 + w->last_pkt->size - skip); - avio_wl24(s->pb, 0); - avio_wl24(s->pb, 0); - avio_wl24(s->pb, st->codecpar->width - 1); - avio_wl24(s->pb, st->codecpar->height - 1); + bytestream_put_le32(&bufp, MKTAG('A', 'N', 'M', 'F')); + bytestream_put_le32(&bufp, 16 + w->last_pkt->size - skip); + bytestream_put_le24(&bufp, 0); + bytestream_put_le24(&bufp, 0); + bytestream_put_le24(&bufp, st->codecpar->width - 1); + bytestream_put_le24(&bufp, st->codecpar->height - 1); if (w->last_pkt->pts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE) { - avio_wl24(s->pb, pts - w->last_pkt->pts); + bytestream_put_le24(&bufp, pts - w->last_pkt->pts); } else - avio_wl24(s->pb, w->last_pkt->duration); - avio_w8(s->pb, 0); + bytestream_put_le24(&bufp, w->last_pkt->duration); + bytestream_put_byte(&bufp, 0); } + if (trailer && writing_webp_header) + AV_WL32(buf + 4, bufp - (buf + 8) + w->last_pkt->size - skip); + avio_write(s->pb, buf, bufp - buf); avio_write(s->pb, w->last_pkt->data + skip, w->last_pkt->size - skip); av_packet_unref(w->last_pkt); - return 0; + return trailer && writing_webp_header; } static int webp_write_packet(AVFormatContext *s, AVPacket *pkt) @@ -185,11 +197,13 @@ static int webp_write_trailer(AVFormatContext *s) if ((ret = flush(s, 1, AV_NOPTS_VALUE)) < 0) return ret; - filesize = avio_tell(s->pb); - if (avio_seek(s->pb, 4, SEEK_SET) == 4) { - avio_wl32(s->pb, filesize - 8); - // Note: without the following, avio only writes 8 bytes to the file. - avio_seek(s->pb, filesize, SEEK_SET); + if (!ret) { + filesize = avio_tell(s->pb); + if (avio_seek(s->pb, 4, SEEK_SET) == 4) { + avio_wl32(s->pb, filesize - 8); + // Note: without the following, avio only writes 8 bytes to the file. + avio_seek(s->pb, filesize, SEEK_SET); + } } }