FFmpeg
truemotion1.c
Go to the documentation of this file.
1 /*
2  * Duck TrueMotion 1.0 Decoder
3  * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 /**
23  * @file
24  * Duck TrueMotion v1 Video Decoder by
25  * Alex Beregszaszi and
26  * Mike Melanson (melanson@pcisys.net)
27  *
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.
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "avcodec.h"
37 #include "codec_internal.h"
38 #include "decode.h"
39 #include "libavutil/imgutils.h"
40 #include "libavutil/internal.h"
41 #include "libavutil/intreadwrite.h"
42 #include "libavutil/mem.h"
43 
44 #include "truemotion1data.h"
45 
46 typedef struct TrueMotion1Context {
49 
50  const uint8_t *buf;
51  int size;
52 
53  const uint8_t *mb_change_bits;
55  const uint8_t *index_stream;
57 
58  int flags;
59  int x, y, w, h;
60 
61  uint32_t y_predictor_table[1024];
62  uint32_t c_predictor_table[1024];
63  uint32_t fat_y_predictor_table[1024];
64  uint32_t fat_c_predictor_table[1024];
65 
70 
71  int16_t ydt[8];
72  int16_t cdt[8];
73  int16_t fat_ydt[8];
74  int16_t fat_cdt[8];
75 
77 
78  unsigned int *vert_pred;
80 
82 
83 #define FLAG_SPRITE 32
84 #define FLAG_KEYFRAME 16
85 #define FLAG_INTERFRAME 8
86 #define FLAG_INTERPOLATED 4
87 
88 struct frame_header {
89  uint8_t header_size;
90  uint8_t compression;
91  uint8_t deltaset;
92  uint8_t vectable;
93  uint16_t ysize;
94  uint16_t xsize;
95  uint16_t checksum;
96  uint8_t version;
97  uint8_t header_type;
98  uint8_t flags;
99  uint8_t control;
100  uint16_t xoffset;
101  uint16_t yoffset;
102  uint16_t width;
103  uint16_t height;
104 };
105 
106 #define ALGO_NOP 0
107 #define ALGO_RGB16V 1
108 #define ALGO_RGB16H 2
109 #define ALGO_RGB24H 3
110 
111 /* these are the various block sizes that can occupy a 4x4 block */
112 #define BLOCK_2x2 0
113 #define BLOCK_2x4 1
114 #define BLOCK_4x2 2
115 #define BLOCK_4x4 3
116 
117 typedef struct comp_types {
119  int block_width; // vres
120  int block_height; // hres
122 } comp_types;
123 
124 /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
125 static const comp_types compression_types[17] = {
126  { ALGO_NOP, 0, 0, 0 },
127 
128  { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
129  { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
130  { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
131  { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
132 
133  { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
134  { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
135  { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
136  { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
137 
138  { ALGO_NOP, 4, 4, BLOCK_4x4 },
139  { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
140  { ALGO_NOP, 4, 2, BLOCK_4x2 },
141  { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
142 
143  { ALGO_NOP, 2, 4, BLOCK_2x4 },
144  { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
145  { ALGO_NOP, 2, 2, BLOCK_2x2 },
146  { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
147 };
148 
149 static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
150 {
151  int i;
152 
153  if (delta_table_index > 3)
154  return;
155 
156  memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t));
157  memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t));
158  memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t));
159  memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t));
160 
161  /* Y skinny deltas need to be halved for some reason; maybe the
162  * skinny Y deltas should be modified */
163  for (i = 0; i < 8; i++)
164  {
165  /* drop the lsb before dividing by 2-- net effect: round down
166  * when dividing a negative number (e.g., -3/2 = -2, not -1) */
167  s->ydt[i] &= 0xFFFE;
168  s->ydt[i] /= 2;
169  }
170 }
171 
172 #if HAVE_BIGENDIAN
173 static int make_ydt15_entry(int p2, int p1, int16_t *ydt)
174 #else
175 static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
176 #endif
177 {
178  int lo, hi;
179 
180  lo = ydt[p1];
181  lo += (lo * 32) + (lo * 1024);
182  hi = ydt[p2];
183  hi += (hi * 32) + (hi * 1024);
184  return (lo + (hi * (1U << 16))) * 2;
185 }
186 
187 static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
188 {
189  int r, b, lo;
190 
191  b = cdt[p2];
192  r = cdt[p1] * 1024;
193  lo = b + r;
194  return (lo + (lo * (1U << 16))) * 2;
195 }
196 
197 #if HAVE_BIGENDIAN
198 static int make_ydt16_entry(int p2, int p1, int16_t *ydt)
199 #else
200 static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
201 #endif
202 {
203  int lo, hi;
204 
205  lo = ydt[p1];
206  lo += (lo << 6) + (lo << 11);
207  hi = ydt[p2];
208  hi += (hi << 6) + (hi << 11);
209  return (lo + (hi << 16)) << 1;
210 }
211 
212 static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
213 {
214  int r, b, lo;
215 
216  b = cdt[p2];
217  r = cdt[p1] << 11;
218  lo = b + r;
219  return (lo + (lo * (1 << 16))) * 2;
220 }
221 
222 static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
223 {
224  int lo, hi;
225 
226  lo = ydt[p1];
227  hi = ydt[p2];
228  return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2;
229 }
230 
231 static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
232 {
233  int r, b;
234 
235  b = cdt[p2];
236  r = cdt[p1] * (1 << 16);
237  return (b+r) * 2;
238 }
239 
240 static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
241 {
242  int len, i, j;
243  unsigned char delta_pair;
244 
245  for (i = 0; i < 1024; i += 4)
246  {
247  len = *sel_vector_table++ / 2;
248  for (j = 0; j < len; j++)
249  {
250  delta_pair = *sel_vector_table++;
251  s->y_predictor_table[i+j] = 0xfffffffe &
252  make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
253  s->c_predictor_table[i+j] = 0xfffffffe &
254  make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
255  }
256  s->y_predictor_table[i+(j-1)] |= 1;
257  s->c_predictor_table[i+(j-1)] |= 1;
258  }
259 }
260 
261 static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
262 {
263  int len, i, j;
264  unsigned char delta_pair;
265 
266  for (i = 0; i < 1024; i += 4)
267  {
268  len = *sel_vector_table++ / 2;
269  for (j = 0; j < len; j++)
270  {
271  delta_pair = *sel_vector_table++;
272  s->y_predictor_table[i+j] = 0xfffffffe &
273  make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
274  s->c_predictor_table[i+j] = 0xfffffffe &
275  make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
276  }
277  s->y_predictor_table[i+(j-1)] |= 1;
278  s->c_predictor_table[i+(j-1)] |= 1;
279  }
280 }
281 
282 static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
283 {
284  int len, i, j;
285  unsigned char delta_pair;
286 
287  for (i = 0; i < 1024; i += 4)
288  {
289  len = *sel_vector_table++ / 2;
290  for (j = 0; j < len; j++)
291  {
292  delta_pair = *sel_vector_table++;
293  s->y_predictor_table[i+j] = 0xfffffffe &
294  make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
295  s->c_predictor_table[i+j] = 0xfffffffe &
296  make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
297  s->fat_y_predictor_table[i+j] = 0xfffffffe &
298  make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt);
299  s->fat_c_predictor_table[i+j] = 0xfffffffe &
300  make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt);
301  }
302  s->y_predictor_table[i+(j-1)] |= 1;
303  s->c_predictor_table[i+(j-1)] |= 1;
304  s->fat_y_predictor_table[i+(j-1)] |= 1;
305  s->fat_c_predictor_table[i+(j-1)] |= 1;
306  }
307 }
308 
309 /* Returns the number of bytes consumed from the bytestream. Returns -1 if
310  * there was an error while decoding the header */
312 {
313  int i, ret;
314  int width_shift = 0;
315  int new_pix_fmt;
316  struct frame_header header;
317  uint8_t header_buffer[128] = { 0 }; /* logical maximum size of the header */
318  const uint8_t *sel_vector_table;
319 
320  header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
321  if (s->buf[0] < 0x10)
322  {
323  av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
324  return AVERROR_INVALIDDATA;
325  }
326 
327  if (header.header_size + 1 > s->size) {
328  av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n");
329  return AVERROR_INVALIDDATA;
330  }
331 
332  /* unscramble the header bytes with a XOR operation */
333  for (i = 1; i < header.header_size; i++)
334  header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
335 
336  header.compression = header_buffer[0];
337  header.deltaset = header_buffer[1];
338  header.vectable = header_buffer[2];
339  header.ysize = AV_RL16(&header_buffer[3]);
340  header.xsize = AV_RL16(&header_buffer[5]);
341  header.checksum = AV_RL16(&header_buffer[7]);
342  header.version = header_buffer[9];
343  header.header_type = header_buffer[10];
344  header.flags = header_buffer[11];
345  header.control = header_buffer[12];
346 
347  /* Version 2 */
348  if (header.version >= 2)
349  {
350  if (header.header_type > 3)
351  {
352  av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
353  return AVERROR_INVALIDDATA;
354  } else if ((header.header_type == 2) || (header.header_type == 3)) {
355  s->flags = header.flags;
356  if (!(s->flags & FLAG_INTERFRAME))
357  s->flags |= FLAG_KEYFRAME;
358  } else
359  s->flags = FLAG_KEYFRAME;
360  } else /* Version 1 */
361  s->flags = FLAG_KEYFRAME;
362 
363  if (s->flags & FLAG_SPRITE) {
364  avpriv_request_sample(s->avctx, "Frame with sprite");
365  /* FIXME header.width, height, xoffset and yoffset aren't initialized */
366  return AVERROR_PATCHWELCOME;
367  } else {
368  s->w = header.xsize;
369  s->h = header.ysize;
370  if (header.header_type < 2) {
371  if ((s->w < 213) && (s->h >= 176))
372  {
373  s->flags |= FLAG_INTERPOLATED;
374  avpriv_request_sample(s->avctx, "Interpolated frame");
375  }
376  }
377  }
378 
379  if (header.compression >= 17) {
380  av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
381  return AVERROR_INVALIDDATA;
382  }
383 
384  if ((header.deltaset != s->last_deltaset) ||
385  (header.vectable != s->last_vectable))
386  select_delta_tables(s, header.deltaset);
387 
388  if ((header.compression & 1) && header.header_type)
389  sel_vector_table = pc_tbl2;
390  else {
391  if (header.vectable > 0 && header.vectable < 4)
392  sel_vector_table = tables[header.vectable - 1];
393  else {
394  av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
395  return AVERROR_INVALIDDATA;
396  }
397  }
398 
399  if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
400  new_pix_fmt = AV_PIX_FMT_0RGB32;
401  width_shift = 1;
402  } else
403  new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
404 
405  s->w >>= width_shift;
406  if (s->w & 1) {
407  avpriv_request_sample(s->avctx, "Frame with odd width");
408  return AVERROR_PATCHWELCOME;
409  }
410 
411  if (s->h & 3) {
412  avpriv_request_sample(s->avctx, "Frame with height not being a multiple of 4");
413  return AVERROR_PATCHWELCOME;
414  }
415 
416  if (s->w != s->avctx->width || s->h != s->avctx->height ||
417  new_pix_fmt != s->avctx->pix_fmt) {
418  av_frame_unref(s->frame);
419  s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
420  s->avctx->pix_fmt = new_pix_fmt;
421 
422  if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
423  return ret;
424 
425  ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
426 
427  av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
428  if (!s->vert_pred)
429  return AVERROR(ENOMEM);
430  }
431 
432  /* There is 1 change bit per 4 pixels, so each change byte represents
433  * 32 pixels; divide width by 4 to obtain the number of change bits and
434  * then round up to the nearest byte. */
435  s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
436 
437  if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
438  {
439  if (compression_types[header.compression].algorithm == ALGO_RGB24H)
440  gen_vector_table24(s, sel_vector_table);
441  else
442  if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
443  gen_vector_table15(s, sel_vector_table);
444  else
445  gen_vector_table16(s, sel_vector_table);
446  }
447 
448  /* set up pointers to the other key data chunks */
449  s->mb_change_bits = s->buf + header.header_size;
450  if (s->flags & FLAG_KEYFRAME) {
451  /* no change bits specified for a keyframe; only index bytes */
452  s->index_stream = s->mb_change_bits;
453  if (s->avctx->width * s->avctx->height / 2048 + header.header_size > s->size)
454  return AVERROR_INVALIDDATA;
455  } else {
456  /* one change bit per 4x4 block */
457  s->index_stream = s->mb_change_bits +
458  (s->mb_change_bits_row_size * (s->avctx->height >> 2));
459  }
460  s->index_stream_size = s->size - (s->index_stream - s->buf);
461 
462  s->last_deltaset = header.deltaset;
463  s->last_vectable = header.vectable;
464  s->compression = header.compression;
465  s->block_width = compression_types[header.compression].block_width;
466  s->block_height = compression_types[header.compression].block_height;
467  s->block_type = compression_types[header.compression].block_type;
468 
469  if (s->avctx->debug & FF_DEBUG_PICT_INFO)
470  av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
471  s->last_deltaset, s->last_vectable, s->compression, s->block_width,
472  s->block_height, s->block_type,
473  s->flags & FLAG_KEYFRAME ? " KEY" : "",
474  s->flags & FLAG_INTERFRAME ? " INTER" : "",
475  s->flags & FLAG_SPRITE ? " SPRITE" : "",
476  s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
477 
478  return header.header_size;
479 }
480 
482 {
483  TrueMotion1Context *s = avctx->priv_data;
484 
485  s->avctx = avctx;
486 
487  // FIXME: it may change ?
488 // if (avctx->bits_per_sample == 24)
489 // avctx->pix_fmt = AV_PIX_FMT_RGB24;
490 // else
491 // avctx->pix_fmt = AV_PIX_FMT_RGB555;
492 
493  s->frame = av_frame_alloc();
494  if (!s->frame)
495  return AVERROR(ENOMEM);
496 
497  /* there is a vertical predictor for each pixel in a line; each vertical
498  * predictor is 0 to start with */
499  av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
500  if (!s->vert_pred)
501  return AVERROR(ENOMEM);
502 
503  return 0;
504 }
505 
506 /*
507 Block decoding order:
508 
509 dxi: Y-Y
510 dxic: Y-C-Y
511 dxic2: Y-C-Y-C
512 
513 hres,vres,i,i%vres (0 < i < 4)
514 2x2 0: 0 dxic2
515 2x2 1: 1 dxi
516 2x2 2: 0 dxic2
517 2x2 3: 1 dxi
518 2x4 0: 0 dxic2
519 2x4 1: 1 dxi
520 2x4 2: 2 dxi
521 2x4 3: 3 dxi
522 4x2 0: 0 dxic
523 4x2 1: 1 dxi
524 4x2 2: 0 dxic
525 4x2 3: 1 dxi
526 4x4 0: 0 dxic
527 4x4 1: 1 dxi
528 4x4 2: 2 dxi
529 4x4 3: 3 dxi
530 */
531 
532 #define GET_NEXT_INDEX() \
533 {\
534  if (index_stream_index >= s->index_stream_size) { \
535  av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
536  return; \
537  } \
538  index = s->index_stream[index_stream_index++] * 4; \
539 }
540 
541 #define INC_INDEX \
542 do { \
543  if (index >= 1023) { \
544  av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
545  return; \
546  } \
547  index++; \
548 } while (0)
549 
550 #define APPLY_C_PREDICTOR() \
551  predictor_pair = s->c_predictor_table[index]; \
552  horiz_pred += (predictor_pair >> 1); \
553  if (predictor_pair & 1) { \
554  GET_NEXT_INDEX() \
555  if (!index) { \
556  GET_NEXT_INDEX() \
557  predictor_pair = s->c_predictor_table[index]; \
558  horiz_pred += ((predictor_pair >> 1) * 5); \
559  if (predictor_pair & 1) \
560  GET_NEXT_INDEX() \
561  else \
562  INC_INDEX; \
563  } \
564  } else \
565  INC_INDEX;
566 
567 #define APPLY_C_PREDICTOR_24() \
568  predictor_pair = s->c_predictor_table[index]; \
569  horiz_pred += (predictor_pair >> 1); \
570  if (predictor_pair & 1) { \
571  GET_NEXT_INDEX() \
572  if (!index) { \
573  GET_NEXT_INDEX() \
574  predictor_pair = s->fat_c_predictor_table[index]; \
575  horiz_pred += (predictor_pair >> 1); \
576  if (predictor_pair & 1) \
577  GET_NEXT_INDEX() \
578  else \
579  INC_INDEX; \
580  } \
581  } else \
582  INC_INDEX;
583 
584 
585 #define APPLY_Y_PREDICTOR() \
586  predictor_pair = s->y_predictor_table[index]; \
587  horiz_pred += (predictor_pair >> 1); \
588  if (predictor_pair & 1) { \
589  GET_NEXT_INDEX() \
590  if (!index) { \
591  GET_NEXT_INDEX() \
592  predictor_pair = s->y_predictor_table[index]; \
593  horiz_pred += ((predictor_pair >> 1) * 5); \
594  if (predictor_pair & 1) \
595  GET_NEXT_INDEX() \
596  else \
597  INC_INDEX; \
598  } \
599  } else \
600  INC_INDEX;
601 
602 #define APPLY_Y_PREDICTOR_24() \
603  predictor_pair = s->y_predictor_table[index]; \
604  horiz_pred += (predictor_pair >> 1); \
605  if (predictor_pair & 1) { \
606  GET_NEXT_INDEX() \
607  if (!index) { \
608  GET_NEXT_INDEX() \
609  predictor_pair = s->fat_y_predictor_table[index]; \
610  horiz_pred += (predictor_pair >> 1); \
611  if (predictor_pair & 1) \
612  GET_NEXT_INDEX() \
613  else \
614  INC_INDEX; \
615  } \
616  } else \
617  INC_INDEX;
618 
619 #define OUTPUT_PIXEL_PAIR() \
620  *current_pixel_pair = *vert_pred + horiz_pred; \
621  *vert_pred++ = *current_pixel_pair++;
622 
624 {
625  int y;
626  int pixels_left; /* remaining pixels on this line */
627  unsigned int predictor_pair;
628  unsigned int horiz_pred;
629  unsigned int *vert_pred;
630  unsigned int *current_pixel_pair;
631  unsigned char *current_line = s->frame->data[0];
632  int keyframe = s->flags & FLAG_KEYFRAME;
633 
634  /* these variables are for managing the stream of macroblock change bits */
635  const unsigned char *mb_change_bits = s->mb_change_bits;
636  unsigned char mb_change_byte;
637  unsigned char mb_change_byte_mask;
638  int mb_change_index;
639 
640  /* these variables are for managing the main index stream */
641  int index_stream_index = 0; /* yes, the index into the index stream */
642  int index;
643 
644  /* clean out the line buffer */
645  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
646 
647  GET_NEXT_INDEX();
648 
649  for (y = 0; y < s->avctx->height; y++) {
650 
651  /* re-init variables for the next line iteration */
652  horiz_pred = 0;
653  current_pixel_pair = (unsigned int *)current_line;
654  vert_pred = s->vert_pred;
655  mb_change_index = 0;
656  if (!keyframe)
657  mb_change_byte = mb_change_bits[mb_change_index++];
658  mb_change_byte_mask = 0x01;
659  pixels_left = s->avctx->width;
660 
661  while (pixels_left > 0) {
662 
663  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
664 
665  switch (y & 3) {
666  case 0:
667  /* if macroblock width is 2, apply C-Y-C-Y; else
668  * apply C-Y-Y */
669  if (s->block_width == 2) {
676  } else {
682  }
683  break;
684 
685  case 1:
686  case 3:
687  /* always apply 2 Y predictors on these iterations */
692  break;
693 
694  case 2:
695  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
696  * depending on the macroblock type */
697  if (s->block_type == BLOCK_2x2) {
704  } else if (s->block_type == BLOCK_4x2) {
710  } else {
715  }
716  break;
717  }
718 
719  } else {
720 
721  /* skip (copy) four pixels, but reassign the horizontal
722  * predictor */
723  *vert_pred++ = *current_pixel_pair++;
724  horiz_pred = *current_pixel_pair - *vert_pred;
725  *vert_pred++ = *current_pixel_pair++;
726 
727  }
728 
729  if (!keyframe) {
730  mb_change_byte_mask <<= 1;
731 
732  /* next byte */
733  if (!mb_change_byte_mask) {
734  mb_change_byte = mb_change_bits[mb_change_index++];
735  mb_change_byte_mask = 0x01;
736  }
737  }
738 
739  pixels_left -= 4;
740  }
741 
742  /* next change row */
743  if (((y + 1) & 3) == 0)
744  mb_change_bits += s->mb_change_bits_row_size;
745 
746  current_line += s->frame->linesize[0];
747  }
748 }
749 
751 {
752  int y;
753  int pixels_left; /* remaining pixels on this line */
754  unsigned int predictor_pair;
755  unsigned int horiz_pred;
756  unsigned int *vert_pred;
757  unsigned int *current_pixel_pair;
758  unsigned char *current_line = s->frame->data[0];
759  int keyframe = s->flags & FLAG_KEYFRAME;
760 
761  /* these variables are for managing the stream of macroblock change bits */
762  const unsigned char *mb_change_bits = s->mb_change_bits;
763  unsigned char mb_change_byte;
764  unsigned char mb_change_byte_mask;
765  int mb_change_index;
766 
767  /* these variables are for managing the main index stream */
768  int index_stream_index = 0; /* yes, the index into the index stream */
769  int index;
770 
771  /* clean out the line buffer */
772  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
773 
774  GET_NEXT_INDEX();
775 
776  for (y = 0; y < s->avctx->height; y++) {
777 
778  /* re-init variables for the next line iteration */
779  horiz_pred = 0;
780  current_pixel_pair = (unsigned int *)current_line;
781  vert_pred = s->vert_pred;
782  mb_change_index = 0;
783  mb_change_byte = mb_change_bits[mb_change_index++];
784  mb_change_byte_mask = 0x01;
785  pixels_left = s->avctx->width;
786 
787  while (pixels_left > 0) {
788 
789  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
790 
791  switch (y & 3) {
792  case 0:
793  /* if macroblock width is 2, apply C-Y-C-Y; else
794  * apply C-Y-Y */
795  if (s->block_width == 2) {
802  } else {
808  }
809  break;
810 
811  case 1:
812  case 3:
813  /* always apply 2 Y predictors on these iterations */
818  break;
819 
820  case 2:
821  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
822  * depending on the macroblock type */
823  if (s->block_type == BLOCK_2x2) {
830  } else if (s->block_type == BLOCK_4x2) {
836  } else {
841  }
842  break;
843  }
844 
845  } else {
846 
847  /* skip (copy) four pixels, but reassign the horizontal
848  * predictor */
849  *vert_pred++ = *current_pixel_pair++;
850  horiz_pred = *current_pixel_pair - *vert_pred;
851  *vert_pred++ = *current_pixel_pair++;
852 
853  }
854 
855  if (!keyframe) {
856  mb_change_byte_mask <<= 1;
857 
858  /* next byte */
859  if (!mb_change_byte_mask) {
860  mb_change_byte = mb_change_bits[mb_change_index++];
861  mb_change_byte_mask = 0x01;
862  }
863  }
864 
865  pixels_left -= 2;
866  }
867 
868  /* next change row */
869  if (((y + 1) & 3) == 0)
870  mb_change_bits += s->mb_change_bits_row_size;
871 
872  current_line += s->frame->linesize[0];
873  }
874 }
875 
876 
878  int *got_frame, AVPacket *avpkt)
879 {
880  const uint8_t *buf = avpkt->data;
881  int ret, buf_size = avpkt->size;
882  TrueMotion1Context *s = avctx->priv_data;
883 
884  s->buf = buf;
885  s->size = buf_size;
886 
887  if ((ret = truemotion1_decode_header(s)) < 0)
888  return ret;
889 
890  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
891  return ret;
892 
893  if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
895  } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
897  }
898 
899  if ((ret = av_frame_ref(rframe, s->frame)) < 0)
900  return ret;
901 
902  *got_frame = 1;
903 
904  /* report that the buffer was completely consumed */
905  return buf_size;
906 }
907 
909 {
910  TrueMotion1Context *s = avctx->priv_data;
911 
912  av_frame_free(&s->frame);
913  av_freep(&s->vert_pred);
914 
915  return 0;
916 }
917 
919  .p.name = "truemotion1",
920  CODEC_LONG_NAME("Duck TrueMotion 1.0"),
921  .p.type = AVMEDIA_TYPE_VIDEO,
922  .p.id = AV_CODEC_ID_TRUEMOTION1,
923  .priv_data_size = sizeof(TrueMotion1Context),
925  .close = truemotion1_decode_end,
927  .p.capabilities = AV_CODEC_CAP_DR1,
928  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
929 };
TrueMotion1Context::fat_y_predictor_table
uint32_t fat_y_predictor_table[1024]
Definition: truemotion1.c:63
BLOCK_4x2
#define BLOCK_4x2
Definition: truemotion1.c:114
comp_types::block_type
int block_type
Definition: truemotion1.c:121
BLOCK_2x2
#define BLOCK_2x2
Definition: truemotion1.c:112
TrueMotion1Context::index_stream_size
int index_stream_size
Definition: truemotion1.c:56
APPLY_C_PREDICTOR
#define APPLY_C_PREDICTOR()
Definition: truemotion1.c:550
TrueMotion1Context::frame
AVFrame * frame
Definition: truemotion1.c:48
comp_types::algorithm
int algorithm
Definition: truemotion1.c:118
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: codec_internal.h:42
r
const char * r
Definition: vf_curves.c:126
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
frame_header::header_type
uint8_t header_type
Definition: truemotion1.c:97
TrueMotion1Context::buf
const uint8_t * buf
Definition: truemotion1.c:50
fat_cdts
static const int16_t *const fat_cdts[]
Definition: truemotion1data.h:51
FLAG_SPRITE
#define FLAG_SPRITE
Definition: truemotion1.c:83
truemotion1_decode_init
static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
Definition: truemotion1.c:481
make_cdt16_entry
static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:212
TrueMotion1Context::fat_ydt
int16_t fat_ydt[8]
Definition: truemotion1.c:73
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:100
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVPacket::data
uint8_t * data
Definition: packet.h:491
truemotion1_decode_16bit
static void truemotion1_decode_16bit(TrueMotion1Context *s)
Definition: truemotion1.c:623
BLOCK_4x4
#define BLOCK_4x4
Definition: truemotion1.c:115
b
#define b
Definition: input.c:41
frame_header::control
uint8_t control
Definition: truemotion1.c:99
FFCodec
Definition: codec_internal.h:127
AV_CODEC_ID_TRUEMOTION1
@ AV_CODEC_ID_TRUEMOTION1
Definition: codec_id.h:103
APPLY_C_PREDICTOR_24
#define APPLY_C_PREDICTOR_24()
Definition: truemotion1.c:567
frame_header::height
uint16_t height
Definition: truemotion1.c:103
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:94
TrueMotion1Context::w
int w
Definition: truemotion1.c:59
BLOCK_2x4
#define BLOCK_2x4
Definition: truemotion1.c:113
TrueMotion1Context::y_predictor_table
uint32_t y_predictor_table[1024]
Definition: truemotion1.c:61
FF_DEBUG_PICT_INFO
#define FF_DEBUG_PICT_INFO
Definition: avcodec.h:1389
ALGO_RGB16V
#define ALGO_RGB16V
Definition: truemotion1.c:107
TrueMotion1Context::size
int size
Definition: truemotion1.c:51
cdts
static const int16_t *const cdts[]
Definition: truemotion1data.h:50
TrueMotion1Context::c_predictor_table
uint32_t c_predictor_table[1024]
Definition: truemotion1.c:62
fat_ydts
static const int16_t *const fat_ydts[]
Definition: truemotion1data.h:49
TrueMotion1Context::flags
int flags
Definition: truemotion1.c:58
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
ALGO_NOP
#define ALGO_NOP
Definition: truemotion1.c:106
tables
Writing a table generator This documentation is preliminary Parts of the API are not good and should be changed Basic concepts A table generator consists of two *_tablegen c and *_tablegen h The h file will provide the variable declarations and initialization code for the tables
Definition: tablegen.txt:10
frame_header::deltaset
uint8_t deltaset
Definition: truemotion1.c:91
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:88
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
select_delta_tables
static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
Definition: truemotion1.c:149
pc_tbl2
static const uint8_t pc_tbl2[]
Definition: truemotion1data.h:53
TrueMotion1Context::cdt
int16_t cdt[8]
Definition: truemotion1.c:72
FF_CODEC_DECODE_CB
#define FF_CODEC_DECODE_CB(func)
Definition: codec_internal.h:306
intreadwrite.h
TrueMotion1Context
Definition: truemotion1.c:46
s
#define s(width, name)
Definition: cbs_vp9.c:198
frame_header::xsize
uint16_t xsize
Definition: truemotion1.c:94
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts_bsf.c:365
FLAG_INTERFRAME
#define FLAG_INTERFRAME
Definition: truemotion1.c:85
decode.h
AV_RL16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:94
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
make_ydt16_entry
static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:200
frame_header::yoffset
uint16_t yoffset
Definition: truemotion1.c:101
TrueMotion1Context::last_deltaset
int last_deltaset
Definition: truemotion1.c:76
ff_truemotion1_decoder
const FFCodec ff_truemotion1_decoder
Definition: truemotion1.c:918
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
comp_types::block_width
int block_width
Definition: truemotion1.c:119
make_ydt15_entry
static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:175
gen_vector_table16
static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:261
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
TrueMotion1Context::avctx
AVCodecContext * avctx
Definition: truemotion1.c:47
TrueMotion1Context::h
int h
Definition: truemotion1.c:59
TrueMotion1Context::vert_pred
unsigned int * vert_pred
Definition: truemotion1.c:78
frame_header::width
uint16_t width
Definition: truemotion1.c:102
TrueMotion1Context::block_width
int block_width
Definition: truemotion1.c:68
ff_set_sar
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition: utils.c:109
FLAG_INTERPOLATED
#define FLAG_INTERPOLATED
Definition: truemotion1.c:86
truemotion1data.h
comp_types
Definition: truemotion1.c:117
index
int index
Definition: gxfenc.c:89
frame_header::vectable
uint8_t vectable
Definition: truemotion1.c:92
OUTPUT_PIXEL_PAIR
#define OUTPUT_PIXEL_PAIR()
Definition: truemotion1.c:619
TrueMotion1Context::ydt
int16_t ydt[8]
Definition: truemotion1.c:71
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:492
av_frame_ref
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:361
codec_internal.h
ALGO_RGB16H
#define ALGO_RGB16H
Definition: truemotion1.c:108
make_cdt24_entry
static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:231
TrueMotion1Context::vert_pred_size
int vert_pred_size
Definition: truemotion1.c:79
TrueMotion1Context::block_type
int block_type
Definition: truemotion1.c:67
make_cdt15_entry
static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:187
header
static const uint8_t header[24]
Definition: sdr2.c:67
gen_vector_table15
static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:240
APPLY_Y_PREDICTOR_24
#define APPLY_Y_PREDICTOR_24()
Definition: truemotion1.c:602
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
frame_header::checksum
uint16_t checksum
Definition: truemotion1.c:95
GET_NEXT_INDEX
#define GET_NEXT_INDEX()
Definition: truemotion1.c:532
frame_header::compression
uint8_t compression
Definition: truemotion1.c:90
frame_header::header_size
uint8_t header_size
Definition: truemotion1.c:89
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
gen_vector_table24
static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:282
internal.h
APPLY_Y_PREDICTOR
#define APPLY_Y_PREDICTOR()
Definition: truemotion1.c:585
TrueMotion1Context::fat_c_predictor_table
uint32_t fat_c_predictor_table[1024]
Definition: truemotion1.c:64
AV_PIX_FMT_RGB555
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:456
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:590
TrueMotion1Context::fat_cdt
int16_t fat_cdt[8]
Definition: truemotion1.c:74
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:622
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
len
int len
Definition: vorbis_enc_data.h:426
comp_types::block_height
int block_height
Definition: truemotion1.c:120
avcodec.h
ff_reget_buffer
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
Definition: decode.c:1735
ret
ret
Definition: filter_design.txt:187
compression_types
static const comp_types compression_types[17]
Definition: truemotion1.c:125
frame_header::version
uint8_t version
Definition: truemotion1.c:96
AV_PIX_FMT_0RGB32
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:445
TrueMotion1Context::compression
int compression
Definition: truemotion1.c:66
ydts
static const int16_t *const ydts[]
Definition: truemotion1data.h:48
U
#define U(x)
Definition: vpx_arith.h:37
TrueMotion1Context::x
int x
Definition: truemotion1.c:59
AVCodecContext
main external API structure.
Definition: avcodec.h:441
frame_header
Definition: truemotion1.c:88
TrueMotion1Context::block_height
int block_height
Definition: truemotion1.c:69
truemotion1_decode_24bit
static void truemotion1_decode_24bit(TrueMotion1Context *s)
Definition: truemotion1.c:750
frame_header::xoffset
uint16_t xoffset
Definition: truemotion1.c:100
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
TrueMotion1Context::y
int y
Definition: truemotion1.c:59
mem.h
frame_header::flags
uint8_t flags
Definition: truemotion1.c:98
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:36
TrueMotion1Context::index_stream
const uint8_t * index_stream
Definition: truemotion1.c:55
AVPacket
This structure stores compressed data.
Definition: packet.h:468
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
TrueMotion1Context::mb_change_bits
const uint8_t * mb_change_bits
Definition: truemotion1.c:53
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_fast_malloc
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:555
imgutils.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
TrueMotion1Context::last_vectable
int last_vectable
Definition: truemotion1.c:76
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
frame_header::ysize
uint16_t ysize
Definition: truemotion1.c:93
truemotion1_decode_frame
static int truemotion1_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
Definition: truemotion1.c:877
FLAG_KEYFRAME
#define FLAG_KEYFRAME
Definition: truemotion1.c:84
truemotion1_decode_end
static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
Definition: truemotion1.c:908
truemotion1_decode_header
static int truemotion1_decode_header(TrueMotion1Context *s)
Definition: truemotion1.c:311
TrueMotion1Context::mb_change_bits_row_size
int mb_change_bits_row_size
Definition: truemotion1.c:54
make_ydt24_entry
static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:222
ALGO_RGB24H
#define ALGO_RGB24H
Definition: truemotion1.c:109