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 "internal.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->w != s->avctx->width || s->h != s->avctx->height ||
412  new_pix_fmt != s->avctx->pix_fmt) {
413  av_frame_unref(s->frame);
414  s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
415  s->avctx->pix_fmt = new_pix_fmt;
416 
417  if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
418  return ret;
419 
420  ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
421 
422  av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
423  if (!s->vert_pred)
424  return AVERROR(ENOMEM);
425  }
426 
427  /* There is 1 change bit per 4 pixels, so each change byte represents
428  * 32 pixels; divide width by 4 to obtain the number of change bits and
429  * then round up to the nearest byte. */
430  s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
431 
432  if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
433  {
434  if (compression_types[header.compression].algorithm == ALGO_RGB24H)
435  gen_vector_table24(s, sel_vector_table);
436  else
437  if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
438  gen_vector_table15(s, sel_vector_table);
439  else
440  gen_vector_table16(s, sel_vector_table);
441  }
442 
443  /* set up pointers to the other key data chunks */
444  s->mb_change_bits = s->buf + header.header_size;
445  if (s->flags & FLAG_KEYFRAME) {
446  /* no change bits specified for a keyframe; only index bytes */
447  s->index_stream = s->mb_change_bits;
448  if (s->avctx->width * s->avctx->height / 2048 + header.header_size > s->size)
449  return AVERROR_INVALIDDATA;
450  } else {
451  /* one change bit per 4x4 block */
452  s->index_stream = s->mb_change_bits +
453  (s->mb_change_bits_row_size * (s->avctx->height >> 2));
454  }
455  s->index_stream_size = s->size - (s->index_stream - s->buf);
456 
457  s->last_deltaset = header.deltaset;
458  s->last_vectable = header.vectable;
459  s->compression = header.compression;
460  s->block_width = compression_types[header.compression].block_width;
461  s->block_height = compression_types[header.compression].block_height;
462  s->block_type = compression_types[header.compression].block_type;
463 
464  if (s->avctx->debug & FF_DEBUG_PICT_INFO)
465  av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
466  s->last_deltaset, s->last_vectable, s->compression, s->block_width,
467  s->block_height, s->block_type,
468  s->flags & FLAG_KEYFRAME ? " KEY" : "",
469  s->flags & FLAG_INTERFRAME ? " INTER" : "",
470  s->flags & FLAG_SPRITE ? " SPRITE" : "",
471  s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
472 
473  return header.header_size;
474 }
475 
477 {
478  TrueMotion1Context *s = avctx->priv_data;
479 
480  s->avctx = avctx;
481 
482  // FIXME: it may change ?
483 // if (avctx->bits_per_sample == 24)
484 // avctx->pix_fmt = AV_PIX_FMT_RGB24;
485 // else
486 // avctx->pix_fmt = AV_PIX_FMT_RGB555;
487 
488  s->frame = av_frame_alloc();
489  if (!s->frame)
490  return AVERROR(ENOMEM);
491 
492  /* there is a vertical predictor for each pixel in a line; each vertical
493  * predictor is 0 to start with */
494  av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
495  if (!s->vert_pred)
496  return AVERROR(ENOMEM);
497 
498  return 0;
499 }
500 
501 /*
502 Block decoding order:
503 
504 dxi: Y-Y
505 dxic: Y-C-Y
506 dxic2: Y-C-Y-C
507 
508 hres,vres,i,i%vres (0 < i < 4)
509 2x2 0: 0 dxic2
510 2x2 1: 1 dxi
511 2x2 2: 0 dxic2
512 2x2 3: 1 dxi
513 2x4 0: 0 dxic2
514 2x4 1: 1 dxi
515 2x4 2: 2 dxi
516 2x4 3: 3 dxi
517 4x2 0: 0 dxic
518 4x2 1: 1 dxi
519 4x2 2: 0 dxic
520 4x2 3: 1 dxi
521 4x4 0: 0 dxic
522 4x4 1: 1 dxi
523 4x4 2: 2 dxi
524 4x4 3: 3 dxi
525 */
526 
527 #define GET_NEXT_INDEX() \
528 {\
529  if (index_stream_index >= s->index_stream_size) { \
530  av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
531  return; \
532  } \
533  index = s->index_stream[index_stream_index++] * 4; \
534 }
535 
536 #define INC_INDEX \
537 do { \
538  if (index >= 1023) { \
539  av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
540  return; \
541  } \
542  index++; \
543 } while (0)
544 
545 #define APPLY_C_PREDICTOR() \
546  predictor_pair = s->c_predictor_table[index]; \
547  horiz_pred += (predictor_pair >> 1); \
548  if (predictor_pair & 1) { \
549  GET_NEXT_INDEX() \
550  if (!index) { \
551  GET_NEXT_INDEX() \
552  predictor_pair = s->c_predictor_table[index]; \
553  horiz_pred += ((predictor_pair >> 1) * 5); \
554  if (predictor_pair & 1) \
555  GET_NEXT_INDEX() \
556  else \
557  INC_INDEX; \
558  } \
559  } else \
560  INC_INDEX;
561 
562 #define APPLY_C_PREDICTOR_24() \
563  predictor_pair = s->c_predictor_table[index]; \
564  horiz_pred += (predictor_pair >> 1); \
565  if (predictor_pair & 1) { \
566  GET_NEXT_INDEX() \
567  if (!index) { \
568  GET_NEXT_INDEX() \
569  predictor_pair = s->fat_c_predictor_table[index]; \
570  horiz_pred += (predictor_pair >> 1); \
571  if (predictor_pair & 1) \
572  GET_NEXT_INDEX() \
573  else \
574  INC_INDEX; \
575  } \
576  } else \
577  INC_INDEX;
578 
579 
580 #define APPLY_Y_PREDICTOR() \
581  predictor_pair = s->y_predictor_table[index]; \
582  horiz_pred += (predictor_pair >> 1); \
583  if (predictor_pair & 1) { \
584  GET_NEXT_INDEX() \
585  if (!index) { \
586  GET_NEXT_INDEX() \
587  predictor_pair = s->y_predictor_table[index]; \
588  horiz_pred += ((predictor_pair >> 1) * 5); \
589  if (predictor_pair & 1) \
590  GET_NEXT_INDEX() \
591  else \
592  INC_INDEX; \
593  } \
594  } else \
595  INC_INDEX;
596 
597 #define APPLY_Y_PREDICTOR_24() \
598  predictor_pair = s->y_predictor_table[index]; \
599  horiz_pred += (predictor_pair >> 1); \
600  if (predictor_pair & 1) { \
601  GET_NEXT_INDEX() \
602  if (!index) { \
603  GET_NEXT_INDEX() \
604  predictor_pair = s->fat_y_predictor_table[index]; \
605  horiz_pred += (predictor_pair >> 1); \
606  if (predictor_pair & 1) \
607  GET_NEXT_INDEX() \
608  else \
609  INC_INDEX; \
610  } \
611  } else \
612  INC_INDEX;
613 
614 #define OUTPUT_PIXEL_PAIR() \
615  *current_pixel_pair = *vert_pred + horiz_pred; \
616  *vert_pred++ = *current_pixel_pair++;
617 
619 {
620  int y;
621  int pixels_left; /* remaining pixels on this line */
622  unsigned int predictor_pair;
623  unsigned int horiz_pred;
624  unsigned int *vert_pred;
625  unsigned int *current_pixel_pair;
626  unsigned char *current_line = s->frame->data[0];
627  int keyframe = s->flags & FLAG_KEYFRAME;
628 
629  /* these variables are for managing the stream of macroblock change bits */
630  const unsigned char *mb_change_bits = s->mb_change_bits;
631  unsigned char mb_change_byte;
632  unsigned char mb_change_byte_mask;
633  int mb_change_index;
634 
635  /* these variables are for managing the main index stream */
636  int index_stream_index = 0; /* yes, the index into the index stream */
637  int index;
638 
639  /* clean out the line buffer */
640  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
641 
642  GET_NEXT_INDEX();
643 
644  for (y = 0; y < s->avctx->height; y++) {
645 
646  /* re-init variables for the next line iteration */
647  horiz_pred = 0;
648  current_pixel_pair = (unsigned int *)current_line;
649  vert_pred = s->vert_pred;
650  mb_change_index = 0;
651  if (!keyframe)
652  mb_change_byte = mb_change_bits[mb_change_index++];
653  mb_change_byte_mask = 0x01;
654  pixels_left = s->avctx->width;
655 
656  while (pixels_left > 0) {
657 
658  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
659 
660  switch (y & 3) {
661  case 0:
662  /* if macroblock width is 2, apply C-Y-C-Y; else
663  * apply C-Y-Y */
664  if (s->block_width == 2) {
671  } else {
677  }
678  break;
679 
680  case 1:
681  case 3:
682  /* always apply 2 Y predictors on these iterations */
687  break;
688 
689  case 2:
690  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
691  * depending on the macroblock type */
692  if (s->block_type == BLOCK_2x2) {
699  } else if (s->block_type == BLOCK_4x2) {
705  } else {
710  }
711  break;
712  }
713 
714  } else {
715 
716  /* skip (copy) four pixels, but reassign the horizontal
717  * predictor */
718  *vert_pred++ = *current_pixel_pair++;
719  horiz_pred = *current_pixel_pair - *vert_pred;
720  *vert_pred++ = *current_pixel_pair++;
721 
722  }
723 
724  if (!keyframe) {
725  mb_change_byte_mask <<= 1;
726 
727  /* next byte */
728  if (!mb_change_byte_mask) {
729  mb_change_byte = mb_change_bits[mb_change_index++];
730  mb_change_byte_mask = 0x01;
731  }
732  }
733 
734  pixels_left -= 4;
735  }
736 
737  /* next change row */
738  if (((y + 1) & 3) == 0)
739  mb_change_bits += s->mb_change_bits_row_size;
740 
741  current_line += s->frame->linesize[0];
742  }
743 }
744 
746 {
747  int y;
748  int pixels_left; /* remaining pixels on this line */
749  unsigned int predictor_pair;
750  unsigned int horiz_pred;
751  unsigned int *vert_pred;
752  unsigned int *current_pixel_pair;
753  unsigned char *current_line = s->frame->data[0];
754  int keyframe = s->flags & FLAG_KEYFRAME;
755 
756  /* these variables are for managing the stream of macroblock change bits */
757  const unsigned char *mb_change_bits = s->mb_change_bits;
758  unsigned char mb_change_byte;
759  unsigned char mb_change_byte_mask;
760  int mb_change_index;
761 
762  /* these variables are for managing the main index stream */
763  int index_stream_index = 0; /* yes, the index into the index stream */
764  int index;
765 
766  /* clean out the line buffer */
767  memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
768 
769  GET_NEXT_INDEX();
770 
771  for (y = 0; y < s->avctx->height; y++) {
772 
773  /* re-init variables for the next line iteration */
774  horiz_pred = 0;
775  current_pixel_pair = (unsigned int *)current_line;
776  vert_pred = s->vert_pred;
777  mb_change_index = 0;
778  mb_change_byte = mb_change_bits[mb_change_index++];
779  mb_change_byte_mask = 0x01;
780  pixels_left = s->avctx->width;
781 
782  while (pixels_left > 0) {
783 
784  if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
785 
786  switch (y & 3) {
787  case 0:
788  /* if macroblock width is 2, apply C-Y-C-Y; else
789  * apply C-Y-Y */
790  if (s->block_width == 2) {
797  } else {
803  }
804  break;
805 
806  case 1:
807  case 3:
808  /* always apply 2 Y predictors on these iterations */
813  break;
814 
815  case 2:
816  /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
817  * depending on the macroblock type */
818  if (s->block_type == BLOCK_2x2) {
825  } else if (s->block_type == BLOCK_4x2) {
831  } else {
836  }
837  break;
838  }
839 
840  } else {
841 
842  /* skip (copy) four pixels, but reassign the horizontal
843  * predictor */
844  *vert_pred++ = *current_pixel_pair++;
845  horiz_pred = *current_pixel_pair - *vert_pred;
846  *vert_pred++ = *current_pixel_pair++;
847 
848  }
849 
850  if (!keyframe) {
851  mb_change_byte_mask <<= 1;
852 
853  /* next byte */
854  if (!mb_change_byte_mask) {
855  mb_change_byte = mb_change_bits[mb_change_index++];
856  mb_change_byte_mask = 0x01;
857  }
858  }
859 
860  pixels_left -= 2;
861  }
862 
863  /* next change row */
864  if (((y + 1) & 3) == 0)
865  mb_change_bits += s->mb_change_bits_row_size;
866 
867  current_line += s->frame->linesize[0];
868  }
869 }
870 
871 
873  int *got_frame, 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(rframe, 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  .p.name = "truemotion1",
915  .p.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
916  .p.type = AVMEDIA_TYPE_VIDEO,
917  .p.id = AV_CODEC_ID_TRUEMOTION1,
918  .priv_data_size = sizeof(TrueMotion1Context),
920  .close = truemotion1_decode_end,
922  .p.capabilities = AV_CODEC_CAP_DR1,
924 };
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:545
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:39
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: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:476
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:111
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
truemotion1_decode_16bit
static void truemotion1_decode_16bit(TrueMotion1Context *s)
Definition: truemotion1.c:618
BLOCK_4x4
#define BLOCK_4x4
Definition: truemotion1.c:115
b
#define b
Definition: input.c:34
frame_header::control
uint8_t control
Definition: truemotion1.c:99
FFCodec
Definition: codec_internal.h:112
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:562
frame_header::height
uint16_t height
Definition: truemotion1.c:103
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:1323
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
init
static int init
Definition: av_tx.c:47
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:116
U
#define U(x)
Definition: vp56_arith.h:37
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: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: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:254
intreadwrite.h
TrueMotion1Context
Definition: truemotion1.c:46
s
#define s(width, name)
Definition: cbs_vp9.c:256
frame_header::xsize
uint16_t xsize
Definition: truemotion1.c:94
FLAG_INTERFRAME
#define FLAG_INTERFRAME
Definition: truemotion1.c:85
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: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:913
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
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:614
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:375
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:343
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:597
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:527
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:269
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:580
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:394
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:74
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: codec_internal.h:31
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:477
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:203
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:1521
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:383
TrueMotion1Context::compression
int compression
Definition: truemotion1.c:66
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:105
TrueMotion1Context::x
int x
Definition: truemotion1.c:59
AVCodecContext
main external API structure.
Definition: avcodec.h:389
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:745
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
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:90
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:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
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:565
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:872
FLAG_KEYFRAME
#define FLAG_KEYFRAME
Definition: truemotion1.c:84
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: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