From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id A627C4E31B for ; Thu, 1 May 2025 09:58:52 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A0F4868B5C9; Thu, 1 May 2025 12:58:17 +0300 (EEST) 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 ECAEB68B3F9 for ; Thu, 1 May 2025 12:58:07 +0300 (EEST) Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-39c266c2dd5so741933f8f.3 for ; Thu, 01 May 2025 02:58:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746093487; x=1746698287; 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=SOkvP6/ZwnLtENrODJDkYrHdxz0uFeelsz3RX+OmFIA=; b=OR/aYLRaaYK4X2euzNBxWxaaCwS8oe3RMzDpe8Wm+LMwB5zNm2yh4mDYRd165ct/TX 5djOTiZTnViRUYvhMnzx8I3T8NlxX5iZadEJ2kBdKajbs8G0s7vn54Lk0y9Nh4331lEy nZbchlsaOz41c+HQotFJALHUacNBE0efDbvD2C/PzqVs3rOhHLi2UWnG5kOhH+ubaXx0 kG+V6cbBtsNttjcWjRUZ0bW9cnK2c85npYXrxHFD7XohGyu8+fDMUT2aVDNBgOLY2luQ QiNmlydfEbBEJ+0iBvTQl3JRS2u4mMrzEHoGI+V4cQIn0+Ejk/3LCTxXlWwAxyyFb3k9 QPtQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746093487; x=1746698287; 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=SOkvP6/ZwnLtENrODJDkYrHdxz0uFeelsz3RX+OmFIA=; b=aJb3uqUuK6EnyK4Q0uVDuqr06YS5hXcZqzuzaatsDt9tzM/AGraY9TJHr4ls9GsKGz oLD93y4T1Dww1I0Jnb/S4eGr12Vhnk5k48fhPsd9HnlxKLGD+a9OA6/sCxdb9mcjwiMs 4tvQ1/WKvAb2/Y8ZCxsWCjHa/56xEVYthl82x7wuBDuqpLXlt/YdnJFTjhwtvU3J1PJg b6qLYcnTTpQj+YfuJ7e28pgof9QbSmz0VVNQ6kkT+yoBCUmU3gcvRVgyxXz+JHd53oML nOvOv/NyEsiXdKsitMfFRbFBwFlDU2fbtqKtnM3yFCQUWLO8n/xiL30I8owUDX00b6oZ s6Dw== X-Gm-Message-State: AOJu0Yxw9lLcFhbMw6LLCSagy40YyJ2HERh63uZVjn4lZVQ/V9Mp7LpO jAj2rG+f7gKfggy205vVFEYEZ+kQ5JZA/2BI4Oi/1yc92KNLGK7yc2G8Tg== X-Gm-Gg: ASbGncu/hfVb5PPpeeeXUc0PjUFB7U1fjKajgOfwplPL5xAA0KwoiFZe7MpWl2KXcTa 4gG/L/P6t/XlflXcoAxoDm74pAsnFshH8mdlAj5yRUCs5402qoAyzwyT93dEar+/UXZlhIFj2xa m8dviVrdRM9r8yKIhFlYs1A7i/r7Um1MPRI3tt+/lp1lhrM2Dd54DGrT/9T6dKfVBe3EiVmrWQw DDzEocT/9x+8rJdBivCiOY0behineGzNrRIOON9utsDPHGyi52wcZ3YvDUoalvsnEu3T/TylIm0 cDXS47e5n1AnKNfTFcb8uWKwbXeXL/kbTqHAFARbcoPAx7zujsDTydWyqr7BUQOD7gm8/gENafM jgh8i8VpfzpQ1BXvxh3RFBxXUbcFddPgWDdBsgf1GfkejXmtLgA== X-Google-Smtp-Source: AGHT+IGBT5k5M7l3/QldgEbLj+0URv+R+2viPdO7iUV4ChKLr7St3uXpbfPomYjSvAOW/oy4txeEow== X-Received: by 2002:a05:6000:1844:b0:3a0:85ad:5ed9 with SMTP id ffacd0b85a97d-3a09404451fmr1249612f8f.4.1746093487138; Thu, 01 May 2025 02:58:07 -0700 (PDT) Received: from flagship3.deu.mlau.at (p200300c0272bdf00de833b3b0c942d7a.dip0.t-ipconnect.de. [2003:c0:272b:df00:de83:3b3b:c94:2d7a]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3a095a3df60sm421041f8f.3.2025.05.01.02.58.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 May 2025 02:58:06 -0700 (PDT) From: Manuel Lauss To: ffmpeg-devel@ffmpeg.org Date: Thu, 1 May 2025 11:58:01 +0200 Message-ID: <20250501095801.68542-4-manuel.lauss@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250501095801.68542-1-manuel.lauss@gmail.com> References: <20250501095801.68542-1-manuel.lauss@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/3] avcodec/sanm: support "StarWars - Making Magic" video 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: Manuel Lauss Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: The title "StarWars - Making Magic" consists of 640x480 codec3 frames, with a 320x240 codec48 video put on top of that at random x/y offsets. To support this, a new default buffer "fbuf", which holds the final image to be presented, is added, since codec37/47/48 need their buffers need to be private to themselves. The decoded result is then copied to the fbuf, honoring the x/y offsets if required. Signed-off-by: Manuel Lauss --- libavcodec/sanm.c | 63 +++++++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 63f5c2cc7f..0af0527ce6 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -274,9 +274,9 @@ typedef struct SANMVideoContext { int prev_seq; AVFrame *frame; - uint16_t *frm0, *frm1, *frm2; + uint16_t *fbuf, *frm0, *frm1, *frm2; uint8_t *stored_frame; - uint32_t frm0_size, frm1_size, frm2_size; + uint32_t fbuf_size, frm0_size, frm1_size, frm2_size; uint32_t stored_frame_size; uint8_t *rle_buf; @@ -453,6 +453,7 @@ static void init_sizes(SANMVideoContext *ctx, int width, int height) static void destroy_buffers(SANMVideoContext *ctx) { + av_freep(&ctx->fbuf); av_freep(&ctx->frm0); av_freep(&ctx->frm1); av_freep(&ctx->frm2); @@ -466,6 +467,7 @@ static void destroy_buffers(SANMVideoContext *ctx) static av_cold int init_buffers(SANMVideoContext *ctx) { + av_fast_padded_mallocz(&ctx->fbuf, &ctx->fbuf_size, ctx->buf_size); av_fast_padded_mallocz(&ctx->frm0, &ctx->frm0_size, ctx->buf_size); av_fast_padded_mallocz(&ctx->frm1, &ctx->frm1_size, ctx->buf_size); av_fast_padded_mallocz(&ctx->frm2, &ctx->frm2_size, ctx->buf_size); @@ -674,7 +676,7 @@ static int old_codec4(SANMVideoContext *ctx, GetByteContext *gb, int top, int le { const uint16_t p = ctx->pitch; const uint32_t maxpxo = ctx->height * p; - uint8_t mask, bits, idx, *gs, *dst = (uint8_t *)ctx->frm0; + uint8_t mask, bits, idx, *gs, *dst = (uint8_t *)ctx->fbuf; int i, j, k, l, bit, ret; int32_t pxoff, pxo2; @@ -805,7 +807,7 @@ static int old_codec23(SANMVideoContext *ctx, GetByteContext *gb, int top, int l if (bytestream2_get_bytes_left(gb) < 1) return 0; /* some c23 frames just set up the LUT */ - dst = (uint8_t *)ctx->frm0; + dst = (uint8_t *)ctx->fbuf; for (i = 0; i < height; i++) { if (bytestream2_get_bytes_left(gb) < 2) return 0; @@ -840,10 +842,10 @@ static int old_codec21(SANMVideoContext *ctx, GetByteContext *gb, int top, int l int width, int height) { const uint32_t maxpxo = ctx->height * ctx->pitch; - uint8_t *dst = (uint8_t *)ctx->frm0, c; + uint8_t *dst = (uint8_t *)ctx->fbuf, c; int i, j, k, pc, sk, pxoff; - dst = (uint8_t *)ctx->frm0; + dst = (uint8_t *)ctx->fbuf; for (i = 0; i < height; i++) { if (bytestream2_get_bytes_left(gb) < 2) return 0; @@ -884,7 +886,7 @@ static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top, { int i, j, len, flag, code, val, end, pxoff; const int maxpxo = ctx->height * ctx->pitch; - uint8_t *dst = (uint8_t *)ctx->frm0; + uint8_t *dst = (uint8_t *)ctx->fbuf; for (i = 0; i < height; i++) { if (bytestream2_get_bytes_left(gb) < 2) @@ -932,7 +934,7 @@ static int old_codec1(SANMVideoContext *ctx, GetByteContext *gb, int top, static int old_codec2(SANMVideoContext *ctx, GetByteContext *gb, int top, int left, int width, int height) { - uint8_t *dst = (uint8_t *)ctx->frm0, col; + uint8_t *dst = (uint8_t *)ctx->fbuf, col; int16_t xpos = left, ypos = top; while (bytestream2_get_bytes_left(gb) > 3) { @@ -949,7 +951,7 @@ static int old_codec2(SANMVideoContext *ctx, GetByteContext *gb, int top, static int old_codec20(SANMVideoContext *ctx, int w, int h) { - uint8_t *dst = (uint8_t *)ctx->frm0; + uint8_t *dst = (uint8_t *)ctx->fbuf; if (bytestream2_get_bytes_left(&ctx->gb) < w * h) return AVERROR_INVALIDDATA; @@ -1008,10 +1010,10 @@ static int old_codec37(SANMVideoContext *ctx, int width, int height) ctx->rotate_code = 0; if (((seq & 1) || !(flags & 1)) && (compr && compr != 2)) { - FFSWAP(uint16_t*, ctx->frm1, ctx->frm2); + FFSWAP(uint16_t*, ctx->frm0, ctx->frm2); } - dst = ((uint8_t*)ctx->frm1); + dst = ((uint8_t*)ctx->frm0); prev = ((uint8_t*)ctx->frm2); if (mvoff > 2) { @@ -1145,7 +1147,6 @@ static int old_codec37(SANMVideoContext *ctx, int width, int height) return AVERROR_PATCHWELCOME; } - memcpy(ctx->frm0, ctx->frm1, ctx->buf_size); return 0; } @@ -1603,7 +1604,7 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) uint16_t w, h, parm2; uint8_t codec, param; int16_t left, top; - int fsc, sote; + int fsc, sote, ret; codec = bytestream2_get_byteu(gb); param = bytestream2_get_byteu(gb); @@ -1687,12 +1688,12 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) } /* on first FOBJ, when the codec is not one of the - * full-buffer codecs (37/47/48), frm0 needs to be cleared. + * full-buffer codecs (37/47/48), fbuf needs to be cleared. */ if (ctx->first_fob) { ctx->first_fob = 0; if (!fsc) - memset(ctx->frm0, 0, ctx->frm0_size); + memset(ctx->fbuf, 0, ctx->frm0_size); } switch (codec) { @@ -1713,18 +1714,38 @@ static int process_frame_obj(SANMVideoContext *ctx, GetByteContext *gb) case 23: return old_codec23(ctx, gb, top, left, w, h, param, parm2); case 37: - return old_codec37(ctx, w, h); + ret = old_codec37(ctx, w, h); break; case 45: return 0; case 47: - return old_codec47(ctx, w, h); + ret = old_codec47(ctx, w, h); break; case 48: - return old_codec48(ctx, w, h); + ret = old_codec48(ctx, w, h); break; default: avpriv_request_sample(ctx->avctx, "Subcodec %d", codec); ctx->frame->flags |= AV_FRAME_FLAG_CORRUPT; return 0; } + if (ret) + return ret; + + /* copy the codec37/47/48 result to main buffer */ + if ((w == ctx->width) && (h == ctx->height)) { + memcpy(ctx->fbuf, ctx->frm0, ctx->fbuf_size); + } else { + uint8_t *dst = (uint8_t *)ctx->fbuf + left + top * ctx->pitch; + const uint8_t *src = (uint8_t *)ctx->frm0; + int cw = FFMIN(w, ctx->width - left); + int ch = FFMIN(h, ctx->height - top); + if ((cw > 0) && (ch > 0) && (left > 0) && (top > 0)) { + for (int i = 0; i < ch; i++) { + memcpy(dst, src, cw); + dst += ctx->pitch; + src += w; + } + } + } + return 0; } static int process_ftch(SANMVideoContext *ctx, int size) @@ -2196,7 +2217,7 @@ static void fill_frame(uint16_t *pbuf, int buf_size, uint16_t color) static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr) { uint8_t *dst; - const uint8_t *src = (uint8_t*) ctx->frm0; + const uint8_t *src = hdr ? (uint8_t *)ctx->frm0 : (uint8_t *)ctx->fbuf; int ret, height = ctx->height; ptrdiff_t dstpitch, srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1); @@ -2279,7 +2300,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, ret = AVERROR(ENOMEM); } } else { - memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size); + memcpy(ctx->stored_frame, ctx->fbuf, ctx->buf_size); } } break; @@ -2295,7 +2316,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, if (ret = process_ftch(ctx, size)) return ret; } else { - memcpy(ctx->frm0, ctx->stored_frame, ctx->buf_size); + memcpy(ctx->fbuf, ctx->stored_frame, ctx->buf_size); } have_img = 1; break; -- 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".