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 data. 24-bit TM1 data is not supported yet.
39 #include "truemotion1data.h"
41 #define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
43 typedef struct TrueMotion1Context
{
44 AVCodecContext
*avctx
;
51 unsigned char *mb_change_bits
;
52 int mb_change_bits_row_size
;
53 unsigned char *index_stream
;
54 int index_stream_size
;
59 uint32_t y_predictor_table
[1024];
60 uint32_t 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
{
119 /* { valid for metatype }, algorithm, num of deltas, horiz res, vert 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 s
->ydt
= ydts
[delta_table_index
];
152 s
->cdt
= cdts
[delta_table_index
];
153 s
->fat_ydt
= fat_ydts
[delta_table_index
];
154 s
->fat_cdt
= fat_cdts
[delta_table_index
];
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 static int make_ydt_entry(int p1
, int p2
, int16_t *ydt
)
172 lo
+= (lo
<< 5) + (lo
<< 10);
174 hi
+= (hi
<< 5) + (hi
<< 10);
175 return ((lo
+ (hi
<< 16)) << 1);
178 static int make_cdt_entry(int p1
, int p2
, int16_t *cdt
)
185 return ((lo
+ (lo
<< 16)) << 1);
188 static void gen_vector_table(TrueMotion1Context
*s
, uint8_t *sel_vector_table
)
191 unsigned char delta_pair
;
193 for (i
= 0; i
< 1024; i
+= 4)
195 len
= *sel_vector_table
++ / 2;
196 for (j
= 0; j
< len
; j
++)
198 delta_pair
= *sel_vector_table
++;
199 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
200 make_ydt_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
201 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
202 make_cdt_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
204 s
->y_predictor_table
[i
+(j
-1)] |= 1;
205 s
->c_predictor_table
[i
+(j
-1)] |= 1;
209 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
210 * there was an error while decoding the header */
211 static int truemotion1_decode_header(TrueMotion1Context
*s
)
214 struct frame_header header
;
215 uint8_t header_buffer
[128]; /* logical maximum size of the header */
216 uint8_t *sel_vector_table
;
218 /* There is 1 change bit per 4 pixels, so each change byte represents
219 * 32 pixels; divide width by 4 to obtain the number of change bits and
220 * then round up to the nearest byte. */
221 s
->mb_change_bits_row_size
= ((s
->avctx
->width
>> 2) + 7) >> 3;
223 header
.header_size
= ((s
->buf
[0] >> 5) | (s
->buf
[0] << 3)) & 0x7f;
224 if (s
->buf
[0] < 0x10)
226 printf("invalid header size\n");
230 /* unscramble the header bytes with a XOR operation */
231 memset(header_buffer
, 0, 128);
232 for (i
= 1; i
< header
.header_size
; i
++)
233 header_buffer
[i
- 1] = s
->buf
[i
] ^ s
->buf
[i
+ 1];
234 header
.compression
= header_buffer
[0];
235 header
.deltaset
= header_buffer
[1];
236 header
.vectable
= header_buffer
[2];
237 header
.ysize
= LE_16(&header_buffer
[3]);
238 header
.xsize
= LE_16(&header_buffer
[5]);
239 header
.checksum
= LE_16(&header_buffer
[7]);
240 header
.version
= header_buffer
[9];
241 header
.header_type
= header_buffer
[10];
242 header
.flags
= header_buffer
[11];
243 header
.control
= header_buffer
[12];
246 if (header
.version
>= 2)
248 if (header
.header_type
> 3)
250 av_log(s
->avctx
, AV_LOG_ERROR
, "truemotion1: invalid header type\n");
252 } else if ((header
.header_type
== 2) || (header
.header_type
== 3)) {
253 s
->flags
= header
.flags
;
254 if (!(s
->flags
& FLAG_INTERFRAME
))
255 s
->flags
|= FLAG_KEYFRAME
;
257 s
->flags
= FLAG_KEYFRAME
;
258 } else /* Version 1 */
259 s
->flags
= FLAG_KEYFRAME
;
261 if (s
->flags
& FLAG_SPRITE
) {
263 s
->h
= header
.height
;
264 s
->x
= header
.xoffset
;
265 s
->y
= header
.yoffset
;
269 if (header
.header_type
< 2) {
270 if ((s
->w
< 213) && (s
->h
>= 176))
271 s
->flags
|= FLAG_INTERPOLATED
;
275 if (header
.compression
> 17) {
276 printf("invalid compression type (%d)\n", header
.compression
);
280 if ((header
.deltaset
!= s
->last_deltaset
) ||
281 (header
.vectable
!= s
->last_vectable
))
282 select_delta_tables(s
, header
.deltaset
);
284 if ((header
.compression
& 1) && header
.header_type
)
285 sel_vector_table
= pc_tbl2
;
287 if (header
.vectable
< 4)
288 sel_vector_table
= tables
[header
.vectable
- 1];
290 printf("invalid vector table id (%d)\n", header
.vectable
);
295 if ((header
.deltaset
!= s
->last_deltaset
) || (header
.vectable
!= s
->last_vectable
))
297 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
299 printf("24bit compression not yet supported\n");
302 gen_vector_table(s
, sel_vector_table
);
305 /* set up pointers to the other key data chunks */
306 s
->mb_change_bits
= s
->buf
+ header
.header_size
;
307 if (s
->flags
& FLAG_KEYFRAME
) {
308 /* no change bits specified for a keyframe; only index bytes */
309 s
->index_stream
= s
->mb_change_bits
;
311 /* one change bit per 4x4 block */
312 s
->index_stream
= s
->mb_change_bits
+
313 (s
->mb_change_bits_row_size
* (s
->avctx
->height
>> 2));
315 s
->index_stream_size
= s
->size
- (s
->index_stream
- s
->buf
);
317 s
->last_deltaset
= header
.deltaset
;
318 s
->last_vectable
= header
.vectable
;
319 s
->compression
= header
.compression
;
320 s
->block_width
= compression_types
[header
.compression
].block_width
;
321 s
->block_height
= compression_types
[header
.compression
].block_height
;
322 s
->block_type
= compression_types
[header
.compression
].block_type
;
324 return header
.header_size
;
327 static int truemotion1_decode_init(AVCodecContext
*avctx
)
329 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
333 avctx
->pix_fmt
= PIX_FMT_RGB555
;
334 avctx
->has_b_frames
= 0;
335 s
->frame
.data
[0] = s
->prev_frame
.data
[0] = NULL
;
337 /* there is a vertical predictor for each pixel in a line; each vertical
338 * predictor is 0 to start with */
340 (unsigned int *)av_malloc(s
->avctx
->width
* sizeof(unsigned short));
345 #define GET_NEXT_INDEX() \
347 if (index_stream_index >= s->index_stream_size) { \
348 printf (" help! truemotion1 decoder went out of bounds\n"); \
351 index = s->index_stream[index_stream_index++] * 4; \
354 #define APPLY_C_PREDICTOR() \
355 predictor_pair = s->c_predictor_table[index]; \
356 horiz_pred += (predictor_pair >> 1); \
357 if (predictor_pair & 1) { \
361 predictor_pair = s->c_predictor_table[index]; \
362 horiz_pred += ((predictor_pair >> 1) * 5); \
363 if (predictor_pair & 1) \
371 #define APPLY_Y_PREDICTOR() \
372 predictor_pair = s->y_predictor_table[index]; \
373 horiz_pred += (predictor_pair >> 1); \
374 if (predictor_pair & 1) { \
378 predictor_pair = s->y_predictor_table[index]; \
379 horiz_pred += ((predictor_pair >> 1) * 5); \
380 if (predictor_pair & 1) \
388 #define OUTPUT_PIXEL_PAIR() \
389 *current_pixel_pair = *vert_pred + horiz_pred; \
390 *vert_pred++ = *current_pixel_pair++; \
393 static void truemotion1_decode_16bit(TrueMotion1Context
*s
)
396 int pixels_left
; /* remaining pixels on this line */
397 unsigned int predictor_pair
;
398 unsigned int horiz_pred
;
399 unsigned int *vert_pred
;
400 unsigned int *current_pixel_pair
;
401 unsigned int *prev_pixel_pair
;
402 unsigned char *current_line
= s
->frame
.data
[0];
403 unsigned char *prev_line
= s
->prev_frame
.data
[0];
404 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
406 /* these variables are for managing the stream of macroblock change bits */
407 unsigned char *mb_change_bits
= s
->mb_change_bits
;
408 unsigned char mb_change_byte
;
409 unsigned char mb_change_byte_mask
;
412 /* these variables are for managing the main index stream */
413 int index_stream_index
= 0; /* yes, the index into the index stream */
416 /* clean out the line buffer */
417 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned short));
421 for (y
= 0; y
< s
->avctx
->height
; y
++) {
423 /* re-init variables for the next line iteration */
425 current_pixel_pair
= (unsigned int *)current_line
;
426 prev_pixel_pair
= (unsigned int *)prev_line
;
427 vert_pred
= s
->vert_pred
;
429 mb_change_byte
= mb_change_bits
[mb_change_index
++];
430 mb_change_byte_mask
= 0x01;
431 pixels_left
= s
->avctx
->width
;
433 while (pixels_left
> 0) {
435 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
439 /* if macroblock width is 2, apply C-Y-C-Y; else
441 if ((s
->block_type
== BLOCK_2x2
) ||
442 (s
->block_type
== BLOCK_2x4
)) {
460 /* always apply 2 Y predictors on these iterations */
468 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
469 * depending on the macroblock type */
470 if (s
->block_type
== BLOCK_2x2
) {
477 } else if (s
->block_type
== BLOCK_4x2
) {
494 /* skip (copy) four pixels, but reassign the horizontal
496 *current_pixel_pair
= *prev_pixel_pair
++;
497 *vert_pred
++ = *current_pixel_pair
++;
498 *current_pixel_pair
= *prev_pixel_pair
++;
499 horiz_pred
= *current_pixel_pair
- *vert_pred
;
500 *vert_pred
++ = *current_pixel_pair
++;
505 mb_change_byte_mask
<<= 1;
508 if (!mb_change_byte_mask
) {
509 mb_change_byte
= mb_change_bits
[mb_change_index
++];
510 mb_change_byte_mask
= 0x01;
517 /* next change row */
518 if (((y
+ 1) & 3) == 0)
519 mb_change_bits
+= s
->mb_change_bits_row_size
;
521 current_line
+= s
->frame
.linesize
[0];
522 prev_line
+= s
->prev_frame
.linesize
[0];
526 static int truemotion1_decode_frame(AVCodecContext
*avctx
,
527 void *data
, int *data_size
,
528 uint8_t *buf
, int buf_size
)
530 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
535 s
->frame
.reference
= 1;
536 if (avctx
->get_buffer(avctx
, &s
->frame
) < 0) {
537 fprintf(stderr
, "truemotion1: get_buffer() failed\n");
541 /* no supplementary picture */
547 if (truemotion1_decode_header(s
) == -1)
550 /* check for a do-nothing frame and copy the previous frame */
551 if (compression_types
[s
->compression
].algorithm
== ALGO_NOP
)
553 memcpy(s
->frame
.data
[0], s
->prev_frame
.data
[0],
554 s
->frame
.linesize
[0] * s
->avctx
->height
);
555 } else if (compression_types
[s
->compression
].algorithm
== ALGO_RGB24H
) {
556 printf (" 24-bit Duck TrueMotion decoding not yet implemented\n");
558 truemotion1_decode_16bit(s
);
561 if (s
->prev_frame
.data
[0])
562 avctx
->release_buffer(avctx
, &s
->prev_frame
);
565 s
->prev_frame
= s
->frame
;
567 *data_size
= sizeof(AVFrame
);
568 *(AVFrame
*)data
= s
->frame
;
570 /* report that the buffer was completely consumed */
574 static int truemotion1_decode_end(AVCodecContext
*avctx
)
576 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
578 /* release the last frame */
579 if (s
->prev_frame
.data
[0])
580 avctx
->release_buffer(avctx
, &s
->prev_frame
);
582 av_free(s
->vert_pred
);
587 AVCodec truemotion1_decoder
= {
590 CODEC_ID_TRUEMOTION1
,
591 sizeof(TrueMotion1Context
),
592 truemotion1_decode_init
,
594 truemotion1_decode_end
,
595 truemotion1_decode_frame
,