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