[FFmpeg-devel] [PATCH v2 1/2] avcodec/sanm: implement codec37 subcodec1
Manuel Lauss
manuel.lauss at gmail.com
Wed Jan 15 19:24:44 EET 2025
Ping?
Incidentally this also closes trac ticket #5753; while commit
b22ce90d ("avcodec/sanm: SMUSH codec48 decoder") fixes #5746.
Thanks!
Manuel
On Thu, Jan 9, 2025 at 9:03 AM Manuel Lauss <manuel.lauss at gmail.com> wrote:
>
> RLE-compressed stream of motion vector indices and a special opcode
> to fill a block with data from the source stream.
>
> It is used in the LucasArts "Full Throttle" blink*.san animations.
>
> Signed-off-by: Manuel Lauss <manuel.lauss at gmail.com>
> ---
> v2: move variable declarations to top of functions.
>
> libavcodec/sanm.c | 65 ++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 62 insertions(+), 3 deletions(-)
>
> diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c
> index a278ef24b1..0d04b09c8d 100644
> --- a/libavcodec/sanm.c
> +++ b/libavcodec/sanm.c
> @@ -624,8 +624,8 @@ static inline void codec37_mv(uint8_t *dst, const uint8_t *src,
> static int old_codec37(SANMVideoContext *ctx, int top,
> int left, int width, int height)
> {
> + int i, j, k, l, t, run, len, code, skip, mx, my;
> ptrdiff_t stride = ctx->pitch;
> - int i, j, k, t;
> uint8_t *dst, *prev;
> int skip_run = 0;
> int compr = bytestream2_get_byte(&ctx->gb);
> @@ -665,6 +665,67 @@ static int old_codec37(SANMVideoContext *ctx, int top,
> memset(ctx->frm1, 0, ctx->height * stride);
> memset(ctx->frm2, 0, ctx->height * stride);
> break;
> + case 1:
> + run = 0;
> + len = -1;
> + code = 0;
> +
> + for (j = 0; j < height; j += 4) {
> + for (i = 0; i < width; i += 4) {
> + if (len < 0) {
> + if (bytestream2_get_bytes_left(&ctx->gb) < 1)
> + return AVERROR_INVALIDDATA;
> + code = bytestream2_get_byte(&ctx->gb);
> + len = code >> 1;
> + run = code & 1;
> + skip = 0;
> + } else {
> + skip = run;
> + }
> +
> + if (!skip) {
> + if (bytestream2_get_bytes_left(&ctx->gb) < 1)
> + return AVERROR_INVALIDDATA;
> + code = bytestream2_get_byte(&ctx->gb);
> + if (code == 0xff) {
> + len--;
> + for (k = 0; k < 4; k++) {
> + for (l = 0; l < 4; l++) {
> + if (len < 0) {
> + if (bytestream2_get_bytes_left(&ctx->gb) < 1)
> + return AVERROR_INVALIDDATA;
> + code = bytestream2_get_byte(&ctx->gb);
> + len = code >> 1;
> + run = code & 1;
> + if (run) {
> + if (bytestream2_get_bytes_left(&ctx->gb) < 1)
> + return AVERROR_INVALIDDATA;
> + code = bytestream2_get_byte(&ctx->gb);
> + }
> + }
> + if (!run) {
> + if (bytestream2_get_bytes_left(&ctx->gb) < 1)
> + return AVERROR_INVALIDDATA;
> + code = bytestream2_get_byte(&ctx->gb);
> + }
> + *(dst + i + (k * stride) + l) = code;
> + len--;
> + }
> + }
> + continue;
> + }
> + }
> + /* 4x4 block copy from prev with MV */
> + mx = c37_mv[(mvoff * 255 + code) * 2];
> + my = c37_mv[(mvoff * 255 + code) * 2 + 1];
> + codec37_mv(dst + i, prev + i + mx + my * stride,
> + ctx->height, stride, i + mx, j + my);
> + len--;
> + }
> + dst += stride * 4;
> + prev += stride * 4;
> + }
> + break;
> case 2:
> if (rle_decode(ctx, dst, decoded_size))
> return AVERROR_INVALIDDATA;
> @@ -712,8 +773,6 @@ static int old_codec37(SANMVideoContext *ctx, int top,
> skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
> i -= 4;
> } else {
> - int mx, my;
> -
> mx = c37_mv[(mvoff * 255 + code) * 2];
> my = c37_mv[(mvoff * 255 + code) * 2 + 1];
> codec37_mv(dst + i, prev + i + mx + my * stride,
> --
> 2.47.1
>
More information about the ffmpeg-devel
mailing list