2 * Duck TrueMotion 1.0 Decoder
3 * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
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.
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.
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
22 * Duck TrueMotion v1 Video Decoder by
23 * Alex Beregszaszi (alex@fsn.hu) and
24 * Mike Melanson (melanson@pcisys.net)
26 * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
27 * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
39 #include "truemotion1data.h"
41 typedef struct TrueMotion1Context
{
42 AVCodecContext
*avctx
;
49 uint8_t *mb_change_bits
;
50 int mb_change_bits_row_size
;
51 uint8_t *index_stream
;
52 int index_stream_size
;
57 uint32_t y_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];
72 int last_deltaset
, last_vectable
;
74 unsigned int *vert_pred
;
78 #define FLAG_SPRITE 32
79 #define FLAG_KEYFRAME 16
80 #define FLAG_INTERFRAME 8
81 #define FLAG_INTERPOLATED 4
102 #define ALGO_RGB16V 1
103 #define ALGO_RGB16H 2
104 #define ALGO_RGB24H 3
106 /* these are the various block sizes that can occupy a 4x4 block */
112 typedef struct comp_types
{
114 int block_width
; // vres
115 int block_height
; // hres
119 /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
120 static comp_types compression_types
[17] = {
121 { ALGO_NOP
, 0, 0, 0 },
123 { ALGO_RGB16V
, 4, 4, BLOCK_4x4
},
124 { ALGO_RGB16H
, 4, 4, BLOCK_4x4
},
125 { ALGO_RGB16V
, 4, 2, BLOCK_4x2
},
126 { ALGO_RGB16H
, 4, 2, BLOCK_4x2
},
128 { ALGO_RGB16V
, 2, 4, BLOCK_2x4
},
129 { ALGO_RGB16H
, 2, 4, BLOCK_2x4
},
130 { ALGO_RGB16V
, 2, 2, BLOCK_2x2
},
131 { ALGO_RGB16H
, 2, 2, BLOCK_2x2
},
133 { ALGO_NOP
, 4, 4, BLOCK_4x4
},
134 { ALGO_RGB24H
, 4, 4, BLOCK_4x4
},
135 { ALGO_NOP
, 4, 2, BLOCK_4x2
},
136 { ALGO_RGB24H
, 4, 2, BLOCK_4x2
},
138 { ALGO_NOP
, 2, 4, BLOCK_2x4
},
139 { ALGO_RGB24H
, 2, 4, BLOCK_2x4
},
140 { ALGO_NOP
, 2, 2, BLOCK_2x2
},
141 { ALGO_RGB24H
, 2, 2, BLOCK_2x2
}
144 static void select_delta_tables(TrueMotion1Context
*s
, int delta_table_index
)
148 if (delta_table_index
> 3)
151 memcpy(s
->ydt
, ydts
[delta_table_index
], 8 * sizeof(int16_t));
152 memcpy(s
->cdt
, cdts
[delta_table_index
], 8 * sizeof(int16_t));
153 memcpy(s
->fat_ydt
, fat_ydts
[delta_table_index
], 8 * sizeof(int16_t));
154 memcpy(s
->fat_cdt
, fat_cdts
[delta_table_index
], 8 * sizeof(int16_t));
156 /* Y skinny deltas need to be halved for some reason; maybe the
157 * skinny Y deltas should be modified */
158 for (i
= 0; i
< 8; i
++)
160 /* drop the lsb before dividing by 2-- net effect: round down
161 * when dividing a negative number (e.g., -3/2 = -2, not -1) */
167 #ifdef WORDS_BIGENDIAN
168 static int make_ydt15_entry(int p2
, int p1
, int16_t *ydt
)
170 static int make_ydt15_entry(int p1
, int p2
, int16_t *ydt
)
176 lo
+= (lo
<< 5) + (lo
<< 10);
178 hi
+= (hi
<< 5) + (hi
<< 10);
179 return ((lo
+ (hi
<< 16)) << 1);
182 #ifdef WORDS_BIGENDIAN
183 static int make_cdt15_entry(int p2
, int p1
, int16_t *cdt
)
185 static int make_cdt15_entry(int p1
, int p2
, int16_t *cdt
)
193 return ((lo
+ (lo
<< 16)) << 1);
196 #ifdef WORDS_BIGENDIAN
197 static int make_ydt16_entry(int p2
, int p1
, int16_t *ydt
)
199 static int make_ydt16_entry(int p1
, int p2
, int16_t *ydt
)
205 lo
+= (lo
<< 6) + (lo
<< 11);
207 hi
+= (hi
<< 6) + (hi
<< 11);
208 return ((lo
+ (hi
<< 16)) << 1);
211 #ifdef WORDS_BIGENDIAN
212 static int make_cdt16_entry(int p2
, int p1
, int16_t *cdt
)
214 static int make_cdt16_entry(int p1
, int p2
, int16_t *cdt
)
222 return ((lo
+ (lo
<< 16)) << 1);
225 #ifdef WORDS_BIGENDIAN
226 static int make_ydt24_entry(int p2
, int p1
, int16_t *ydt
)
228 static int make_ydt24_entry(int p1
, int p2
, int16_t *ydt
)
235 return ((lo
+ (hi
<< 8)) << 1);
238 #ifdef WORDS_BIGENDIAN
239 static int make_cdt24_entry(int p2
, int p1
, int16_t *cdt
)
241 static int make_cdt24_entry(int p1
, int p2
, int16_t *cdt
)
251 static void gen_vector_table15(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
254 unsigned char delta_pair
;
256 for (i
= 0; i
< 1024; i
+= 4)
258 len
= *sel_vector_table
++ / 2;
259 for (j
= 0; j
< len
; j
++)
261 delta_pair
= *sel_vector_table
++;
262 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
263 make_ydt15_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
264 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
265 make_cdt15_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
267 s
->y_predictor_table
[i
+(j
-1)] |= 1;
268 s
->c_predictor_table
[i
+(j
-1)] |= 1;
272 static void gen_vector_table16(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
275 unsigned char delta_pair
;
277 for (i
= 0; i
< 1024; i
+= 4)
279 len
= *sel_vector_table
++ / 2;
280 for (j
= 0; j
< len
; j
++)
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
);
288 s
->y_predictor_table
[i
+(j
-1)] |= 1;
289 s
->c_predictor_table
[i
+(j
-1)] |= 1;
293 static void gen_vector_table24(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
296 unsigned char delta_pair
;
298 for (i
= 0; i
< 1024; i
+= 4)
300 len
= *sel_vector_table
++ / 2;
301 for (j
= 0; j
< len
; j
++)
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
);
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;
320 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
321 * there was an error while decoding the header */
322 static int truemotion1_decode_header(TrueMotion1Context
*s
)
325 struct frame_header header
;
326 uint8_t header_buffer
[128]; /* logical maximum size of the header */
327 const uint8_t *sel_vector_table
;
329 /* There is 1 change bit per 4 pixels, so each change byte represents
330 * 32 pixels; divide width by 4 to obtain the number of change bits and
331 * then round up to the nearest byte. */
332 s
->mb_change_bits_row_size
= ((s
->avctx
->width
>> 2) + 7) >> 3;
334 header
.header_size
= ((s
->buf
[0] >> 5) | (s
->buf
[0] << 3)) & 0x7f;
335 if (s
->buf
[0] < 0x10)
337 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid header size (%d)\n", s
->buf
[0]);
341 /* unscramble the header bytes with a XOR operation */
342 memset(header_buffer
, 0, 128);
343 for (i
= 1; i
< header
.header_size
; i
++)
344 header_buffer
[i
- 1] = s
->buf
[i
] ^ s
->buf
[i
+ 1];
346 header
.compression
= header_buffer
[0];
347 header
.deltaset
= header_buffer
[1];
348 header
.vectable
= header_buffer
[2];
349 header
.ysize
= LE_16(&header_buffer
[3]);
350 header
.xsize
= LE_16(&header_buffer
[5]);
351 header
.checksum
= LE_16(&header_buffer
[7]);
352 header
.version
= header_buffer
[9];
353 header
.header_type
= header_buffer
[10];
354 header
.flags
= header_buffer
[11];
355 header
.control
= header_buffer
[12];
358 if (header
.version
>= 2)
360 if (header
.header_type
> 3)
362 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid header type (%d)\n", header
.header_type
);
364 } else if ((header
.header_type
== 2) || (header
.header_type
== 3)) {
365 s
->flags
= header
.flags
;
366 if (!(s
->flags
& FLAG_INTERFRAME
))
367 s
->flags
|= FLAG_KEYFRAME
;
369 s
->flags
= FLAG_KEYFRAME
;
370 } else /* Version 1 */
371 s
->flags
= FLAG_KEYFRAME
;
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");
376 s
->h
= header
.height
;
377 s
->x
= header
.xoffset
;
378 s
->y
= header
.yoffset
;
382 if (header
.header_type
< 2) {
383 if ((s
->w
< 213) && (s
->h
>= 176))
385 s
->flags
|= FLAG_INTERPOLATED
;
386 av_log(s
->avctx
, AV_LOG_INFO
, "INTERPOLATION selected, please report the sample to the developers\n");
391 if (header
.compression
> 17) {
392 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid compression type (%d)\n", header
.compression
);
396 if ((header
.deltaset
!= s
->last_deltaset
) ||
397 (header
.vectable
!= s
->last_vectable
))
398 select_delta_tables(s
, header
.deltaset
);
400 if ((header
.compression
& 1) && header
.header_type
)
401 sel_vector_table
= pc_tbl2
;
403 if (header
.vectable
< 4)
404 sel_vector_table
= tables
[header
.vectable
- 1];
406 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid vector table id (%d)\n", header
.vectable
);
411 // FIXME: where to place this ?!?!
412 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
413 s
->avctx
->pix_fmt
= PIX_FMT_BGR24
;
415 s
->avctx
->pix_fmt
= PIX_FMT_RGB555
; // RGB565 is supported aswell
417 if ((header
.deltaset
!= s
->last_deltaset
) || (header
.vectable
!= s
->last_vectable
))
419 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
420 gen_vector_table24(s
, sel_vector_table
);
422 if (s
->avctx
->pix_fmt
== PIX_FMT_RGB555
)
423 gen_vector_table15(s
, sel_vector_table
);
425 gen_vector_table16(s
, sel_vector_table
);
428 /* set up pointers to the other key data chunks */
429 s
->mb_change_bits
= s
->buf
+ header
.header_size
;
430 if (s
->flags
& FLAG_KEYFRAME
) {
431 /* no change bits specified for a keyframe; only index bytes */
432 s
->index_stream
= s
->mb_change_bits
;
434 /* one change bit per 4x4 block */
435 s
->index_stream
= s
->mb_change_bits
+
436 (s
->mb_change_bits_row_size
* (s
->avctx
->height
>> 2));
438 s
->index_stream_size
= s
->size
- (s
->index_stream
- s
->buf
);
440 s
->last_deltaset
= header
.deltaset
;
441 s
->last_vectable
= header
.vectable
;
442 s
->compression
= header
.compression
;
443 s
->block_width
= compression_types
[header
.compression
].block_width
;
444 s
->block_height
= compression_types
[header
.compression
].block_height
;
445 s
->block_type
= compression_types
[header
.compression
].block_type
;
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" : "");
456 return header
.header_size
;
459 static int truemotion1_decode_init(AVCodecContext
*avctx
)
461 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
465 // FIXME: it may change ?
466 // if (avctx->bits_per_sample == 24)
467 // avctx->pix_fmt = PIX_FMT_RGB24;
469 // avctx->pix_fmt = PIX_FMT_RGB555;
471 avctx
->has_b_frames
= 0;
472 s
->frame
.data
[0] = s
->prev_frame
.data
[0] = NULL
;
474 /* there is a vertical predictor for each pixel in a line; each vertical
475 * predictor is 0 to start with */
477 (unsigned int *)av_malloc(s
->avctx
->width
* sizeof(unsigned short));
483 Block decoding order:
489 hres,vres,i,i%vres (0 < i < 4)
508 #define GET_NEXT_INDEX() \
510 if (index_stream_index >= s->index_stream_size) { \
511 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
514 index = s->index_stream[index_stream_index++] * 4; \
517 #define APPLY_C_PREDICTOR() \
518 predictor_pair = s->c_predictor_table[index]; \
519 horiz_pred += (predictor_pair >> 1); \
520 if (predictor_pair & 1) { \
524 predictor_pair = s->c_predictor_table[index]; \
525 horiz_pred += ((predictor_pair >> 1) * 5); \
526 if (predictor_pair & 1) \
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) { \
541 predictor_pair = s->fat_c_predictor_table[index]; \
542 c_horiz_pred += (predictor_pair >> 1); \
543 if (predictor_pair & 1) \
550 // c_last+coff = clast+c_horiz_pred;
553 #define APPLY_Y_PREDICTOR() \
554 predictor_pair = s->y_predictor_table[index]; \
555 horiz_pred += (predictor_pair >> 1); \
556 if (predictor_pair & 1) { \
560 predictor_pair = s->y_predictor_table[index]; \
561 horiz_pred += ((predictor_pair >> 1) * 5); \
562 if (predictor_pair & 1) \
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) { \
577 predictor_pair = s->fat_y_predictor_table[index]; \
578 horiz_pred += (predictor_pair >> 1); \
579 if (predictor_pair & 1) \
587 #define OUTPUT_PIXEL_PAIR() \
588 *current_pixel_pair = *vert_pred + horiz_pred; \
589 *vert_pred++ = *current_pixel_pair++; \
592 static void truemotion1_decode_16bit(TrueMotion1Context
*s
)
595 int pixels_left
; /* remaining pixels on this line */
596 unsigned int predictor_pair
;
597 unsigned int horiz_pred
;
598 unsigned int *vert_pred
;
599 unsigned int *current_pixel_pair
;
600 unsigned int *prev_pixel_pair
;
601 unsigned char *current_line
= s
->frame
.data
[0];
602 unsigned char *prev_line
= s
->prev_frame
.data
[0];
603 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
605 /* these variables are for managing the stream of macroblock change bits */
606 unsigned char *mb_change_bits
= s
->mb_change_bits
;
607 unsigned char mb_change_byte
;
608 unsigned char mb_change_byte_mask
;
611 /* these variables are for managing the main index stream */
612 int index_stream_index
= 0; /* yes, the index into the index stream */
615 /* clean out the line buffer */
616 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned short));
620 for (y
= 0; y
< s
->avctx
->height
; y
++) {
622 /* re-init variables for the next line iteration */
624 current_pixel_pair
= (unsigned int *)current_line
;
625 prev_pixel_pair
= (unsigned int *)prev_line
;
626 vert_pred
= s
->vert_pred
;
628 mb_change_byte
= mb_change_bits
[mb_change_index
++];
629 mb_change_byte_mask
= 0x01;
630 pixels_left
= s
->avctx
->width
;
632 while (pixels_left
> 0) {
634 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
638 /* if macroblock width is 2, apply C-Y-C-Y; else
640 if (s
->block_width
== 2) {
658 /* always apply 2 Y predictors on these iterations */
666 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
667 * depending on the macroblock type */
668 if (s
->block_type
== BLOCK_2x2
) {
675 } else if (s
->block_type
== BLOCK_4x2
) {
692 /* skip (copy) four pixels, but reassign the horizontal
694 *current_pixel_pair
= *prev_pixel_pair
++;
695 *vert_pred
++ = *current_pixel_pair
++;
696 *current_pixel_pair
= *prev_pixel_pair
++;
697 horiz_pred
= *current_pixel_pair
- *vert_pred
;
698 *vert_pred
++ = *current_pixel_pair
++;
703 mb_change_byte_mask
<<= 1;
706 if (!mb_change_byte_mask
) {
707 mb_change_byte
= mb_change_bits
[mb_change_index
++];
708 mb_change_byte_mask
= 0x01;
715 /* next change row */
716 if (((y
+ 1) & 3) == 0)
717 mb_change_bits
+= s
->mb_change_bits_row_size
;
719 current_line
+= s
->frame
.linesize
[0];
720 prev_line
+= s
->prev_frame
.linesize
[0];
724 static void truemotion1_decode_24bit(TrueMotion1Context
*s
)
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
;
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
;
744 /* these variables are for managing the main index stream */
745 int index_stream_index
= 0; /* yes, the index into the index stream */
748 /* clean out the line buffer */
749 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned short));
753 for (y
= 0; y
< s
->avctx
->height
; y
++) {
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
;
761 mb_change_byte
= mb_change_bits
[mb_change_index
++];
762 mb_change_byte_mask
= 0x01;
763 pixels_left
= s
->avctx
->width
;
765 while (pixels_left
> 0) {
767 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
771 /* if macroblock width is 2, apply C-Y-C-Y; else
773 if (s
->block_width
== 2) {
774 APPLY_C_PREDICTOR_24();
775 APPLY_Y_PREDICTOR_24();
777 // OUTPUT_PIXEL_PAIR_24_C();
778 APPLY_C_PREDICTOR_24();
779 APPLY_Y_PREDICTOR_24();
781 // OUTPUT_PIXEL_PAIR_24_C();
783 APPLY_C_PREDICTOR_24();
784 APPLY_Y_PREDICTOR_24();
786 // OUTPUT_PIXEL_PAIR_24_C();
787 APPLY_Y_PREDICTOR_24();
789 // OUTPUT_PIXEL_PAIR_24_C();
795 /* always apply 2 Y predictors on these iterations */
796 APPLY_Y_PREDICTOR_24();
798 APPLY_Y_PREDICTOR_24();
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();
809 // OUTPUT_PIXEL_PAIR_24_C();
810 APPLY_C_PREDICTOR_24();
811 APPLY_Y_PREDICTOR_24();
813 // OUTPUT_PIXEL_PAIR_24_C();
814 } else if (s
->block_type
== BLOCK_4x2
) {
815 APPLY_C_PREDICTOR_24();
816 APPLY_Y_PREDICTOR_24();
818 // OUTPUT_PIXEL_PAIR_24_C();
819 APPLY_Y_PREDICTOR_24();
821 // OUTPUT_PIXEL_PAIR_24_C();
823 APPLY_Y_PREDICTOR_24();
825 APPLY_Y_PREDICTOR_24();
833 /* skip (copy) four pixels, but reassign the horizontal
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
++;
845 mb_change_byte_mask
<<= 1;
848 if (!mb_change_byte_mask
) {
849 mb_change_byte
= mb_change_bits
[mb_change_index
++];
850 mb_change_byte_mask
= 0x01;
857 /* next change row */
858 if (((y
+ 1) & 3) == 0)
859 mb_change_bits
+= s
->mb_change_bits_row_size
;
861 current_line
+= s
->frame
.linesize
[0];
862 prev_line
+= s
->prev_frame
.linesize
[0];
867 static int truemotion1_decode_frame(AVCodecContext
*avctx
,
868 void *data
, int *data_size
,
869 uint8_t *buf
, int buf_size
)
871 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
876 if (truemotion1_decode_header(s
) == -1)
879 s
->frame
.reference
= 1;
880 if (avctx
->get_buffer(avctx
, &s
->frame
) < 0) {
881 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
885 /* check for a do-nothing frame and copy the previous frame */
886 if (compression_types
[s
->compression
].algorithm
== ALGO_NOP
)
888 memcpy(s
->frame
.data
[0], s
->prev_frame
.data
[0],
889 s
->frame
.linesize
[0] * s
->avctx
->height
);
890 } else if (compression_types
[s
->compression
].algorithm
== ALGO_RGB24H
) {
891 truemotion1_decode_24bit(s
);
893 truemotion1_decode_16bit(s
);
896 if (s
->prev_frame
.data
[0])
897 avctx
->release_buffer(avctx
, &s
->prev_frame
);
900 s
->prev_frame
= s
->frame
;
902 *data_size
= sizeof(AVFrame
);
903 *(AVFrame
*)data
= s
->frame
;
905 /* report that the buffer was completely consumed */
909 static int truemotion1_decode_end(AVCodecContext
*avctx
)
911 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
913 /* release the last frame */
914 if (s
->prev_frame
.data
[0])
915 avctx
->release_buffer(avctx
, &s
->prev_frame
);
917 av_free(s
->vert_pred
);
922 AVCodec truemotion1_decoder
= {
925 CODEC_ID_TRUEMOTION1
,
926 sizeof(TrueMotion1Context
),
927 truemotion1_decode_init
,
929 truemotion1_decode_end
,
930 truemotion1_decode_frame
,