From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <ffmpeg-devel-bounces@ffmpeg.org>
Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100])
	by master.gitmailbox.com (Postfix) with ESMTPS id 339F94E8B4
	for <ffmpegdev@gitmailbox.com>; Mon, 17 Mar 2025 17:50:11 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D6DC0687C16;
	Mon, 17 Mar 2025 19:49:32 +0200 (EET)
Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com
 [209.85.221.53])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BF9B5687BDE
 for <ffmpeg-devel@ffmpeg.org>; Mon, 17 Mar 2025 19:49:23 +0200 (EET)
Received: by mail-wr1-f53.google.com with SMTP id
 ffacd0b85a97d-3913d129c1aso3825585f8f.0
 for <ffmpeg-devel@ffmpeg.org>; Mon, 17 Mar 2025 10:49:23 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1742233763; x=1742838563; darn=ffmpeg.org;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:from:to:cc:subject:date
 :message-id:reply-to;
 bh=jm9auESIWoxDp+6yMpBGmT/dePnNS4XXgOaemIQLias=;
 b=gTTWrh5yfRvtOhkSHctCD2VfPkKH4N8JGLfZOr0soHwa6n/3TGHyL8Zx1EpheYnpSW
 UyU6Dv+508AJZTWpqBP6iclG3N7Phz7RseQyXzFQgQuBTTa2ihMzAqk57roFU19v3yyK
 TyxKwtz4vP4asF5WLlidQc78u5avO7SPpslvrClszGwqwyAHTHahTRm4KoEkp7q+hGSe
 u5xFYaywhnzLUc1ibqA5UM4T2s2irRF64m3EPxpoA0OftlKaXONRdJLi/I0q36puujel
 GEG+N75kUGSG6dly+YptkHNuSlYJpRGy7FZ/VutHt6M3v6q1fPMG0zdUQ06oB/s3G3a4
 99dw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1742233763; x=1742838563;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
 :subject:date:message-id:reply-to;
 bh=jm9auESIWoxDp+6yMpBGmT/dePnNS4XXgOaemIQLias=;
 b=pyWeu9jxia0VpuqdAThRibb4bqFh1R2inE9eNEZpDt/9nlccTcnlM2cgV/XQ42TZOD
 39X7C+QGsOO5ilfw+kmb3FHjWmGG7hrBPOZGmVwioNHi4PjPxlqvSkW7QMuH2FXfUQbB
 saSRJMbDlM8JUhQbzTlyFk1Ck6FLcbWUFTU92gZimntg3XfPzUWWm3ErNnVN0tCwrxBz
 JIKl5UwIQDw7mOifyIiR7SdCqiaHeaPLwCtw539JQvW1UesrG3W1HfXTZYzpaYqlSgRo
 exbrnIUgKrZI5HyAcFvgc6zZiE6w4CzpAje7OPfXF1juBix3DGeT+/ywWA3zTDCjx2NR
 eJXg==
X-Gm-Message-State: AOJu0YxygfHZfcJUoRQIuP6/HHtf2JXXxgawaRwquvMbNJeLdJe+A60x
 hzNzMys5YUHnEcAEg7eDjYG1r2tazs5CNg0Ly+dWP/Vxyqw9Fv+RL1Fb80rG
X-Gm-Gg: ASbGncvRVjnYUl3K8Z7+FqcElA4ba6u+2zjD6/Q7FUstHGGg6+zl1E7iZB8+xmL+TWS
 M6kHrFBY3pMPjIRAahQ9sSZIwmd17SAWdvRVRlpVXEU/BMZ3vdFQt7aL4qeqVg0J0diR7r4BSAE
 WHaMLc/wex5iSWO6ft/S1sy6yz/yrO4Kpwh8ozyW2abLpkE3s4Ov946Nj19nO8+zEn+SLyEj5be
 fxURuJYb7CYXfktU6tlkS7roxh5lDhbZr5ZgKgkmIy43DHSnP2ufAMCISCp1aGybgi+tjXIcpDh
 cdyur6w9Kkb25ZvB2M8bbzYvHuniplSNAfjTagKOFCpYYVTyUW0af4JO6ev5EuuPfcPJXYJMswl
 Z3QndSrqjopMUHEBicVtSNHvk+Y2h1g==
X-Google-Smtp-Source: AGHT+IEn8fl/rseeLAxIgEaOH1qUzl0JmIAFJByapxkCK+PvnyfI90xz97naAEbkOwoWYtnh3ECt8g==
X-Received: by 2002:a05:6000:4022:b0:391:2e6a:30fa with SMTP id
 ffacd0b85a97d-3996bb82787mr252072f8f.27.1742233762980; 
 Mon, 17 Mar 2025 10:49:22 -0700 (PDT)
Received: from flagship3.deu.mlau.at (p54bc8686.dip0.t-ipconnect.de.
 [84.188.134.134]) by smtp.gmail.com with ESMTPSA id
 ffacd0b85a97d-395c7df35ecsm15809347f8f.16.2025.03.17.10.49.22
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Mon, 17 Mar 2025 10:49:22 -0700 (PDT)
From: Manuel Lauss <manuel.lauss@gmail.com>
To: ffmpeg-devel@ffmpeg.org
Date: Mon, 17 Mar 2025 18:49:05 +0100
Message-ID: <20250317174917.6872-4-manuel.lauss@gmail.com>
X-Mailer: git-send-email 2.49.0
In-Reply-To: <20250317174917.6872-1-manuel.lauss@gmail.com>
References: <20250317174917.6872-1-manuel.lauss@gmail.com>
MIME-Version: 1.0
Subject: [FFmpeg-devel] [PATCH v3 03/14] avcodec/sanm: better frame size
 detection for old codecs
X-BeenThere: ffmpeg-devel@ffmpeg.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org>
List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe>
List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel>
List-Post: <mailto:ffmpeg-devel@ffmpeg.org>
List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help>
List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>,
 <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe>
Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Cc: Manuel Lauss <manuel.lauss@gmail.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: ffmpeg-devel-bounces@ffmpeg.org
Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org>
Archived-At: <https://master.gitmailbox.com/ffmpegdev/20250317174917.6872-4-manuel.lauss@gmail.com/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

The size of the video frame (FOBJ) of the old codecs (ANIMv0/1/2) can
very reliably be determined:
- ANIMv0/1 (=Rebel Assault 1) uses a 384x242 internal buffer for
  everything.  The codec parameters only describe the size and offset
  of the specific FOBJ on that buffer.
- ANIMv2 titles usually use one of the fullscreen codecs (37/47/48)
  as first FOBJ, and their dimensions can generally be trusted.
- RA2 uses 424x260 as internal buffer, use that if encountered:
  08PLAY.SAN does not use codec37 so we need to guess using the
  codec coordinates.
- ignore sizes larger than 800x600.
- some game videos have an initial fobj with either 1x1 or -1x-1
  pixels in size, ignore them with a warning (Full Throttle
  and the Rebel Assault 2 xxRETRY.SAN videos).

Once a known/valid dimension set has been discovered, use it and
don't change it for subsequent FOBJs, rather clamp the large frame
to the determined dimensions.

Tested with RA1, RA2, Full Throttle, Dig, Outlaws, SotE and MotS
videos.

Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
---
v2, v3: no changes

 libavcodec/sanm.c | 63 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 14 deletions(-)

diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
index 65ca525b9d..38cdb533eb 100644
--- a/libavcodec/sanm.c
+++ b/libavcodec/sanm.c
@@ -264,7 +264,7 @@ typedef struct SANMVideoContext {
     AVCodecContext *avctx;
     GetByteContext gb;
 
-    int version, subversion;
+    int version, subversion, have_dimensions;
     uint32_t pal[PALETTE_SIZE];
     int16_t delta_pal[PALETTE_DELTA];
 
@@ -1244,21 +1244,56 @@ static int process_frame_obj(SANMVideoContext *ctx)
     uint16_t w     = bytestream2_get_le16u(&ctx->gb);
     uint16_t h     = bytestream2_get_le16u(&ctx->gb);
 
-    if (!w || !h) {
-        av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n");
-        return AVERROR_INVALIDDATA;
+    if (w < 1 || h < 1 || w > 800 || h > 600 || left > 800 || top > 600) {
+        av_log(ctx->avctx, AV_LOG_WARNING,
+               "ignoring invalid fobj dimensions: c%d %d %d @ %d %d\n",
+               codec, w, h, left, top);
+        return 0;
     }
 
-    if (ctx->width < left + w || ctx->height < top + h) {
-        int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
-                                    FFMAX(top + h, ctx->height));
-        if (ret < 0)
-            return ret;
-        init_sizes(ctx, FFMAX(left + w, ctx->width),
-                   FFMAX(top + h, ctx->height));
-        if (init_buffers(ctx)) {
-            av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n");
-            return AVERROR(ENOMEM);
+    if (!ctx->have_dimensions) {
+        int xres, yres;
+        if (ctx->subversion < 2) {
+            /* Rebel Assault 1: 384x242 internal size */
+            xres = 384;
+            yres = 242;
+            ctx->have_dimensions = 1;
+        } else if (codec == 37 || codec == 47 || codec == 48) {
+            /* these codecs work on full frames, trust their dimensions */
+            xres = w;
+            yres = h;
+            ctx->have_dimensions = 1;
+        } else {
+            /* Rebel Assault 2: 424x260 internal size */
+            if (((left + w) == 424) && ((top + h) == 260))
+                ctx->have_dimensions = 1;
+
+            xres = FFMAX(left + w, ctx->width);
+            yres = FFMAX(top + h, ctx->height);
+        }
+
+        if (ctx->width < xres || ctx->height < yres) {
+            int ret = ff_set_dimensions(ctx->avctx, xres, yres);
+            if (ret < 0)
+                return ret;
+            init_sizes(ctx, xres, yres);
+            if (init_buffers(ctx)) {
+                av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n");
+                return AVERROR(ENOMEM);
+            }
+        }
+    } else {
+        if (((left + w > ctx->width) || (top + h > ctx->height))
+            && (codec >= 37)) {
+            /* correct unexpected overly large frames: this happens
+             * for instance with The Dig's sq1.san video: it has a few
+             * (all black) 640x480 frames halfway in, while the rest is
+             * 320x200.
+             */
+            av_log(ctx->avctx, AV_LOG_WARNING,
+                   "resizing too large fobj: c%d  %d %d @ %d %d\n", codec, w, h, left, top);
+            w = ctx->width;
+            h = ctx->height;
         }
     }
     bytestream2_skip(&ctx->gb, 4);
-- 
2.49.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".