ffmpeg / libavcodec / truemotion2.c @ 5509bffa
History | View | Annotate | Download (24.7 KB)
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 64 |
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 * 8); |
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) * 8);
|
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) * 8);
|
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) * 8);
|
316 |
for(i = 0; i < toks; i++) |
317 |
ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); |
318 |
} else {
|
319 |
for(i = 0; i < toks; i++) |
320 |
ctx->tokens[stream_id][i] = codes.recode[0];
|
321 |
} |
322 |
tm2_free_codes(&codes); |
323 |
|
324 |
return skip;
|
325 |
} |
326 |
|
327 |
static inline int GET_TOK(TM2Context *ctx,int type) { |
328 |
if(ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
|
329 |
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]);
|
330 |
return 0; |
331 |
} |
332 |
if(type <= TM2_MOT)
|
333 |
return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
|
334 |
return ctx->tokens[type][ctx->tok_ptrs[type]++];
|
335 |
} |
336 |
|
337 |
/* blocks decoding routines */
|
338 |
|
339 |
/* common Y, U, V pointers initialisation */
|
340 |
#define TM2_INIT_POINTERS() \
|
341 |
int *last, *clast; \
|
342 |
int *Y, *U, *V;\
|
343 |
int Ystride, Ustride, Vstride;\
|
344 |
\ |
345 |
Ystride = ctx->avctx->width;\ |
346 |
Vstride = (ctx->avctx->width + 1) >> 1;\ |
347 |
Ustride = (ctx->avctx->width + 1) >> 1;\ |
348 |
Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\ |
349 |
V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\ |
350 |
U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\ |
351 |
last = ctx->last + bx * 4;\
|
352 |
clast = ctx->clast + bx * 4;
|
353 |
|
354 |
#define TM2_INIT_POINTERS_2() \
|
355 |
int *Yo, *Uo, *Vo;\
|
356 |
int oYstride, oUstride, oVstride;\
|
357 |
\ |
358 |
TM2_INIT_POINTERS();\ |
359 |
oYstride = Ystride;\ |
360 |
oVstride = Vstride;\ |
361 |
oUstride = Ustride;\ |
362 |
Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\ |
363 |
Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\ |
364 |
Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2; |
365 |
|
366 |
/* recalculate last and delta values for next blocks */
|
367 |
#define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\
|
368 |
CD[0] = (CHR[1] - 128) - last[1];\ |
369 |
CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\ |
370 |
last[0] = (int)CHR[stride + 0] - 128;\ |
371 |
last[1] = (int)CHR[stride + 1] - 128;} |
372 |
|
373 |
/* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */
|
374 |
static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last) |
375 |
{ |
376 |
int ct, d;
|
377 |
int i, j;
|
378 |
|
379 |
for(j = 0; j < 4; j++){ |
380 |
ct = ctx->D[j]; |
381 |
for(i = 0; i < 4; i++){ |
382 |
d = deltas[i + j * 4];
|
383 |
ct += d; |
384 |
last[i] += ct; |
385 |
Y[i] = clip_uint8(last[i]); |
386 |
} |
387 |
Y += stride; |
388 |
ctx->D[j] = ct; |
389 |
} |
390 |
} |
391 |
|
392 |
static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas) |
393 |
{ |
394 |
int i, j;
|
395 |
for(j = 0; j < 2; j++){ |
396 |
for(i = 0; i < 2; i++){ |
397 |
CD[j] += deltas[i + j * 2];
|
398 |
last[i] += CD[j]; |
399 |
data[i] = last[i] + 128;
|
400 |
} |
401 |
data += stride; |
402 |
} |
403 |
} |
404 |
|
405 |
static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx) |
406 |
{ |
407 |
int t;
|
408 |
int l;
|
409 |
int prev;
|
410 |
|
411 |
if(bx > 0) |
412 |
prev = clast[-3];
|
413 |
else
|
414 |
prev = 0;
|
415 |
t = (CD[0] + CD[1]) >> 1; |
416 |
l = (prev - CD[0] - CD[1] + clast[1]) >> 1; |
417 |
CD[1] = CD[0] + CD[1] - t; |
418 |
CD[0] = t;
|
419 |
clast[0] = l;
|
420 |
|
421 |
tm2_high_chroma(data, stride, clast, CD, deltas); |
422 |
} |
423 |
|
424 |
static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
425 |
{ |
426 |
int i;
|
427 |
int deltas[16]; |
428 |
TM2_INIT_POINTERS(); |
429 |
|
430 |
/* hi-res chroma */
|
431 |
for(i = 0; i < 4; i++) { |
432 |
deltas[i] = GET_TOK(ctx, TM2_C_HI); |
433 |
deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
|
434 |
} |
435 |
tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas); |
436 |
tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4); |
437 |
|
438 |
/* hi-res luma */
|
439 |
for(i = 0; i < 16; i++) |
440 |
deltas[i] = GET_TOK(ctx, TM2_L_HI); |
441 |
|
442 |
tm2_apply_deltas(ctx, Y, Ystride, deltas, last); |
443 |
} |
444 |
|
445 |
static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
446 |
{ |
447 |
int i;
|
448 |
int deltas[16]; |
449 |
TM2_INIT_POINTERS(); |
450 |
|
451 |
/* low-res chroma */
|
452 |
deltas[0] = GET_TOK(ctx, TM2_C_LO);
|
453 |
deltas[1] = deltas[2] = deltas[3] = 0; |
454 |
tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); |
455 |
|
456 |
deltas[0] = GET_TOK(ctx, TM2_C_LO);
|
457 |
deltas[1] = deltas[2] = deltas[3] = 0; |
458 |
tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); |
459 |
|
460 |
/* hi-res luma */
|
461 |
for(i = 0; i < 16; i++) |
462 |
deltas[i] = GET_TOK(ctx, TM2_L_HI); |
463 |
|
464 |
tm2_apply_deltas(ctx, Y, Ystride, deltas, last); |
465 |
} |
466 |
|
467 |
static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
468 |
{ |
469 |
int i;
|
470 |
int t1, t2;
|
471 |
int deltas[16]; |
472 |
TM2_INIT_POINTERS(); |
473 |
|
474 |
/* low-res chroma */
|
475 |
deltas[0] = GET_TOK(ctx, TM2_C_LO);
|
476 |
deltas[1] = deltas[2] = deltas[3] = 0; |
477 |
tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); |
478 |
|
479 |
deltas[0] = GET_TOK(ctx, TM2_C_LO);
|
480 |
deltas[1] = deltas[2] = deltas[3] = 0; |
481 |
tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); |
482 |
|
483 |
/* low-res luma */
|
484 |
for(i = 0; i < 16; i++) |
485 |
deltas[i] = 0;
|
486 |
|
487 |
deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
|
488 |
deltas[ 2] = GET_TOK(ctx, TM2_L_LO);
|
489 |
deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
|
490 |
deltas[10] = GET_TOK(ctx, TM2_L_LO);
|
491 |
|
492 |
if(bx > 0) |
493 |
last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1; |
494 |
else
|
495 |
last[0] = (last[1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1; |
496 |
last[2] = (last[1] + last[3]) >> 1; |
497 |
|
498 |
t1 = ctx->D[0] + ctx->D[1]; |
499 |
ctx->D[0] = t1 >> 1; |
500 |
ctx->D[1] = t1 - (t1 >> 1); |
501 |
t2 = ctx->D[2] + ctx->D[3]; |
502 |
ctx->D[2] = t2 >> 1; |
503 |
ctx->D[3] = t2 - (t2 >> 1); |
504 |
|
505 |
tm2_apply_deltas(ctx, Y, Ystride, deltas, last); |
506 |
} |
507 |
|
508 |
static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
509 |
{ |
510 |
int i;
|
511 |
int ct;
|
512 |
int left, right, diff;
|
513 |
int deltas[16]; |
514 |
TM2_INIT_POINTERS(); |
515 |
|
516 |
/* null chroma */
|
517 |
deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0; |
518 |
tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx); |
519 |
|
520 |
deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0; |
521 |
tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx); |
522 |
|
523 |
/* null luma */
|
524 |
for(i = 0; i < 16; i++) |
525 |
deltas[i] = 0;
|
526 |
|
527 |
ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3]; |
528 |
|
529 |
if(bx > 0) |
530 |
left = last[-1] - ct;
|
531 |
else
|
532 |
left = 0;
|
533 |
|
534 |
right = last[3];
|
535 |
diff = right - left; |
536 |
last[0] = left + (diff >> 2); |
537 |
last[1] = left + (diff >> 1); |
538 |
last[2] = right - (diff >> 2); |
539 |
last[3] = right;
|
540 |
{ |
541 |
int tp = left;
|
542 |
|
543 |
ctx->D[0] = (tp + (ct >> 2)) - left; |
544 |
left += ctx->D[0];
|
545 |
ctx->D[1] = (tp + (ct >> 1)) - left; |
546 |
left += ctx->D[1];
|
547 |
ctx->D[2] = ((tp + ct) - (ct >> 2)) - left; |
548 |
left += ctx->D[2];
|
549 |
ctx->D[3] = (tp + ct) - left;
|
550 |
} |
551 |
tm2_apply_deltas(ctx, Y, Ystride, deltas, last); |
552 |
} |
553 |
|
554 |
static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
555 |
{ |
556 |
int i, j;
|
557 |
TM2_INIT_POINTERS_2(); |
558 |
|
559 |
/* update chroma */
|
560 |
for(j = 0; j < 2; j++){ |
561 |
for(i = 0; i < 2; i++){ |
562 |
U[i] = Uo[i]; |
563 |
V[i] = Vo[i]; |
564 |
} |
565 |
U += Ustride; V += Vstride; |
566 |
Uo += oUstride; Vo += oVstride; |
567 |
} |
568 |
U -= Ustride * 2;
|
569 |
V -= Vstride * 2;
|
570 |
TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); |
571 |
TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); |
572 |
|
573 |
/* update deltas */
|
574 |
ctx->D[0] = Yo[3] - last[3]; |
575 |
ctx->D[1] = Yo[3 + oYstride] - Yo[3]; |
576 |
ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride]; |
577 |
ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2]; |
578 |
|
579 |
for(j = 0; j < 4; j++){ |
580 |
for(i = 0; i < 4; i++){ |
581 |
Y[i] = Yo[i]; |
582 |
last[i] = Yo[i]; |
583 |
} |
584 |
Y += Ystride; |
585 |
Yo += oYstride; |
586 |
} |
587 |
} |
588 |
|
589 |
static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
590 |
{ |
591 |
int i, j;
|
592 |
int d;
|
593 |
TM2_INIT_POINTERS_2(); |
594 |
|
595 |
/* update chroma */
|
596 |
for(j = 0; j < 2; j++){ |
597 |
for(i = 0; i < 2; i++){ |
598 |
U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD); |
599 |
V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD); |
600 |
} |
601 |
U += Ustride; V += Vstride; |
602 |
Uo += oUstride; Vo += oVstride; |
603 |
} |
604 |
U -= Ustride * 2;
|
605 |
V -= Vstride * 2;
|
606 |
TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); |
607 |
TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); |
608 |
|
609 |
/* update deltas */
|
610 |
ctx->D[0] = Yo[3] - last[3]; |
611 |
ctx->D[1] = Yo[3 + oYstride] - Yo[3]; |
612 |
ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride]; |
613 |
ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2]; |
614 |
|
615 |
for(j = 0; j < 4; j++){ |
616 |
d = last[3];
|
617 |
for(i = 0; i < 4; i++){ |
618 |
Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD); |
619 |
last[i] = Y[i]; |
620 |
} |
621 |
ctx->D[j] = last[3] - d;
|
622 |
Y += Ystride; |
623 |
Yo += oYstride; |
624 |
} |
625 |
} |
626 |
|
627 |
static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by) |
628 |
{ |
629 |
int i, j;
|
630 |
int mx, my;
|
631 |
TM2_INIT_POINTERS_2(); |
632 |
|
633 |
mx = GET_TOK(ctx, TM2_MOT); |
634 |
my = GET_TOK(ctx, TM2_MOT); |
635 |
|
636 |
Yo += my * oYstride + mx; |
637 |
Uo += (my >> 1) * oUstride + (mx >> 1); |
638 |
Vo += (my >> 1) * oVstride + (mx >> 1); |
639 |
|
640 |
/* copy chroma */
|
641 |
for(j = 0; j < 2; j++){ |
642 |
for(i = 0; i < 2; i++){ |
643 |
U[i] = Uo[i]; |
644 |
V[i] = Vo[i]; |
645 |
} |
646 |
U += Ustride; V += Vstride; |
647 |
Uo += oUstride; Vo += oVstride; |
648 |
} |
649 |
U -= Ustride * 2;
|
650 |
V -= Vstride * 2;
|
651 |
TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD); |
652 |
TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2)); |
653 |
|
654 |
/* copy luma */
|
655 |
for(j = 0; j < 4; j++){ |
656 |
for(i = 0; i < 4; i++){ |
657 |
Y[i] = Yo[i]; |
658 |
} |
659 |
Y += Ystride; |
660 |
Yo += oYstride; |
661 |
} |
662 |
/* calculate deltas */
|
663 |
Y -= Ystride * 4;
|
664 |
ctx->D[0] = Y[3] - last[3]; |
665 |
ctx->D[1] = Y[3 + Ystride] - Y[3]; |
666 |
ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride]; |
667 |
ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2]; |
668 |
for(i = 0; i < 4; i++) |
669 |
last[i] = Y[i + Ystride * 3];
|
670 |
} |
671 |
|
672 |
static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p) |
673 |
{ |
674 |
int i, j;
|
675 |
int bw, bh;
|
676 |
int type;
|
677 |
int keyframe = 1; |
678 |
uint8_t *Y, *U, *V; |
679 |
int *src;
|
680 |
|
681 |
bw = ctx->avctx->width >> 2;
|
682 |
bh = ctx->avctx->height >> 2;
|
683 |
|
684 |
for(i = 0; i < TM2_NUM_STREAMS; i++) |
685 |
ctx->tok_ptrs[i] = 0;
|
686 |
|
687 |
if (ctx->tok_lens[TM2_TYPE]<bw*bh){
|
688 |
av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
|
689 |
return -1; |
690 |
} |
691 |
|
692 |
memset(ctx->last, 0, 4 * bw * sizeof(int)); |
693 |
memset(ctx->clast, 0, 4 * bw * sizeof(int)); |
694 |
|
695 |
for(j = 0; j < bh; j++) { |
696 |
memset(ctx->D, 0, 4 * sizeof(int)); |
697 |
memset(ctx->CD, 0, 4 * sizeof(int)); |
698 |
for(i = 0; i < bw; i++) { |
699 |
type = GET_TOK(ctx, TM2_TYPE); |
700 |
switch(type) {
|
701 |
case TM2_HI_RES:
|
702 |
tm2_hi_res_block(ctx, p, i, j); |
703 |
break;
|
704 |
case TM2_MED_RES:
|
705 |
tm2_med_res_block(ctx, p, i, j); |
706 |
break;
|
707 |
case TM2_LOW_RES:
|
708 |
tm2_low_res_block(ctx, p, i, j); |
709 |
break;
|
710 |
case TM2_NULL_RES:
|
711 |
tm2_null_res_block(ctx, p, i, j); |
712 |
break;
|
713 |
case TM2_UPDATE:
|
714 |
tm2_update_block(ctx, p, i, j); |
715 |
keyframe = 0;
|
716 |
break;
|
717 |
case TM2_STILL:
|
718 |
tm2_still_block(ctx, p, i, j); |
719 |
keyframe = 0;
|
720 |
break;
|
721 |
case TM2_MOTION:
|
722 |
tm2_motion_block(ctx, p, i, j); |
723 |
keyframe = 0;
|
724 |
break;
|
725 |
default:
|
726 |
av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
|
727 |
} |
728 |
} |
729 |
} |
730 |
|
731 |
/* copy data from our buffer to AVFrame */
|
732 |
Y = p->data[0];
|
733 |
src = (ctx->cur?ctx->Y2:ctx->Y1); |
734 |
for(j = 0; j < ctx->avctx->height; j++){ |
735 |
for(i = 0; i < ctx->avctx->width; i++){ |
736 |
Y[i] = clip_uint8(*src++); |
737 |
} |
738 |
Y += p->linesize[0];
|
739 |
} |
740 |
U = p->data[2];
|
741 |
src = (ctx->cur?ctx->U2:ctx->U1); |
742 |
for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){ |
743 |
for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){ |
744 |
U[i] = clip_uint8(*src++); |
745 |
} |
746 |
U += p->linesize[2];
|
747 |
} |
748 |
V = p->data[1];
|
749 |
src = (ctx->cur?ctx->V2:ctx->V1); |
750 |
for(j = 0; j < (ctx->avctx->height + 1) >> 1; j++){ |
751 |
for(i = 0; i < (ctx->avctx->width + 1) >> 1; i++){ |
752 |
V[i] = clip_uint8(*src++); |
753 |
} |
754 |
V += p->linesize[1];
|
755 |
} |
756 |
|
757 |
return keyframe;
|
758 |
} |
759 |
|
760 |
static int decode_frame(AVCodecContext *avctx, |
761 |
void *data, int *data_size, |
762 |
uint8_t *buf, int buf_size)
|
763 |
{ |
764 |
TM2Context * const l = avctx->priv_data;
|
765 |
AVFrame * const p= (AVFrame*)&l->pic;
|
766 |
int skip, t;
|
767 |
|
768 |
p->reference = 1;
|
769 |
p->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; |
770 |
if(avctx->reget_buffer(avctx, p) < 0){ |
771 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
772 |
return -1; |
773 |
} |
774 |
|
775 |
l->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, buf_size >> 2);
|
776 |
skip = tm2_read_header(l, buf); |
777 |
|
778 |
if(skip == -1) |
779 |
return -1; |
780 |
|
781 |
t = tm2_read_stream(l, buf + skip, TM2_C_HI); |
782 |
if(t == -1) |
783 |
return -1; |
784 |
skip += t; |
785 |
t = tm2_read_stream(l, buf + skip, TM2_C_LO); |
786 |
if(t == -1) |
787 |
return -1; |
788 |
skip += t; |
789 |
t = tm2_read_stream(l, buf + skip, TM2_L_HI); |
790 |
if(t == -1) |
791 |
return -1; |
792 |
skip += t; |
793 |
t = tm2_read_stream(l, buf + skip, TM2_L_LO); |
794 |
if(t == -1) |
795 |
return -1; |
796 |
skip += t; |
797 |
t = tm2_read_stream(l, buf + skip, TM2_UPD); |
798 |
if(t == -1) |
799 |
return -1; |
800 |
skip += t; |
801 |
t = tm2_read_stream(l, buf + skip, TM2_MOT); |
802 |
if(t == -1) |
803 |
return -1; |
804 |
skip += t; |
805 |
t = tm2_read_stream(l, buf + skip, TM2_TYPE); |
806 |
if(t == -1) |
807 |
return -1; |
808 |
p->key_frame = tm2_decode_blocks(l, p); |
809 |
if(p->key_frame)
|
810 |
p->pict_type = FF_I_TYPE; |
811 |
else
|
812 |
p->pict_type = FF_P_TYPE; |
813 |
|
814 |
l->cur = !l->cur; |
815 |
*data_size = sizeof(AVFrame);
|
816 |
*(AVFrame*)data = l->pic; |
817 |
|
818 |
return buf_size;
|
819 |
} |
820 |
|
821 |
static int decode_init(AVCodecContext *avctx){ |
822 |
TM2Context * const l = avctx->priv_data;
|
823 |
int i;
|
824 |
|
825 |
if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { |
826 |
return -1; |
827 |
} |
828 |
if((avctx->width & 3) || (avctx->height & 3)){ |
829 |
av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n");
|
830 |
return -1; |
831 |
} |
832 |
|
833 |
l->avctx = avctx; |
834 |
l->pic.data[0]=NULL; |
835 |
avctx->has_b_frames = 0;
|
836 |
avctx->pix_fmt = PIX_FMT_YUV420P; |
837 |
|
838 |
dsputil_init(&l->dsp, avctx); |
839 |
|
840 |
l->last = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); |
841 |
l->clast = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); |
842 |
|
843 |
for(i = 0; i < TM2_NUM_STREAMS; i++) { |
844 |
l->tokens[i] = NULL;
|
845 |
l->tok_lens[i] = 0;
|
846 |
} |
847 |
|
848 |
l->Y1 = av_malloc(sizeof(int) * avctx->width * avctx->height); |
849 |
l->U1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); |
850 |
l->V1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); |
851 |
l->Y2 = av_malloc(sizeof(int) * avctx->width * avctx->height); |
852 |
l->U2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); |
853 |
l->V2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); |
854 |
l->cur = 0;
|
855 |
|
856 |
return 0; |
857 |
} |
858 |
|
859 |
static int decode_end(AVCodecContext *avctx){ |
860 |
TM2Context * const l = avctx->priv_data;
|
861 |
int i;
|
862 |
|
863 |
if(l->last)
|
864 |
av_free(l->last); |
865 |
if(l->clast)
|
866 |
av_free(l->clast); |
867 |
for(i = 0; i < TM2_NUM_STREAMS; i++) |
868 |
if(l->tokens[i])
|
869 |
av_free(l->tokens[i]); |
870 |
if(l->Y1){
|
871 |
av_free(l->Y1); |
872 |
av_free(l->U1); |
873 |
av_free(l->V1); |
874 |
av_free(l->Y2); |
875 |
av_free(l->U2); |
876 |
av_free(l->V2); |
877 |
} |
878 |
return 0; |
879 |
} |
880 |
|
881 |
AVCodec truemotion2_decoder = { |
882 |
"truemotion2",
|
883 |
CODEC_TYPE_VIDEO, |
884 |
CODEC_ID_TRUEMOTION2, |
885 |
sizeof(TM2Context),
|
886 |
decode_init, |
887 |
NULL,
|
888 |
decode_end, |
889 |
decode_frame, |
890 |
CODEC_CAP_DR1, |
891 |
}; |