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 
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 {
92  uint16_t ysize;
93  uint16_t xsize;
94  uint16_t checksum;
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  av_frame_free(&s->frame);
496  return AVERROR(ENOMEM);
497  }
498 
499  return 0;
500 }
501 
502 /*
503 Block decoding order:
504 
505 dxi: Y-Y
506 dxic: Y-C-Y
507 dxic2: Y-C-Y-C
508 
509 hres,vres,i,i%vres (0 < i < 4)
510 2x2 0: 0 dxic2
511 2x2 1: 1 dxi
512 2x2 2: 0 dxic2
513 2x2 3: 1 dxi
514 2x4 0: 0 dxic2
515 2x4 1: 1 dxi
516 2x4 2: 2 dxi
517 2x4 3: 3 dxi
518 4x2 0: 0 dxic
519 4x2 1: 1 dxi
520 4x2 2: 0 dxic
521 4x2 3: 1 dxi
522 4x4 0: 0 dxic
523 4x4 1: 1 dxi
524 4x4 2: 2 dxi
525 4x4 3: 3 dxi
526 */
527 
528 #define GET_NEXT_INDEX() \
529 {\
530  if (index_stream_index >= s->index_stream_size) { \
531  av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
532  return; \
533  } \
534  index = s->index_stream[index_stream_index++] * 4; \
535 }
536 
537 #define INC_INDEX \
538 do { \
539  if (index >= 1023) { \
540  av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
541  return; \
542  } \
543  index++; \
544 } while (0)
545 
546 #define APPLY_C_PREDICTOR() \
547  predictor_pair = s->c_predictor_table[index]; \
548  horiz_pred += (predictor_pair >> 1); \
549  if (predictor_pair & 1) { \
550  GET_NEXT_INDEX() \
551  if (!index) { \
552  GET_NEXT_INDEX() \
553  predictor_pair = s->c_predictor_table[index]; \
554  horiz_pred += ((predictor_pair >> 1) * 5); \
555  if (predictor_pair & 1) \
556  GET_NEXT_INDEX() \
557  else \
558  INC_INDEX; \
559  } \
560  } else \
561  INC_INDEX;
562 
563 #define APPLY_C_PREDICTOR_24() \
564  predictor_pair = s->c_predictor_table[index]; \
565  horiz_pred += (predictor_pair >> 1); \
566  if (predictor_pair & 1) { \
567  GET_NEXT_INDEX() \
568  if (!index) { \
569  GET_NEXT_INDEX() \
570  predictor_pair = s->fat_c_predictor_table[index]; \
571  horiz_pred += (predictor_pair >> 1); \
572  if (predictor_pair & 1) \
573  GET_NEXT_INDEX() \
574  else \
575  INC_INDEX; \
576  } \
577  } else \
578  INC_INDEX;
579 
580 
581 #define APPLY_Y_PREDICTOR() \
582  predictor_pair = s->y_predictor_table[index]; \
583  horiz_pred += (predictor_pair >> 1); \
584  if (predictor_pair & 1) { \
585  GET_NEXT_INDEX() \
586  if (!index) { \
587  GET_NEXT_INDEX() \
588  predictor_pair = s->y_predictor_table[index]; \
589  horiz_pred += ((predictor_pair >> 1) * 5); \
590  if (predictor_pair & 1) \
591  GET_NEXT_INDEX() \
592  else \
593  INC_INDEX; \
594  } \
595  } else \
596  INC_INDEX;
597 
598 #define APPLY_Y_PREDICTOR_24() \
599  predictor_pair = s->y_predictor_table[index]; \
600  horiz_pred += (predictor_pair >> 1); \
601  if (predictor_pair & 1) { \
602  GET_NEXT_INDEX() \
603  if (!index) { \
604  GET_NEXT_INDEX() \
605  predictor_pair = s->fat_y_predictor_table[index]; \
606  horiz_pred += (predictor_pair >> 1); \
607  if (predictor_pair & 1) \
608  GET_NEXT_INDEX() \
609  else \
610  INC_INDEX; \
611  } \
612  } else \
613  INC_INDEX;
614 
615 #define OUTPUT_PIXEL_PAIR() \
616  *current_pixel_pair = *vert_pred + horiz_pred; \
617  *vert_pred++ = *current_pixel_pair++;
618 
620 {
621  int y;
622  int pixels_left; /* remaining pixels on this line */
623  unsigned int predictor_pair;
624  unsigned int horiz_pred;
625  unsigned int *vert_pred;
626  unsigned int *current_pixel_pair;
627  unsigned char *current_line = s->frame->data[0];
628  int keyframe = s->flags & FLAG_KEYFRAME;
629 
630  /* these variables are for managing the stream of macroblock change bits */
631  const unsigned char *mb_change_bits = s->mb_change_bits;
632  unsigned char mb_change_byte;
633  unsigned char mb_change_byte_mask;
634  int mb_change_index;
635 
636  /* these variables are for managing the main index stream */
637  int index_stream_index = 0; /* yes, the index into the index stream */
638  int index;
639 
640  /* clean out the line buffer */
641  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
642 
643  GET_NEXT_INDEX();
644 
645  for (y = 0; y < s->avctx->height; y++) {
646 
647  /* re-init variables for the next line iteration */
648  horiz_pred = 0;
649  current_pixel_pair = (unsigned int *)current_line;
650  vert_pred = s->vert_pred;
651  mb_change_index = 0;
652  if (!keyframe)
653  mb_change_byte = mb_change_bits[mb_change_index++];
654  mb_change_byte_mask = 0x01;
655  pixels_left = s->avctx->width;
656 
657  while (pixels_left > 0) {
658 
659  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
660 
661  switch (y & 3) {
662  case 0:
663  /* if macroblock width is 2, apply C-Y-C-Y; else
664  * apply C-Y-Y */
665  if (s->block_width == 2) {
672  } else {
678  }
679  break;
680 
681  case 1:
682  case 3:
683  /* always apply 2 Y predictors on these iterations */
688  break;
689 
690  case 2:
691  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
692  * depending on the macroblock type */
693  if (s->block_type == BLOCK_2x2) {
700  } else if (s->block_type == BLOCK_4x2) {
706  } else {
711  }
712  break;
713  }
714 
715  } else {
716 
717  /* skip (copy) four pixels, but reassign the horizontal
718  * predictor */
719  *vert_pred++ = *current_pixel_pair++;
720  horiz_pred = *current_pixel_pair - *vert_pred;
721  *vert_pred++ = *current_pixel_pair++;
722 
723  }
724 
725  if (!keyframe) {
726  mb_change_byte_mask <<= 1;
727 
728  /* next byte */
729  if (!mb_change_byte_mask) {
730  mb_change_byte = mb_change_bits[mb_change_index++];
731  mb_change_byte_mask = 0x01;
732  }
733  }
734 
735  pixels_left -= 4;
736  }
737 
738  /* next change row */
739  if (((y + 1) & 3) == 0)
740  mb_change_bits += s->mb_change_bits_row_size;
741 
742  current_line += s->frame->linesize[0];
743  }
744 }
745 
747 {
748  int y;
749  int pixels_left; /* remaining pixels on this line */
750  unsigned int predictor_pair;
751  unsigned int horiz_pred;
752  unsigned int *vert_pred;
753  unsigned int *current_pixel_pair;
754  unsigned char *current_line = s->frame->data[0];
755  int keyframe = s->flags & FLAG_KEYFRAME;
756 
757  /* these variables are for managing the stream of macroblock change bits */
758  const unsigned char *mb_change_bits = s->mb_change_bits;
759  unsigned char mb_change_byte;
760  unsigned char mb_change_byte_mask;
761  int mb_change_index;
762 
763  /* these variables are for managing the main index stream */
764  int index_stream_index = 0; /* yes, the index into the index stream */
765  int index;
766 
767  /* clean out the line buffer */
768  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
769 
770  GET_NEXT_INDEX();
771 
772  for (y = 0; y < s->avctx->height; y++) {
773 
774  /* re-init variables for the next line iteration */
775  horiz_pred = 0;
776  current_pixel_pair = (unsigned int *)current_line;
777  vert_pred = s->vert_pred;
778  mb_change_index = 0;
779  mb_change_byte = mb_change_bits[mb_change_index++];
780  mb_change_byte_mask = 0x01;
781  pixels_left = s->avctx->width;
782 
783  while (pixels_left > 0) {
784 
785  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
786 
787  switch (y & 3) {
788  case 0:
789  /* if macroblock width is 2, apply C-Y-C-Y; else
790  * apply C-Y-Y */
791  if (s->block_width == 2) {
798  } else {
804  }
805  break;
806 
807  case 1:
808  case 3:
809  /* always apply 2 Y predictors on these iterations */
814  break;
815 
816  case 2:
817  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
818  * depending on the macroblock type */
819  if (s->block_type == BLOCK_2x2) {
826  } else if (s->block_type == BLOCK_4x2) {
832  } else {
837  }
838  break;
839  }
840 
841  } else {
842 
843  /* skip (copy) four pixels, but reassign the horizontal
844  * predictor */
845  *vert_pred++ = *current_pixel_pair++;
846  horiz_pred = *current_pixel_pair - *vert_pred;
847  *vert_pred++ = *current_pixel_pair++;
848 
849  }
850 
851  if (!keyframe) {
852  mb_change_byte_mask <<= 1;
853 
854  /* next byte */
855  if (!mb_change_byte_mask) {
856  mb_change_byte = mb_change_bits[mb_change_index++];
857  mb_change_byte_mask = 0x01;
858  }
859  }
860 
861  pixels_left -= 2;
862  }
863 
864  /* next change row */
865  if (((y + 1) & 3) == 0)
866  mb_change_bits += s->mb_change_bits_row_size;
867 
868  current_line += s->frame->linesize[0];
869  }
870 }
871 
872 
874  void *data, int *got_frame,
875  AVPacket *avpkt)
876 {
877  const uint8_t *buf = avpkt->data;
878  int ret, buf_size = avpkt->size;
879  TrueMotion1Context *s = avctx->priv_data;
880 
881  s->buf = buf;
882  s->size = buf_size;
883 
884  if ((ret = truemotion1_decode_header(s)) < 0)
885  return ret;
886 
887  if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
888  return ret;
889 
890  if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
892  } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
894  }
895 
896  if ((ret = av_frame_ref(data, s->frame)) < 0)
897  return ret;
898 
899  *got_frame = 1;
900 
901  /* report that the buffer was completely consumed */
902  return buf_size;
903 }
904 
906 {
907  TrueMotion1Context *s = avctx->priv_data;
908 
909  av_frame_free(&s->frame);
910  av_freep(&s->vert_pred);
911 
912  return 0;
913 }
914 
916  .name = "truemotion1",
917  .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
918  .type = AVMEDIA_TYPE_VIDEO,
920  .priv_data_size = sizeof(TrueMotion1Context),
922  .close = truemotion1_decode_end,
924  .capabilities = AV_CODEC_CAP_DR1,
925 };
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:190
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:546
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:35
r
const char * r
Definition: vf_curves.c:114
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:203
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
truemotion1_decode_16bit
static void truemotion1_decode_16bit(TrueMotion1Context *s)
Definition: truemotion1.c:619
BLOCK_4x4
#define BLOCK_4x4
Definition: truemotion1.c:114
b
#define b
Definition: input.c:41
data
const char data[16]
Definition: mxf.c:91
frame_header::control
uint8_t control
Definition: truemotion1.c:98
AV_CODEC_ID_TRUEMOTION1
@ AV_CODEC_ID_TRUEMOTION1
Definition: codec_id.h:100
APPLY_C_PREDICTOR_24
#define APPLY_C_PREDICTOR_24()
Definition: truemotion1.c:563
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:1612
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
ff_truemotion1_decoder
AVCodec ff_truemotion1_decoder
Definition: truemotion1.c:915
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:190
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
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:90
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:62
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
index
int index
Definition: gxfenc.c:89
frame_header::vectable
uint8_t vectable
Definition: truemotion1.c:91
OUTPUT_PIXEL_PAIR
#define OUTPUT_PIXEL_PAIR()
Definition: truemotion1.c:615
TrueMotion1Context::ydt
int16_t ydt[8]
Definition: truemotion1.c:70
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
AVPacket::size
int size
Definition: packet.h:356
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:188
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:444
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:598
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
frame_header::checksum
uint16_t checksum
Definition: truemotion1.c:94
GET_NEXT_INDEX
#define GET_NEXT_INDEX()
Definition: truemotion1.c:528
frame_header::compression
uint8_t compression
Definition: truemotion1.c:89
frame_header::header_size
uint8_t header_size
Definition: truemotion1.c:88
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:581
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:385
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:668
TrueMotion1Context::fat_cdt
int16_t fat_cdt[8]
Definition: truemotion1.c:73
uint8_t
uint8_t
Definition: audio_convert.c:194
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:554
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
len
int len
Definition: vorbis_enc_data.h:452
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:1961
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:374
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:119
TrueMotion1Context::x
int x
Definition: truemotion1.c:58
AVCodecContext
main external API structure.
Definition: avcodec.h:526
frame_header
Definition: truemotion1.c:87
TrueMotion1Context::block_height
int block_height
Definition: truemotion1.c:68
truemotion1_decode_24bit
static void truemotion1_decode_24bit(TrueMotion1Context *s)
Definition: truemotion1.c:746
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:873
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:104
frame_header::flags
uint8_t flags
Definition: truemotion1.c:97
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:39
TrueMotion1Context::index_stream
const uint8_t * index_stream
Definition: truemotion1.c:54
AVPacket
This structure stores compressed data.
Definition: packet.h:332
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
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:502
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:59
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:905
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