From: Manuel Lauss <manuel.lauss@gmail.com> To: ffmpeg-devel@ffmpeg.org Cc: Manuel Lauss <manuel.lauss@gmail.com> Subject: [FFmpeg-devel] [PATCH v2 03/13] avcodec/sanm: better frame size detection for old codecs Date: Sat, 15 Mar 2025 10:32:10 +0100 Message-ID: <20250315093220.2565-4-manuel.lauss@gmail.com> (raw) In-Reply-To: <20250315093220.2565-1-manuel.lauss@gmail.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 smaller than 2x2 or 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> --- 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.48.1 _______________________________________________ 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".
next prev parent reply other threads:[~2025-03-15 9:33 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-03-15 9:32 [FFmpeg-devel] [PATCH v2 00/13] avcodec/sanm: various improvements Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 01/13] avcodec/sanm: disable left/top for fullscreen codecs Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 02/13] avcodec/sanm: FOBJ left/top are signed values Manuel Lauss 2025-03-15 9:32 ` Manuel Lauss [this message] 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 04/13] avcodec/sanm: better ANIMv1 engine support Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 05/13] avcodec/sanm: fix codec3 Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 06/13] avcodec/sanm: codec2 decoder Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 07/13] avcodec/sanm: codec23 decoder Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 08/13] avcodec/sanm: codec21 decoder Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 09/13] avcodec/sanm: codec4/5/33/34 decoder Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 10/13] avcodec/sanm: codec37: reimplement comp4 Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 11/13] avcodec/sanm: implement STOR/FTCH for ANIMv1 Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 12/13] avcodec/sanm: ignore codec45 Manuel Lauss 2025-03-15 9:32 ` [FFmpeg-devel] [PATCH v2 13/13] MAINTAINERS: add Manuel Lauss as sanm.c/smush.c Maintainer Manuel Lauss 2025-03-16 14:27 ` Michael Niedermayer
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20250315093220.2565-4-manuel.lauss@gmail.com \ --to=manuel.lauss@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git