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