1 /*
2 * Duck TrueMotion 1.0 Decoder
3 * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * Duck TrueMotion v1 Video Decoder by
25 * Alex Beregszaszi and
26 * Mike Melanson (melanson@pcisys.net)
27 *
28 * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
29 * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
42
44
48
51
56
59
64
69
74
76
79
81
82 #define FLAG_SPRITE 32
83 #define FLAG_KEYFRAME 16
84 #define FLAG_INTERFRAME 8
85 #define FLAG_INTERPOLATED 4
86
103 };
104
106 #define ALGO_RGB16V 1
107 #define ALGO_RGB16H 2
108 #define ALGO_RGB24H 3
109
110 /* these are the various block sizes that can occupy a 4x4 block */
115
122
123 /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
126
131
136
141
146 };
147
149 {
150 int i;
151
152 if (delta_table_index > 3)
153 return;
154
155 memcpy(s->
ydt,
ydts[delta_table_index], 8 *
sizeof(int16_t));
156 memcpy(s->
cdt,
cdts[delta_table_index], 8 *
sizeof(int16_t));
159
160 /* Y skinny deltas need to be halved for some reason; maybe the
161 * skinny Y deltas should be modified */
162 for (i = 0; i < 8; i++)
163 {
164 /* drop the lsb before dividing by 2-- net effect: round down
165 * when dividing a negative number (e.g., -3/2 = -2, not -1) */
168 }
169 }
170
171 #if HAVE_BIGENDIAN
173 #else
175 #endif
176 {
177 int lo, hi;
178
179 lo = ydt[p1];
180 lo += (lo << 5) + (lo << 10);
181 hi = ydt[p2];
182 hi += (hi << 5) + (hi << 10);
183 return (lo + (hi << 16)) << 1;
184 }
185
187 {
189
190 b = cdt[p2];
191 r = cdt[p1] << 10;
193 return (lo + (lo << 16)) << 1;
194 }
195
196 #if HAVE_BIGENDIAN
198 #else
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
212 {
214
215 b = cdt[p2];
216 r = cdt[p1] << 11;
218 return (lo + (lo << 16)) << 1;
219 }
220
222 {
223 int lo, hi;
224
225 lo = ydt[p1];
226 hi = ydt[p2];
227 return (lo + (hi << 8) + (hi << 16)) << 1;
228 }
229
231 {
233
234 b = cdt[p2];
235 r = cdt[p1]<<16;
236 return (b+r) << 1;
237 }
238
240 {
242 unsigned char delta_pair;
243
244 for (i = 0; i < 1024; i += 4)
245 {
246 len = *sel_vector_table++ / 2;
247 for (j = 0; j <
len; j++)
248 {
249 delta_pair = *sel_vector_table++;
254 }
257 }
258 }
259
261 {
263 unsigned char delta_pair;
264
265 for (i = 0; i < 1024; i += 4)
266 {
267 len = *sel_vector_table++ / 2;
268 for (j = 0; j <
len; j++)
269 {
270 delta_pair = *sel_vector_table++;
275 }
278 }
279 }
280
282 {
284 unsigned char delta_pair;
285
286 for (i = 0; i < 1024; i += 4)
287 {
288 len = *sel_vector_table++ / 2;
289 for (j = 0; j <
len; j++)
290 {
291 delta_pair = *sel_vector_table++;
300 }
305 }
306 }
307
308 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
309 * there was an error while decoding the header */
311 {
313 int width_shift = 0;
314 int new_pix_fmt;
316 uint8_t header_buffer[128] = { 0 };
/* logical maximum size of the header */
317 const uint8_t *sel_vector_table;
318
320 if (s->
buf[0] < 0x10)
321 {
324 }
325
329 }
330
331 /* unscramble the header bytes with a XOR operation */
333 header_buffer[i - 1] = s->
buf[i] ^ s->
buf[i + 1];
334
341 header.
version = header_buffer[9];
343 header.
flags = header_buffer[11];
344 header.
control = header_buffer[12];
345
346 /* Version 2 */
348 {
350 {
357 } else
359 } else /* Version 1 */
361
364 /* FIXME header.width, height, xoffset and yoffset aren't initialized */
366 } else {
370 if ((s->
w < 213) && (s->
h >= 176))
371 {
374 }
375 }
376 }
377
381 }
382
386
389 else {
392 else {
395 }
396 }
397
400 width_shift = 1;
401 } else
403
404 s->
w >>= width_shift;
405
411
413 return ret;
414
416
420 }
421
422 /* There is 1 change bit per 4 pixels, so each change byte represents
423 * 32 pixels; divide width by 4 to obtain the number of change bits and
424 * then round up to the nearest byte. */
426
428 {
431 else
434 else
436 }
437
438 /* set up pointers to the other key data chunks */
441 /* no change bits specified for a keyframe; only index bytes */
443 } else {
444 /* one change bit per 4x4 block */
447 }
449
456
465
467 }
468
470 {
472
474
475 // FIXME: it may change ?
476 // if (avctx->bits_per_sample == 24)
477 // avctx->pix_fmt = AV_PIX_FMT_RGB24;
478 // else
479 // avctx->pix_fmt = AV_PIX_FMT_RGB555;
480
484
485 /* there is a vertical predictor for each pixel in a line; each vertical
486 * predictor is 0 to start with */
490
491 return 0;
492 }
493
494 /*
495 Block decoding order:
496
497 dxi: Y-Y
498 dxic: Y-C-Y
499 dxic2: Y-C-Y-C
500
501 hres,vres,i,i%vres (0 < i < 4)
502 2x2 0: 0 dxic2
503 2x2 1: 1 dxi
504 2x2 2: 0 dxic2
505 2x2 3: 1 dxi
506 2x4 0: 0 dxic2
507 2x4 1: 1 dxi
508 2x4 2: 2 dxi
509 2x4 3: 3 dxi
510 4x2 0: 0 dxic
511 4x2 1: 1 dxi
512 4x2 2: 0 dxic
513 4x2 3: 1 dxi
514 4x4 0: 0 dxic
515 4x4 1: 1 dxi
516 4x4 2: 2 dxi
517 4x4 3: 3 dxi
518 */
519
520 #define GET_NEXT_INDEX() \
521 {\
522 if (index_stream_index >= s->index_stream_size) { \
523 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
524 return; \
525 } \
526 index = s->index_stream[index_stream_index++] * 4; \
527 }
528
530 do { \
531 if (index >= 1023) { \
532 av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
533 return; \
534 } \
535 index++; \
536 } while (0)
537
538 #define APPLY_C_PREDICTOR() \
539 predictor_pair = s->c_predictor_table[index]; \
540 horiz_pred += (predictor_pair >> 1); \
541 if (predictor_pair & 1) { \
542 GET_NEXT_INDEX() \
543 if (!index) { \
544 GET_NEXT_INDEX() \
545 predictor_pair = s->c_predictor_table[index]; \
546 horiz_pred += ((predictor_pair >> 1) * 5); \
547 if (predictor_pair & 1) \
548 GET_NEXT_INDEX() \
549 else \
550 INC_INDEX; \
551 } \
552 } else \
553 INC_INDEX;
554
555 #define APPLY_C_PREDICTOR_24() \
556 predictor_pair = s->c_predictor_table[index]; \
557 horiz_pred += (predictor_pair >> 1); \
558 if (predictor_pair & 1) { \
559 GET_NEXT_INDEX() \
560 if (!index) { \
561 GET_NEXT_INDEX() \
562 predictor_pair = s->fat_c_predictor_table[index]; \
563 horiz_pred += (predictor_pair >> 1); \
564 if (predictor_pair & 1) \
565 GET_NEXT_INDEX() \
566 else \
567 INC_INDEX; \
568 } \
569 } else \
570 INC_INDEX;
571
572
573 #define APPLY_Y_PREDICTOR() \
574 predictor_pair = s->y_predictor_table[index]; \
575 horiz_pred += (predictor_pair >> 1); \
576 if (predictor_pair & 1) { \
577 GET_NEXT_INDEX() \
578 if (!index) { \
579 GET_NEXT_INDEX() \
580 predictor_pair = s->y_predictor_table[index]; \
581 horiz_pred += ((predictor_pair >> 1) * 5); \
582 if (predictor_pair & 1) \
583 GET_NEXT_INDEX() \
584 else \
585 INC_INDEX; \
586 } \
587 } else \
588 INC_INDEX;
589
590 #define APPLY_Y_PREDICTOR_24() \
591 predictor_pair = s->y_predictor_table[index]; \
592 horiz_pred += (predictor_pair >> 1); \
593 if (predictor_pair & 1) { \
594 GET_NEXT_INDEX() \
595 if (!index) { \
596 GET_NEXT_INDEX() \
597 predictor_pair = s->fat_y_predictor_table[index]; \
598 horiz_pred += (predictor_pair >> 1); \
599 if (predictor_pair & 1) \
600 GET_NEXT_INDEX() \
601 else \
602 INC_INDEX; \
603 } \
604 } else \
605 INC_INDEX;
606
607 #define OUTPUT_PIXEL_PAIR() \
608 *current_pixel_pair = *vert_pred + horiz_pred; \
609 *vert_pred++ = *current_pixel_pair++;
610
612 {
614 int pixels_left; /* remaining pixels on this line */
615 unsigned int predictor_pair;
616 unsigned int horiz_pred;
617 unsigned int *vert_pred;
618 unsigned int *current_pixel_pair;
619 unsigned char *current_line = s->
frame->
data[0];
621
622 /* these variables are for managing the stream of macroblock change bits */
624 unsigned char mb_change_byte;
625 unsigned char mb_change_byte_mask;
626 int mb_change_index;
627
628 /* these variables are for managing the main index stream */
629 int index_stream_index = 0; /* yes, the index into the index stream */
631
632 /* clean out the line buffer */
634
636
638
639 /* re-init variables for the next line iteration */
640 horiz_pred = 0;
641 current_pixel_pair = (unsigned int *)current_line;
643 mb_change_index = 0;
644 mb_change_byte = mb_change_bits[mb_change_index++];
645 mb_change_byte_mask = 0x01;
647
648 while (pixels_left > 0) {
649
650 if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
651
652 switch (y & 3) {
653 case 0:
654 /* if macroblock width is 2, apply C-Y-C-Y; else
655 * apply C-Y-Y */
663 } else {
669 }
670 break;
671
672 case 1:
673 case 3:
674 /* always apply 2 Y predictors on these iterations */
679 break;
680
681 case 2:
682 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
683 * depending on the macroblock type */
697 } else {
702 }
703 break;
704 }
705
706 } else {
707
708 /* skip (copy) four pixels, but reassign the horizontal
709 * predictor */
710 *vert_pred++ = *current_pixel_pair++;
711 horiz_pred = *current_pixel_pair - *vert_pred;
712 *vert_pred++ = *current_pixel_pair++;
713
714 }
715
716 if (!keyframe) {
717 mb_change_byte_mask <<= 1;
718
719 /* next byte */
720 if (!mb_change_byte_mask) {
721 mb_change_byte = mb_change_bits[mb_change_index++];
722 mb_change_byte_mask = 0x01;
723 }
724 }
725
726 pixels_left -= 4;
727 }
728
729 /* next change row */
730 if (((y + 1) & 3) == 0)
732
734 }
735 }
736
738 {
740 int pixels_left; /* remaining pixels on this line */
741 unsigned int predictor_pair;
742 unsigned int horiz_pred;
743 unsigned int *vert_pred;
744 unsigned int *current_pixel_pair;
745 unsigned char *current_line = s->
frame->
data[0];
747
748 /* these variables are for managing the stream of macroblock change bits */
750 unsigned char mb_change_byte;
751 unsigned char mb_change_byte_mask;
752 int mb_change_index;
753
754 /* these variables are for managing the main index stream */
755 int index_stream_index = 0; /* yes, the index into the index stream */
757
758 /* clean out the line buffer */
760
762
764
765 /* re-init variables for the next line iteration */
766 horiz_pred = 0;
767 current_pixel_pair = (unsigned int *)current_line;
769 mb_change_index = 0;
770 mb_change_byte = mb_change_bits[mb_change_index++];
771 mb_change_byte_mask = 0x01;
773
774 while (pixels_left > 0) {
775
776 if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
777
778 switch (y & 3) {
779 case 0:
780 /* if macroblock width is 2, apply C-Y-C-Y; else
781 * apply C-Y-Y */
789 } else {
795 }
796 break;
797
798 case 1:
799 case 3:
800 /* always apply 2 Y predictors on these iterations */
805 break;
806
807 case 2:
808 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
809 * depending on the macroblock type */
823 } else {
828 }
829 break;
830 }
831
832 } else {
833
834 /* skip (copy) four pixels, but reassign the horizontal
835 * predictor */
836 *vert_pred++ = *current_pixel_pair++;
837 horiz_pred = *current_pixel_pair - *vert_pred;
838 *vert_pred++ = *current_pixel_pair++;
839
840 }
841
842 if (!keyframe) {
843 mb_change_byte_mask <<= 1;
844
845 /* next byte */
846 if (!mb_change_byte_mask) {
847 mb_change_byte = mb_change_bits[mb_change_index++];
848 mb_change_byte_mask = 0x01;
849 }
850 }
851
852 pixels_left -= 2;
853 }
854
855 /* next change row */
856 if (((y + 1) & 3) == 0)
858
860 }
861 }
862
863
865 void *
data,
int *got_frame,
867 {
869 int ret, buf_size = avpkt->
size;
871
874
877
880
885 }
886
889
890 *got_frame = 1;
891
892 /* report that the buffer was completely consumed */
893 return buf_size;
894 }
895
897 {
899
902
903 return 0;
904 }
905
907 .
name =
"truemotion1",
916 };