From patchwork Thu Jun 8 14:20:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thilo Borgmann X-Patchwork-Id: 42008 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c526:b0:117:ac03:c9de with SMTP id gm38csp434348pzb; Thu, 8 Jun 2023 07:21:05 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5nYly6H8UOOxKUQM33LYZGtY/Al86fxa5yAKT0HvEvWabXPPLyBftbVrj1mGVO5Mzq5rIu X-Received: by 2002:a17:907:8a1a:b0:977:bf02:b158 with SMTP id sc26-20020a1709078a1a00b00977bf02b158mr9723198ejc.10.1686234064835; Thu, 08 Jun 2023 07:21:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686234064; cv=none; d=google.com; s=arc-20160816; b=G/mR+gptH30mcOjxrmMpWmCMQUPCwbAHb9pssoOFxp/MhSFQTjWbKhYLDT82lfB3i4 6ceWcA8OtfLeq98krvHfRx7asDc1BIKA4IO4r8UYeHze441Ss0vrQ9JJb5Tz5+8sehbZ wiU1649xjaMtU7mFYDfrZxx5aDJPVobU8QypppkmZiy5CIdTEPLpy4bRN40yFAkSLx8j EO9hnV4ObIzrO83z0dWfrQXIcyaM2aSIbM7saIvB4HNVO/XCcDgBNRKtp8UWfSgvqCAO Ih2KRZR9mR41JNt11kGX6mL2WfyH3xMSiVUgWml3QYCihBa/G5Mwlma5Pije/jA0UUSs jxcw== 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:dkim-signature:delivered-to; bh=eLfssWoVam8mJfbkxDH4oodYcBhJy912Q1oaTofHGrs=; b=XH/eo18LQY1FFk++ig8U9FrJYUsOrO5cHjy7aAtWLVlR7OGXWY1ufO7/dKqivC/ker jL2WnMGSrNPCIn/bFp5eeXgqRkQjoUiEGyai8ISNAL5NHlL1IWtSs/JZlWX+cw4fhoQn wzyeCkqeBvMHGbTgfsfcwJcp8VX6opjmkpuySDGkjojuF3HbPjjGF15Fu5jhtep+wEzJ E+vE6m/hVEarx9HLsWeu86kYILZrWtlMU1Wtln7A8wXK871k01z1Zb6lrKtM3hzxhBdr 6ynDmPh5xAqvU/zg9ixVhbEEn2hNIYUalBdv9ToRSHh7qjOGPgB9Fcmu/TU0TPLrHvhF MM1g== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@mail.de header.s=mailde202009 header.b=wBrz9Y2J; 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=NONE dis=NONE) header.from=mail.de Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g9-20020a170906868900b009745eb4fa51si1009032ejx.98.2023.06.08.07.21.04; Thu, 08 Jun 2023 07:21:04 -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=@mail.de header.s=mailde202009 header.b=wBrz9Y2J; 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=NONE dis=NONE) header.from=mail.de Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B0D4F68C2EE; Thu, 8 Jun 2023 17:20:39 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from shout02.mail.de (shout02.mail.de [62.201.172.25]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id D124068B896 for ; Thu, 8 Jun 2023 17:20:31 +0300 (EEST) Received: from postfix03.mail.de (postfix03.bt.mail.de [10.0.121.127]) by shout02.mail.de (Postfix) with ESMTP id 717BAA0635 for ; Thu, 8 Jun 2023 16:20:31 +0200 (CEST) Received: from smtp01.mail.de (smtp01.bt.mail.de [10.0.121.211]) by postfix03.mail.de (Postfix) with ESMTP id 5A43280167 for ; Thu, 8 Jun 2023 16:20:31 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mail.de; s=mailde202009; t=1686234031; bh=xQheYRATXB4BcI9cqWFYQPNSM3MXnD0AreygwU3Yav4=; h=From:To:Subject:Date:Message-Id:From:To:CC:Subject:Reply-To; b=wBrz9Y2JEmTpwFMnwuu0lhUFSc0KtSvL/j5wbMrIi8LmLc9xt+1KO211hZsJAKCkr mnYQQpCG6QP8NHkZUlugxFkWT5X0Xt8NshHjrgElugRJViQmOkz7d5OI3RW8mRj+97 TC579fNBcrdmmeAiyz7J42+qXbHpppqXXD35m7aqUXriosLYNERLUFK1oDvbddDPWz 9khQuD1p+0040UP8c2jvHgcp8bB5JIvglsmvSIYc4nD6ja2NE/D0ksgQqskgVdYxk2 cTHrezBI5ncX88eZaRfgbmC55UHZxS+/APWYzReMECoPpY+4PxxgZU++UtgE5hnGQo 0GpLRuasz3CFw== Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by smtp01.mail.de (Postfix) with ESMTPSA id 17500100462 for ; Thu, 8 Jun 2023 16:20:31 +0200 (CEST) From: Thilo Borgmann To: ffmpeg-devel@ffmpeg.org Date: Thu, 8 Jun 2023 16:20:27 +0200 Message-Id: <20230608142029.16564-3-thilo.borgmann@mail.de> In-Reply-To: <20230608142029.16564-1-thilo.borgmann@mail.de> References: <20230608142029.16564-1-thilo.borgmann@mail.de> MIME-Version: 1.0 X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate: clean X-purgate-size: 6672 X-purgate-ID: 154282::1686234031-077FA7B6-4B2A3693/0/0 Subject: [FFmpeg-devel] [PATCH v1 2/4] avcodec/webp_parser: parse each frame into one packet 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: h2S/8B7bCKu2 --- libavcodec/webp_parser.c | 132 ++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 42 deletions(-) diff --git a/libavcodec/webp_parser.c b/libavcodec/webp_parser.c index bd5f94dac5..d10d06bd0e 100644 --- a/libavcodec/webp_parser.c +++ b/libavcodec/webp_parser.c @@ -25,13 +25,17 @@ #include "libavutil/bswap.h" #include "libavutil/common.h" +#include "libavutil/intreadwrite.h" #include "parser.h" typedef struct WebPParseContext { ParseContext pc; + int frame; + int first_frame; uint32_t fsize; - uint32_t remaining_size; + uint32_t remaining_file_size; + uint32_t remaining_tag_size; } WebPParseContext; static int webp_parse(AVCodecParserContext *s, AVCodecContext *avctx, @@ -41,62 +45,106 @@ static int webp_parse(AVCodecParserContext *s, AVCodecContext *avctx, WebPParseContext *ctx = s->priv_data; uint64_t state = ctx->pc.state64; int next = END_NOT_FOUND; - int i = 0; + int i, len; - *poutbuf = NULL; - *poutbuf_size = 0; - -restart: - if (ctx->pc.frame_start_found <= 8) { - for (; i < buf_size; i++) { + for (i = 0; i < buf_size;) { + if (ctx->remaining_tag_size) { + /* consuming tag */ + len = FFMIN(ctx->remaining_tag_size, buf_size - i); + i += len; + ctx->remaining_tag_size -= len; + ctx->remaining_file_size -= len; + } else { + /* scan for the next tag or file */ state = (state << 8) | buf[i]; - if (ctx->pc.frame_start_found == 0) { - if ((state >> 32) == MKBETAG('R', 'I', 'F', 'F')) { - ctx->fsize = av_bswap32(state); - if (ctx->fsize > 15 && ctx->fsize <= UINT32_MAX - 10) { - ctx->pc.frame_start_found = 1; - ctx->fsize += 8; + i++; + + if (!ctx->remaining_file_size) { + /* scan for the next file */ + if (ctx->pc.frame_start_found == 4) { + ctx->pc.frame_start_found = 0; + if ((uint32_t) state == MKBETAG('W', 'E', 'B', 'P')) { + if (ctx->frame || i != 12) { + ctx->frame = 0; + next = i - 12; + state = 0; + ctx->pc.frame_start_found = 0; + break; + } + ctx->remaining_file_size = ctx->fsize - 4; + ctx->first_frame = 1; + continue; } } - } else if (ctx->pc.frame_start_found == 8) { - if ((state >> 32) != MKBETAG('W', 'E', 'B', 'P')) { + if (ctx->pc.frame_start_found == 0) { + if ((state >> 32) == MKBETAG('R', 'I', 'F', 'F')) { + ctx->fsize = av_bswap32(state); + if (ctx->fsize > 15 && ctx->fsize <= UINT32_MAX - 10) { + ctx->fsize += (ctx->fsize & 1); + ctx->pc.frame_start_found = 1; + } + } + } else + ctx->pc.frame_start_found++; + } else { + /* read the next tag */ + ctx->remaining_file_size--; + if (ctx->remaining_file_size == 0) { ctx->pc.frame_start_found = 0; continue; } ctx->pc.frame_start_found++; - ctx->remaining_size = ctx->fsize + i - 15; - if (ctx->pc.index + i > 15) { - next = i - 15; - state = 0; - break; - } else { - ctx->pc.state64 = 0; - goto restart; + if (ctx->pc.frame_start_found < 8) + continue; + + switch (state >> 32) { + case MKBETAG('A', 'N', 'M', 'F'): + case MKBETAG('V', 'P', '8', ' '): + case MKBETAG('V', 'P', '8', 'L'): + if (ctx->frame) { + ctx->frame = 0; + next = i - 8; + state = 0; + ctx->pc.frame_start_found = 0; + goto flush; + } + ctx->frame = 1; + break; + default: + break; } - } else if (ctx->pc.frame_start_found) - ctx->pc.frame_start_found++; - } - ctx->pc.state64 = state; - } else { - if (ctx->remaining_size) { - i = FFMIN(ctx->remaining_size, buf_size); - ctx->remaining_size -= i; - if (ctx->remaining_size) - goto flush; - ctx->pc.frame_start_found = 0; - goto restart; + ctx->remaining_tag_size = av_bswap32(state); + ctx->remaining_tag_size += ctx->remaining_tag_size & 1; + if (ctx->remaining_tag_size > ctx->remaining_file_size) { + /* this is probably trash at the end of file */ + ctx->remaining_tag_size = ctx->remaining_file_size; + } + ctx->pc.frame_start_found = 0; + state = 0; + } } } - flush: - if (ff_combine_frame(&ctx->pc, next, &buf, &buf_size) < 0) + ctx->pc.state64 = state; + + if (ff_combine_frame(&ctx->pc, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; return buf_size; + } - if (next != END_NOT_FOUND && next < 0) - ctx->pc.frame_start_found = FFMAX(ctx->pc.frame_start_found - i - 1, 0); - else - ctx->pc.frame_start_found = 0; + // Extremely simplified key frame detection: + // - the first frame (containing headers) is marked as a key frame + // - other frames are marked as non-key frames + if (ctx->first_frame) { + ctx->first_frame = 0; + s->pict_type = AV_PICTURE_TYPE_I; + s->key_frame = 1; + } else { + s->pict_type = AV_PICTURE_TYPE_P; + s->key_frame = 0; + } *poutbuf = buf; *poutbuf_size = buf_size;