Mercurial > libavcodec.hg
comparison truemotion1.c @ 2245:81802fed5b8c libavcodec
Decoding to bgr15/16 from 16bit input. Decoding of 24bit input added, not yet finished, but at least the picture can be recognized
author | alex |
---|---|
date | Tue, 21 Sep 2004 17:37:28 +0000 |
parents | 95d303a305d2 |
children | f67b63ed036d |
comparison
equal
deleted
inserted
replaced
2244:4a0cfd63f078 | 2245:81802fed5b8c |
---|---|
22 * Duck TrueMotion v1 Video Decoder by | 22 * Duck TrueMotion v1 Video Decoder by |
23 * Alex Beregszaszi (alex@fsn.hu) and | 23 * Alex Beregszaszi (alex@fsn.hu) and |
24 * Mike Melanson (melanson@pcisys.net) | 24 * Mike Melanson (melanson@pcisys.net) |
25 * | 25 * |
26 * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and | 26 * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and |
27 * outputs RGB555 data. 24-bit TM1 data is not supported yet. | 27 * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet. |
28 */ | 28 */ |
29 | 29 |
30 #include <stdio.h> | 30 #include <stdio.h> |
31 #include <stdlib.h> | 31 #include <stdlib.h> |
32 #include <string.h> | 32 #include <string.h> |
41 typedef struct TrueMotion1Context { | 41 typedef struct TrueMotion1Context { |
42 AVCodecContext *avctx; | 42 AVCodecContext *avctx; |
43 AVFrame frame; | 43 AVFrame frame; |
44 AVFrame prev_frame; | 44 AVFrame prev_frame; |
45 | 45 |
46 unsigned char *buf; | 46 uint8_t *buf; |
47 int size; | 47 int size; |
48 | 48 |
49 unsigned char *mb_change_bits; | 49 uint8_t *mb_change_bits; |
50 int mb_change_bits_row_size; | 50 int mb_change_bits_row_size; |
51 unsigned char *index_stream; | 51 uint8_t *index_stream; |
52 int index_stream_size; | 52 int index_stream_size; |
53 | 53 |
54 int flags; | 54 int flags; |
55 int x, y, w, h; | 55 int x, y, w, h; |
56 | 56 |
57 uint32_t y_predictor_table[1024]; | 57 uint32_t y_predictor_table[1024]; |
58 uint32_t c_predictor_table[1024]; | 58 uint32_t c_predictor_table[1024]; |
59 uint32_t fat_y_predictor_table[1024]; | |
60 uint32_t fat_c_predictor_table[1024]; | |
59 | 61 |
60 int compression; | 62 int compression; |
61 int block_type; | 63 int block_type; |
62 int block_width; | 64 int block_width; |
63 int block_height; | 65 int block_height; |
107 #define BLOCK_4x2 2 | 109 #define BLOCK_4x2 2 |
108 #define BLOCK_4x4 3 | 110 #define BLOCK_4x4 3 |
109 | 111 |
110 typedef struct comp_types { | 112 typedef struct comp_types { |
111 int algorithm; | 113 int algorithm; |
112 int block_width; | 114 int block_width; // vres |
113 int block_height; | 115 int block_height; // hres |
114 int block_type; | 116 int block_type; |
115 } comp_types; | 117 } comp_types; |
116 | 118 |
117 /* { valid for metatype }, algorithm, num of deltas, horiz res, vert res */ | 119 /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */ |
118 static comp_types compression_types[17] = { | 120 static comp_types compression_types[17] = { |
119 { ALGO_NOP, 0, 0, 0 }, | 121 { ALGO_NOP, 0, 0, 0 }, |
120 | 122 |
121 { ALGO_RGB16V, 4, 4, BLOCK_4x4 }, | 123 { ALGO_RGB16V, 4, 4, BLOCK_4x4 }, |
122 { ALGO_RGB16H, 4, 4, BLOCK_4x4 }, | 124 { ALGO_RGB16H, 4, 4, BLOCK_4x4 }, |
161 s->ydt[i] /= 2; | 163 s->ydt[i] /= 2; |
162 } | 164 } |
163 } | 165 } |
164 | 166 |
165 #ifdef WORDS_BIGENDIAN | 167 #ifdef WORDS_BIGENDIAN |
166 static int make_ydt_entry(int p2, int p1, int16_t *ydt) | 168 static int make_ydt15_entry(int p2, int p1, int16_t *ydt) |
167 #else | 169 #else |
168 static int make_ydt_entry(int p1, int p2, int16_t *ydt) | 170 static int make_ydt15_entry(int p1, int p2, int16_t *ydt) |
169 #endif | 171 #endif |
170 { | 172 { |
171 int lo, hi; | 173 int lo, hi; |
172 | 174 |
173 lo = ydt[p1]; | 175 lo = ydt[p1]; |
176 hi += (hi << 5) + (hi << 10); | 178 hi += (hi << 5) + (hi << 10); |
177 return ((lo + (hi << 16)) << 1); | 179 return ((lo + (hi << 16)) << 1); |
178 } | 180 } |
179 | 181 |
180 #ifdef WORDS_BIGENDIAN | 182 #ifdef WORDS_BIGENDIAN |
181 static int make_cdt_entry(int p2, int p1, int16_t *cdt) | 183 static int make_cdt15_entry(int p2, int p1, int16_t *cdt) |
182 #else | 184 #else |
183 static int make_cdt_entry(int p1, int p2, int16_t *cdt) | 185 static int make_cdt15_entry(int p1, int p2, int16_t *cdt) |
184 #endif | 186 #endif |
185 { | 187 { |
186 int r, b, lo; | 188 int r, b, lo; |
187 | 189 |
188 b = cdt[p2]; | 190 b = cdt[p2]; |
189 r = cdt[p1] << 10; | 191 r = cdt[p1] << 10; |
190 lo = b + r; | 192 lo = b + r; |
191 return ((lo + (lo << 16)) << 1); | 193 return ((lo + (lo << 16)) << 1); |
192 } | 194 } |
193 | 195 |
194 static void gen_vector_table(TrueMotion1Context *s, uint8_t *sel_vector_table) | 196 #ifdef WORDS_BIGENDIAN |
197 static int make_ydt16_entry(int p2, int p1, int16_t *ydt) | |
198 #else | |
199 static int make_ydt16_entry(int p1, int p2, int16_t *ydt) | |
200 #endif | |
201 { | |
202 int lo, hi; | |
203 | |
204 lo = ydt[p1]; | |
205 lo += (lo << 6) + (lo << 11); | |
206 hi = ydt[p2]; | |
207 hi += (hi << 6) + (hi << 11); | |
208 return ((lo + (hi << 16)) << 1); | |
209 } | |
210 | |
211 #ifdef WORDS_BIGENDIAN | |
212 static int make_cdt16_entry(int p2, int p1, int16_t *cdt) | |
213 #else | |
214 static int make_cdt16_entry(int p1, int p2, int16_t *cdt) | |
215 #endif | |
216 { | |
217 int r, b, lo; | |
218 | |
219 b = cdt[p2]; | |
220 r = cdt[p1] << 11; | |
221 lo = b + r; | |
222 return ((lo + (lo << 16)) << 1); | |
223 } | |
224 | |
225 #ifdef WORDS_BIGENDIAN | |
226 static int make_ydt24_entry(int p2, int p1, int16_t *ydt) | |
227 #else | |
228 static int make_ydt24_entry(int p1, int p2, int16_t *ydt) | |
229 #endif | |
230 { | |
231 int lo, hi; | |
232 | |
233 lo = ydt[p1]; | |
234 hi = ydt[p2]; | |
235 return ((lo + (hi << 8)) << 1); | |
236 } | |
237 | |
238 #ifdef WORDS_BIGENDIAN | |
239 static int make_cdt24_entry(int p2, int p1, int16_t *cdt) | |
240 #else | |
241 static int make_cdt24_entry(int p1, int p2, int16_t *cdt) | |
242 #endif | |
243 { | |
244 int r, b; | |
245 | |
246 b = cdt[p2]; | |
247 r = cdt[p1]<<16; | |
248 return ((b+r) << 1); | |
249 } | |
250 | |
251 static void gen_vector_table15(TrueMotion1Context *s, uint8_t *sel_vector_table) | |
195 { | 252 { |
196 int len, i, j; | 253 int len, i, j; |
197 unsigned char delta_pair; | 254 unsigned char delta_pair; |
198 | 255 |
199 for (i = 0; i < 1024; i += 4) | 256 for (i = 0; i < 1024; i += 4) |
201 len = *sel_vector_table++ / 2; | 258 len = *sel_vector_table++ / 2; |
202 for (j = 0; j < len; j++) | 259 for (j = 0; j < len; j++) |
203 { | 260 { |
204 delta_pair = *sel_vector_table++; | 261 delta_pair = *sel_vector_table++; |
205 s->y_predictor_table[i+j] = 0xfffffffe & | 262 s->y_predictor_table[i+j] = 0xfffffffe & |
206 make_ydt_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | 263 make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); |
207 s->c_predictor_table[i+j] = 0xfffffffe & | 264 s->c_predictor_table[i+j] = 0xfffffffe & |
208 make_cdt_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | 265 make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); |
209 } | 266 } |
210 s->y_predictor_table[i+(j-1)] |= 1; | 267 s->y_predictor_table[i+(j-1)] |= 1; |
211 s->c_predictor_table[i+(j-1)] |= 1; | 268 s->c_predictor_table[i+(j-1)] |= 1; |
269 } | |
270 } | |
271 | |
272 static void gen_vector_table16(TrueMotion1Context *s, uint8_t *sel_vector_table) | |
273 { | |
274 int len, i, j; | |
275 unsigned char delta_pair; | |
276 | |
277 for (i = 0; i < 1024; i += 4) | |
278 { | |
279 len = *sel_vector_table++ / 2; | |
280 for (j = 0; j < len; j++) | |
281 { | |
282 delta_pair = *sel_vector_table++; | |
283 s->y_predictor_table[i+j] = 0xfffffffe & | |
284 make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | |
285 s->c_predictor_table[i+j] = 0xfffffffe & | |
286 make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | |
287 } | |
288 s->y_predictor_table[i+(j-1)] |= 1; | |
289 s->c_predictor_table[i+(j-1)] |= 1; | |
290 } | |
291 } | |
292 | |
293 static void gen_vector_table24(TrueMotion1Context *s, uint8_t *sel_vector_table) | |
294 { | |
295 int len, i, j; | |
296 unsigned char delta_pair; | |
297 | |
298 for (i = 0; i < 1024; i += 4) | |
299 { | |
300 len = *sel_vector_table++ / 2; | |
301 for (j = 0; j < len; j++) | |
302 { | |
303 delta_pair = *sel_vector_table++; | |
304 s->y_predictor_table[i+j] = 0xfffffffe & | |
305 make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | |
306 s->c_predictor_table[i+j] = 0xfffffffe & | |
307 make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | |
308 s->fat_y_predictor_table[i+j] = 0xfffffffe & | |
309 make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt); | |
310 s->fat_c_predictor_table[i+j] = 0xfffffffe & | |
311 make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt); | |
312 } | |
313 s->y_predictor_table[i+(j-1)] |= 1; | |
314 s->c_predictor_table[i+(j-1)] |= 1; | |
315 s->fat_y_predictor_table[i+(j-1)] |= 1; | |
316 s->fat_c_predictor_table[i+(j-1)] |= 1; | |
212 } | 317 } |
213 } | 318 } |
214 | 319 |
215 /* Returns the number of bytes consumed from the bytestream. Returns -1 if | 320 /* Returns the number of bytes consumed from the bytestream. Returns -1 if |
216 * there was an error while decoding the header */ | 321 * there was an error while decoding the header */ |
227 s->mb_change_bits_row_size = ((s->avctx->width >> 2) + 7) >> 3; | 332 s->mb_change_bits_row_size = ((s->avctx->width >> 2) + 7) >> 3; |
228 | 333 |
229 header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f; | 334 header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f; |
230 if (s->buf[0] < 0x10) | 335 if (s->buf[0] < 0x10) |
231 { | 336 { |
232 av_log(s->avctx, AV_LOG_ERROR, "invalid header size\n"); | 337 av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]); |
233 return -1; | 338 return -1; |
234 } | 339 } |
235 | 340 |
236 /* unscramble the header bytes with a XOR operation */ | 341 /* unscramble the header bytes with a XOR operation */ |
237 memset(header_buffer, 0, 128); | 342 memset(header_buffer, 0, 128); |
238 for (i = 1; i < header.header_size; i++) | 343 for (i = 1; i < header.header_size; i++) |
239 header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; | 344 header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; |
345 | |
240 header.compression = header_buffer[0]; | 346 header.compression = header_buffer[0]; |
241 header.deltaset = header_buffer[1]; | 347 header.deltaset = header_buffer[1]; |
242 header.vectable = header_buffer[2]; | 348 header.vectable = header_buffer[2]; |
243 header.ysize = LE_16(&header_buffer[3]); | 349 header.ysize = LE_16(&header_buffer[3]); |
244 header.xsize = LE_16(&header_buffer[5]); | 350 header.xsize = LE_16(&header_buffer[5]); |
251 /* Version 2 */ | 357 /* Version 2 */ |
252 if (header.version >= 2) | 358 if (header.version >= 2) |
253 { | 359 { |
254 if (header.header_type > 3) | 360 if (header.header_type > 3) |
255 { | 361 { |
256 av_log(s->avctx, AV_LOG_ERROR, "truemotion1: invalid header type\n"); | 362 av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type); |
257 return -1; | 363 return -1; |
258 } else if ((header.header_type == 2) || (header.header_type == 3)) { | 364 } else if ((header.header_type == 2) || (header.header_type == 3)) { |
259 s->flags = header.flags; | 365 s->flags = header.flags; |
260 if (!(s->flags & FLAG_INTERFRAME)) | 366 if (!(s->flags & FLAG_INTERFRAME)) |
261 s->flags |= FLAG_KEYFRAME; | 367 s->flags |= FLAG_KEYFRAME; |
263 s->flags = FLAG_KEYFRAME; | 369 s->flags = FLAG_KEYFRAME; |
264 } else /* Version 1 */ | 370 } else /* Version 1 */ |
265 s->flags = FLAG_KEYFRAME; | 371 s->flags = FLAG_KEYFRAME; |
266 | 372 |
267 if (s->flags & FLAG_SPRITE) { | 373 if (s->flags & FLAG_SPRITE) { |
374 av_log(s->avctx, AV_LOG_INFO, "SPRITE frame found, please report the sample to the developers\n"); | |
268 s->w = header.width; | 375 s->w = header.width; |
269 s->h = header.height; | 376 s->h = header.height; |
270 s->x = header.xoffset; | 377 s->x = header.xoffset; |
271 s->y = header.yoffset; | 378 s->y = header.yoffset; |
272 } else { | 379 } else { |
273 s->w = header.xsize; | 380 s->w = header.xsize; |
274 s->h = header.ysize; | 381 s->h = header.ysize; |
275 if (header.header_type < 2) { | 382 if (header.header_type < 2) { |
276 if ((s->w < 213) && (s->h >= 176)) | 383 if ((s->w < 213) && (s->h >= 176)) |
384 { | |
277 s->flags |= FLAG_INTERPOLATED; | 385 s->flags |= FLAG_INTERPOLATED; |
386 av_log(s->avctx, AV_LOG_INFO, "INTERPOLATION selected, please report the sample to the developers\n"); | |
387 } | |
278 } | 388 } |
279 } | 389 } |
280 | 390 |
281 if (header.compression > 17) { | 391 if (header.compression > 17) { |
282 av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression); | 392 av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression); |
295 else { | 405 else { |
296 av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable); | 406 av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable); |
297 return -1; | 407 return -1; |
298 } | 408 } |
299 } | 409 } |
410 | |
411 // FIXME: where to place this ?!?! | |
412 if (compression_types[header.compression].algorithm == ALGO_RGB24H) | |
413 s->avctx->pix_fmt = PIX_FMT_BGR24; | |
414 else | |
415 s->avctx->pix_fmt = PIX_FMT_RGB555; // RGB565 is supported aswell | |
300 | 416 |
301 if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) | 417 if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) |
302 { | 418 { |
303 if (compression_types[header.compression].algorithm == ALGO_RGB24H) | 419 if (compression_types[header.compression].algorithm == ALGO_RGB24H) |
304 { | 420 gen_vector_table24(s, sel_vector_table); |
305 av_log(s->avctx, AV_LOG_ERROR, "24bit compression not yet supported\n"); | |
306 } | |
307 else | 421 else |
308 gen_vector_table(s, sel_vector_table); | 422 if (s->avctx->pix_fmt == PIX_FMT_RGB555) |
423 gen_vector_table15(s, sel_vector_table); | |
424 else | |
425 gen_vector_table16(s, sel_vector_table); | |
309 } | 426 } |
310 | 427 |
311 /* set up pointers to the other key data chunks */ | 428 /* set up pointers to the other key data chunks */ |
312 s->mb_change_bits = s->buf + header.header_size; | 429 s->mb_change_bits = s->buf + header.header_size; |
313 if (s->flags & FLAG_KEYFRAME) { | 430 if (s->flags & FLAG_KEYFRAME) { |
325 s->compression = header.compression; | 442 s->compression = header.compression; |
326 s->block_width = compression_types[header.compression].block_width; | 443 s->block_width = compression_types[header.compression].block_width; |
327 s->block_height = compression_types[header.compression].block_height; | 444 s->block_height = compression_types[header.compression].block_height; |
328 s->block_type = compression_types[header.compression].block_type; | 445 s->block_type = compression_types[header.compression].block_type; |
329 | 446 |
447 if (s->avctx->debug & FF_DEBUG_PICT_INFO) | |
448 av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n", | |
449 s->last_deltaset, s->last_vectable, s->compression, s->block_width, | |
450 s->block_height, s->block_type, | |
451 s->flags & FLAG_KEYFRAME ? " KEY" : "", | |
452 s->flags & FLAG_INTERFRAME ? " INTER" : "", | |
453 s->flags & FLAG_SPRITE ? " SPRITE" : "", | |
454 s->flags & FLAG_INTERPOLATED ? " INTERPOL" : ""); | |
455 | |
330 return header.header_size; | 456 return header.header_size; |
331 } | 457 } |
332 | 458 |
333 static int truemotion1_decode_init(AVCodecContext *avctx) | 459 static int truemotion1_decode_init(AVCodecContext *avctx) |
334 { | 460 { |
335 TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; | 461 TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; |
336 | 462 |
337 s->avctx = avctx; | 463 s->avctx = avctx; |
338 | 464 |
339 avctx->pix_fmt = PIX_FMT_RGB555; | 465 // FIXME: it may change ? |
466 // if (avctx->bits_per_sample == 24) | |
467 // avctx->pix_fmt = PIX_FMT_RGB24; | |
468 // else | |
469 // avctx->pix_fmt = PIX_FMT_RGB555; | |
470 | |
340 avctx->has_b_frames = 0; | 471 avctx->has_b_frames = 0; |
341 s->frame.data[0] = s->prev_frame.data[0] = NULL; | 472 s->frame.data[0] = s->prev_frame.data[0] = NULL; |
342 | 473 |
343 /* there is a vertical predictor for each pixel in a line; each vertical | 474 /* there is a vertical predictor for each pixel in a line; each vertical |
344 * predictor is 0 to start with */ | 475 * predictor is 0 to start with */ |
345 s->vert_pred = | 476 s->vert_pred = |
346 (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned short)); | 477 (unsigned int *)av_malloc(s->avctx->width * sizeof(unsigned short)); |
347 | 478 |
348 return 0; | 479 return 0; |
349 } | 480 } |
481 | |
482 /* | |
483 Block decoding order: | |
484 | |
485 dxi: Y-Y | |
486 dxic: Y-C-Y | |
487 dxic2: Y-C-Y-C | |
488 | |
489 hres,vres,i,i%vres (0 < i < 4) | |
490 2x2 0: 0 dxic2 | |
491 2x2 1: 1 dxi | |
492 2x2 2: 0 dxic2 | |
493 2x2 3: 1 dxi | |
494 2x4 0: 0 dxic2 | |
495 2x4 1: 1 dxi | |
496 2x4 2: 2 dxi | |
497 2x4 3: 3 dxi | |
498 4x2 0: 0 dxic | |
499 4x2 1: 1 dxi | |
500 4x2 2: 0 dxic | |
501 4x2 3: 1 dxi | |
502 4x4 0: 0 dxic | |
503 4x4 1: 1 dxi | |
504 4x4 2: 2 dxi | |
505 4x4 3: 3 dxi | |
506 */ | |
350 | 507 |
351 #define GET_NEXT_INDEX() \ | 508 #define GET_NEXT_INDEX() \ |
352 {\ | 509 {\ |
353 if (index_stream_index >= s->index_stream_size) { \ | 510 if (index_stream_index >= s->index_stream_size) { \ |
354 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \ | 511 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \ |
372 index++; \ | 529 index++; \ |
373 } \ | 530 } \ |
374 } else \ | 531 } else \ |
375 index++; | 532 index++; |
376 | 533 |
534 #define APPLY_C_PREDICTOR_24() \ | |
535 predictor_pair = s->c_predictor_table[index]; \ | |
536 c_horiz_pred += (predictor_pair >> 1); \ | |
537 if (predictor_pair & 1) { \ | |
538 GET_NEXT_INDEX() \ | |
539 if (!index) { \ | |
540 GET_NEXT_INDEX() \ | |
541 predictor_pair = s->fat_c_predictor_table[index]; \ | |
542 c_horiz_pred += (predictor_pair >> 1); \ | |
543 if (predictor_pair & 1) \ | |
544 GET_NEXT_INDEX() \ | |
545 else \ | |
546 index++; \ | |
547 } \ | |
548 } else \ | |
549 index++; | |
550 // c_last+coff = clast+c_horiz_pred; | |
551 | |
552 | |
377 #define APPLY_Y_PREDICTOR() \ | 553 #define APPLY_Y_PREDICTOR() \ |
378 predictor_pair = s->y_predictor_table[index]; \ | 554 predictor_pair = s->y_predictor_table[index]; \ |
379 horiz_pred += (predictor_pair >> 1); \ | 555 horiz_pred += (predictor_pair >> 1); \ |
380 if (predictor_pair & 1) { \ | 556 if (predictor_pair & 1) { \ |
381 GET_NEXT_INDEX() \ | 557 GET_NEXT_INDEX() \ |
389 index++; \ | 565 index++; \ |
390 } \ | 566 } \ |
391 } else \ | 567 } else \ |
392 index++; | 568 index++; |
393 | 569 |
570 #define APPLY_Y_PREDICTOR_24() \ | |
571 predictor_pair = s->y_predictor_table[index]; \ | |
572 horiz_pred += (predictor_pair >> 1); \ | |
573 if (predictor_pair & 1) { \ | |
574 GET_NEXT_INDEX() \ | |
575 if (!index) { \ | |
576 GET_NEXT_INDEX() \ | |
577 predictor_pair = s->fat_y_predictor_table[index]; \ | |
578 horiz_pred += (predictor_pair >> 1); \ | |
579 if (predictor_pair & 1) \ | |
580 GET_NEXT_INDEX() \ | |
581 else \ | |
582 index++; \ | |
583 } \ | |
584 } else \ | |
585 index++; | |
586 | |
394 #define OUTPUT_PIXEL_PAIR() \ | 587 #define OUTPUT_PIXEL_PAIR() \ |
395 *current_pixel_pair = *vert_pred + horiz_pred; \ | 588 *current_pixel_pair = *vert_pred + horiz_pred; \ |
396 *vert_pred++ = *current_pixel_pair++; \ | 589 *vert_pred++ = *current_pixel_pair++; \ |
397 prev_pixel_pair++; | 590 prev_pixel_pair++; |
398 | 591 |
526 current_line += s->frame.linesize[0]; | 719 current_line += s->frame.linesize[0]; |
527 prev_line += s->prev_frame.linesize[0]; | 720 prev_line += s->prev_frame.linesize[0]; |
528 } | 721 } |
529 } | 722 } |
530 | 723 |
724 static void truemotion1_decode_24bit(TrueMotion1Context *s) | |
725 { | |
726 int y; | |
727 int pixels_left; /* remaining pixels on this line */ | |
728 unsigned int predictor_pair; | |
729 unsigned int horiz_pred; | |
730 unsigned int c_horiz_pred; | |
731 unsigned int *vert_pred; | |
732 unsigned int *current_pixel_pair; | |
733 unsigned int *prev_pixel_pair; | |
734 unsigned char *current_line = s->frame.data[0]; | |
735 unsigned char *prev_line = s->prev_frame.data[0]; | |
736 int keyframe = s->flags & FLAG_KEYFRAME; | |
737 | |
738 /* these variables are for managing the stream of macroblock change bits */ | |
739 unsigned char *mb_change_bits = s->mb_change_bits; | |
740 unsigned char mb_change_byte; | |
741 unsigned char mb_change_byte_mask; | |
742 int mb_change_index; | |
743 | |
744 /* these variables are for managing the main index stream */ | |
745 int index_stream_index = 0; /* yes, the index into the index stream */ | |
746 int index; | |
747 | |
748 /* clean out the line buffer */ | |
749 memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned short)); | |
750 | |
751 GET_NEXT_INDEX(); | |
752 | |
753 for (y = 0; y < s->avctx->height; y++) { | |
754 | |
755 /* re-init variables for the next line iteration */ | |
756 horiz_pred = c_horiz_pred = 0; | |
757 current_pixel_pair = (unsigned int *)current_line; | |
758 prev_pixel_pair = (unsigned int *)prev_line; | |
759 vert_pred = s->vert_pred; | |
760 mb_change_index = 0; | |
761 mb_change_byte = mb_change_bits[mb_change_index++]; | |
762 mb_change_byte_mask = 0x01; | |
763 pixels_left = s->avctx->width; | |
764 | |
765 while (pixels_left > 0) { | |
766 | |
767 if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) { | |
768 | |
769 switch (y & 3) { | |
770 case 0: | |
771 /* if macroblock width is 2, apply C-Y-C-Y; else | |
772 * apply C-Y-Y */ | |
773 if (s->block_width == 2) { | |
774 APPLY_C_PREDICTOR_24(); | |
775 APPLY_Y_PREDICTOR_24(); | |
776 OUTPUT_PIXEL_PAIR(); | |
777 // OUTPUT_PIXEL_PAIR_24_C(); | |
778 APPLY_C_PREDICTOR_24(); | |
779 APPLY_Y_PREDICTOR_24(); | |
780 OUTPUT_PIXEL_PAIR(); | |
781 // OUTPUT_PIXEL_PAIR_24_C(); | |
782 } else { | |
783 APPLY_C_PREDICTOR_24(); | |
784 APPLY_Y_PREDICTOR_24(); | |
785 OUTPUT_PIXEL_PAIR(); | |
786 // OUTPUT_PIXEL_PAIR_24_C(); | |
787 APPLY_Y_PREDICTOR_24(); | |
788 OUTPUT_PIXEL_PAIR(); | |
789 // OUTPUT_PIXEL_PAIR_24_C(); | |
790 } | |
791 break; | |
792 | |
793 case 1: | |
794 case 3: | |
795 /* always apply 2 Y predictors on these iterations */ | |
796 APPLY_Y_PREDICTOR_24(); | |
797 OUTPUT_PIXEL_PAIR(); | |
798 APPLY_Y_PREDICTOR_24(); | |
799 OUTPUT_PIXEL_PAIR(); | |
800 break; | |
801 | |
802 case 2: | |
803 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y | |
804 * depending on the macroblock type */ | |
805 if (s->block_type == BLOCK_2x2) { | |
806 APPLY_C_PREDICTOR_24(); | |
807 APPLY_Y_PREDICTOR_24(); | |
808 OUTPUT_PIXEL_PAIR(); | |
809 // OUTPUT_PIXEL_PAIR_24_C(); | |
810 APPLY_C_PREDICTOR_24(); | |
811 APPLY_Y_PREDICTOR_24(); | |
812 OUTPUT_PIXEL_PAIR(); | |
813 // OUTPUT_PIXEL_PAIR_24_C(); | |
814 } else if (s->block_type == BLOCK_4x2) { | |
815 APPLY_C_PREDICTOR_24(); | |
816 APPLY_Y_PREDICTOR_24(); | |
817 OUTPUT_PIXEL_PAIR(); | |
818 // OUTPUT_PIXEL_PAIR_24_C(); | |
819 APPLY_Y_PREDICTOR_24(); | |
820 OUTPUT_PIXEL_PAIR(); | |
821 // OUTPUT_PIXEL_PAIR_24_C(); | |
822 } else { | |
823 APPLY_Y_PREDICTOR_24(); | |
824 OUTPUT_PIXEL_PAIR(); | |
825 APPLY_Y_PREDICTOR_24(); | |
826 OUTPUT_PIXEL_PAIR(); | |
827 } | |
828 break; | |
829 } | |
830 | |
831 } else { | |
832 | |
833 /* skip (copy) four pixels, but reassign the horizontal | |
834 * predictor */ | |
835 *current_pixel_pair = *prev_pixel_pair++; | |
836 *vert_pred++ = *current_pixel_pair++; | |
837 *current_pixel_pair = *prev_pixel_pair++; | |
838 horiz_pred = *current_pixel_pair - *vert_pred; | |
839 // c_horiz_pred = *current_pixel_pair - *vert_pred; | |
840 *vert_pred++ = *current_pixel_pair++; | |
841 | |
842 } | |
843 | |
844 if (!keyframe) { | |
845 mb_change_byte_mask <<= 1; | |
846 | |
847 /* next byte */ | |
848 if (!mb_change_byte_mask) { | |
849 mb_change_byte = mb_change_bits[mb_change_index++]; | |
850 mb_change_byte_mask = 0x01; | |
851 } | |
852 } | |
853 | |
854 pixels_left -= 4; | |
855 } | |
856 | |
857 /* next change row */ | |
858 if (((y + 1) & 3) == 0) | |
859 mb_change_bits += s->mb_change_bits_row_size; | |
860 | |
861 current_line += s->frame.linesize[0]; | |
862 prev_line += s->prev_frame.linesize[0]; | |
863 } | |
864 } | |
865 | |
866 | |
531 static int truemotion1_decode_frame(AVCodecContext *avctx, | 867 static int truemotion1_decode_frame(AVCodecContext *avctx, |
532 void *data, int *data_size, | 868 void *data, int *data_size, |
533 uint8_t *buf, int buf_size) | 869 uint8_t *buf, int buf_size) |
534 { | 870 { |
535 TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; | 871 TrueMotion1Context *s = (TrueMotion1Context *)avctx->priv_data; |
536 | 872 |
537 s->buf = buf; | 873 s->buf = buf; |
538 s->size = buf_size; | 874 s->size = buf_size; |
539 | 875 |
540 s->frame.reference = 1; | |
541 if (avctx->get_buffer(avctx, &s->frame) < 0) { | |
542 av_log(s->avctx, AV_LOG_ERROR, "truemotion1: get_buffer() failed\n"); | |
543 return -1; | |
544 } | |
545 | |
546 /* no supplementary picture */ | 876 /* no supplementary picture */ |
547 if (buf_size == 0) | 877 if (buf_size == 0) |
548 return 0; | 878 return 0; |
549 | 879 |
550 if (truemotion1_decode_header(s) == -1) | 880 if (truemotion1_decode_header(s) == -1) |
551 return -1; | 881 return -1; |
882 | |
883 s->frame.reference = 1; | |
884 if (avctx->get_buffer(avctx, &s->frame) < 0) { | |
885 av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
886 return -1; | |
887 } | |
552 | 888 |
553 /* check for a do-nothing frame and copy the previous frame */ | 889 /* check for a do-nothing frame and copy the previous frame */ |
554 if (compression_types[s->compression].algorithm == ALGO_NOP) | 890 if (compression_types[s->compression].algorithm == ALGO_NOP) |
555 { | 891 { |
556 memcpy(s->frame.data[0], s->prev_frame.data[0], | 892 memcpy(s->frame.data[0], s->prev_frame.data[0], |
557 s->frame.linesize[0] * s->avctx->height); | 893 s->frame.linesize[0] * s->avctx->height); |
558 } else if (compression_types[s->compression].algorithm == ALGO_RGB24H) { | 894 } else if (compression_types[s->compression].algorithm == ALGO_RGB24H) { |
559 av_log(s->avctx, AV_LOG_ERROR, "24bit compression not yet supported\n"); | 895 truemotion1_decode_24bit(s); |
560 } else { | 896 } else { |
561 truemotion1_decode_16bit(s); | 897 truemotion1_decode_16bit(s); |
562 } | 898 } |
563 | 899 |
564 if (s->prev_frame.data[0]) | 900 if (s->prev_frame.data[0]) |