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  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",
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 };
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:615
#define avpriv_request_sample(...)
static void truemotion1_decode_16bit(TrueMotion1Context *s)
Definition: truemotion1.c:619
int size
Definition: avcodec.h:1484
#define GET_NEXT_INDEX()
Definition: truemotion1.c:528
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:1950
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1781
static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
Definition: truemotion1.c:281
AVCodec.
Definition: avcodec.h:3495
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:915
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
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:2657
#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:1483
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:905
#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
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:2015
const char * r
Definition: vf_curves.c:114
static void truemotion1_decode_24bit(TrueMotion1Context *s)
Definition: truemotion1.c:746
uint16_t xsize
Definition: truemotion1.c:93
const char * name
Name of the codec implementation.
Definition: avcodec.h:3502
#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:1744
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:563
#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:2656
main external API structure.
Definition: avcodec.h:1571
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:475
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:873
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:581
#define APPLY_C_PREDICTOR()
Definition: truemotion1.c:546
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:1598
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:598
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:1460
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:987
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