truemotion2.c 24.6 KB
Newer Older
1 2 3 4
/*
 * Duck/ON2 TrueMotion 2 Decoder
 * Copyright (c) 2005 Konstantin Shishkov
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22
/**
23
 * @file
24 25
 * Duck TrueMotion2 decoder.
 */
26

27
#include "avcodec.h"
28
#include "get_bits.h"
29 30 31
#include "dsputil.h"

#define TM2_ESCAPE 0x80000000
Mike Melanson's avatar
Mike Melanson committed
32
#define TM2_DELTAS 64
33 34 35 36 37 38 39 40 41 42 43 44 45
/* Huffman-coded streams of different types of blocks */
enum TM2_STREAMS{ TM2_C_HI = 0, TM2_C_LO, TM2_L_HI, TM2_L_LO,
     TM2_UPD, TM2_MOT, TM2_TYPE, TM2_NUM_STREAMS};
/* Block types */
enum TM2_BLOCKS{ TM2_HI_RES = 0, TM2_MED_RES, TM2_LOW_RES, TM2_NULL_RES,
                 TM2_UPDATE, TM2_STILL, TM2_MOTION};

typedef struct TM2Context{
    AVCodecContext *avctx;
    AVFrame pic;

    GetBitContext gb;
    DSPContext dsp;
46

47 48 49 50 51 52 53 54 55 56
    /* TM2 streams */
    int *tokens[TM2_NUM_STREAMS];
    int tok_lens[TM2_NUM_STREAMS];
    int tok_ptrs[TM2_NUM_STREAMS];
    int deltas[TM2_NUM_STREAMS][TM2_DELTAS];
    /* for blocks decoding */
    int D[4];
    int CD[4];
    int *last;
    int *clast;
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
    /* data for current and previous frame */
    int *Y1, *U1, *V1, *Y2, *U2, *V2;
    int cur;
} TM2Context;

/**
* Huffman codes for each of streams
*/
typedef struct TM2Codes{
    VLC vlc; ///< table for FFmpeg bitstream reader
    int bits;
    int *recode; ///< table for converting from code indexes to values
    int length;
} TM2Codes;

/**
* structure for gathering Huffman codes information
*/
typedef struct TM2Huff{
    int val_bits; ///< length of literal
    int max_bits; ///< maximum length of code
    int min_bits; ///< minimum length of code
    int nodes; ///< total number of nodes in tree
    int num; ///< current number filled
    int max_num; ///< total number of codes
    int *nums; ///< literals
    uint32_t *bits; ///< codes
    int *lens; ///< codelengths
} TM2Huff;

static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
{
    if(length > huff->max_bits) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n", huff->max_bits);
        return -1;
    }

    if(!get_bits1(&ctx->gb)) { /* literal */
        if (length == 0) {
            length = 1;
        }
        if(huff->num >= huff->max_num) {
            av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
            return -1;
        }
        huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits);
        huff->bits[huff->num] = prefix;
        huff->lens[huff->num] = length;
        huff->num++;
        return 0;
    } else { /* non-terminal node */
        if(tm2_read_tree(ctx, prefix << 1, length + 1, huff) == -1)
            return -1;
        if(tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff) == -1)
            return -1;
    }
    return 0;
}

static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
{
    TM2Huff huff;
    int res = 0;
121

122 123 124 125 126
    huff.val_bits = get_bits(&ctx->gb, 5);
    huff.max_bits = get_bits(&ctx->gb, 5);
    huff.min_bits = get_bits(&ctx->gb, 5);
    huff.nodes = get_bits_long(&ctx->gb, 17);
    huff.num = 0;
127

128 129 130 131 132 133 134 135 136 137 138 139 140 141
    /* check for correct codes parameters */
    if((huff.val_bits < 1) || (huff.val_bits > 32) ||
       (huff.max_bits < 0) || (huff.max_bits > 32)) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n",
               huff.val_bits, huff.max_bits);
        return -1;
    }
    if((huff.nodes < 0) || (huff.nodes > 0x10000)) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes);
        return -1;
    }
    /* one-node tree */
    if(huff.max_bits == 0)
        huff.max_bits = 1;
142

143 144 145 146 147
    /* allocate space for codes - it is exactly ceil(nodes / 2) entries */
    huff.max_num = (huff.nodes + 1) >> 1;
    huff.nums = av_mallocz(huff.max_num * sizeof(int));
    huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));
    huff.lens = av_mallocz(huff.max_num * sizeof(int));
148

149 150
    if(tm2_read_tree(ctx, 0, 0, &huff) == -1)
        res = -1;
151

152 153 154 155 156
    if(huff.num != huff.max_num) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
               huff.num, huff.max_num);
        res = -1;
    }
157

158 159 160
    /* convert codes to vlc_table */
    if(res != -1) {
        int i;
161

162 163 164 165 166 167
        res = init_vlc(&code->vlc, huff.max_bits, huff.max_num,
                    huff.lens, sizeof(int), sizeof(int),
                    huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
        if(res < 0) {
            av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
            res = -1;
168
        } else
169 170 171 172 173 174 175 176 177 178 179 180 181
            res = 0;
        if(res != -1) {
            code->bits = huff.max_bits;
            code->length = huff.max_num;
            code->recode = av_malloc(code->length * sizeof(int));
            for(i = 0; i < code->length; i++)
                code->recode[i] = huff.nums[i];
        }
    }
    /* free allocated memory */
    av_free(huff.nums);
    av_free(huff.bits);
    av_free(huff.lens);
182

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
    return res;
}

static void tm2_free_codes(TM2Codes *code)
{
    if(code->recode)
        av_free(code->recode);
    if(code->vlc.table)
        free_vlc(&code->vlc);
}

static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code)
{
    int val;
    val = get_vlc2(gb, code->vlc.table, code->bits, 1);
    return code->recode[val];
}

Michael Niedermayer's avatar
Michael Niedermayer committed
201
static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
202 203
{
    uint32_t magic;
Michael Niedermayer's avatar
Michael Niedermayer committed
204
    const uint8_t *obuf;
205
    int length;
206

207
    obuf = buf;
208

209
    magic = AV_RL32(buf);
210
    buf += 4;
211

212 213 214 215 216
    if(magic == 0x00000100) { /* old header */
/*      av_log (ctx->avctx, AV_LOG_ERROR, "TM2 old header: not implemented (yet)\n"); */
        return 40;
    } else if(magic == 0x00000101) { /* new header */
        int w, h, size, flags, xr, yr;
217

218
        length = AV_RL32(buf);
219
        buf += 4;
220

Mike Melanson's avatar
Mike Melanson committed
221
        init_get_bits(&ctx->gb, buf, 32 * 8);
222 223 224 225 226 227
        size = get_bits_long(&ctx->gb, 31);
        h = get_bits(&ctx->gb, 15);
        w = get_bits(&ctx->gb, 15);
        flags = get_bits_long(&ctx->gb, 31);
        yr = get_bits(&ctx->gb, 9);
        xr = get_bits(&ctx->gb, 9);
228

229 230 231 232 233
        return 40;
    } else {
        av_log (ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
        return -1;
    }
234

235
    return buf - obuf;
236 237 238 239 240
}

static int tm2_read_deltas(TM2Context *ctx, int stream_id) {
    int d, mb;
    int i, v;
241

242 243
    d = get_bits(&ctx->gb, 9);
    mb = get_bits(&ctx->gb, 5);
244

245 246 247 248
    if((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
        return -1;
    }
249

250 251 252 253 254 255 256 257 258
    for(i = 0; i < d; i++) {
        v = get_bits_long(&ctx->gb, mb);
        if(v & (1 << (mb - 1)))
            ctx->deltas[stream_id][i] = v - (1 << mb);
        else
            ctx->deltas[stream_id][i] = v;
    }
    for(; i < TM2_DELTAS; i++)
        ctx->deltas[stream_id][i] = 0;
259

260 261 262
    return 0;
}

Michael Niedermayer's avatar
Michael Niedermayer committed
263
static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id) {
264 265 266 267 268
    int i;
    int cur = 0;
    int skip = 0;
    int len, toks;
    TM2Codes codes;
269

270
    /* get stream length in dwords */
271
    len = AV_RB32(buf); buf += 4; cur += 4;
272
    skip = len * 4 + 4;
273

274 275
    if(len == 0)
        return 4;
276

277
    toks = AV_RB32(buf); buf += 4; cur += 4;
278
    if(toks & 1) {
279
        len = AV_RB32(buf); buf += 4; cur += 4;
280
        if(len == TM2_ESCAPE) {
281
            len = AV_RB32(buf); buf += 4; cur += 4;
282 283
        }
        if(len > 0) {
Mike Melanson's avatar
Mike Melanson committed
284
            init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
285 286 287 288 289 290 291
            if(tm2_read_deltas(ctx, stream_id) == -1)
                return -1;
            buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2;
            cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2;
        }
    }
    /* skip unused fields */
292
    if(AV_RB32(buf) == TM2_ESCAPE) {
293 294 295 296
        buf += 4; cur += 4; /* some unknown length - could be escaped too */
    }
    buf += 4; cur += 4;
    buf += 4; cur += 4; /* unused by decoder */
297

Mike Melanson's avatar
Mike Melanson committed
298
    init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
299 300 301 302
    if(tm2_build_huff_table(ctx, &codes) == -1)
        return -1;
    buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2;
    cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2;
303

304 305 306 307 308 309 310 311 312
    toks >>= 1;
    /* check if we have sane number of tokens */
    if((toks < 0) || (toks > 0xFFFFFF)){
        av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
        tm2_free_codes(&codes);
        return -1;
    }
    ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
    ctx->tok_lens[stream_id] = toks;
313
    len = AV_RB32(buf); buf += 4; cur += 4;
314
    if(len > 0) {
Mike Melanson's avatar
Mike Melanson committed
315
        init_get_bits(&ctx->gb, buf, (skip - cur) * 8);
316 317 318
        for(i = 0; i < toks; i++)
            ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
    } else {
Mike Melanson's avatar
Mike Melanson committed
319 320
        for(i = 0; i < toks; i++)
            ctx->tokens[stream_id][i] = codes.recode[0];
321 322
    }
    tm2_free_codes(&codes);
323

324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    return skip;
}

static inline int GET_TOK(TM2Context *ctx,int type) {
    if(ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
        av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]);
        return 0;
    }
    if(type <= TM2_MOT)
        return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
    return ctx->tokens[type][ctx->tok_ptrs[type]++];
}

/* blocks decoding routines */

/* common Y, U, V pointers initialisation */
340
#define TM2_INIT_POINTERS() \
341 342 343 344 345 346 347 348 349 350 351 352 353
    int *last, *clast; \
    int *Y, *U, *V;\
    int Ystride, Ustride, Vstride;\
\
    Ystride = ctx->avctx->width;\
    Vstride = (ctx->avctx->width + 1) >> 1;\
    Ustride = (ctx->avctx->width + 1) >> 1;\
    Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\
    V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\
    U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\
    last = ctx->last + bx * 4;\
    clast = ctx->clast + bx * 4;

354
#define TM2_INIT_POINTERS_2() \
355 356 357 358 359 360 361 362 363 364 365 366 367
    int *Yo, *Uo, *Vo;\
    int oYstride, oUstride, oVstride;\
\
    TM2_INIT_POINTERS();\
    oYstride = Ystride;\
    oVstride = Vstride;\
    oUstride = Ustride;\
    Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\
    Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\
    Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2;

/* recalculate last and delta values for next blocks */
#define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\
368
    CD[0] = CHR[1] - last[1];\
369
    CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\
370 371
    last[0] = (int)CHR[stride + 0];\
    last[1] = (int)CHR[stride + 1];}
372 373 374 375 376 377

/* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */
static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last)
{
    int ct, d;
    int i, j;
378

379 380 381 382 383 384
    for(j = 0; j < 4; j++){
        ct = ctx->D[j];
        for(i = 0; i < 4; i++){
            d = deltas[i + j * 4];
            ct += d;
            last[i] += ct;
385
            Y[i] = av_clip_uint8(last[i]);
386 387 388 389 390 391 392 393 394 395 396 397 398
        }
        Y += stride;
        ctx->D[j] = ct;
    }
}

static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
{
    int i, j;
    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            CD[j] += deltas[i + j * 2];
            last[i] += CD[j];
399
            data[i] = last[i];
400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
        }
        data += stride;
    }
}

static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx)
{
    int t;
    int l;
    int prev;

    if(bx > 0)
        prev = clast[-3];
    else
        prev = 0;
    t = (CD[0] + CD[1]) >> 1;
416
    l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
417 418 419
    CD[1] = CD[0] + CD[1] - t;
    CD[0] = t;
    clast[0] = l;
420

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
    tm2_high_chroma(data, stride, clast, CD, deltas);
}

static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i;
    int deltas[16];
    TM2_INIT_POINTERS();

    /* hi-res chroma */
    for(i = 0; i < 4; i++) {
        deltas[i] = GET_TOK(ctx, TM2_C_HI);
        deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
    }
    tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
    tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
437

438 439 440
    /* hi-res luma */
    for(i = 0; i < 16; i++)
        deltas[i] = GET_TOK(ctx, TM2_L_HI);
441

442 443 444 445 446 447 448 449
    tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
}

static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i;
    int deltas[16];
    TM2_INIT_POINTERS();
450

451 452 453 454 455 456 457 458 459 460 461 462
    /* low-res chroma */
    deltas[0] = GET_TOK(ctx, TM2_C_LO);
    deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);

    deltas[0] = GET_TOK(ctx, TM2_C_LO);
    deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);

    /* hi-res luma */
    for(i = 0; i < 16; i++)
        deltas[i] = GET_TOK(ctx, TM2_L_HI);
463

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
    tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
}

static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i;
    int t1, t2;
    int deltas[16];
    TM2_INIT_POINTERS();

    /* low-res chroma */
    deltas[0] = GET_TOK(ctx, TM2_C_LO);
    deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);

    deltas[0] = GET_TOK(ctx, TM2_C_LO);
    deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);

    /* low-res luma */
    for(i = 0; i < 16; i++)
        deltas[i] = 0;
486

487 488 489 490
    deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
    deltas[ 2] = GET_TOK(ctx, TM2_L_LO);
    deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
    deltas[10] = GET_TOK(ctx, TM2_L_LO);
491

492 493 494 495 496 497 498 499 500 501 502 503
    if(bx > 0)
        last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
    else
        last[0] = (last[1]  - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
    last[2] = (last[1] + last[3]) >> 1;

    t1 = ctx->D[0] + ctx->D[1];
    ctx->D[0] = t1 >> 1;
    ctx->D[1] = t1 - (t1 >> 1);
    t2 = ctx->D[2] + ctx->D[3];
    ctx->D[2] = t2 >> 1;
    ctx->D[3] = t2 - (t2 >> 1);
504

505 506 507 508 509 510 511 512 513 514
    tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
}

static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i;
    int ct;
    int left, right, diff;
    int deltas[16];
    TM2_INIT_POINTERS();
515

516 517 518 519 520 521
    /* null chroma */
    deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);

    deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
    tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
522

523 524 525 526 527
    /* null luma */
    for(i = 0; i < 16; i++)
        deltas[i] = 0;

    ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
528

529 530 531 532
    if(bx > 0)
        left = last[-1] - ct;
    else
        left = 0;
533

534 535 536 537 538 539 540 541
    right = last[3];
    diff = right - left;
    last[0] = left + (diff >> 2);
    last[1] = left + (diff >> 1);
    last[2] = right - (diff >> 2);
    last[3] = right;
    {
        int tp = left;
542

543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
        ctx->D[0] = (tp + (ct >> 2)) - left;
        left += ctx->D[0];
        ctx->D[1] = (tp + (ct >> 1)) - left;
        left += ctx->D[1];
        ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
        left += ctx->D[2];
        ctx->D[3] = (tp + ct) - left;
    }
    tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
}

static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i, j;
    TM2_INIT_POINTERS_2();

    /* update chroma */
    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            U[i] = Uo[i];
            V[i] = Vo[i];
        }
        U += Ustride; V += Vstride;
        Uo += oUstride; Vo += oVstride;
    }
    U -= Ustride * 2;
    V -= Vstride * 2;
    TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
    TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));

    /* update deltas */
    ctx->D[0] = Yo[3] - last[3];
    ctx->D[1] = Yo[3 + oYstride] - Yo[3];
    ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
    ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];

    for(j = 0; j < 4; j++){
        for(i = 0; i < 4; i++){
            Y[i] = Yo[i];
            last[i] = Yo[i];
        }
        Y += Ystride;
        Yo += oYstride;
    }
}

static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i, j;
    int d;
    TM2_INIT_POINTERS_2();
594

595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634
    /* update chroma */
    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
            V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
        }
        U += Ustride; V += Vstride;
        Uo += oUstride; Vo += oVstride;
    }
    U -= Ustride * 2;
    V -= Vstride * 2;
    TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
    TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));

    /* update deltas */
    ctx->D[0] = Yo[3] - last[3];
    ctx->D[1] = Yo[3 + oYstride] - Yo[3];
    ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
    ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];

    for(j = 0; j < 4; j++){
        d = last[3];
        for(i = 0; i < 4; i++){
            Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
            last[i] = Y[i];
        }
        ctx->D[j] = last[3] - d;
        Y += Ystride;
        Yo += oYstride;
    }
}

static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
{
    int i, j;
    int mx, my;
    TM2_INIT_POINTERS_2();

    mx = GET_TOK(ctx, TM2_MOT);
    my = GET_TOK(ctx, TM2_MOT);
635

636 637 638
    Yo += my * oYstride + mx;
    Uo += (my >> 1) * oUstride + (mx >> 1);
    Vo += (my >> 1) * oVstride + (mx >> 1);
639

640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
    /* copy chroma */
    for(j = 0; j < 2; j++){
        for(i = 0; i < 2; i++){
            U[i] = Uo[i];
            V[i] = Vo[i];
        }
        U += Ustride; V += Vstride;
        Uo += oUstride; Vo += oVstride;
    }
    U -= Ustride * 2;
    V -= Vstride * 2;
    TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
    TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));

    /* copy luma */
    for(j = 0; j < 4; j++){
        for(i = 0; i < 4; i++){
            Y[i] = Yo[i];
        }
        Y += Ystride;
        Yo += oYstride;
    }
    /* calculate deltas */
    Y -= Ystride * 4;
    ctx->D[0] = Y[3] - last[3];
    ctx->D[1] = Y[3 + Ystride] - Y[3];
    ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
    ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
    for(i = 0; i < 4; i++)
        last[i] = Y[i + Ystride * 3];
}

static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
{
    int i, j;
    int bw, bh;
    int type;
    int keyframe = 1;
678 679
    int *Y, *U, *V;
    uint8_t *dst;
680

681 682 683 684 685
    bw = ctx->avctx->width >> 2;
    bh = ctx->avctx->height >> 2;

    for(i = 0; i < TM2_NUM_STREAMS; i++)
        ctx->tok_ptrs[i] = 0;
686

687 688 689 690
    if (ctx->tok_lens[TM2_TYPE]<bw*bh){
        av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
        return -1;
    }
691

692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
    memset(ctx->last, 0, 4 * bw * sizeof(int));
    memset(ctx->clast, 0, 4 * bw * sizeof(int));

    for(j = 0; j < bh; j++) {
        memset(ctx->D, 0, 4 * sizeof(int));
        memset(ctx->CD, 0, 4 * sizeof(int));
        for(i = 0; i < bw; i++) {
            type = GET_TOK(ctx, TM2_TYPE);
            switch(type) {
            case TM2_HI_RES:
                tm2_hi_res_block(ctx, p, i, j);
                break;
            case TM2_MED_RES:
                tm2_med_res_block(ctx, p, i, j);
                break;
            case TM2_LOW_RES:
                tm2_low_res_block(ctx, p, i, j);
                break;
            case TM2_NULL_RES:
                tm2_null_res_block(ctx, p, i, j);
                break;
            case TM2_UPDATE:
                tm2_update_block(ctx, p, i, j);
                keyframe = 0;
                break;
            case TM2_STILL:
                tm2_still_block(ctx, p, i, j);
                keyframe = 0;
                break;
            case TM2_MOTION:
                tm2_motion_block(ctx, p, i, j);
                keyframe = 0;
                break;
            default:
                av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
            }
        }
    }
730 731

    /* copy data from our buffer to AVFrame */
732 733 734 735
    Y = (ctx->cur?ctx->Y2:ctx->Y1);
    U = (ctx->cur?ctx->U2:ctx->U1);
    V = (ctx->cur?ctx->V2:ctx->V1);
    dst = p->data[0];
736 737
    for(j = 0; j < ctx->avctx->height; j++){
        for(i = 0; i < ctx->avctx->width; i++){
738 739 740 741
            int y = Y[i], u = U[i >> 1], v = V[i >> 1];
            dst[3*i+0] = av_clip_uint8(y + v);
            dst[3*i+1] = av_clip_uint8(y);
            dst[3*i+2] = av_clip_uint8(y + u);
742
        }
743 744 745 746
        Y += ctx->avctx->width;
        if (j & 1) {
            U += ctx->avctx->width >> 1;
            V += ctx->avctx->width >> 1;
747
        }
748
        dst += p->linesize[0];
749
    }
750

751 752 753
    return keyframe;
}

754 755 756 757
static const int tm2_stream_order[TM2_NUM_STREAMS] = {
    TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE
};

758
static int decode_frame(AVCodecContext *avctx,
759
                        void *data, int *data_size,
760
                        AVPacket *avpkt)
761
{
762 763
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
764 765
    TM2Context * const l = avctx->priv_data;
    AVFrame * const p= (AVFrame*)&l->pic;
766
    int i, skip, t;
767
    uint8_t *swbuf;
768

769 770 771 772 773
    swbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if(!swbuf){
        av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
        return -1;
    }
774
    p->reference = 1;
Mike Melanson's avatar
Mike Melanson committed
775 776
    p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
    if(avctx->reget_buffer(avctx, p) < 0){
777
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
778
        av_free(swbuf);
779 780 781
        return -1;
    }

782 783
    l->dsp.bswap_buf((uint32_t*)swbuf, (const uint32_t*)buf, buf_size >> 2);
    skip = tm2_read_header(l, swbuf);
784

785 786
    if(skip == -1){
        av_free(swbuf);
787
        return -1;
788
    }
789

790
    for(i = 0; i < TM2_NUM_STREAMS; i++){
791
        t = tm2_read_stream(l, swbuf + skip, tm2_stream_order[i]);
792
        if(t == -1){
793
            av_free(swbuf);
794 795 796 797
            return -1;
        }
        skip += t;
    }
798 799 800 801 802
    p->key_frame = tm2_decode_blocks(l, p);
    if(p->key_frame)
        p->pict_type = FF_I_TYPE;
    else
        p->pict_type = FF_P_TYPE;
803

804 805 806
    l->cur = !l->cur;
    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = l->pic;
807
    av_free(swbuf);
808

809 810 811
    return buf_size;
}

812
static av_cold int decode_init(AVCodecContext *avctx){
813 814 815 816 817 818 819
    TM2Context * const l = avctx->priv_data;
    int i;

    if((avctx->width & 3) || (avctx->height & 3)){
        av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
        return -1;
    }
820

821 822
    l->avctx = avctx;
    l->pic.data[0]=NULL;
823
    avctx->pix_fmt = PIX_FMT_BGR24;
824 825

    dsputil_init(&l->dsp, avctx);
826

827 828
    l->last = av_malloc(4 * sizeof(int) * (avctx->width >> 2));
    l->clast = av_malloc(4 * sizeof(int) * (avctx->width >> 2));
829

830 831 832 833
    for(i = 0; i < TM2_NUM_STREAMS; i++) {
        l->tokens[i] = NULL;
        l->tok_lens[i] = 0;
    }
834

835 836 837 838 839 840 841
    l->Y1 = av_malloc(sizeof(int) * avctx->width * avctx->height);
    l->U1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1));
    l->V1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1));
    l->Y2 = av_malloc(sizeof(int) * avctx->width * avctx->height);
    l->U2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1));
    l->V2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1));
    l->cur = 0;
842

843 844 845
    return 0;
}

846
static av_cold int decode_end(AVCodecContext *avctx){
847
    TM2Context * const l = avctx->priv_data;
848
    AVFrame *pic = &l->pic;
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865
    int i;

    if(l->last)
        av_free(l->last);
    if(l->clast)
        av_free(l->clast);
    for(i = 0; i < TM2_NUM_STREAMS; i++)
        if(l->tokens[i])
            av_free(l->tokens[i]);
    if(l->Y1){
        av_free(l->Y1);
        av_free(l->U1);
        av_free(l->V1);
        av_free(l->Y2);
        av_free(l->U2);
        av_free(l->V2);
    }
866 867 868 869

    if (pic->data[0])
        avctx->release_buffer(avctx, pic);

870 871 872 873 874
    return 0;
}

AVCodec truemotion2_decoder = {
    "truemotion2",
875
    AVMEDIA_TYPE_VIDEO,
876 877 878 879 880 881 882
    CODEC_ID_TRUEMOTION2,
    sizeof(TM2Context),
    decode_init,
    NULL,
    decode_end,
    decode_frame,
    CODEC_CAP_DR1,
883
    .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
884
};