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 typedef struct TrueMotion1Context
{
42 AVCodecContext
*avctx
;
49 unsigned char *mb_change_bits
;
50 int mb_change_bits_row_size
;
51 unsigned char *index_stream
;
52 int index_stream_size
;
57 uint32_t y_predictor_table
[1024];
58 uint32_t c_predictor_table
[1024];
70 int last_deltaset
, last_vectable
;
72 unsigned int *vert_pred
;
76 #define FLAG_SPRITE 32
77 #define FLAG_KEYFRAME 16
78 #define FLAG_INTERFRAME 8
79 #define FLAG_INTERPOLATED 4
100 #define ALGO_RGB16V 1
101 #define ALGO_RGB16H 2
102 #define ALGO_RGB24H 3
104 /* these are the various block sizes that can occupy a 4x4 block */
110 typedef struct comp_types
{
117 /* { valid for metatype }, algorithm, num of deltas, horiz res, vert res */
118 static comp_types compression_types
[17] = {
119 { ALGO_NOP
, 0, 0, 0 },
121 { ALGO_RGB16V
, 4, 4, BLOCK_4x4
},
122 { ALGO_RGB16H
, 4, 4, BLOCK_4x4
},
123 { ALGO_RGB16V
, 4, 2, BLOCK_4x2
},
124 { ALGO_RGB16H
, 4, 2, BLOCK_4x2
},
126 { ALGO_RGB16V
, 2, 4, BLOCK_2x4
},
127 { ALGO_RGB16H
, 2, 4, BLOCK_2x4
},
128 { ALGO_RGB16V
, 2, 2, BLOCK_2x2
},
129 { ALGO_RGB16H
, 2, 2, BLOCK_2x2
},
131 { ALGO_NOP
, 4, 4, BLOCK_4x4
},
132 { ALGO_RGB24H
, 4, 4, BLOCK_4x4
},
133 { ALGO_NOP
, 4, 2, BLOCK_4x2
},
134 { ALGO_RGB24H
, 4, 2, BLOCK_4x2
},
136 { ALGO_NOP
, 2, 4, BLOCK_2x4
},
137 { ALGO_RGB24H
, 2, 4, BLOCK_2x4
},
138 { ALGO_NOP
, 2, 2, BLOCK_2x2
},
139 { ALGO_RGB24H
, 2, 2, BLOCK_2x2
}
142 static void select_delta_tables(TrueMotion1Context
*s
, int delta_table_index
)
146 if (delta_table_index
> 3)
149 memcpy(s
->ydt
, ydts
[delta_table_index
], 8 * sizeof(int16_t));
150 memcpy(s
->cdt
, cdts
[delta_table_index
], 8 * sizeof(int16_t));
151 memcpy(s
->fat_ydt
, fat_ydts
[delta_table_index
], 8 * sizeof(int16_t));
152 memcpy(s
->fat_cdt
, fat_cdts
[delta_table_index
], 8 * sizeof(int16_t));
154 /* Y skinny deltas need to be halved for some reason; maybe the
155 * skinny Y deltas should be modified */
156 for (i
= 0; i
< 8; i
++)
158 /* drop the lsb before dividing by 2-- net effect: round down
159 * when dividing a negative number (e.g., -3/2 = -2, not -1) */
165 #ifdef WORDS_BIGENDIAN
166 static int make_ydt_entry(int p2
, int p1
, int16_t *ydt
)
168 static int make_ydt_entry(int p1
, int p2
, int16_t *ydt
)
174 lo
+= (lo
<< 5) + (lo
<< 10);
176 hi
+= (hi
<< 5) + (hi
<< 10);
177 return ((lo
+ (hi
<< 16)) << 1);
180 #ifdef WORDS_BIGENDIAN
181 static int make_cdt_entry(int p2
, int p1
, int16_t *cdt
)
183 static int make_cdt_entry(int p1
, int p2
, int16_t *cdt
)
191 return ((lo
+ (lo
<< 16)) << 1);
194 static void gen_vector_table(TrueMotion1Context
*s
, uint8_t *sel_vector_table
)
197 unsigned char delta_pair
;
199 for (i
= 0; i
< 1024; i
+= 4)
201 len
= *sel_vector_table
++ / 2;
202 for (j
= 0; j
< len
; j
++)
204 delta_pair
= *sel_vector_table
++;
205 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
206 make_ydt_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
207 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
208 make_cdt_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
210 s
->y_predictor_table
[i
+(j
-1)] |= 1;
211 s
->c_predictor_table
[i
+(j
-1)] |= 1;
215 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
216 * there was an error while decoding the header */
217 static int truemotion1_decode_header(TrueMotion1Context
*s
)
220 struct frame_header header
;
221 uint8_t header_buffer
[128]; /* logical maximum size of the header */
222 uint8_t *sel_vector_table
;
224 /* There is 1 change bit per 4 pixels, so each change byte represents
225 * 32 pixels; divide width by 4 to obtain the number of change bits and
226 * then round up to the nearest byte. */
227 s
->mb_change_bits_row_size
= ((s
->avctx
->width
>> 2) + 7) >> 3;
229 header
.header_size
= ((s
->buf
[0] >> 5) | (s
->buf
[0] << 3)) & 0x7f;
230 if (s
->buf
[0] < 0x10)
232 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid header size\n");
236 /* unscramble the header bytes with a XOR operation */
237 memset(header_buffer
, 0, 128);
238 for (i
= 1; i
< header
.header_size
; i
++)
239 header_buffer
[i
- 1] = s
->buf
[i
] ^ s
->buf
[i
+ 1];
240 header
.compression
= header_buffer
[0];
241 header
.deltaset
= header_buffer
[1];
242 header
.vectable
= header_buffer
[2];
243 header
.ysize
= LE_16(&header_buffer
[3]);
244 header
.xsize
= LE_16(&header_buffer
[5]);
245 header
.checksum
= LE_16(&header_buffer
[7]);
246 header
.version
= header_buffer
[9];
247 header
.header_type
= header_buffer
[10];
248 header
.flags
= header_buffer
[11];
249 header
.control
= header_buffer
[12];
252 if (header
.version
>= 2)
254 if (header
.header_type
> 3)
256 av_log(s
->avctx
, AV_LOG_ERROR
, "truemotion1: invalid header type\n");
258 } else if ((header
.header_type
== 2) || (header
.header_type
== 3)) {
259 s
->flags
= header
.flags
;
260 if (!(s
->flags
& FLAG_INTERFRAME
))
261 s
->flags
|= FLAG_KEYFRAME
;
263 s
->flags
= FLAG_KEYFRAME
;
264 } else /* Version 1 */
265 s
->flags
= FLAG_KEYFRAME
;
267 if (s
->flags
& FLAG_SPRITE
) {
269 s
->h
= header
.height
;
270 s
->x
= header
.xoffset
;
271 s
->y
= header
.yoffset
;
275 if (header
.header_type
< 2) {
276 if ((s
->w
< 213) && (s
->h
>= 176))
277 s
->flags
|= FLAG_INTERPOLATED
;
281 if (header
.compression
> 17) {
282 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid compression type (%d)\n", header
.compression
);
286 if ((header
.deltaset
!= s
->last_deltaset
) ||
287 (header
.vectable
!= s
->last_vectable
))
288 select_delta_tables(s
, header
.deltaset
);
290 if ((header
.compression
& 1) && header
.header_type
)
291 sel_vector_table
= pc_tbl2
;
293 if (header
.vectable
< 4)
294 sel_vector_table
= tables
[header
.vectable
- 1];
296 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid vector table id (%d)\n", header
.vectable
);
301 if ((header
.deltaset
!= s
->last_deltaset
) || (header
.vectable
!= s
->last_vectable
))
303 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
305 av_log(s
->avctx
, AV_LOG_ERROR
, "24bit compression not yet supported\n");
308 gen_vector_table(s
, sel_vector_table
);
311 /* set up pointers to the other key data chunks */
312 s
->mb_change_bits
= s
->buf
+ header
.header_size
;
313 if (s
->flags
& FLAG_KEYFRAME
) {
314 /* no change bits specified for a keyframe; only index bytes */
315 s
->index_stream
= s
->mb_change_bits
;
317 /* one change bit per 4x4 block */
318 s
->index_stream
= s
->mb_change_bits
+
319 (s
->mb_change_bits_row_size
* (s
->avctx
->height
>> 2));
321 s
->index_stream_size
= s
->size
- (s
->index_stream
- s
->buf
);
323 s
->last_deltaset
= header
.deltaset
;
324 s
->last_vectable
= header
.vectable
;
325 s
->compression
= header
.compression
;
326 s
->block_width
= compression_types
[header
.compression
].block_width
;
327 s
->block_height
= compression_types
[header
.compression
].block_height
;
328 s
->block_type
= compression_types
[header
.compression
].block_type
;
330 return header
.header_size
;
333 static int truemotion1_decode_init(AVCodecContext
*avctx
)
335 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
339 avctx
->pix_fmt
= PIX_FMT_RGB555
;
340 avctx
->has_b_frames
= 0;
341 s
->frame
.data
[0] = s
->prev_frame
.data
[0] = NULL
;
343 /* there is a vertical predictor for each pixel in a line; each vertical
344 * predictor is 0 to start with */
346 (unsigned int *)av_malloc(s
->avctx
->width
* sizeof(unsigned short));
351 #define GET_NEXT_INDEX() \
353 if (index_stream_index >= s->index_stream_size) { \
354 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
357 index = s->index_stream[index_stream_index++] * 4; \
360 #define APPLY_C_PREDICTOR() \
361 predictor_pair = s->c_predictor_table[index]; \
362 horiz_pred += (predictor_pair >> 1); \
363 if (predictor_pair & 1) { \
367 predictor_pair = s->c_predictor_table[index]; \
368 horiz_pred += ((predictor_pair >> 1) * 5); \
369 if (predictor_pair & 1) \
377 #define APPLY_Y_PREDICTOR() \
378 predictor_pair = s->y_predictor_table[index]; \
379 horiz_pred += (predictor_pair >> 1); \
380 if (predictor_pair & 1) { \
384 predictor_pair = s->y_predictor_table[index]; \
385 horiz_pred += ((predictor_pair >> 1) * 5); \
386 if (predictor_pair & 1) \
394 #define OUTPUT_PIXEL_PAIR() \
395 *current_pixel_pair = *vert_pred + horiz_pred; \
396 *vert_pred++ = *current_pixel_pair++; \
399 static void truemotion1_decode_16bit(TrueMotion1Context
*s
)
402 int pixels_left
; /* remaining pixels on this line */
403 unsigned int predictor_pair
;
404 unsigned int horiz_pred
;
405 unsigned int *vert_pred
;
406 unsigned int *current_pixel_pair
;
407 unsigned int *prev_pixel_pair
;
408 unsigned char *current_line
= s
->frame
.data
[0];
409 unsigned char *prev_line
= s
->prev_frame
.data
[0];
410 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
412 /* these variables are for managing the stream of macroblock change bits */
413 unsigned char *mb_change_bits
= s
->mb_change_bits
;
414 unsigned char mb_change_byte
;
415 unsigned char mb_change_byte_mask
;
418 /* these variables are for managing the main index stream */
419 int index_stream_index
= 0; /* yes, the index into the index stream */
422 /* clean out the line buffer */
423 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned short));
427 for (y
= 0; y
< s
->avctx
->height
; y
++) {
429 /* re-init variables for the next line iteration */
431 current_pixel_pair
= (unsigned int *)current_line
;
432 prev_pixel_pair
= (unsigned int *)prev_line
;
433 vert_pred
= s
->vert_pred
;
435 mb_change_byte
= mb_change_bits
[mb_change_index
++];
436 mb_change_byte_mask
= 0x01;
437 pixels_left
= s
->avctx
->width
;
439 while (pixels_left
> 0) {
441 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
445 /* if macroblock width is 2, apply C-Y-C-Y; else
447 if (s
->block_width
== 2) {
465 /* always apply 2 Y predictors on these iterations */
473 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
474 * depending on the macroblock type */
475 if (s
->block_type
== BLOCK_2x2
) {
482 } else if (s
->block_type
== BLOCK_4x2
) {
499 /* skip (copy) four pixels, but reassign the horizontal
501 *current_pixel_pair
= *prev_pixel_pair
++;
502 *vert_pred
++ = *current_pixel_pair
++;
503 *current_pixel_pair
= *prev_pixel_pair
++;
504 horiz_pred
= *current_pixel_pair
- *vert_pred
;
505 *vert_pred
++ = *current_pixel_pair
++;
510 mb_change_byte_mask
<<= 1;
513 if (!mb_change_byte_mask
) {
514 mb_change_byte
= mb_change_bits
[mb_change_index
++];
515 mb_change_byte_mask
= 0x01;
522 /* next change row */
523 if (((y
+ 1) & 3) == 0)
524 mb_change_bits
+= s
->mb_change_bits_row_size
;
526 current_line
+= s
->frame
.linesize
[0];
527 prev_line
+= s
->prev_frame
.linesize
[0];
531 static int truemotion1_decode_frame(AVCodecContext
*avctx
,
532 void *data
, int *data_size
,
533 uint8_t *buf
, int buf_size
)
535 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
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");
546 /* no supplementary picture */
550 if (truemotion1_decode_header(s
) == -1)
553 /* check for a do-nothing frame and copy the previous frame */
554 if (compression_types
[s
->compression
].algorithm
== ALGO_NOP
)
556 memcpy(s
->frame
.data
[0], s
->prev_frame
.data
[0],
557 s
->frame
.linesize
[0] * s
->avctx
->height
);
558 } else if (compression_types
[s
->compression
].algorithm
== ALGO_RGB24H
) {
559 av_log(s
->avctx
, AV_LOG_ERROR
, "24bit compression not yet supported\n");
561 truemotion1_decode_16bit(s
);
564 if (s
->prev_frame
.data
[0])
565 avctx
->release_buffer(avctx
, &s
->prev_frame
);
568 s
->prev_frame
= s
->frame
;
570 *data_size
= sizeof(AVFrame
);
571 *(AVFrame
*)data
= s
->frame
;
573 /* report that the buffer was completely consumed */
577 static int truemotion1_decode_end(AVCodecContext
*avctx
)
579 TrueMotion1Context
*s
= (TrueMotion1Context
*)avctx
->priv_data
;
581 /* release the last frame */
582 if (s
->prev_frame
.data
[0])
583 avctx
->release_buffer(avctx
, &s
->prev_frame
);
585 av_free(s
->vert_pred
);
590 AVCodec truemotion1_decoder
= {
593 CODEC_ID_TRUEMOTION1
,
594 sizeof(TrueMotion1Context
),
595 truemotion1_decode_init
,
597 truemotion1_decode_end
,
598 truemotion1_decode_frame
,