From patchwork Thu Jul 20 23:07:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thilo Borgmann X-Patchwork-Id: 42878 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:672f:b0:130:ccc6:6c4b with SMTP id q47csp144647pzh; Thu, 20 Jul 2023 16:08:39 -0700 (PDT) X-Google-Smtp-Source: APBJJlEliz+L9g/N1t9cfAXIeRy1hWoqkDS9K+80fUoW4yFYc0V07vWW3j0i5hlDajTSN+NPGO2s X-Received: by 2002:a05:6402:1646:b0:51e:1093:3a9f with SMTP id s6-20020a056402164600b0051e10933a9fmr213560edx.11.1689894518923; Thu, 20 Jul 2023 16:08:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689894518; cv=none; d=google.com; s=arc-20160816; b=uXbxzSsPIhOjokGRu6HhPW0/87IEb2fce5ywwPuVEScb5PA+nEkjJfxXgVZ94SWSsJ E/ky4fLVkeYpDYUw/gCxOWGL5CTA88aEEXbZrWqxyl+vv4XGeHhctsOYjX/1+BRrcOuR bg7CMFsqAWPbtgcrgavETSrvJ+2t2gsQQ/8GI4JcgfV5PCoWeeKYnDLYBvg3YdzpChN4 jyUyvV22yB4ImZocHHG4i45/nCQWd4ojmjr7iwTLCN7NQsbhu4HxdN+kB78VvYI4rqeJ g6RSp6jLmLM3CUCkDJwLUjTH+uptQqwUg8f5/MUXVoK5mgbsdKZ7JAkxXRByvKp7/Q88 6MRA== 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=kjnIlu+46juVopWYbYKp4bNgWlSHVpUdoTn8YUrfeLc=; fh=HD4ndZ9hLL4mcfDFnlTmTEEgN7ZZ8c1Zu9bV17rPaE8=; b=hdSxvHSNMV3jGp+pB1quvQ8TIqk8ONOm0pQefWArNJISyVJi6qjFkcXyiDcD/rHRl5 sh9NFpbboE9IWefc/qo/DZiNqZkUFeXZw01PZ469RXb5ssslthqoBajlLjOGouqgbkL2 gjDswY7Um4OrRdC1+4WgdQ2Pk3YsjLYr2XUiS4QGarNgsij9dho3kEFvFtdkDcpJws+S UAn/7r1CQF4h8OdLVRMJiNq7L85VIFRLFD/3k/Z3K93tFooKKWReWPex+yB55BE0R0Xx 8zbpLTvYDiCOZCu62vnLPJgMCUWsGiEoIbYTopOT4LdKuqICGVgrp2SL/gr6TlOW7GN2 4NoA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@mail.de header.s=mailde202009 header.b=4yHid0hn; 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=QUARANTINE sp=QUARANTINE 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 w10-20020aa7dcca000000b005217421a386si1429325edu.201.2023.07.20.16.08.38; Thu, 20 Jul 2023 16:08:38 -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=4yHid0hn; 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=QUARANTINE sp=QUARANTINE 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 017C868C679; Fri, 21 Jul 2023 02:08:06 +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 337ED68C637 for ; Fri, 21 Jul 2023 02:07:54 +0300 (EEST) Received: from postfix02.mail.de (postfix02.bt.mail.de [10.0.121.126]) by shout02.mail.de (Postfix) with ESMTP id 22E53A0A6C for ; Fri, 21 Jul 2023 01:07:54 +0200 (CEST) Received: from smtp04.mail.de (smtp04.bt.mail.de [10.0.121.214]) by postfix02.mail.de (Postfix) with ESMTP id 0AB12A00E2 for ; Fri, 21 Jul 2023 01:07:54 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mail.de; s=mailde202009; t=1689894474; bh=3Zbx0i+bRtlSwUiJQz77Tuzi17XuKmB92hijIOT5GWc=; h=From:To:Subject:Date:Message-Id:From:To:CC:Subject:Reply-To; b=4yHid0hnSEovuTue3pN0wxoYfO2tgXV7nbYOz4SIYeRHWCw9Oa34z4uKWI4PYISv1 LlVsh0iHou+Axc5UxfLeiYTGaTTj6QveLbUL+gYjVIPPxMqZ+ViZWXFAn5KJgspaYa jHjp0qU/d0P0cqDQU1USg5A0UxRfG/kn8PxHF9UCXGGgDdFYK5AVMFwQ23rhnI6/u2 bexS9mlo8olBaOPwqOLKNf0VQTbTrNFKq0RLRCJDoCNlQNF4hkgS99YPIx8X2Ccv70 azJBjkRXw/8H0BAucsZetvEmvE105K2jUT1sH/1tD8Er4fICD+xJcLICWuiZW2J2lq X+MlvSTJ11fUA== 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 smtp04.mail.de (Postfix) with ESMTPSA id CC072C009A for ; Fri, 21 Jul 2023 01:07:53 +0200 (CEST) From: Thilo Borgmann To: ffmpeg-devel@ffmpeg.org Date: Fri, 21 Jul 2023 01:07:49 +0200 Message-Id: <20230720230752.68246-4-thilo.borgmann@mail.de> In-Reply-To: <20230720230752.68246-1-thilo.borgmann@mail.de> References: <20230720230752.68246-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: 6596 X-purgate-ID: 154282::1689894473-DA7FEC09-8C341DF2/0/0 Subject: [FFmpeg-devel] [PATCH v3 3/6] 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: KwgZ5s7LDGkj --- libavcodec/webp_parser.c | 130 +++++++++++++++++++++++++++------------ 1 file changed, 89 insertions(+), 41 deletions(-) diff --git a/libavcodec/webp_parser.c b/libavcodec/webp_parser.c index bd5f94dac5..da853bb1f5 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; + 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 { - ctx->pc.state64 = 0; - goto restart; } - } 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 might be truncated remains before 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;