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 
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 */
447  } else {
448  /* one change bit per 4x4 block */
449  s->index_stream = s->mb_change_bits +
450  (s->mb_change_bits_row_size * (s->avctx->height >> 2));
451  }
452  s->index_stream_size = s->size - (s->index_stream - s->buf);
453 
454  s->last_deltaset = header.deltaset;
455  s->last_vectable = header.vectable;
456  s->compression = header.compression;
457  s->block_width = compression_types[header.compression].block_width;
458  s->block_height = compression_types[header.compression].block_height;
459  s->block_type = compression_types[header.compression].block_type;
460 
461  if (s->avctx->debug & FF_DEBUG_PICT_INFO)
462  av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
464  s->block_height, s->block_type,
465  s->flags & FLAG_KEYFRAME ? " KEY" : "",
466  s->flags & FLAG_INTERFRAME ? " INTER" : "",
467  s->flags & FLAG_SPRITE ? " SPRITE" : "",
468  s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
469 
470  return header.header_size;
471 }
472 
474 {
475  TrueMotion1Context *s = avctx->priv_data;
476 
477  s->avctx = avctx;
478 
479  // FIXME: it may change ?
480 // if (avctx->bits_per_sample == 24)
481 // avctx->pix_fmt = AV_PIX_FMT_RGB24;
482 // else
483 // avctx->pix_fmt = AV_PIX_FMT_RGB555;
484 
485  s->frame = av_frame_alloc();
486  if (!s->frame)
487  return AVERROR(ENOMEM);
488 
489  /* there is a vertical predictor for each pixel in a line; each vertical
490  * predictor is 0 to start with */
491  av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
492  if (!s->vert_pred) {
493  av_frame_free(&s->frame);
494  return AVERROR(ENOMEM);
495  }
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)
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,
923 };
uint8_t version
Definition: truemotion1.c:95
uint8_t deltaset
Definition: truemotion1.c:90
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
int16_t fat_ydt[8]
Definition: truemotion1.c:72
int block_height
Definition: truemotion1.c:119
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static const int16_t *const fat_ydts[]
misc image utilities
Memory handling functions.
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
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define OUTPUT_PIXEL_PAIR()
Definition: truemotion1.c:613
#define avpriv_request_sample(...)
static void truemotion1_decode_16bit(TrueMotion1Context *s)
Definition: truemotion1.c:617
int size
Definition: avcodec.h:1478
#define GET_NEXT_INDEX()
Definition: truemotion1.c:526
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
Definition: avcodec.h:1944
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:281
AVCodec.
Definition: avcodec.h:3481
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
AVCodec ff_truemotion1_decoder
Definition: truemotion1.c:913
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
Definition: decode.c:2011
static int truemotion1_decode_header(TrueMotion1Context *s)
Definition: truemotion1.c:310
int16_t cdt[8]
Definition: truemotion1.c:71
const uint8_t * index_stream
Definition: truemotion1.c:54
uint8_t
#define av_cold
Definition: attributes.h:82
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
#define FF_DEBUG_PICT_INFO
Definition: avcodec.h:2651
#define FLAG_KEYFRAME
Definition: truemotion1.c:83
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:443
uint8_t * data
Definition: avcodec.h:1477
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
#define FLAG_SPRITE
Definition: truemotion1.c:82
#define av_log(a,...)
const uint8_t * buf
Definition: truemotion1.c:49
#define U(x)
Definition: vp56_arith.h:37
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
Definition: truemotion1.c:903
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint16_t yoffset
Definition: truemotion1.c:100
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * r
Definition: vf_curves.c:114
static void truemotion1_decode_24bit(TrueMotion1Context *s)
Definition: truemotion1.c:744
uint16_t xsize
Definition: truemotion1.c:93
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
#define BLOCK_4x2
Definition: truemotion1.c:113
static const uint8_t pc_tbl2[]
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:500
uint32_t c_predictor_table[1024]
Definition: truemotion1.c:61
common internal API header
#define b
Definition: input.c:41
AVCodecContext * avctx
Definition: truemotion1.c:46
int width
picture width / height.
Definition: avcodec.h:1738
static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:174
uint16_t height
Definition: truemotion1.c:102
#define s(width, name)
Definition: cbs_vp9.c:257
unsigned int * vert_pred
Definition: truemotion1.c:77
static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:230
static const comp_types compression_types[17]
Definition: truemotion1.c:124
#define APPLY_C_PREDICTOR_24()
Definition: truemotion1.c:561
#define ALGO_RGB16V
Definition: truemotion1.c:106
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
#define ALGO_NOP
Definition: truemotion1.c:105
static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:221
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
uint8_t header_size
Definition: truemotion1.c:88
static const int16_t *const cdts[]
Libavcodec external API header.
static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:260
static const int16_t *const ydts[]
#define ALGO_RGB16H
Definition: truemotion1.c:107
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
int debug
debug
Definition: avcodec.h:2650
main external API structure.
Definition: avcodec.h:1565
uint32_t fat_c_predictor_table[1024]
Definition: truemotion1.c:63
#define ALGO_RGB24H
Definition: truemotion1.c:108
static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:186
int index
Definition: gxfenc.c:89
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int16_t fat_cdt[8]
Definition: truemotion1.c:73
int block_width
Definition: truemotion1.c:118
static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
Definition: truemotion1.c:473
uint16_t width
Definition: truemotion1.c:101
int block_type
Definition: truemotion1.c:120
uint8_t vectable
Definition: truemotion1.c:91
static int truemotion1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: truemotion1.c:871
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:8
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
#define APPLY_Y_PREDICTOR()
Definition: truemotion1.c:579
#define APPLY_C_PREDICTOR()
Definition: truemotion1.c:544
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
uint16_t xoffset
Definition: truemotion1.c:99
common internal api header.
#define BLOCK_2x2
Definition: truemotion1.c:111
uint16_t checksum
Definition: truemotion1.c:94
static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
Definition: truemotion1.c:199
uint8_t flags
Definition: truemotion1.c:97
uint8_t compression
Definition: truemotion1.c:89
static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:239
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
Definition: truemotion1.c:211
void * priv_data
Definition: avcodec.h:1592
uint32_t fat_y_predictor_table[1024]
Definition: truemotion1.c:62
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:664
int len
#define FLAG_INTERFRAME
Definition: truemotion1.c:84
uint16_t ysize
Definition: truemotion1.c:92
uint8_t control
Definition: truemotion1.c:98
uint32_t y_predictor_table[1024]
Definition: truemotion1.c:60
static const int16_t *const fat_cdts[]
#define av_freep(p)
#define BLOCK_4x4
Definition: truemotion1.c:114
#define BLOCK_2x4
Definition: truemotion1.c:112
static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
Definition: truemotion1.c:148
#define APPLY_Y_PREDICTOR_24()
Definition: truemotion1.c:596
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
const uint8_t * mb_change_bits
Definition: truemotion1.c:52
#define FLAG_INTERPOLATED
Definition: truemotion1.c:85
This structure stores compressed data.
Definition: avcodec.h:1454
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:981
int16_t ydt[8]
Definition: truemotion1.c:70
#define AV_PIX_FMT_0RGB32
Definition: pixfmt.h:364
uint8_t header_type
Definition: truemotion1.c:96