annotate ffmpeg/libavcodec/truemotion2.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Duck/ON2 TrueMotion 2 Decoder
yading@10 3 * Copyright (c) 2005 Konstantin Shishkov
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 /**
yading@10 23 * @file
yading@10 24 * Duck TrueMotion2 decoder.
yading@10 25 */
yading@10 26
yading@10 27 #include "avcodec.h"
yading@10 28 #include "bytestream.h"
yading@10 29 #include "get_bits.h"
yading@10 30 #include "dsputil.h"
yading@10 31 #include "internal.h"
yading@10 32
yading@10 33 #define TM2_ESCAPE 0x80000000
yading@10 34 #define TM2_DELTAS 64
yading@10 35
yading@10 36 /* Huffman-coded streams of different types of blocks */
yading@10 37 enum TM2_STREAMS {
yading@10 38 TM2_C_HI = 0,
yading@10 39 TM2_C_LO,
yading@10 40 TM2_L_HI,
yading@10 41 TM2_L_LO,
yading@10 42 TM2_UPD,
yading@10 43 TM2_MOT,
yading@10 44 TM2_TYPE,
yading@10 45 TM2_NUM_STREAMS
yading@10 46 };
yading@10 47
yading@10 48 /* Block types */
yading@10 49 enum TM2_BLOCKS {
yading@10 50 TM2_HI_RES = 0,
yading@10 51 TM2_MED_RES,
yading@10 52 TM2_LOW_RES,
yading@10 53 TM2_NULL_RES,
yading@10 54 TM2_UPDATE,
yading@10 55 TM2_STILL,
yading@10 56 TM2_MOTION
yading@10 57 };
yading@10 58
yading@10 59 typedef struct TM2Context {
yading@10 60 AVCodecContext *avctx;
yading@10 61 AVFrame pic;
yading@10 62
yading@10 63 GetBitContext gb;
yading@10 64 DSPContext dsp;
yading@10 65
yading@10 66 uint8_t *buffer;
yading@10 67 int buffer_size;
yading@10 68
yading@10 69 /* TM2 streams */
yading@10 70 int *tokens[TM2_NUM_STREAMS];
yading@10 71 int tok_lens[TM2_NUM_STREAMS];
yading@10 72 int tok_ptrs[TM2_NUM_STREAMS];
yading@10 73 int deltas[TM2_NUM_STREAMS][TM2_DELTAS];
yading@10 74 /* for blocks decoding */
yading@10 75 int D[4];
yading@10 76 int CD[4];
yading@10 77 int *last;
yading@10 78 int *clast;
yading@10 79
yading@10 80 /* data for current and previous frame */
yading@10 81 int *Y1_base, *U1_base, *V1_base, *Y2_base, *U2_base, *V2_base;
yading@10 82 int *Y1, *U1, *V1, *Y2, *U2, *V2;
yading@10 83 int y_stride, uv_stride;
yading@10 84 int cur;
yading@10 85 } TM2Context;
yading@10 86
yading@10 87 /**
yading@10 88 * Huffman codes for each of streams
yading@10 89 */
yading@10 90 typedef struct TM2Codes {
yading@10 91 VLC vlc; ///< table for FFmpeg bitstream reader
yading@10 92 int bits;
yading@10 93 int *recode; ///< table for converting from code indexes to values
yading@10 94 int length;
yading@10 95 } TM2Codes;
yading@10 96
yading@10 97 /**
yading@10 98 * structure for gathering Huffman codes information
yading@10 99 */
yading@10 100 typedef struct TM2Huff {
yading@10 101 int val_bits; ///< length of literal
yading@10 102 int max_bits; ///< maximum length of code
yading@10 103 int min_bits; ///< minimum length of code
yading@10 104 int nodes; ///< total number of nodes in tree
yading@10 105 int num; ///< current number filled
yading@10 106 int max_num; ///< total number of codes
yading@10 107 int *nums; ///< literals
yading@10 108 uint32_t *bits; ///< codes
yading@10 109 int *lens; ///< codelengths
yading@10 110 } TM2Huff;
yading@10 111
yading@10 112 static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
yading@10 113 {
yading@10 114 int ret;
yading@10 115 if (length > huff->max_bits) {
yading@10 116 av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n",
yading@10 117 huff->max_bits);
yading@10 118 return AVERROR_INVALIDDATA;
yading@10 119 }
yading@10 120
yading@10 121 if (!get_bits1(&ctx->gb)) { /* literal */
yading@10 122 if (length == 0) {
yading@10 123 length = 1;
yading@10 124 }
yading@10 125 if (huff->num >= huff->max_num) {
yading@10 126 av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
yading@10 127 return AVERROR_INVALIDDATA;
yading@10 128 }
yading@10 129 huff->nums[huff->num] = get_bits_long(&ctx->gb, huff->val_bits);
yading@10 130 huff->bits[huff->num] = prefix;
yading@10 131 huff->lens[huff->num] = length;
yading@10 132 huff->num++;
yading@10 133 return 0;
yading@10 134 } else { /* non-terminal node */
yading@10 135 if ((ret = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0)
yading@10 136 return ret;
yading@10 137 if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0)
yading@10 138 return ret;
yading@10 139 }
yading@10 140 return 0;
yading@10 141 }
yading@10 142
yading@10 143 static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
yading@10 144 {
yading@10 145 TM2Huff huff;
yading@10 146 int res = 0;
yading@10 147
yading@10 148 huff.val_bits = get_bits(&ctx->gb, 5);
yading@10 149 huff.max_bits = get_bits(&ctx->gb, 5);
yading@10 150 huff.min_bits = get_bits(&ctx->gb, 5);
yading@10 151 huff.nodes = get_bits_long(&ctx->gb, 17);
yading@10 152 huff.num = 0;
yading@10 153
yading@10 154 /* check for correct codes parameters */
yading@10 155 if ((huff.val_bits < 1) || (huff.val_bits > 32) ||
yading@10 156 (huff.max_bits < 0) || (huff.max_bits > 25)) {
yading@10 157 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal "
yading@10 158 "length: %i, max code length: %i\n", huff.val_bits, huff.max_bits);
yading@10 159 return AVERROR_INVALIDDATA;
yading@10 160 }
yading@10 161 if ((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
yading@10 162 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree "
yading@10 163 "nodes: %i\n", huff.nodes);
yading@10 164 return AVERROR_INVALIDDATA;
yading@10 165 }
yading@10 166 /* one-node tree */
yading@10 167 if (huff.max_bits == 0)
yading@10 168 huff.max_bits = 1;
yading@10 169
yading@10 170 /* allocate space for codes - it is exactly ceil(nodes / 2) entries */
yading@10 171 huff.max_num = (huff.nodes + 1) >> 1;
yading@10 172 huff.nums = av_mallocz(huff.max_num * sizeof(int));
yading@10 173 huff.bits = av_mallocz(huff.max_num * sizeof(uint32_t));
yading@10 174 huff.lens = av_mallocz(huff.max_num * sizeof(int));
yading@10 175
yading@10 176 res = tm2_read_tree(ctx, 0, 0, &huff);
yading@10 177
yading@10 178 if (huff.num != huff.max_num) {
yading@10 179 av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
yading@10 180 huff.num, huff.max_num);
yading@10 181 res = AVERROR_INVALIDDATA;
yading@10 182 }
yading@10 183
yading@10 184 /* convert codes to vlc_table */
yading@10 185 if (res >= 0) {
yading@10 186 int i;
yading@10 187
yading@10 188 res = init_vlc(&code->vlc, huff.max_bits, huff.max_num,
yading@10 189 huff.lens, sizeof(int), sizeof(int),
yading@10 190 huff.bits, sizeof(uint32_t), sizeof(uint32_t), 0);
yading@10 191 if (res < 0)
yading@10 192 av_log(ctx->avctx, AV_LOG_ERROR, "Cannot build VLC table\n");
yading@10 193 else {
yading@10 194 code->bits = huff.max_bits;
yading@10 195 code->length = huff.max_num;
yading@10 196 code->recode = av_malloc(code->length * sizeof(int));
yading@10 197 for (i = 0; i < code->length; i++)
yading@10 198 code->recode[i] = huff.nums[i];
yading@10 199 }
yading@10 200 }
yading@10 201 /* free allocated memory */
yading@10 202 av_free(huff.nums);
yading@10 203 av_free(huff.bits);
yading@10 204 av_free(huff.lens);
yading@10 205
yading@10 206 return res;
yading@10 207 }
yading@10 208
yading@10 209 static void tm2_free_codes(TM2Codes *code)
yading@10 210 {
yading@10 211 av_free(code->recode);
yading@10 212 if (code->vlc.table)
yading@10 213 ff_free_vlc(&code->vlc);
yading@10 214 }
yading@10 215
yading@10 216 static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code)
yading@10 217 {
yading@10 218 int val;
yading@10 219 val = get_vlc2(gb, code->vlc.table, code->bits, 1);
yading@10 220 if(val<0)
yading@10 221 return -1;
yading@10 222 return code->recode[val];
yading@10 223 }
yading@10 224
yading@10 225 #define TM2_OLD_HEADER_MAGIC 0x00000100
yading@10 226 #define TM2_NEW_HEADER_MAGIC 0x00000101
yading@10 227
yading@10 228 static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
yading@10 229 {
yading@10 230 uint32_t magic = AV_RL32(buf);
yading@10 231
yading@10 232 switch (magic) {
yading@10 233 case TM2_OLD_HEADER_MAGIC:
yading@10 234 avpriv_request_sample(ctx->avctx, "Old TM2 header");
yading@10 235 return 0;
yading@10 236 case TM2_NEW_HEADER_MAGIC:
yading@10 237 return 0;
yading@10 238 default:
yading@10 239 av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic);
yading@10 240 return AVERROR_INVALIDDATA;
yading@10 241 }
yading@10 242 }
yading@10 243
yading@10 244 static int tm2_read_deltas(TM2Context *ctx, int stream_id)
yading@10 245 {
yading@10 246 int d, mb;
yading@10 247 int i, v;
yading@10 248
yading@10 249 d = get_bits(&ctx->gb, 9);
yading@10 250 mb = get_bits(&ctx->gb, 5);
yading@10 251
yading@10 252 if ((d < 1) || (d > TM2_DELTAS) || (mb < 1) || (mb > 32)) {
yading@10 253 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
yading@10 254 return AVERROR_INVALIDDATA;
yading@10 255 }
yading@10 256
yading@10 257 for (i = 0; i < d; i++) {
yading@10 258 v = get_bits_long(&ctx->gb, mb);
yading@10 259 if (v & (1 << (mb - 1)))
yading@10 260 ctx->deltas[stream_id][i] = v - (1 << mb);
yading@10 261 else
yading@10 262 ctx->deltas[stream_id][i] = v;
yading@10 263 }
yading@10 264 for (; i < TM2_DELTAS; i++)
yading@10 265 ctx->deltas[stream_id][i] = 0;
yading@10 266
yading@10 267 return 0;
yading@10 268 }
yading@10 269
yading@10 270 static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size)
yading@10 271 {
yading@10 272 int i, ret;
yading@10 273 int skip = 0;
yading@10 274 int len, toks, pos;
yading@10 275 TM2Codes codes;
yading@10 276 GetByteContext gb;
yading@10 277
yading@10 278 if (buf_size < 4) {
yading@10 279 av_log(ctx->avctx, AV_LOG_ERROR, "not enough space for len left\n");
yading@10 280 return AVERROR_INVALIDDATA;
yading@10 281 }
yading@10 282
yading@10 283 /* get stream length in dwords */
yading@10 284 bytestream2_init(&gb, buf, buf_size);
yading@10 285 len = bytestream2_get_be32(&gb);
yading@10 286 skip = len * 4 + 4;
yading@10 287
yading@10 288 if (len == 0)
yading@10 289 return 4;
yading@10 290
yading@10 291 if (len >= INT_MAX/4-1 || len < 0 || skip > buf_size) {
yading@10 292 av_log(ctx->avctx, AV_LOG_ERROR, "invalid stream size\n");
yading@10 293 return AVERROR_INVALIDDATA;
yading@10 294 }
yading@10 295
yading@10 296 toks = bytestream2_get_be32(&gb);
yading@10 297 if (toks & 1) {
yading@10 298 len = bytestream2_get_be32(&gb);
yading@10 299 if (len == TM2_ESCAPE) {
yading@10 300 len = bytestream2_get_be32(&gb);
yading@10 301 }
yading@10 302 if (len > 0) {
yading@10 303 pos = bytestream2_tell(&gb);
yading@10 304 if (skip <= pos)
yading@10 305 return AVERROR_INVALIDDATA;
yading@10 306 init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
yading@10 307 if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
yading@10 308 return ret;
yading@10 309 bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
yading@10 310 }
yading@10 311 }
yading@10 312 /* skip unused fields */
yading@10 313 len = bytestream2_get_be32(&gb);
yading@10 314 if (len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
yading@10 315 bytestream2_skip(&gb, 8); /* unused by decoder */
yading@10 316 } else {
yading@10 317 bytestream2_skip(&gb, 4); /* unused by decoder */
yading@10 318 }
yading@10 319
yading@10 320 pos = bytestream2_tell(&gb);
yading@10 321 if (skip <= pos)
yading@10 322 return AVERROR_INVALIDDATA;
yading@10 323 init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
yading@10 324 if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
yading@10 325 return ret;
yading@10 326 bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
yading@10 327
yading@10 328 toks >>= 1;
yading@10 329 /* check if we have sane number of tokens */
yading@10 330 if ((toks < 0) || (toks > 0xFFFFFF)) {
yading@10 331 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
yading@10 332 tm2_free_codes(&codes);
yading@10 333 return AVERROR_INVALIDDATA;
yading@10 334 }
yading@10 335 ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int));
yading@10 336 ctx->tok_lens[stream_id] = toks;
yading@10 337 len = bytestream2_get_be32(&gb);
yading@10 338 if (len > 0) {
yading@10 339 pos = bytestream2_tell(&gb);
yading@10 340 if (skip <= pos)
yading@10 341 return AVERROR_INVALIDDATA;
yading@10 342 init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
yading@10 343 for (i = 0; i < toks; i++) {
yading@10 344 if (get_bits_left(&ctx->gb) <= 0) {
yading@10 345 av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
yading@10 346 return AVERROR_INVALIDDATA;
yading@10 347 }
yading@10 348 ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
yading@10 349 if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS || ctx->tokens[stream_id][i]<0) {
yading@10 350 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
yading@10 351 ctx->tokens[stream_id][i], stream_id, i);
yading@10 352 return AVERROR_INVALIDDATA;
yading@10 353 }
yading@10 354 }
yading@10 355 } else {
yading@10 356 for (i = 0; i < toks; i++) {
yading@10 357 ctx->tokens[stream_id][i] = codes.recode[0];
yading@10 358 if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
yading@10 359 av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
yading@10 360 ctx->tokens[stream_id][i], stream_id, i);
yading@10 361 return AVERROR_INVALIDDATA;
yading@10 362 }
yading@10 363 }
yading@10 364 }
yading@10 365 tm2_free_codes(&codes);
yading@10 366
yading@10 367 return skip;
yading@10 368 }
yading@10 369
yading@10 370 static inline int GET_TOK(TM2Context *ctx,int type)
yading@10 371 {
yading@10 372 if (ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
yading@10 373 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]);
yading@10 374 return 0;
yading@10 375 }
yading@10 376 if (type <= TM2_MOT) {
yading@10 377 if (ctx->tokens[type][ctx->tok_ptrs[type]] >= TM2_DELTAS) {
yading@10 378 av_log(ctx->avctx, AV_LOG_ERROR, "token %d is too large\n", ctx->tokens[type][ctx->tok_ptrs[type]]);
yading@10 379 return 0;
yading@10 380 }
yading@10 381 return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
yading@10 382 }
yading@10 383 return ctx->tokens[type][ctx->tok_ptrs[type]++];
yading@10 384 }
yading@10 385
yading@10 386 /* blocks decoding routines */
yading@10 387
yading@10 388 /* common Y, U, V pointers initialisation */
yading@10 389 #define TM2_INIT_POINTERS() \
yading@10 390 int *last, *clast; \
yading@10 391 int *Y, *U, *V;\
yading@10 392 int Ystride, Ustride, Vstride;\
yading@10 393 \
yading@10 394 Ystride = ctx->y_stride;\
yading@10 395 Vstride = ctx->uv_stride;\
yading@10 396 Ustride = ctx->uv_stride;\
yading@10 397 Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\
yading@10 398 V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\
yading@10 399 U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\
yading@10 400 last = ctx->last + bx * 4;\
yading@10 401 clast = ctx->clast + bx * 4;
yading@10 402
yading@10 403 #define TM2_INIT_POINTERS_2() \
yading@10 404 int *Yo, *Uo, *Vo;\
yading@10 405 int oYstride, oUstride, oVstride;\
yading@10 406 \
yading@10 407 TM2_INIT_POINTERS();\
yading@10 408 oYstride = Ystride;\
yading@10 409 oVstride = Vstride;\
yading@10 410 oUstride = Ustride;\
yading@10 411 Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\
yading@10 412 Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\
yading@10 413 Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2;
yading@10 414
yading@10 415 /* recalculate last and delta values for next blocks */
yading@10 416 #define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\
yading@10 417 CD[0] = CHR[1] - last[1];\
yading@10 418 CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\
yading@10 419 last[0] = (int)CHR[stride + 0];\
yading@10 420 last[1] = (int)CHR[stride + 1];}
yading@10 421
yading@10 422 /* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */
yading@10 423 static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last)
yading@10 424 {
yading@10 425 int ct, d;
yading@10 426 int i, j;
yading@10 427
yading@10 428 for (j = 0; j < 4; j++){
yading@10 429 ct = ctx->D[j];
yading@10 430 for (i = 0; i < 4; i++){
yading@10 431 d = deltas[i + j * 4];
yading@10 432 ct += d;
yading@10 433 last[i] += ct;
yading@10 434 Y[i] = av_clip_uint8(last[i]);
yading@10 435 }
yading@10 436 Y += stride;
yading@10 437 ctx->D[j] = ct;
yading@10 438 }
yading@10 439 }
yading@10 440
yading@10 441 static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
yading@10 442 {
yading@10 443 int i, j;
yading@10 444 for (j = 0; j < 2; j++) {
yading@10 445 for (i = 0; i < 2; i++) {
yading@10 446 CD[j] += deltas[i + j * 2];
yading@10 447 last[i] += CD[j];
yading@10 448 data[i] = last[i];
yading@10 449 }
yading@10 450 data += stride;
yading@10 451 }
yading@10 452 }
yading@10 453
yading@10 454 static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx)
yading@10 455 {
yading@10 456 int t;
yading@10 457 int l;
yading@10 458 int prev;
yading@10 459
yading@10 460 if (bx > 0)
yading@10 461 prev = clast[-3];
yading@10 462 else
yading@10 463 prev = 0;
yading@10 464 t = (CD[0] + CD[1]) >> 1;
yading@10 465 l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
yading@10 466 CD[1] = CD[0] + CD[1] - t;
yading@10 467 CD[0] = t;
yading@10 468 clast[0] = l;
yading@10 469
yading@10 470 tm2_high_chroma(data, stride, clast, CD, deltas);
yading@10 471 }
yading@10 472
yading@10 473 static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 474 {
yading@10 475 int i;
yading@10 476 int deltas[16];
yading@10 477 TM2_INIT_POINTERS();
yading@10 478
yading@10 479 /* hi-res chroma */
yading@10 480 for (i = 0; i < 4; i++) {
yading@10 481 deltas[i] = GET_TOK(ctx, TM2_C_HI);
yading@10 482 deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
yading@10 483 }
yading@10 484 tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
yading@10 485 tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
yading@10 486
yading@10 487 /* hi-res luma */
yading@10 488 for (i = 0; i < 16; i++)
yading@10 489 deltas[i] = GET_TOK(ctx, TM2_L_HI);
yading@10 490
yading@10 491 tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
yading@10 492 }
yading@10 493
yading@10 494 static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 495 {
yading@10 496 int i;
yading@10 497 int deltas[16];
yading@10 498 TM2_INIT_POINTERS();
yading@10 499
yading@10 500 /* low-res chroma */
yading@10 501 deltas[0] = GET_TOK(ctx, TM2_C_LO);
yading@10 502 deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 503 tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
yading@10 504
yading@10 505 deltas[0] = GET_TOK(ctx, TM2_C_LO);
yading@10 506 deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 507 tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
yading@10 508
yading@10 509 /* hi-res luma */
yading@10 510 for (i = 0; i < 16; i++)
yading@10 511 deltas[i] = GET_TOK(ctx, TM2_L_HI);
yading@10 512
yading@10 513 tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
yading@10 514 }
yading@10 515
yading@10 516 static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 517 {
yading@10 518 int i;
yading@10 519 int t1, t2;
yading@10 520 int deltas[16];
yading@10 521 TM2_INIT_POINTERS();
yading@10 522
yading@10 523 /* low-res chroma */
yading@10 524 deltas[0] = GET_TOK(ctx, TM2_C_LO);
yading@10 525 deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 526 tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
yading@10 527
yading@10 528 deltas[0] = GET_TOK(ctx, TM2_C_LO);
yading@10 529 deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 530 tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
yading@10 531
yading@10 532 /* low-res luma */
yading@10 533 for (i = 0; i < 16; i++)
yading@10 534 deltas[i] = 0;
yading@10 535
yading@10 536 deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
yading@10 537 deltas[ 2] = GET_TOK(ctx, TM2_L_LO);
yading@10 538 deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
yading@10 539 deltas[10] = GET_TOK(ctx, TM2_L_LO);
yading@10 540
yading@10 541 if (bx > 0)
yading@10 542 last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
yading@10 543 else
yading@10 544 last[0] = (last[1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
yading@10 545 last[2] = (last[1] + last[3]) >> 1;
yading@10 546
yading@10 547 t1 = ctx->D[0] + ctx->D[1];
yading@10 548 ctx->D[0] = t1 >> 1;
yading@10 549 ctx->D[1] = t1 - (t1 >> 1);
yading@10 550 t2 = ctx->D[2] + ctx->D[3];
yading@10 551 ctx->D[2] = t2 >> 1;
yading@10 552 ctx->D[3] = t2 - (t2 >> 1);
yading@10 553
yading@10 554 tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
yading@10 555 }
yading@10 556
yading@10 557 static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 558 {
yading@10 559 int i;
yading@10 560 int ct;
yading@10 561 int left, right, diff;
yading@10 562 int deltas[16];
yading@10 563 TM2_INIT_POINTERS();
yading@10 564
yading@10 565 /* null chroma */
yading@10 566 deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 567 tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
yading@10 568
yading@10 569 deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
yading@10 570 tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
yading@10 571
yading@10 572 /* null luma */
yading@10 573 for (i = 0; i < 16; i++)
yading@10 574 deltas[i] = 0;
yading@10 575
yading@10 576 ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
yading@10 577
yading@10 578 if (bx > 0)
yading@10 579 left = last[-1] - ct;
yading@10 580 else
yading@10 581 left = 0;
yading@10 582
yading@10 583 right = last[3];
yading@10 584 diff = right - left;
yading@10 585 last[0] = left + (diff >> 2);
yading@10 586 last[1] = left + (diff >> 1);
yading@10 587 last[2] = right - (diff >> 2);
yading@10 588 last[3] = right;
yading@10 589 {
yading@10 590 int tp = left;
yading@10 591
yading@10 592 ctx->D[0] = (tp + (ct >> 2)) - left;
yading@10 593 left += ctx->D[0];
yading@10 594 ctx->D[1] = (tp + (ct >> 1)) - left;
yading@10 595 left += ctx->D[1];
yading@10 596 ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
yading@10 597 left += ctx->D[2];
yading@10 598 ctx->D[3] = (tp + ct) - left;
yading@10 599 }
yading@10 600 tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
yading@10 601 }
yading@10 602
yading@10 603 static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 604 {
yading@10 605 int i, j;
yading@10 606 TM2_INIT_POINTERS_2();
yading@10 607
yading@10 608 /* update chroma */
yading@10 609 for (j = 0; j < 2; j++) {
yading@10 610 for (i = 0; i < 2; i++){
yading@10 611 U[i] = Uo[i];
yading@10 612 V[i] = Vo[i];
yading@10 613 }
yading@10 614 U += Ustride; V += Vstride;
yading@10 615 Uo += oUstride; Vo += oVstride;
yading@10 616 }
yading@10 617 U -= Ustride * 2;
yading@10 618 V -= Vstride * 2;
yading@10 619 TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
yading@10 620 TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
yading@10 621
yading@10 622 /* update deltas */
yading@10 623 ctx->D[0] = Yo[3] - last[3];
yading@10 624 ctx->D[1] = Yo[3 + oYstride] - Yo[3];
yading@10 625 ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
yading@10 626 ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
yading@10 627
yading@10 628 for (j = 0; j < 4; j++) {
yading@10 629 for (i = 0; i < 4; i++) {
yading@10 630 Y[i] = Yo[i];
yading@10 631 last[i] = Yo[i];
yading@10 632 }
yading@10 633 Y += Ystride;
yading@10 634 Yo += oYstride;
yading@10 635 }
yading@10 636 }
yading@10 637
yading@10 638 static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 639 {
yading@10 640 int i, j;
yading@10 641 int d;
yading@10 642 TM2_INIT_POINTERS_2();
yading@10 643
yading@10 644 /* update chroma */
yading@10 645 for (j = 0; j < 2; j++) {
yading@10 646 for (i = 0; i < 2; i++) {
yading@10 647 U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
yading@10 648 V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
yading@10 649 }
yading@10 650 U += Ustride;
yading@10 651 V += Vstride;
yading@10 652 Uo += oUstride;
yading@10 653 Vo += oVstride;
yading@10 654 }
yading@10 655 U -= Ustride * 2;
yading@10 656 V -= Vstride * 2;
yading@10 657 TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
yading@10 658 TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
yading@10 659
yading@10 660 /* update deltas */
yading@10 661 ctx->D[0] = Yo[3] - last[3];
yading@10 662 ctx->D[1] = Yo[3 + oYstride] - Yo[3];
yading@10 663 ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
yading@10 664 ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
yading@10 665
yading@10 666 for (j = 0; j < 4; j++) {
yading@10 667 d = last[3];
yading@10 668 for (i = 0; i < 4; i++) {
yading@10 669 Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
yading@10 670 last[i] = Y[i];
yading@10 671 }
yading@10 672 ctx->D[j] = last[3] - d;
yading@10 673 Y += Ystride;
yading@10 674 Yo += oYstride;
yading@10 675 }
yading@10 676 }
yading@10 677
yading@10 678 static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
yading@10 679 {
yading@10 680 int i, j;
yading@10 681 int mx, my;
yading@10 682 TM2_INIT_POINTERS_2();
yading@10 683
yading@10 684 mx = GET_TOK(ctx, TM2_MOT);
yading@10 685 my = GET_TOK(ctx, TM2_MOT);
yading@10 686 mx = av_clip(mx, -(bx * 4 + 4), ctx->avctx->width - bx * 4);
yading@10 687 my = av_clip(my, -(by * 4 + 4), ctx->avctx->height - by * 4);
yading@10 688
yading@10 689 if (4*bx+mx<0 || 4*by+my<0 || 4*bx+mx+4 > ctx->avctx->width || 4*by+my+4 > ctx->avctx->height) {
yading@10 690 av_log(ctx->avctx, AV_LOG_ERROR, "MV out of picture\n");
yading@10 691 return;
yading@10 692 }
yading@10 693
yading@10 694 Yo += my * oYstride + mx;
yading@10 695 Uo += (my >> 1) * oUstride + (mx >> 1);
yading@10 696 Vo += (my >> 1) * oVstride + (mx >> 1);
yading@10 697
yading@10 698 /* copy chroma */
yading@10 699 for (j = 0; j < 2; j++) {
yading@10 700 for (i = 0; i < 2; i++) {
yading@10 701 U[i] = Uo[i];
yading@10 702 V[i] = Vo[i];
yading@10 703 }
yading@10 704 U += Ustride;
yading@10 705 V += Vstride;
yading@10 706 Uo += oUstride;
yading@10 707 Vo += oVstride;
yading@10 708 }
yading@10 709 U -= Ustride * 2;
yading@10 710 V -= Vstride * 2;
yading@10 711 TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
yading@10 712 TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
yading@10 713
yading@10 714 /* copy luma */
yading@10 715 for (j = 0; j < 4; j++) {
yading@10 716 for (i = 0; i < 4; i++) {
yading@10 717 Y[i] = Yo[i];
yading@10 718 }
yading@10 719 Y += Ystride;
yading@10 720 Yo += oYstride;
yading@10 721 }
yading@10 722 /* calculate deltas */
yading@10 723 Y -= Ystride * 4;
yading@10 724 ctx->D[0] = Y[3] - last[3];
yading@10 725 ctx->D[1] = Y[3 + Ystride] - Y[3];
yading@10 726 ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
yading@10 727 ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
yading@10 728 for (i = 0; i < 4; i++)
yading@10 729 last[i] = Y[i + Ystride * 3];
yading@10 730 }
yading@10 731
yading@10 732 static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
yading@10 733 {
yading@10 734 int i, j;
yading@10 735 int w = ctx->avctx->width, h = ctx->avctx->height, bw = w >> 2, bh = h >> 2, cw = w >> 1;
yading@10 736 int type;
yading@10 737 int keyframe = 1;
yading@10 738 int *Y, *U, *V;
yading@10 739 uint8_t *dst;
yading@10 740
yading@10 741 for (i = 0; i < TM2_NUM_STREAMS; i++)
yading@10 742 ctx->tok_ptrs[i] = 0;
yading@10 743
yading@10 744 if (ctx->tok_lens[TM2_TYPE]<bw*bh) {
yading@10 745 av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
yading@10 746 return AVERROR_INVALIDDATA;
yading@10 747 }
yading@10 748
yading@10 749 memset(ctx->last, 0, 4 * bw * sizeof(int));
yading@10 750 memset(ctx->clast, 0, 4 * bw * sizeof(int));
yading@10 751
yading@10 752 for (j = 0; j < bh; j++) {
yading@10 753 memset(ctx->D, 0, 4 * sizeof(int));
yading@10 754 memset(ctx->CD, 0, 4 * sizeof(int));
yading@10 755 for (i = 0; i < bw; i++) {
yading@10 756 type = GET_TOK(ctx, TM2_TYPE);
yading@10 757 switch(type) {
yading@10 758 case TM2_HI_RES:
yading@10 759 tm2_hi_res_block(ctx, p, i, j);
yading@10 760 break;
yading@10 761 case TM2_MED_RES:
yading@10 762 tm2_med_res_block(ctx, p, i, j);
yading@10 763 break;
yading@10 764 case TM2_LOW_RES:
yading@10 765 tm2_low_res_block(ctx, p, i, j);
yading@10 766 break;
yading@10 767 case TM2_NULL_RES:
yading@10 768 tm2_null_res_block(ctx, p, i, j);
yading@10 769 break;
yading@10 770 case TM2_UPDATE:
yading@10 771 tm2_update_block(ctx, p, i, j);
yading@10 772 keyframe = 0;
yading@10 773 break;
yading@10 774 case TM2_STILL:
yading@10 775 tm2_still_block(ctx, p, i, j);
yading@10 776 keyframe = 0;
yading@10 777 break;
yading@10 778 case TM2_MOTION:
yading@10 779 tm2_motion_block(ctx, p, i, j);
yading@10 780 keyframe = 0;
yading@10 781 break;
yading@10 782 default:
yading@10 783 av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
yading@10 784 }
yading@10 785 }
yading@10 786 }
yading@10 787
yading@10 788 /* copy data from our buffer to AVFrame */
yading@10 789 Y = (ctx->cur?ctx->Y2:ctx->Y1);
yading@10 790 U = (ctx->cur?ctx->U2:ctx->U1);
yading@10 791 V = (ctx->cur?ctx->V2:ctx->V1);
yading@10 792 dst = p->data[0];
yading@10 793 for (j = 0; j < h; j++) {
yading@10 794 for (i = 0; i < w; i++) {
yading@10 795 int y = Y[i], u = U[i >> 1], v = V[i >> 1];
yading@10 796 dst[3*i+0] = av_clip_uint8(y + v);
yading@10 797 dst[3*i+1] = av_clip_uint8(y);
yading@10 798 dst[3*i+2] = av_clip_uint8(y + u);
yading@10 799 }
yading@10 800
yading@10 801 /* horizontal edge extension */
yading@10 802 Y[-4] = Y[-3] = Y[-2] = Y[-1] = Y[0];
yading@10 803 Y[w + 3] = Y[w + 2] = Y[w + 1] = Y[w] = Y[w - 1];
yading@10 804
yading@10 805 /* vertical edge extension */
yading@10 806 if (j == 0) {
yading@10 807 memcpy(Y - 4 - 1 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 808 memcpy(Y - 4 - 2 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 809 memcpy(Y - 4 - 3 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 810 memcpy(Y - 4 - 4 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 811 } else if (j == h - 1) {
yading@10 812 memcpy(Y - 4 + 1 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 813 memcpy(Y - 4 + 2 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 814 memcpy(Y - 4 + 3 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 815 memcpy(Y - 4 + 4 * ctx->y_stride, Y - 4, ctx->y_stride);
yading@10 816 }
yading@10 817
yading@10 818 Y += ctx->y_stride;
yading@10 819 if (j & 1) {
yading@10 820 /* horizontal edge extension */
yading@10 821 U[-2] = U[-1] = U[0];
yading@10 822 V[-2] = V[-1] = V[0];
yading@10 823 U[cw + 1] = U[cw] = U[cw - 1];
yading@10 824 V[cw + 1] = V[cw] = V[cw - 1];
yading@10 825
yading@10 826 /* vertical edge extension */
yading@10 827 if (j == 1) {
yading@10 828 memcpy(U - 2 - 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
yading@10 829 memcpy(V - 2 - 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
yading@10 830 memcpy(U - 2 - 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
yading@10 831 memcpy(V - 2 - 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
yading@10 832 } else if (j == h - 1) {
yading@10 833 memcpy(U - 2 + 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
yading@10 834 memcpy(V - 2 + 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
yading@10 835 memcpy(U - 2 + 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
yading@10 836 memcpy(V - 2 + 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
yading@10 837 }
yading@10 838
yading@10 839 U += ctx->uv_stride;
yading@10 840 V += ctx->uv_stride;
yading@10 841 }
yading@10 842 dst += p->linesize[0];
yading@10 843 }
yading@10 844
yading@10 845 return keyframe;
yading@10 846 }
yading@10 847
yading@10 848 static const int tm2_stream_order[TM2_NUM_STREAMS] = {
yading@10 849 TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE
yading@10 850 };
yading@10 851
yading@10 852 #define TM2_HEADER_SIZE 40
yading@10 853
yading@10 854 static int decode_frame(AVCodecContext *avctx,
yading@10 855 void *data, int *got_frame,
yading@10 856 AVPacket *avpkt)
yading@10 857 {
yading@10 858 TM2Context * const l = avctx->priv_data;
yading@10 859 const uint8_t *buf = avpkt->data;
yading@10 860 int buf_size = avpkt->size & ~3;
yading@10 861 AVFrame * const p = &l->pic;
yading@10 862 int offset = TM2_HEADER_SIZE;
yading@10 863 int i, t, ret;
yading@10 864
yading@10 865 av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size);
yading@10 866 if (!l->buffer) {
yading@10 867 av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
yading@10 868 return AVERROR(ENOMEM);
yading@10 869 }
yading@10 870
yading@10 871 if ((ret = ff_reget_buffer(avctx, p)) < 0)
yading@10 872 return ret;
yading@10 873
yading@10 874 l->dsp.bswap_buf((uint32_t*)l->buffer, (const uint32_t*)buf, buf_size >> 2);
yading@10 875
yading@10 876 if ((ret = tm2_read_header(l, l->buffer)) < 0) {
yading@10 877 return ret;
yading@10 878 }
yading@10 879
yading@10 880 for (i = 0; i < TM2_NUM_STREAMS; i++) {
yading@10 881 if (offset >= buf_size) {
yading@10 882 av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n");
yading@10 883 return AVERROR_INVALIDDATA;
yading@10 884 }
yading@10 885
yading@10 886 t = tm2_read_stream(l, l->buffer + offset, tm2_stream_order[i],
yading@10 887 buf_size - offset);
yading@10 888 if (t < 0) {
yading@10 889 int j = tm2_stream_order[i];
yading@10 890 memset(l->tokens[j], 0, sizeof(**l->tokens) * l->tok_lens[j]);
yading@10 891 return t;
yading@10 892 }
yading@10 893 offset += t;
yading@10 894 }
yading@10 895 p->key_frame = tm2_decode_blocks(l, p);
yading@10 896 if (p->key_frame)
yading@10 897 p->pict_type = AV_PICTURE_TYPE_I;
yading@10 898 else
yading@10 899 p->pict_type = AV_PICTURE_TYPE_P;
yading@10 900
yading@10 901 l->cur = !l->cur;
yading@10 902 *got_frame = 1;
yading@10 903 ret = av_frame_ref(data, &l->pic);
yading@10 904
yading@10 905 return (ret < 0) ? ret : buf_size;
yading@10 906 }
yading@10 907
yading@10 908 static av_cold int decode_init(AVCodecContext *avctx)
yading@10 909 {
yading@10 910 TM2Context * const l = avctx->priv_data;
yading@10 911 int i, w = avctx->width, h = avctx->height;
yading@10 912
yading@10 913 if ((avctx->width & 3) || (avctx->height & 3)) {
yading@10 914 av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
yading@10 915 return AVERROR(EINVAL);
yading@10 916 }
yading@10 917
yading@10 918 l->avctx = avctx;
yading@10 919 avcodec_get_frame_defaults(&l->pic);
yading@10 920 avctx->pix_fmt = AV_PIX_FMT_BGR24;
yading@10 921
yading@10 922 ff_dsputil_init(&l->dsp, avctx);
yading@10 923
yading@10 924 l->last = av_malloc(4 * sizeof(*l->last) * (w >> 2));
yading@10 925 l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2));
yading@10 926
yading@10 927 for (i = 0; i < TM2_NUM_STREAMS; i++) {
yading@10 928 l->tokens[i] = NULL;
yading@10 929 l->tok_lens[i] = 0;
yading@10 930 }
yading@10 931
yading@10 932 w += 8;
yading@10 933 h += 8;
yading@10 934 l->Y1_base = av_mallocz(sizeof(*l->Y1_base) * w * h);
yading@10 935 l->Y2_base = av_mallocz(sizeof(*l->Y2_base) * w * h);
yading@10 936 l->y_stride = w;
yading@10 937 w = (w + 1) >> 1;
yading@10 938 h = (h + 1) >> 1;
yading@10 939 l->U1_base = av_mallocz(sizeof(*l->U1_base) * w * h);
yading@10 940 l->V1_base = av_mallocz(sizeof(*l->V1_base) * w * h);
yading@10 941 l->U2_base = av_mallocz(sizeof(*l->U2_base) * w * h);
yading@10 942 l->V2_base = av_mallocz(sizeof(*l->V1_base) * w * h);
yading@10 943 l->uv_stride = w;
yading@10 944 l->cur = 0;
yading@10 945 if (!l->Y1_base || !l->Y2_base || !l->U1_base ||
yading@10 946 !l->V1_base || !l->U2_base || !l->V2_base ||
yading@10 947 !l->last || !l->clast) {
yading@10 948 av_freep(l->Y1_base);
yading@10 949 av_freep(l->Y2_base);
yading@10 950 av_freep(l->U1_base);
yading@10 951 av_freep(l->U2_base);
yading@10 952 av_freep(l->V1_base);
yading@10 953 av_freep(l->V2_base);
yading@10 954 av_freep(l->last);
yading@10 955 av_freep(l->clast);
yading@10 956 return AVERROR(ENOMEM);
yading@10 957 }
yading@10 958 l->Y1 = l->Y1_base + l->y_stride * 4 + 4;
yading@10 959 l->Y2 = l->Y2_base + l->y_stride * 4 + 4;
yading@10 960 l->U1 = l->U1_base + l->uv_stride * 2 + 2;
yading@10 961 l->U2 = l->U2_base + l->uv_stride * 2 + 2;
yading@10 962 l->V1 = l->V1_base + l->uv_stride * 2 + 2;
yading@10 963 l->V2 = l->V2_base + l->uv_stride * 2 + 2;
yading@10 964
yading@10 965 return 0;
yading@10 966 }
yading@10 967
yading@10 968 static av_cold int decode_end(AVCodecContext *avctx)
yading@10 969 {
yading@10 970 TM2Context * const l = avctx->priv_data;
yading@10 971 AVFrame *pic = &l->pic;
yading@10 972 int i;
yading@10 973
yading@10 974 av_free(l->last);
yading@10 975 av_free(l->clast);
yading@10 976 for (i = 0; i < TM2_NUM_STREAMS; i++)
yading@10 977 av_free(l->tokens[i]);
yading@10 978 if (l->Y1) {
yading@10 979 av_free(l->Y1_base);
yading@10 980 av_free(l->U1_base);
yading@10 981 av_free(l->V1_base);
yading@10 982 av_free(l->Y2_base);
yading@10 983 av_free(l->U2_base);
yading@10 984 av_free(l->V2_base);
yading@10 985 }
yading@10 986 av_freep(&l->buffer);
yading@10 987 l->buffer_size = 0;
yading@10 988
yading@10 989 av_frame_unref(pic);
yading@10 990
yading@10 991 return 0;
yading@10 992 }
yading@10 993
yading@10 994 AVCodec ff_truemotion2_decoder = {
yading@10 995 .name = "truemotion2",
yading@10 996 .type = AVMEDIA_TYPE_VIDEO,
yading@10 997 .id = AV_CODEC_ID_TRUEMOTION2,
yading@10 998 .priv_data_size = sizeof(TM2Context),
yading@10 999 .init = decode_init,
yading@10 1000 .close = decode_end,
yading@10 1001 .decode = decode_frame,
yading@10 1002 .capabilities = CODEC_CAP_DR1,
yading@10 1003 .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
yading@10 1004 };