2 * Duck TrueMotion 1.0 Decoder
3 * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
5 * This file is part of FFmpeg.
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.
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.
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
23 * @file libavcodec/truemotion1.c
24 * Duck TrueMotion v1 Video Decoder by
25 * Alex Beregszaszi and
26 * Mike Melanson (melanson@pcisys.net)
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.
39 #include "truemotion1data.h"
41 typedef struct TrueMotion1Context
{
42 AVCodecContext
*avctx
;
48 const uint8_t *mb_change_bits
;
49 int mb_change_bits_row_size
;
50 const uint8_t *index_stream
;
51 int index_stream_size
;
56 uint32_t y_predictor_table
[1024];
57 uint32_t c_predictor_table
[1024];
58 uint32_t fat_y_predictor_table
[1024];
59 uint32_t fat_c_predictor_table
[1024];
71 int last_deltaset
, last_vectable
;
73 unsigned int *vert_pred
;
77 #define FLAG_SPRITE 32
78 #define FLAG_KEYFRAME 16
79 #define FLAG_INTERFRAME 8
80 #define FLAG_INTERPOLATED 4
101 #define ALGO_RGB16V 1
102 #define ALGO_RGB16H 2
103 #define ALGO_RGB24H 3
105 /* these are the various block sizes that can occupy a 4x4 block */
111 typedef struct comp_types
{
113 int block_width
; // vres
114 int block_height
; // hres
118 /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
119 static const comp_types compression_types
[17] = {
120 { ALGO_NOP
, 0, 0, 0 },
122 { ALGO_RGB16V
, 4, 4, BLOCK_4x4
},
123 { ALGO_RGB16H
, 4, 4, BLOCK_4x4
},
124 { ALGO_RGB16V
, 4, 2, BLOCK_4x2
},
125 { ALGO_RGB16H
, 4, 2, BLOCK_4x2
},
127 { ALGO_RGB16V
, 2, 4, BLOCK_2x4
},
128 { ALGO_RGB16H
, 2, 4, BLOCK_2x4
},
129 { ALGO_RGB16V
, 2, 2, BLOCK_2x2
},
130 { ALGO_RGB16H
, 2, 2, BLOCK_2x2
},
132 { ALGO_NOP
, 4, 4, BLOCK_4x4
},
133 { ALGO_RGB24H
, 4, 4, BLOCK_4x4
},
134 { ALGO_NOP
, 4, 2, BLOCK_4x2
},
135 { ALGO_RGB24H
, 4, 2, BLOCK_4x2
},
137 { ALGO_NOP
, 2, 4, BLOCK_2x4
},
138 { ALGO_RGB24H
, 2, 4, BLOCK_2x4
},
139 { ALGO_NOP
, 2, 2, BLOCK_2x2
},
140 { ALGO_RGB24H
, 2, 2, BLOCK_2x2
}
143 static void select_delta_tables(TrueMotion1Context
*s
, int delta_table_index
)
147 if (delta_table_index
> 3)
150 memcpy(s
->ydt
, ydts
[delta_table_index
], 8 * sizeof(int16_t));
151 memcpy(s
->cdt
, cdts
[delta_table_index
], 8 * sizeof(int16_t));
152 memcpy(s
->fat_ydt
, fat_ydts
[delta_table_index
], 8 * sizeof(int16_t));
153 memcpy(s
->fat_cdt
, fat_cdts
[delta_table_index
], 8 * sizeof(int16_t));
155 /* Y skinny deltas need to be halved for some reason; maybe the
156 * skinny Y deltas should be modified */
157 for (i
= 0; i
< 8; i
++)
159 /* drop the lsb before dividing by 2-- net effect: round down
160 * when dividing a negative number (e.g., -3/2 = -2, not -1) */
167 static int make_ydt15_entry(int p2
, int p1
, int16_t *ydt
)
169 static int make_ydt15_entry(int p1
, int p2
, int16_t *ydt
)
175 lo
+= (lo
<< 5) + (lo
<< 10);
177 hi
+= (hi
<< 5) + (hi
<< 10);
178 return (lo
+ (hi
<< 16)) << 1;
182 static int make_cdt15_entry(int p2
, int p1
, int16_t *cdt
)
184 static int make_cdt15_entry(int p1
, int p2
, int16_t *cdt
)
192 return (lo
+ (lo
<< 16)) << 1;
196 static int make_ydt16_entry(int p2
, int p1
, int16_t *ydt
)
198 static int make_ydt16_entry(int p1
, int p2
, int16_t *ydt
)
204 lo
+= (lo
<< 6) + (lo
<< 11);
206 hi
+= (hi
<< 6) + (hi
<< 11);
207 return (lo
+ (hi
<< 16)) << 1;
211 static int make_cdt16_entry(int p2
, int p1
, int16_t *cdt
)
213 static int make_cdt16_entry(int p1
, int p2
, int16_t *cdt
)
221 return (lo
+ (lo
<< 16)) << 1;
225 static int make_ydt24_entry(int p2
, int p1
, int16_t *ydt
)
227 static int make_ydt24_entry(int p1
, int p2
, int16_t *ydt
)
234 return (lo
+ (hi
<< 8) + (hi
<< 16)) << 1;
238 static int make_cdt24_entry(int p2
, int p1
, int16_t *cdt
)
240 static int make_cdt24_entry(int p1
, int p2
, int16_t *cdt
)
250 static void gen_vector_table15(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
253 unsigned char delta_pair
;
255 for (i
= 0; i
< 1024; i
+= 4)
257 len
= *sel_vector_table
++ / 2;
258 for (j
= 0; j
< len
; j
++)
260 delta_pair
= *sel_vector_table
++;
261 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
262 make_ydt15_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
263 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
264 make_cdt15_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
266 s
->y_predictor_table
[i
+(j
-1)] |= 1;
267 s
->c_predictor_table
[i
+(j
-1)] |= 1;
271 static void gen_vector_table16(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
274 unsigned char delta_pair
;
276 for (i
= 0; i
< 1024; i
+= 4)
278 len
= *sel_vector_table
++ / 2;
279 for (j
= 0; j
< len
; j
++)
281 delta_pair
= *sel_vector_table
++;
282 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
283 make_ydt16_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
284 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
285 make_cdt16_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
287 s
->y_predictor_table
[i
+(j
-1)] |= 1;
288 s
->c_predictor_table
[i
+(j
-1)] |= 1;
292 static void gen_vector_table24(TrueMotion1Context
*s
, const uint8_t *sel_vector_table
)
295 unsigned char delta_pair
;
297 for (i
= 0; i
< 1024; i
+= 4)
299 len
= *sel_vector_table
++ / 2;
300 for (j
= 0; j
< len
; j
++)
302 delta_pair
= *sel_vector_table
++;
303 s
->y_predictor_table
[i
+j
] = 0xfffffffe &
304 make_ydt24_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->ydt
);
305 s
->c_predictor_table
[i
+j
] = 0xfffffffe &
306 make_cdt24_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->cdt
);
307 s
->fat_y_predictor_table
[i
+j
] = 0xfffffffe &
308 make_ydt24_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->fat_ydt
);
309 s
->fat_c_predictor_table
[i
+j
] = 0xfffffffe &
310 make_cdt24_entry(delta_pair
>> 4, delta_pair
& 0xf, s
->fat_cdt
);
312 s
->y_predictor_table
[i
+(j
-1)] |= 1;
313 s
->c_predictor_table
[i
+(j
-1)] |= 1;
314 s
->fat_y_predictor_table
[i
+(j
-1)] |= 1;
315 s
->fat_c_predictor_table
[i
+(j
-1)] |= 1;
319 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
320 * there was an error while decoding the header */
321 static int truemotion1_decode_header(TrueMotion1Context
*s
)
324 struct frame_header header
;
325 uint8_t header_buffer
[128]; /* logical maximum size of the header */
326 const uint8_t *sel_vector_table
;
328 /* There is 1 change bit per 4 pixels, so each change byte represents
329 * 32 pixels; divide width by 4 to obtain the number of change bits and
330 * then round up to the nearest byte. */
331 s
->mb_change_bits_row_size
= ((s
->avctx
->width
>> 2) + 7) >> 3;
333 header
.header_size
= ((s
->buf
[0] >> 5) | (s
->buf
[0] << 3)) & 0x7f;
334 if (s
->buf
[0] < 0x10)
336 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid header size (%d)\n", s
->buf
[0]);
340 /* unscramble the header bytes with a XOR operation */
341 memset(header_buffer
, 0, 128);
342 for (i
= 1; i
< header
.header_size
; i
++)
343 header_buffer
[i
- 1] = s
->buf
[i
] ^ s
->buf
[i
+ 1];
345 header
.compression
= header_buffer
[0];
346 header
.deltaset
= header_buffer
[1];
347 header
.vectable
= header_buffer
[2];
348 header
.ysize
= AV_RL16(&header_buffer
[3]);
349 header
.xsize
= AV_RL16(&header_buffer
[5]);
350 header
.checksum
= AV_RL16(&header_buffer
[7]);
351 header
.version
= header_buffer
[9];
352 header
.header_type
= header_buffer
[10];
353 header
.flags
= header_buffer
[11];
354 header
.control
= header_buffer
[12];
357 if (header
.version
>= 2)
359 if (header
.header_type
> 3)
361 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid header type (%d)\n", header
.header_type
);
363 } else if ((header
.header_type
== 2) || (header
.header_type
== 3)) {
364 s
->flags
= header
.flags
;
365 if (!(s
->flags
& FLAG_INTERFRAME
))
366 s
->flags
|= FLAG_KEYFRAME
;
368 s
->flags
= FLAG_KEYFRAME
;
369 } else /* Version 1 */
370 s
->flags
= FLAG_KEYFRAME
;
372 if (s
->flags
& FLAG_SPRITE
) {
373 av_log(s
->avctx
, AV_LOG_INFO
, "SPRITE frame found, please report the sample to the developers\n");
374 /* FIXME header.width, height, xoffset and yoffset aren't initialized */
377 s
->h
= header
.height
;
378 s
->x
= header
.xoffset
;
379 s
->y
= header
.yoffset
;
386 if (header
.header_type
< 2) {
387 if ((s
->w
< 213) && (s
->h
>= 176))
389 s
->flags
|= FLAG_INTERPOLATED
;
390 av_log(s
->avctx
, AV_LOG_INFO
, "INTERPOLATION selected, please report the sample to the developers\n");
395 if (header
.compression
>= 17) {
396 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid compression type (%d)\n", header
.compression
);
400 if ((header
.deltaset
!= s
->last_deltaset
) ||
401 (header
.vectable
!= s
->last_vectable
))
402 select_delta_tables(s
, header
.deltaset
);
404 if ((header
.compression
& 1) && header
.header_type
)
405 sel_vector_table
= pc_tbl2
;
407 if (header
.vectable
< 4)
408 sel_vector_table
= tables
[header
.vectable
- 1];
410 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid vector table id (%d)\n", header
.vectable
);
415 // FIXME: where to place this ?!?!
416 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
417 s
->avctx
->pix_fmt
= PIX_FMT_RGB32
;
419 s
->avctx
->pix_fmt
= PIX_FMT_RGB555
; // RGB565 is supported as well
421 if ((header
.deltaset
!= s
->last_deltaset
) || (header
.vectable
!= s
->last_vectable
))
423 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
424 gen_vector_table24(s
, sel_vector_table
);
426 if (s
->avctx
->pix_fmt
== PIX_FMT_RGB555
)
427 gen_vector_table15(s
, sel_vector_table
);
429 gen_vector_table16(s
, sel_vector_table
);
432 /* set up pointers to the other key data chunks */
433 s
->mb_change_bits
= s
->buf
+ header
.header_size
;
434 if (s
->flags
& FLAG_KEYFRAME
) {
435 /* no change bits specified for a keyframe; only index bytes */
436 s
->index_stream
= s
->mb_change_bits
;
438 /* one change bit per 4x4 block */
439 s
->index_stream
= s
->mb_change_bits
+
440 (s
->mb_change_bits_row_size
* (s
->avctx
->height
>> 2));
442 s
->index_stream_size
= s
->size
- (s
->index_stream
- s
->buf
);
444 s
->last_deltaset
= header
.deltaset
;
445 s
->last_vectable
= header
.vectable
;
446 s
->compression
= header
.compression
;
447 s
->block_width
= compression_types
[header
.compression
].block_width
;
448 s
->block_height
= compression_types
[header
.compression
].block_height
;
449 s
->block_type
= compression_types
[header
.compression
].block_type
;
451 if (s
->avctx
->debug
& FF_DEBUG_PICT_INFO
)
452 av_log(s
->avctx
, AV_LOG_INFO
, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
453 s
->last_deltaset
, s
->last_vectable
, s
->compression
, s
->block_width
,
454 s
->block_height
, s
->block_type
,
455 s
->flags
& FLAG_KEYFRAME
? " KEY" : "",
456 s
->flags
& FLAG_INTERFRAME
? " INTER" : "",
457 s
->flags
& FLAG_SPRITE
? " SPRITE" : "",
458 s
->flags
& FLAG_INTERPOLATED
? " INTERPOL" : "");
460 return header
.header_size
;
463 static av_cold
int truemotion1_decode_init(AVCodecContext
*avctx
)
465 TrueMotion1Context
*s
= avctx
->priv_data
;
469 // FIXME: it may change ?
470 // if (avctx->bits_per_sample == 24)
471 // avctx->pix_fmt = PIX_FMT_RGB24;
473 // avctx->pix_fmt = PIX_FMT_RGB555;
475 s
->frame
.data
[0] = NULL
;
477 /* there is a vertical predictor for each pixel in a line; each vertical
478 * predictor is 0 to start with */
480 (unsigned int *)av_malloc(s
->avctx
->width
* sizeof(unsigned int));
486 Block decoding order:
492 hres,vres,i,i%vres (0 < i < 4)
511 #define GET_NEXT_INDEX() \
513 if (index_stream_index >= s->index_stream_size) { \
514 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
517 index = s->index_stream[index_stream_index++] * 4; \
520 #define APPLY_C_PREDICTOR() \
521 predictor_pair = s->c_predictor_table[index]; \
522 horiz_pred += (predictor_pair >> 1); \
523 if (predictor_pair & 1) { \
527 predictor_pair = s->c_predictor_table[index]; \
528 horiz_pred += ((predictor_pair >> 1) * 5); \
529 if (predictor_pair & 1) \
537 #define APPLY_C_PREDICTOR_24() \
538 predictor_pair = s->c_predictor_table[index]; \
539 horiz_pred += (predictor_pair >> 1); \
540 if (predictor_pair & 1) { \
544 predictor_pair = s->fat_c_predictor_table[index]; \
545 horiz_pred += (predictor_pair >> 1); \
546 if (predictor_pair & 1) \
555 #define APPLY_Y_PREDICTOR() \
556 predictor_pair = s->y_predictor_table[index]; \
557 horiz_pred += (predictor_pair >> 1); \
558 if (predictor_pair & 1) { \
562 predictor_pair = s->y_predictor_table[index]; \
563 horiz_pred += ((predictor_pair >> 1) * 5); \
564 if (predictor_pair & 1) \
572 #define APPLY_Y_PREDICTOR_24() \
573 predictor_pair = s->y_predictor_table[index]; \
574 horiz_pred += (predictor_pair >> 1); \
575 if (predictor_pair & 1) { \
579 predictor_pair = s->fat_y_predictor_table[index]; \
580 horiz_pred += (predictor_pair >> 1); \
581 if (predictor_pair & 1) \
589 #define OUTPUT_PIXEL_PAIR() \
590 *current_pixel_pair = *vert_pred + horiz_pred; \
591 *vert_pred++ = *current_pixel_pair++;
593 static void truemotion1_decode_16bit(TrueMotion1Context
*s
)
596 int pixels_left
; /* remaining pixels on this line */
597 unsigned int predictor_pair
;
598 unsigned int horiz_pred
;
599 unsigned int *vert_pred
;
600 unsigned int *current_pixel_pair
;
601 unsigned char *current_line
= s
->frame
.data
[0];
602 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
604 /* these variables are for managing the stream of macroblock change bits */
605 const unsigned char *mb_change_bits
= s
->mb_change_bits
;
606 unsigned char mb_change_byte
;
607 unsigned char mb_change_byte_mask
;
610 /* these variables are for managing the main index stream */
611 int index_stream_index
= 0; /* yes, the index into the index stream */
614 /* clean out the line buffer */
615 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned int));
619 for (y
= 0; y
< s
->avctx
->height
; y
++) {
621 /* re-init variables for the next line iteration */
623 current_pixel_pair
= (unsigned int *)current_line
;
624 vert_pred
= s
->vert_pred
;
626 mb_change_byte
= mb_change_bits
[mb_change_index
++];
627 mb_change_byte_mask
= 0x01;
628 pixels_left
= s
->avctx
->width
;
630 while (pixels_left
> 0) {
632 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
636 /* if macroblock width is 2, apply C-Y-C-Y; else
638 if (s
->block_width
== 2) {
656 /* always apply 2 Y predictors on these iterations */
664 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
665 * depending on the macroblock type */
666 if (s
->block_type
== BLOCK_2x2
) {
673 } else if (s
->block_type
== BLOCK_4x2
) {
690 /* skip (copy) four pixels, but reassign the horizontal
692 *vert_pred
++ = *current_pixel_pair
++;
693 horiz_pred
= *current_pixel_pair
- *vert_pred
;
694 *vert_pred
++ = *current_pixel_pair
++;
699 mb_change_byte_mask
<<= 1;
702 if (!mb_change_byte_mask
) {
703 mb_change_byte
= mb_change_bits
[mb_change_index
++];
704 mb_change_byte_mask
= 0x01;
711 /* next change row */
712 if (((y
+ 1) & 3) == 0)
713 mb_change_bits
+= s
->mb_change_bits_row_size
;
715 current_line
+= s
->frame
.linesize
[0];
719 static void truemotion1_decode_24bit(TrueMotion1Context
*s
)
722 int pixels_left
; /* remaining pixels on this line */
723 unsigned int predictor_pair
;
724 unsigned int horiz_pred
;
725 unsigned int *vert_pred
;
726 unsigned int *current_pixel_pair
;
727 unsigned char *current_line
= s
->frame
.data
[0];
728 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
730 /* these variables are for managing the stream of macroblock change bits */
731 const unsigned char *mb_change_bits
= s
->mb_change_bits
;
732 unsigned char mb_change_byte
;
733 unsigned char mb_change_byte_mask
;
736 /* these variables are for managing the main index stream */
737 int index_stream_index
= 0; /* yes, the index into the index stream */
740 /* clean out the line buffer */
741 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned int));
745 for (y
= 0; y
< s
->avctx
->height
; y
++) {
747 /* re-init variables for the next line iteration */
749 current_pixel_pair
= (unsigned int *)current_line
;
750 vert_pred
= s
->vert_pred
;
752 mb_change_byte
= mb_change_bits
[mb_change_index
++];
753 mb_change_byte_mask
= 0x01;
754 pixels_left
= s
->avctx
->width
;
756 while (pixels_left
> 0) {
758 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
762 /* if macroblock width is 2, apply C-Y-C-Y; else
764 if (s
->block_width
== 2) {
765 APPLY_C_PREDICTOR_24();
766 APPLY_Y_PREDICTOR_24();
768 APPLY_C_PREDICTOR_24();
769 APPLY_Y_PREDICTOR_24();
772 APPLY_C_PREDICTOR_24();
773 APPLY_Y_PREDICTOR_24();
775 APPLY_Y_PREDICTOR_24();
782 /* always apply 2 Y predictors on these iterations */
783 APPLY_Y_PREDICTOR_24();
785 APPLY_Y_PREDICTOR_24();
790 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
791 * depending on the macroblock type */
792 if (s
->block_type
== BLOCK_2x2
) {
793 APPLY_C_PREDICTOR_24();
794 APPLY_Y_PREDICTOR_24();
796 APPLY_C_PREDICTOR_24();
797 APPLY_Y_PREDICTOR_24();
799 } else if (s
->block_type
== BLOCK_4x2
) {
800 APPLY_C_PREDICTOR_24();
801 APPLY_Y_PREDICTOR_24();
803 APPLY_Y_PREDICTOR_24();
806 APPLY_Y_PREDICTOR_24();
808 APPLY_Y_PREDICTOR_24();
816 /* skip (copy) four pixels, but reassign the horizontal
818 *vert_pred
++ = *current_pixel_pair
++;
819 horiz_pred
= *current_pixel_pair
- *vert_pred
;
820 *vert_pred
++ = *current_pixel_pair
++;
825 mb_change_byte_mask
<<= 1;
828 if (!mb_change_byte_mask
) {
829 mb_change_byte
= mb_change_bits
[mb_change_index
++];
830 mb_change_byte_mask
= 0x01;
837 /* next change row */
838 if (((y
+ 1) & 3) == 0)
839 mb_change_bits
+= s
->mb_change_bits_row_size
;
841 current_line
+= s
->frame
.linesize
[0];
846 static int truemotion1_decode_frame(AVCodecContext
*avctx
,
847 void *data
, int *data_size
,
850 const uint8_t *buf
= avpkt
->data
;
851 int buf_size
= avpkt
->size
;
852 TrueMotion1Context
*s
= avctx
->priv_data
;
857 if (truemotion1_decode_header(s
) == -1)
860 s
->frame
.reference
= 1;
861 s
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
|
862 FF_BUFFER_HINTS_PRESERVE
| FF_BUFFER_HINTS_REUSABLE
;
863 if (avctx
->reget_buffer(avctx
, &s
->frame
) < 0) {
864 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
868 if (compression_types
[s
->compression
].algorithm
== ALGO_RGB24H
) {
869 truemotion1_decode_24bit(s
);
870 } else if (compression_types
[s
->compression
].algorithm
!= ALGO_NOP
) {
871 truemotion1_decode_16bit(s
);
874 *data_size
= sizeof(AVFrame
);
875 *(AVFrame
*)data
= s
->frame
;
877 /* report that the buffer was completely consumed */
881 static av_cold
int truemotion1_decode_end(AVCodecContext
*avctx
)
883 TrueMotion1Context
*s
= avctx
->priv_data
;
885 if (s
->frame
.data
[0])
886 avctx
->release_buffer(avctx
, &s
->frame
);
888 av_free(s
->vert_pred
);
893 AVCodec truemotion1_decoder
= {
896 CODEC_ID_TRUEMOTION1
,
897 sizeof(TrueMotion1Context
),
898 truemotion1_decode_init
,
900 truemotion1_decode_end
,
901 truemotion1_decode_frame
,
903 .long_name
= NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),