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
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.
40 #include "truemotion1data.h"
42 typedef struct TrueMotion1Context
{
43 AVCodecContext
*avctx
;
49 const uint8_t *mb_change_bits
;
50 int mb_change_bits_row_size
;
51 const 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 const 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) + (hi
<< 16)) << 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
= AV_RL16(&header_buffer
[3]);
350 header
.xsize
= AV_RL16(&header_buffer
[5]);
351 header
.checksum
= AV_RL16(&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");
375 /* FIXME header.width, height, xoffset and yoffset aren't initialized */
378 s
->h
= header
.height
;
379 s
->x
= header
.xoffset
;
380 s
->y
= header
.yoffset
;
387 if (header
.header_type
< 2) {
388 if ((s
->w
< 213) && (s
->h
>= 176))
390 s
->flags
|= FLAG_INTERPOLATED
;
391 av_log(s
->avctx
, AV_LOG_INFO
, "INTERPOLATION selected, please report the sample to the developers\n");
396 if (header
.compression
>= 17) {
397 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid compression type (%d)\n", header
.compression
);
401 if ((header
.deltaset
!= s
->last_deltaset
) ||
402 (header
.vectable
!= s
->last_vectable
))
403 select_delta_tables(s
, header
.deltaset
);
405 if ((header
.compression
& 1) && header
.header_type
)
406 sel_vector_table
= pc_tbl2
;
408 if (header
.vectable
< 4)
409 sel_vector_table
= tables
[header
.vectable
- 1];
411 av_log(s
->avctx
, AV_LOG_ERROR
, "invalid vector table id (%d)\n", header
.vectable
);
416 // FIXME: where to place this ?!?!
417 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
418 s
->avctx
->pix_fmt
= PIX_FMT_RGB32
;
420 s
->avctx
->pix_fmt
= PIX_FMT_RGB555
; // RGB565 is supported as well
422 if ((header
.deltaset
!= s
->last_deltaset
) || (header
.vectable
!= s
->last_vectable
))
424 if (compression_types
[header
.compression
].algorithm
== ALGO_RGB24H
)
425 gen_vector_table24(s
, sel_vector_table
);
427 if (s
->avctx
->pix_fmt
== PIX_FMT_RGB555
)
428 gen_vector_table15(s
, sel_vector_table
);
430 gen_vector_table16(s
, sel_vector_table
);
433 /* set up pointers to the other key data chunks */
434 s
->mb_change_bits
= s
->buf
+ header
.header_size
;
435 if (s
->flags
& FLAG_KEYFRAME
) {
436 /* no change bits specified for a keyframe; only index bytes */
437 s
->index_stream
= s
->mb_change_bits
;
439 /* one change bit per 4x4 block */
440 s
->index_stream
= s
->mb_change_bits
+
441 (s
->mb_change_bits_row_size
* (s
->avctx
->height
>> 2));
443 s
->index_stream_size
= s
->size
- (s
->index_stream
- s
->buf
);
445 s
->last_deltaset
= header
.deltaset
;
446 s
->last_vectable
= header
.vectable
;
447 s
->compression
= header
.compression
;
448 s
->block_width
= compression_types
[header
.compression
].block_width
;
449 s
->block_height
= compression_types
[header
.compression
].block_height
;
450 s
->block_type
= compression_types
[header
.compression
].block_type
;
452 if (s
->avctx
->debug
& FF_DEBUG_PICT_INFO
)
453 av_log(s
->avctx
, AV_LOG_INFO
, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
454 s
->last_deltaset
, s
->last_vectable
, s
->compression
, s
->block_width
,
455 s
->block_height
, s
->block_type
,
456 s
->flags
& FLAG_KEYFRAME
? " KEY" : "",
457 s
->flags
& FLAG_INTERFRAME
? " INTER" : "",
458 s
->flags
& FLAG_SPRITE
? " SPRITE" : "",
459 s
->flags
& FLAG_INTERPOLATED
? " INTERPOL" : "");
461 return header
.header_size
;
464 static av_cold
int truemotion1_decode_init(AVCodecContext
*avctx
)
466 TrueMotion1Context
*s
= avctx
->priv_data
;
470 // FIXME: it may change ?
471 // if (avctx->bits_per_sample == 24)
472 // avctx->pix_fmt = PIX_FMT_RGB24;
474 // avctx->pix_fmt = PIX_FMT_RGB555;
476 s
->frame
.data
[0] = NULL
;
478 /* there is a vertical predictor for each pixel in a line; each vertical
479 * predictor is 0 to start with */
481 (unsigned int *)av_malloc(s
->avctx
->width
* sizeof(unsigned int));
487 Block decoding order:
493 hres,vres,i,i%vres (0 < i < 4)
512 #define GET_NEXT_INDEX() \
514 if (index_stream_index >= s->index_stream_size) { \
515 av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
518 index = s->index_stream[index_stream_index++] * 4; \
521 #define APPLY_C_PREDICTOR() \
522 predictor_pair = s->c_predictor_table[index]; \
523 horiz_pred += (predictor_pair >> 1); \
524 if (predictor_pair & 1) { \
528 predictor_pair = s->c_predictor_table[index]; \
529 horiz_pred += ((predictor_pair >> 1) * 5); \
530 if (predictor_pair & 1) \
538 #define APPLY_C_PREDICTOR_24() \
539 predictor_pair = s->c_predictor_table[index]; \
540 horiz_pred += (predictor_pair >> 1); \
541 if (predictor_pair & 1) { \
545 predictor_pair = s->fat_c_predictor_table[index]; \
546 horiz_pred += (predictor_pair >> 1); \
547 if (predictor_pair & 1) \
556 #define APPLY_Y_PREDICTOR() \
557 predictor_pair = s->y_predictor_table[index]; \
558 horiz_pred += (predictor_pair >> 1); \
559 if (predictor_pair & 1) { \
563 predictor_pair = s->y_predictor_table[index]; \
564 horiz_pred += ((predictor_pair >> 1) * 5); \
565 if (predictor_pair & 1) \
573 #define APPLY_Y_PREDICTOR_24() \
574 predictor_pair = s->y_predictor_table[index]; \
575 horiz_pred += (predictor_pair >> 1); \
576 if (predictor_pair & 1) { \
580 predictor_pair = s->fat_y_predictor_table[index]; \
581 horiz_pred += (predictor_pair >> 1); \
582 if (predictor_pair & 1) \
590 #define OUTPUT_PIXEL_PAIR() \
591 *current_pixel_pair = *vert_pred + horiz_pred; \
592 *vert_pred++ = *current_pixel_pair++;
594 static void truemotion1_decode_16bit(TrueMotion1Context
*s
)
597 int pixels_left
; /* remaining pixels on this line */
598 unsigned int predictor_pair
;
599 unsigned int horiz_pred
;
600 unsigned int *vert_pred
;
601 unsigned int *current_pixel_pair
;
602 unsigned char *current_line
= s
->frame
.data
[0];
603 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
605 /* these variables are for managing the stream of macroblock change bits */
606 const 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 int));
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 vert_pred
= s
->vert_pred
;
627 mb_change_byte
= mb_change_bits
[mb_change_index
++];
628 mb_change_byte_mask
= 0x01;
629 pixels_left
= s
->avctx
->width
;
631 while (pixels_left
> 0) {
633 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
637 /* if macroblock width is 2, apply C-Y-C-Y; else
639 if (s
->block_width
== 2) {
657 /* always apply 2 Y predictors on these iterations */
665 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
666 * depending on the macroblock type */
667 if (s
->block_type
== BLOCK_2x2
) {
674 } else if (s
->block_type
== BLOCK_4x2
) {
691 /* skip (copy) four pixels, but reassign the horizontal
693 *vert_pred
++ = *current_pixel_pair
++;
694 horiz_pred
= *current_pixel_pair
- *vert_pred
;
695 *vert_pred
++ = *current_pixel_pair
++;
700 mb_change_byte_mask
<<= 1;
703 if (!mb_change_byte_mask
) {
704 mb_change_byte
= mb_change_bits
[mb_change_index
++];
705 mb_change_byte_mask
= 0x01;
712 /* next change row */
713 if (((y
+ 1) & 3) == 0)
714 mb_change_bits
+= s
->mb_change_bits_row_size
;
716 current_line
+= s
->frame
.linesize
[0];
720 static void truemotion1_decode_24bit(TrueMotion1Context
*s
)
723 int pixels_left
; /* remaining pixels on this line */
724 unsigned int predictor_pair
;
725 unsigned int horiz_pred
;
726 unsigned int *vert_pred
;
727 unsigned int *current_pixel_pair
;
728 unsigned char *current_line
= s
->frame
.data
[0];
729 int keyframe
= s
->flags
& FLAG_KEYFRAME
;
731 /* these variables are for managing the stream of macroblock change bits */
732 const unsigned char *mb_change_bits
= s
->mb_change_bits
;
733 unsigned char mb_change_byte
;
734 unsigned char mb_change_byte_mask
;
737 /* these variables are for managing the main index stream */
738 int index_stream_index
= 0; /* yes, the index into the index stream */
741 /* clean out the line buffer */
742 memset(s
->vert_pred
, 0, s
->avctx
->width
* sizeof(unsigned int));
746 for (y
= 0; y
< s
->avctx
->height
; y
++) {
748 /* re-init variables for the next line iteration */
750 current_pixel_pair
= (unsigned int *)current_line
;
751 vert_pred
= s
->vert_pred
;
753 mb_change_byte
= mb_change_bits
[mb_change_index
++];
754 mb_change_byte_mask
= 0x01;
755 pixels_left
= s
->avctx
->width
;
757 while (pixels_left
> 0) {
759 if (keyframe
|| ((mb_change_byte
& mb_change_byte_mask
) == 0)) {
763 /* if macroblock width is 2, apply C-Y-C-Y; else
765 if (s
->block_width
== 2) {
766 APPLY_C_PREDICTOR_24();
767 APPLY_Y_PREDICTOR_24();
769 APPLY_C_PREDICTOR_24();
770 APPLY_Y_PREDICTOR_24();
773 APPLY_C_PREDICTOR_24();
774 APPLY_Y_PREDICTOR_24();
776 APPLY_Y_PREDICTOR_24();
783 /* always apply 2 Y predictors on these iterations */
784 APPLY_Y_PREDICTOR_24();
786 APPLY_Y_PREDICTOR_24();
791 /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
792 * depending on the macroblock type */
793 if (s
->block_type
== BLOCK_2x2
) {
794 APPLY_C_PREDICTOR_24();
795 APPLY_Y_PREDICTOR_24();
797 APPLY_C_PREDICTOR_24();
798 APPLY_Y_PREDICTOR_24();
800 } else if (s
->block_type
== BLOCK_4x2
) {
801 APPLY_C_PREDICTOR_24();
802 APPLY_Y_PREDICTOR_24();
804 APPLY_Y_PREDICTOR_24();
807 APPLY_Y_PREDICTOR_24();
809 APPLY_Y_PREDICTOR_24();
817 /* skip (copy) four pixels, but reassign the horizontal
819 *vert_pred
++ = *current_pixel_pair
++;
820 horiz_pred
= *current_pixel_pair
- *vert_pred
;
821 *vert_pred
++ = *current_pixel_pair
++;
826 mb_change_byte_mask
<<= 1;
829 if (!mb_change_byte_mask
) {
830 mb_change_byte
= mb_change_bits
[mb_change_index
++];
831 mb_change_byte_mask
= 0x01;
838 /* next change row */
839 if (((y
+ 1) & 3) == 0)
840 mb_change_bits
+= s
->mb_change_bits_row_size
;
842 current_line
+= s
->frame
.linesize
[0];
847 static int truemotion1_decode_frame(AVCodecContext
*avctx
,
848 void *data
, int *data_size
,
849 const uint8_t *buf
, int buf_size
)
851 TrueMotion1Context
*s
= avctx
->priv_data
;
856 if (truemotion1_decode_header(s
) == -1)
859 s
->frame
.reference
= 1;
860 s
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
|
861 FF_BUFFER_HINTS_PRESERVE
| FF_BUFFER_HINTS_REUSABLE
;
862 if (avctx
->reget_buffer(avctx
, &s
->frame
) < 0) {
863 av_log(s
->avctx
, AV_LOG_ERROR
, "get_buffer() failed\n");
867 if (compression_types
[s
->compression
].algorithm
== ALGO_RGB24H
) {
868 truemotion1_decode_24bit(s
);
869 } else if (compression_types
[s
->compression
].algorithm
!= ALGO_NOP
) {
870 truemotion1_decode_16bit(s
);
873 *data_size
= sizeof(AVFrame
);
874 *(AVFrame
*)data
= s
->frame
;
876 /* report that the buffer was completely consumed */
880 static av_cold
int truemotion1_decode_end(AVCodecContext
*avctx
)
882 TrueMotion1Context
*s
= avctx
->priv_data
;
884 if (s
->frame
.data
[0])
885 avctx
->release_buffer(avctx
, &s
->frame
);
887 av_free(s
->vert_pred
);
892 AVCodec truemotion1_decoder
= {
895 CODEC_ID_TRUEMOTION1
,
896 sizeof(TrueMotion1Context
),
897 truemotion1_decode_init
,
899 truemotion1_decode_end
,
900 truemotion1_decode_frame
,
902 .long_name
= NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),