FFmpeg
indeo3.c
Go to the documentation of this file.
1 /*
2  * Indeo Video v3 compatible decoder
3  * Copyright (c) 2009 - 2011 Maxim Poliakovski
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  * This is a decoder for Intel Indeo Video v3.
25  * It is based on vector quantization, run-length coding and motion compensation.
26  * Known container formats: .avi and .mov
27  * Known FOURCCs: 'IV31', 'IV32'
28  *
29  * @see http://wiki.multimedia.cx/index.php?title=Indeo_3
30  */
31 
32 #include "libavutil/imgutils.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/thread.h"
35 #include "avcodec.h"
36 #include "copy_block.h"
37 #include "bytestream.h"
38 #include "get_bits.h"
39 #include "hpeldsp.h"
40 #include "internal.h"
41 
42 #include "indeo3data.h"
43 
44 /* RLE opcodes. */
45 enum {
46  RLE_ESC_F9 = 249, ///< same as RLE_ESC_FA + do the same with next block
47  RLE_ESC_FA = 250, ///< INTRA: skip block, INTER: copy data from reference
48  RLE_ESC_FB = 251, ///< apply null delta to N blocks / skip N blocks
49  RLE_ESC_FC = 252, ///< same as RLE_ESC_FD + do the same with next block
50  RLE_ESC_FD = 253, ///< apply null delta to all remaining lines of this block
51  RLE_ESC_FE = 254, ///< apply null delta to all lines up to the 3rd line
52  RLE_ESC_FF = 255 ///< apply null delta to all lines up to the 2nd line
53 };
54 
55 
56 /* Some constants for parsing frame bitstream flags. */
57 #define BS_8BIT_PEL (1 << 1) ///< 8-bit pixel bitdepth indicator
58 #define BS_KEYFRAME (1 << 2) ///< intra frame indicator
59 #define BS_MV_Y_HALF (1 << 4) ///< vertical mv halfpel resolution indicator
60 #define BS_MV_X_HALF (1 << 5) ///< horizontal mv halfpel resolution indicator
61 #define BS_NONREF (1 << 8) ///< nonref (discardable) frame indicator
62 #define BS_BUFFER 9 ///< indicates which of two frame buffers should be used
63 
64 
65 typedef struct Plane {
66  uint8_t *buffers[2];
67  uint8_t *pixels[2]; ///< pointer to the actual pixel data of the buffers above
68  uint32_t width;
69  uint32_t height;
70  ptrdiff_t pitch;
71 } Plane;
72 
73 #define CELL_STACK_MAX 20
74 
75 typedef struct Cell {
76  int16_t xpos; ///< cell coordinates in 4x4 blocks
77  int16_t ypos;
78  int16_t width; ///< cell width in 4x4 blocks
79  int16_t height; ///< cell height in 4x4 blocks
80  uint8_t tree; ///< tree id: 0- MC tree, 1 - VQ tree
81  const int8_t *mv_ptr; ///< ptr to the motion vector if any
82 } Cell;
83 
84 typedef struct Indeo3DecodeContext {
87 
90  int skip_bits;
91  const uint8_t *next_cell_data;
92  const uint8_t *last_byte;
93  const int8_t *mc_vectors;
94  unsigned num_vectors; ///< number of motion vectors in mc_vectors
95 
96  int16_t width, height;
97  uint32_t frame_num; ///< current frame number (zero-based)
98  int data_size; ///< size of the frame data in bytes
99  uint16_t frame_flags; ///< frame properties
100  uint8_t cb_offset; ///< needed for selecting VQ tables
101  uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary
102  const uint8_t *y_data_ptr;
103  const uint8_t *v_data_ptr;
104  const uint8_t *u_data_ptr;
108  const uint8_t *alt_quant; ///< secondary VQ table set for the modes 1 and 4
111 
112 
113 static uint8_t requant_tab[8][128];
114 
115 /*
116  * Build the static requantization table.
117  * This table is used to remap pixel values according to a specific
118  * quant index and thus avoid overflows while adding deltas.
119  */
120 static av_cold void build_requant_tab(void)
121 {
122  static const int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
123  static const int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 };
124 
125  int i, j, step;
126 
127  for (i = 0; i < 8; i++) {
128  step = i + 2;
129  for (j = 0; j < 128; j++)
130  requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
131  }
132 
133  /* some last elements calculated above will have values >= 128 */
134  /* pixel values shall never exceed 127 so set them to non-overflowing values */
135  /* according with the quantization step of the respective section */
136  requant_tab[0][127] = 126;
137  requant_tab[1][119] = 118;
138  requant_tab[1][120] = 118;
139  requant_tab[2][126] = 124;
140  requant_tab[2][127] = 124;
141  requant_tab[6][124] = 120;
142  requant_tab[6][125] = 120;
143  requant_tab[6][126] = 120;
144  requant_tab[6][127] = 120;
145 
146  /* Patch for compatibility with the Intel's binary decoders */
147  requant_tab[1][7] = 10;
148  requant_tab[4][8] = 10;
149 }
150 
151 
153 {
154  int p;
155 
156  ctx->width = ctx->height = 0;
157 
158  for (p = 0; p < 3; p++) {
159  av_freep(&ctx->planes[p].buffers[0]);
160  av_freep(&ctx->planes[p].buffers[1]);
161  ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0;
162  }
163 }
164 
165 
167  AVCodecContext *avctx, int luma_width, int luma_height)
168 {
169  int p, chroma_width, chroma_height;
170  int luma_size, chroma_size;
171  ptrdiff_t luma_pitch, chroma_pitch;
172 
173  if (luma_width < 16 || luma_width > 640 ||
174  luma_height < 16 || luma_height > 480 ||
175  luma_width & 1 || luma_height & 1) {
176  av_log(avctx, AV_LOG_ERROR, "Invalid picture dimensions: %d x %d!\n",
177  luma_width, luma_height);
178  return AVERROR_INVALIDDATA;
179  }
180 
181  ctx->width = luma_width ;
182  ctx->height = luma_height;
183 
184  chroma_width = FFALIGN(luma_width >> 2, 4);
185  chroma_height = FFALIGN(luma_height >> 2, 4);
186 
187  luma_pitch = FFALIGN(luma_width, 16);
188  chroma_pitch = FFALIGN(chroma_width, 16);
189 
190  /* Calculate size of the luminance plane. */
191  /* Add one line more for INTRA prediction. */
192  luma_size = luma_pitch * (luma_height + 1);
193 
194  /* Calculate size of a chrominance planes. */
195  /* Add one line more for INTRA prediction. */
196  chroma_size = chroma_pitch * (chroma_height + 1);
197 
198  /* allocate frame buffers */
199  for (p = 0; p < 3; p++) {
200  ctx->planes[p].pitch = !p ? luma_pitch : chroma_pitch;
201  ctx->planes[p].width = !p ? luma_width : chroma_width;
202  ctx->planes[p].height = !p ? luma_height : chroma_height;
203 
204  ctx->planes[p].buffers[0] = av_malloc(!p ? luma_size : chroma_size);
205  ctx->planes[p].buffers[1] = av_malloc(!p ? luma_size : chroma_size);
206 
207  if (!ctx->planes[p].buffers[0] || !ctx->planes[p].buffers[1])
208  return AVERROR(ENOMEM);
209 
210  /* fill the INTRA prediction lines with the middle pixel value = 64 */
211  memset(ctx->planes[p].buffers[0], 0x40, ctx->planes[p].pitch);
212  memset(ctx->planes[p].buffers[1], 0x40, ctx->planes[p].pitch);
213 
214  /* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */
215  ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch;
216  ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch;
217  memset(ctx->planes[p].pixels[0], 0, ctx->planes[p].pitch * ctx->planes[p].height);
218  memset(ctx->planes[p].pixels[1], 0, ctx->planes[p].pitch * ctx->planes[p].height);
219  }
220 
221  return 0;
222 }
223 
224 /**
225  * Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into
226  * the cell(x, y) in the current frame.
227  *
228  * @param ctx pointer to the decoder context
229  * @param plane pointer to the plane descriptor
230  * @param cell pointer to the cell descriptor
231  */
232 static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
233 {
234  int h, w, mv_x, mv_y, offset, offset_dst;
235  uint8_t *src, *dst;
236 
237  /* setup output and reference pointers */
238  offset_dst = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
239  dst = plane->pixels[ctx->buf_sel] + offset_dst;
240  if(cell->mv_ptr){
241  mv_y = cell->mv_ptr[0];
242  mv_x = cell->mv_ptr[1];
243  }else
244  mv_x= mv_y= 0;
245 
246  /* -1 because there is an extra line on top for prediction */
247  if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
248  ((cell->ypos + cell->height) << 2) + mv_y > plane->height ||
249  ((cell->xpos + cell->width) << 2) + mv_x > plane->width) {
250  av_log(ctx->avctx, AV_LOG_ERROR,
251  "Motion vectors point out of the frame.\n");
252  return AVERROR_INVALIDDATA;
253  }
254 
255  offset = offset_dst + mv_y * plane->pitch + mv_x;
256  src = plane->pixels[ctx->buf_sel ^ 1] + offset;
257 
258  h = cell->height << 2;
259 
260  for (w = cell->width; w > 0;) {
261  /* copy using 16xH blocks */
262  if (!((cell->xpos << 2) & 15) && w >= 4) {
263  for (; w >= 4; src += 16, dst += 16, w -= 4)
264  ctx->hdsp.put_pixels_tab[0][0](dst, src, plane->pitch, h);
265  }
266 
267  /* copy using 8xH blocks */
268  if (!((cell->xpos << 2) & 7) && w >= 2) {
269  ctx->hdsp.put_pixels_tab[1][0](dst, src, plane->pitch, h);
270  w -= 2;
271  src += 8;
272  dst += 8;
273  } else if (w >= 1) {
274  ctx->hdsp.put_pixels_tab[2][0](dst, src, plane->pitch, h);
275  w--;
276  src += 4;
277  dst += 4;
278  }
279  }
280 
281  return 0;
282 }
283 
284 
285 /* Average 4/8 pixels at once without rounding using SWAR */
286 #define AVG_32(dst, src, ref) \
287  AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL)
288 
289 #define AVG_64(dst, src, ref) \
290  AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL)
291 
292 
293 /*
294  * Replicate each even pixel as follows:
295  * ABCDEFGH -> AACCEEGG
296  */
297 static inline uint64_t replicate64(uint64_t a) {
298 #if HAVE_BIGENDIAN
299  a &= 0xFF00FF00FF00FF00ULL;
300  a |= a >> 8;
301 #else
302  a &= 0x00FF00FF00FF00FFULL;
303  a |= a << 8;
304 #endif
305  return a;
306 }
307 
308 static inline uint32_t replicate32(uint32_t a) {
309 #if HAVE_BIGENDIAN
310  a &= 0xFF00FF00UL;
311  a |= a >> 8;
312 #else
313  a &= 0x00FF00FFUL;
314  a |= a << 8;
315 #endif
316  return a;
317 }
318 
319 
320 /* Fill n lines with 64-bit pixel value pix */
321 static inline void fill_64(uint8_t *dst, const uint64_t pix, int32_t n,
322  int32_t row_offset)
323 {
324  for (; n > 0; dst += row_offset, n--)
325  AV_WN64A(dst, pix);
326 }
327 
328 
329 /* Error codes for cell decoding. */
330 enum {
337 };
338 
339 
340 #define BUFFER_PRECHECK \
341 if (*data_ptr >= last_ptr) \
342  return IV3_OUT_OF_DATA; \
343 
344 #define RLE_BLOCK_COPY \
345  if (cell->mv_ptr || !skip_flag) \
346  copy_block4(dst, ref, row_offset, row_offset, 4 << v_zoom)
347 
348 #define RLE_BLOCK_COPY_8 \
349  pix64 = AV_RN64(ref);\
350  if (is_first_row) {/* special prediction case: top line of a cell */\
351  pix64 = replicate64(pix64);\
352  fill_64(dst + row_offset, pix64, 7, row_offset);\
353  AVG_64(dst, ref, dst + row_offset);\
354  } else \
355  fill_64(dst, pix64, 8, row_offset)
356 
357 #define RLE_LINES_COPY \
358  copy_block4(dst, ref, row_offset, row_offset, num_lines << v_zoom)
359 
360 #define RLE_LINES_COPY_M10 \
361  pix64 = AV_RN64(ref);\
362  if (is_top_of_cell) {\
363  pix64 = replicate64(pix64);\
364  fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\
365  AVG_64(dst, ref, dst + row_offset);\
366  } else \
367  fill_64(dst, pix64, num_lines << 1, row_offset)
368 
369 #define APPLY_DELTA_4 \
370  AV_WN16A(dst + line_offset ,\
371  (AV_RN16(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
372  AV_WN16A(dst + line_offset + 2,\
373  (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
374  if (mode >= 3) {\
375  if (is_top_of_cell && !cell->ypos) {\
376  AV_COPY32U(dst, dst + row_offset);\
377  } else {\
378  AVG_32(dst, ref, dst + row_offset);\
379  }\
380  }
381 
382 #define APPLY_DELTA_8 \
383  /* apply two 32-bit VQ deltas to next even line */\
384  if (is_top_of_cell) { \
385  AV_WN32A(dst + row_offset , \
386  (replicate32(AV_RN32(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
387  AV_WN32A(dst + row_offset + 4, \
388  (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
389  } else { \
390  AV_WN32A(dst + row_offset , \
391  (AV_RN32(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
392  AV_WN32A(dst + row_offset + 4, \
393  (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
394  } \
395  /* odd lines are not coded but rather interpolated/replicated */\
396  /* first line of the cell on the top of image? - replicate */\
397  /* otherwise - interpolate */\
398  if (is_top_of_cell && !cell->ypos) {\
399  AV_COPY64U(dst, dst + row_offset);\
400  } else \
401  AVG_64(dst, ref, dst + row_offset);
402 
403 
404 #define APPLY_DELTA_1011_INTER \
405  if (mode == 10) { \
406  AV_WN32A(dst , \
407  (AV_RN32(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
408  AV_WN32A(dst + 4 , \
409  (AV_RN32(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
410  AV_WN32A(dst + row_offset , \
411  (AV_RN32(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\
412  AV_WN32A(dst + row_offset + 4, \
413  (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\
414  } else { \
415  AV_WN16A(dst , \
416  (AV_RN16(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
417  AV_WN16A(dst + 2 , \
418  (AV_RN16(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\
419  AV_WN16A(dst + row_offset , \
420  (AV_RN16(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\
421  AV_WN16A(dst + row_offset + 2, \
422  (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\
423  }
424 
425 
427  uint8_t *block, uint8_t *ref_block,
428  ptrdiff_t row_offset, int h_zoom, int v_zoom, int mode,
429  const vqEntry *delta[2], int swap_quads[2],
430  const uint8_t **data_ptr, const uint8_t *last_ptr)
431 {
432  int x, y, line, num_lines;
433  int rle_blocks = 0;
434  uint8_t code, *dst, *ref;
435  const vqEntry *delta_tab;
436  unsigned int dyad1, dyad2;
437  uint64_t pix64;
438  int skip_flag = 0, is_top_of_cell, is_first_row = 1;
439  int blk_row_offset, line_offset;
440 
441  blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2);
442  line_offset = v_zoom ? row_offset : 0;
443 
444  if (cell->height & v_zoom || cell->width & h_zoom)
445  return IV3_BAD_DATA;
446 
447  for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) {
448  for (x = 0; x < cell->width; x += 1 + h_zoom) {
449  ref = ref_block;
450  dst = block;
451 
452  if (rle_blocks > 0) {
453  if (mode <= 4) {
455  } else if (mode == 10 && !cell->mv_ptr) {
457  }
458  rle_blocks--;
459  } else {
460  for (line = 0; line < 4;) {
461  num_lines = 1;
462  is_top_of_cell = is_first_row && !line;
463 
464  /* select primary VQ table for odd, secondary for even lines */
465  if (mode <= 4)
466  delta_tab = delta[line & 1];
467  else
468  delta_tab = delta[1];
470  code = bytestream_get_byte(data_ptr);
471  if (code < 248) {
472  if (code < delta_tab->num_dyads) {
474  dyad1 = bytestream_get_byte(data_ptr);
475  dyad2 = code;
476  if (dyad1 >= delta_tab->num_dyads || dyad1 >= 248)
477  return IV3_BAD_DATA;
478  } else {
479  /* process QUADS */
480  code -= delta_tab->num_dyads;
481  dyad1 = code / delta_tab->quad_exp;
482  dyad2 = code % delta_tab->quad_exp;
483  if (swap_quads[line & 1])
484  FFSWAP(unsigned int, dyad1, dyad2);
485  }
486  if (mode <= 4) {
488  } else if (mode == 10 && !cell->mv_ptr) {
490  } else {
492  }
493  } else {
494  /* process RLE codes */
495  switch (code) {
496  case RLE_ESC_FC:
497  skip_flag = 0;
498  rle_blocks = 1;
499  code = 253;
500  /* FALLTHROUGH */
501  case RLE_ESC_FF:
502  case RLE_ESC_FE:
503  case RLE_ESC_FD:
504  num_lines = 257 - code - line;
505  if (num_lines <= 0)
506  return IV3_BAD_RLE;
507  if (mode <= 4) {
509  } else if (mode == 10 && !cell->mv_ptr) {
511  }
512  break;
513  case RLE_ESC_FB:
515  code = bytestream_get_byte(data_ptr);
516  rle_blocks = (code & 0x1F) - 1; /* set block counter */
517  if (code >= 64 || rle_blocks < 0)
518  return IV3_BAD_COUNTER;
519  skip_flag = code & 0x20;
520  num_lines = 4 - line; /* enforce next block processing */
521  if (mode >= 10 || (cell->mv_ptr || !skip_flag)) {
522  if (mode <= 4) {
524  } else if (mode == 10 && !cell->mv_ptr) {
526  }
527  }
528  break;
529  case RLE_ESC_F9:
530  skip_flag = 1;
531  rle_blocks = 1;
532  /* FALLTHROUGH */
533  case RLE_ESC_FA:
534  if (line)
535  return IV3_BAD_RLE;
536  num_lines = 4; /* enforce next block processing */
537  if (cell->mv_ptr) {
538  if (mode <= 4) {
540  } else if (mode == 10 && !cell->mv_ptr) {
542  }
543  }
544  break;
545  default:
546  return IV3_UNSUPPORTED;
547  }
548  }
549 
550  line += num_lines;
551  ref += row_offset * (num_lines << v_zoom);
552  dst += row_offset * (num_lines << v_zoom);
553  }
554  }
555 
556  /* move to next horizontal block */
557  block += 4 << h_zoom;
558  ref_block += 4 << h_zoom;
559  }
560 
561  /* move to next line of blocks */
562  ref_block += blk_row_offset;
563  block += blk_row_offset;
564  }
565  return IV3_NOERR;
566 }
567 
568 
569 /**
570  * Decode a vector-quantized cell.
571  * It consists of several routines, each of which handles one or more "modes"
572  * with which a cell can be encoded.
573  *
574  * @param ctx pointer to the decoder context
575  * @param avctx ptr to the AVCodecContext
576  * @param plane pointer to the plane descriptor
577  * @param cell pointer to the cell descriptor
578  * @param data_ptr pointer to the compressed data
579  * @param last_ptr pointer to the last byte to catch reads past end of buffer
580  * @return number of consumed bytes or negative number in case of error
581  */
583  Plane *plane, Cell *cell, const uint8_t *data_ptr,
584  const uint8_t *last_ptr)
585 {
586  int x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
587  int zoom_fac;
588  int offset, error = 0, swap_quads[2];
589  uint8_t code, *block, *ref_block = 0;
590  const vqEntry *delta[2];
591  const uint8_t *data_start = data_ptr;
592 
593  /* get coding mode and VQ table index from the VQ descriptor byte */
594  code = *data_ptr++;
595  mode = code >> 4;
596  vq_index = code & 0xF;
597 
598  /* setup output and reference pointers */
599  offset = (cell->ypos << 2) * plane->pitch + (cell->xpos << 2);
600  block = plane->pixels[ctx->buf_sel] + offset;
601 
602  if (!cell->mv_ptr) {
603  /* use previous line as reference for INTRA cells */
604  ref_block = block - plane->pitch;
605  } else if (mode >= 10) {
606  /* for mode 10 and 11 INTER first copy the predicted cell into the current one */
607  /* so we don't need to do data copying for each RLE code later */
608  int ret = copy_cell(ctx, plane, cell);
609  if (ret < 0)
610  return ret;
611  } else {
612  /* set the pointer to the reference pixels for modes 0-4 INTER */
613  mv_y = cell->mv_ptr[0];
614  mv_x = cell->mv_ptr[1];
615 
616  /* -1 because there is an extra line on top for prediction */
617  if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 ||
618  ((cell->ypos + cell->height) << 2) + mv_y > plane->height ||
619  ((cell->xpos + cell->width) << 2) + mv_x > plane->width) {
620  av_log(ctx->avctx, AV_LOG_ERROR,
621  "Motion vectors point out of the frame.\n");
622  return AVERROR_INVALIDDATA;
623  }
624 
625  offset += mv_y * plane->pitch + mv_x;
626  ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset;
627  }
628 
629  /* select VQ tables as follows: */
630  /* modes 0 and 3 use only the primary table for all lines in a block */
631  /* while modes 1 and 4 switch between primary and secondary tables on alternate lines */
632  if (mode == 1 || mode == 4) {
633  code = ctx->alt_quant[vq_index];
634  prim_indx = (code >> 4) + ctx->cb_offset;
635  second_indx = (code & 0xF) + ctx->cb_offset;
636  } else {
637  vq_index += ctx->cb_offset;
638  prim_indx = second_indx = vq_index;
639  }
640 
641  if (prim_indx >= 24 || second_indx >= 24) {
642  av_log(avctx, AV_LOG_ERROR, "Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
643  prim_indx, second_indx);
644  return AVERROR_INVALIDDATA;
645  }
646 
647  delta[0] = &vq_tab[second_indx];
648  delta[1] = &vq_tab[prim_indx];
649  swap_quads[0] = second_indx >= 16;
650  swap_quads[1] = prim_indx >= 16;
651 
652  /* requantize the prediction if VQ index of this cell differs from VQ index */
653  /* of the predicted cell in order to avoid overflows. */
654  if (vq_index >= 8 && ref_block) {
655  for (x = 0; x < cell->width << 2; x++)
656  ref_block[x] = requant_tab[vq_index & 7][ref_block[x] & 127];
657  }
658 
659  error = IV3_NOERR;
660 
661  switch (mode) {
662  case 0: /*------------------ MODES 0 & 1 (4x4 block processing) --------------------*/
663  case 1:
664  case 3: /*------------------ MODES 3 & 4 (4x8 block processing) --------------------*/
665  case 4:
666  if (mode >= 3 && cell->mv_ptr) {
667  av_log(avctx, AV_LOG_ERROR, "Attempt to apply Mode 3/4 to an INTER cell!\n");
668  return AVERROR_INVALIDDATA;
669  }
670 
671  zoom_fac = mode >= 3;
672  error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
673  0, zoom_fac, mode, delta, swap_quads,
674  &data_ptr, last_ptr);
675  break;
676  case 10: /*-------------------- MODE 10 (8x8 block processing) ---------------------*/
677  case 11: /*----------------- MODE 11 (4x8 INTER block processing) ------------------*/
678  if (mode == 10 && !cell->mv_ptr) { /* MODE 10 INTRA processing */
679  error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
680  1, 1, mode, delta, swap_quads,
681  &data_ptr, last_ptr);
682  } else { /* mode 10 and 11 INTER processing */
683  if (mode == 11 && !cell->mv_ptr) {
684  av_log(avctx, AV_LOG_ERROR, "Attempt to use Mode 11 for an INTRA cell!\n");
685  return AVERROR_INVALIDDATA;
686  }
687 
688  zoom_fac = mode == 10;
689  error = decode_cell_data(ctx, cell, block, ref_block, plane->pitch,
690  zoom_fac, 1, mode, delta, swap_quads,
691  &data_ptr, last_ptr);
692  }
693  break;
694  default:
695  av_log(avctx, AV_LOG_ERROR, "Unsupported coding mode: %d\n", mode);
696  return AVERROR_INVALIDDATA;
697  }//switch mode
698 
699  switch (error) {
700  case IV3_BAD_RLE:
701  av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE code %X is not allowed at the current line\n",
702  mode, data_ptr[-1]);
703  return AVERROR_INVALIDDATA;
704  case IV3_BAD_DATA:
705  av_log(avctx, AV_LOG_ERROR, "Mode %d: invalid VQ data\n", mode);
706  return AVERROR_INVALIDDATA;
707  case IV3_BAD_COUNTER:
708  av_log(avctx, AV_LOG_ERROR, "Mode %d: RLE-FB invalid counter: %d\n", mode, code);
709  return AVERROR_INVALIDDATA;
710  case IV3_UNSUPPORTED:
711  av_log(avctx, AV_LOG_ERROR, "Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
712  return AVERROR_INVALIDDATA;
713  case IV3_OUT_OF_DATA:
714  av_log(avctx, AV_LOG_ERROR, "Mode %d: attempt to read past end of buffer\n", mode);
715  return AVERROR_INVALIDDATA;
716  }
717 
718  return data_ptr - data_start; /* report number of bytes consumed from the input buffer */
719 }
720 
721 
722 /* Binary tree codes. */
723 enum {
724  H_SPLIT = 0,
725  V_SPLIT = 1,
728 };
729 
730 
731 #define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1
732 
733 #define UPDATE_BITPOS(n) \
734  ctx->skip_bits += (n); \
735  ctx->need_resync = 1
736 
737 #define RESYNC_BITSTREAM \
738  if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \
739  skip_bits_long(&ctx->gb, ctx->skip_bits); \
740  ctx->skip_bits = 0; \
741  ctx->need_resync = 0; \
742  }
743 
744 #define CHECK_CELL \
745  if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) || \
746  curr_cell.ypos + curr_cell.height > (plane->height >> 2)) { \
747  av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n", \
748  curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \
749  return AVERROR_INVALIDDATA; \
750  }
751 
752 
754  Plane *plane, int code, Cell *ref_cell,
755  const int depth, const int strip_width)
756 {
757  Cell curr_cell;
758  int bytes_used, ret;
759 
760  if (depth <= 0) {
761  av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n");
762  return AVERROR_INVALIDDATA; // unwind recursion
763  }
764 
765  curr_cell = *ref_cell; // clone parent cell
766  if (code == H_SPLIT) {
767  SPLIT_CELL(ref_cell->height, curr_cell.height);
768  ref_cell->ypos += curr_cell.height;
769  ref_cell->height -= curr_cell.height;
770  if (ref_cell->height <= 0 || curr_cell.height <= 0)
771  return AVERROR_INVALIDDATA;
772  } else if (code == V_SPLIT) {
773  if (curr_cell.width > strip_width) {
774  /* split strip */
775  curr_cell.width = (curr_cell.width <= (strip_width << 1) ? 1 : 2) * strip_width;
776  } else
777  SPLIT_CELL(ref_cell->width, curr_cell.width);
778  ref_cell->xpos += curr_cell.width;
779  ref_cell->width -= curr_cell.width;
780  if (ref_cell->width <= 0 || curr_cell.width <= 0)
781  return AVERROR_INVALIDDATA;
782  }
783 
784  while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */
786  switch (code = get_bits(&ctx->gb, 2)) {
787  case H_SPLIT:
788  case V_SPLIT:
789  if (parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
790  return AVERROR_INVALIDDATA;
791  break;
792  case INTRA_NULL:
793  if (!curr_cell.tree) { /* MC tree INTRA code */
794  curr_cell.mv_ptr = 0; /* mark the current strip as INTRA */
795  curr_cell.tree = 1; /* enter the VQ tree */
796  } else { /* VQ tree NULL code */
798  code = get_bits(&ctx->gb, 2);
799  if (code >= 2) {
800  av_log(avctx, AV_LOG_ERROR, "Invalid VQ_NULL code: %d\n", code);
801  return AVERROR_INVALIDDATA;
802  }
803  if (code == 1)
804  av_log(avctx, AV_LOG_ERROR, "SkipCell procedure not implemented yet!\n");
805 
806  CHECK_CELL
807  if (!curr_cell.mv_ptr)
808  return AVERROR_INVALIDDATA;
809 
810  ret = copy_cell(ctx, plane, &curr_cell);
811  return ret;
812  }
813  break;
814  case INTER_DATA:
815  if (!curr_cell.tree) { /* MC tree INTER code */
816  unsigned mv_idx;
817  /* get motion vector index and setup the pointer to the mv set */
818  if (!ctx->need_resync)
819  ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
820  if (ctx->next_cell_data >= ctx->last_byte) {
821  av_log(avctx, AV_LOG_ERROR, "motion vector out of array\n");
822  return AVERROR_INVALIDDATA;
823  }
824  mv_idx = *(ctx->next_cell_data++);
825  if (mv_idx >= ctx->num_vectors) {
826  av_log(avctx, AV_LOG_ERROR, "motion vector index out of range\n");
827  return AVERROR_INVALIDDATA;
828  }
829  curr_cell.mv_ptr = &ctx->mc_vectors[mv_idx << 1];
830  curr_cell.tree = 1; /* enter the VQ tree */
831  UPDATE_BITPOS(8);
832  } else { /* VQ tree DATA code */
833  if (!ctx->need_resync)
834  ctx->next_cell_data = &ctx->gb.buffer[(get_bits_count(&ctx->gb) + 7) >> 3];
835 
836  CHECK_CELL
837  bytes_used = decode_cell(ctx, avctx, plane, &curr_cell,
838  ctx->next_cell_data, ctx->last_byte);
839  if (bytes_used < 0)
840  return AVERROR_INVALIDDATA;
841 
842  UPDATE_BITPOS(bytes_used << 3);
843  ctx->next_cell_data += bytes_used;
844  return 0;
845  }
846  break;
847  }
848  }//while
849 
850  return AVERROR_INVALIDDATA;
851 }
852 
853 
855  Plane *plane, const uint8_t *data, int32_t data_size,
856  int32_t strip_width)
857 {
858  Cell curr_cell;
859  unsigned num_vectors;
860 
861  /* each plane data starts with mc_vector_count field, */
862  /* an optional array of motion vectors followed by the vq data */
863  num_vectors = bytestream_get_le32(&data); data_size -= 4;
864  if (num_vectors > 256) {
865  av_log(ctx->avctx, AV_LOG_ERROR,
866  "Read invalid number of motion vectors %d\n", num_vectors);
867  return AVERROR_INVALIDDATA;
868  }
869  if (num_vectors * 2 > data_size)
870  return AVERROR_INVALIDDATA;
871 
872  ctx->num_vectors = num_vectors;
873  ctx->mc_vectors = num_vectors ? data : 0;
874 
875  /* init the bitreader */
876  init_get_bits(&ctx->gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3);
877  ctx->skip_bits = 0;
878  ctx->need_resync = 0;
879 
880  ctx->last_byte = data + data_size;
881 
882  /* initialize the 1st cell and set its dimensions to whole plane */
883  curr_cell.xpos = curr_cell.ypos = 0;
884  curr_cell.width = plane->width >> 2;
885  curr_cell.height = plane->height >> 2;
886  curr_cell.tree = 0; // we are in the MC tree now
887  curr_cell.mv_ptr = 0; // no motion vector = INTRA cell
888 
889  return parse_bintree(ctx, avctx, plane, INTRA_NULL, &curr_cell, CELL_STACK_MAX, strip_width);
890 }
891 
892 
893 #define OS_HDR_ID MKBETAG('F', 'R', 'M', 'H')
894 
896  const uint8_t *buf, int buf_size)
897 {
898  GetByteContext gb;
899  const uint8_t *bs_hdr;
900  uint32_t frame_num, word2, check_sum, data_size;
901  int y_offset, u_offset, v_offset;
902  uint32_t starts[3], ends[3];
903  uint16_t height, width;
904  int i, j;
905 
906  bytestream2_init(&gb, buf, buf_size);
907 
908  /* parse and check the OS header */
909  frame_num = bytestream2_get_le32(&gb);
910  word2 = bytestream2_get_le32(&gb);
911  check_sum = bytestream2_get_le32(&gb);
912  data_size = bytestream2_get_le32(&gb);
913 
914  if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) {
915  av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n");
916  return AVERROR_INVALIDDATA;
917  }
918 
919  /* parse the bitstream header */
920  bs_hdr = gb.buffer;
921 
922  if (bytestream2_get_le16(&gb) != 32) {
923  av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n");
924  return AVERROR_INVALIDDATA;
925  }
926 
927  ctx->frame_num = frame_num;
928  ctx->frame_flags = bytestream2_get_le16(&gb);
929  ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3;
930  ctx->cb_offset = bytestream2_get_byte(&gb);
931 
932  if (ctx->data_size == 16)
933  return 4;
934  ctx->data_size = FFMIN(ctx->data_size, buf_size - 16);
935 
936  bytestream2_skip(&gb, 3); // skip reserved byte and checksum
937 
938  /* check frame dimensions */
939  height = bytestream2_get_le16(&gb);
940  width = bytestream2_get_le16(&gb);
941  if (av_image_check_size(width, height, 0, avctx))
942  return AVERROR_INVALIDDATA;
943 
944  if (width != ctx->width || height != ctx->height) {
945  int res;
946 
947  ff_dlog(avctx, "Frame dimensions changed!\n");
948 
949  if (width < 16 || width > 640 ||
950  height < 16 || height > 480 ||
951  width & 3 || height & 3) {
952  av_log(avctx, AV_LOG_ERROR,
953  "Invalid picture dimensions: %d x %d!\n", width, height);
954  return AVERROR_INVALIDDATA;
955  }
957  if ((res = allocate_frame_buffers(ctx, avctx, width, height)) < 0)
958  return res;
959  if ((res = ff_set_dimensions(avctx, width, height)) < 0)
960  return res;
961  }
962 
963  y_offset = bytestream2_get_le32(&gb);
964  v_offset = bytestream2_get_le32(&gb);
965  u_offset = bytestream2_get_le32(&gb);
966  bytestream2_skip(&gb, 4);
967 
968  /* unfortunately there is no common order of planes in the buffer */
969  /* so we use that sorting algo for determining planes data sizes */
970  starts[0] = y_offset;
971  starts[1] = v_offset;
972  starts[2] = u_offset;
973 
974  for (j = 0; j < 3; j++) {
975  ends[j] = ctx->data_size;
976  for (i = 2; i >= 0; i--)
977  if (starts[i] < ends[j] && starts[i] > starts[j])
978  ends[j] = starts[i];
979  }
980 
981  ctx->y_data_size = ends[0] - starts[0];
982  ctx->v_data_size = ends[1] - starts[1];
983  ctx->u_data_size = ends[2] - starts[2];
984  if (FFMIN3(y_offset, v_offset, u_offset) < 0 ||
985  FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 ||
986  FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 ||
987  FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) {
988  av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n");
989  return AVERROR_INVALIDDATA;
990  }
991 
992  ctx->y_data_ptr = bs_hdr + y_offset;
993  ctx->v_data_ptr = bs_hdr + v_offset;
994  ctx->u_data_ptr = bs_hdr + u_offset;
995  ctx->alt_quant = gb.buffer;
996 
997  if (ctx->data_size == 16) {
998  av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n");
999  return 16;
1000  }
1001 
1002  if (ctx->frame_flags & BS_8BIT_PEL) {
1003  avpriv_request_sample(avctx, "8-bit pixel format");
1004  return AVERROR_PATCHWELCOME;
1005  }
1006 
1007  if (ctx->frame_flags & BS_MV_X_HALF || ctx->frame_flags & BS_MV_Y_HALF) {
1008  avpriv_request_sample(avctx, "Halfpel motion vectors");
1009  return AVERROR_PATCHWELCOME;
1010  }
1011 
1012  return 0;
1013 }
1014 
1015 
1016 /**
1017  * Convert and output the current plane.
1018  * All pixel values will be upsampled by shifting right by one bit.
1019  *
1020  * @param[in] plane pointer to the descriptor of the plane being processed
1021  * @param[in] buf_sel indicates which frame buffer the input data stored in
1022  * @param[out] dst pointer to the buffer receiving converted pixels
1023  * @param[in] dst_pitch pitch for moving to the next y line
1024  * @param[in] dst_height output plane height
1025  */
1026 static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst,
1027  ptrdiff_t dst_pitch, int dst_height)
1028 {
1029  int x,y;
1030  const uint8_t *src = plane->pixels[buf_sel];
1031  ptrdiff_t pitch = plane->pitch;
1032 
1033  dst_height = FFMIN(dst_height, plane->height);
1034  for (y = 0; y < dst_height; y++) {
1035  /* convert four pixels at once using SWAR */
1036  for (x = 0; x < plane->width >> 2; x++) {
1037  AV_WN32A(dst, (AV_RN32A(src) & 0x7F7F7F7F) << 1);
1038  src += 4;
1039  dst += 4;
1040  }
1041 
1042  for (x <<= 2; x < plane->width; x++)
1043  *dst++ = *src++ << 1;
1044 
1045  src += pitch - plane->width;
1046  dst += dst_pitch - plane->width;
1047  }
1048 }
1049 
1050 
1052 {
1053  static AVOnce init_static_once = AV_ONCE_INIT;
1054  Indeo3DecodeContext *ctx = avctx->priv_data;
1055 
1056  ctx->avctx = avctx;
1057  avctx->pix_fmt = AV_PIX_FMT_YUV410P;
1058 
1059  ff_thread_once(&init_static_once, build_requant_tab);
1060 
1061  ff_hpeldsp_init(&ctx->hdsp, avctx->flags);
1062 
1063  return allocate_frame_buffers(ctx, avctx, avctx->width, avctx->height);
1064 }
1065 
1066 
1067 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
1068  AVPacket *avpkt)
1069 {
1070  Indeo3DecodeContext *ctx = avctx->priv_data;
1071  const uint8_t *buf = avpkt->data;
1072  int buf_size = avpkt->size;
1073  AVFrame *frame = data;
1074  int res;
1075 
1076  res = decode_frame_headers(ctx, avctx, buf, buf_size);
1077  if (res < 0)
1078  return res;
1079 
1080  /* skip sync(null) frames */
1081  if (res) {
1082  // we have processed 16 bytes but no data was decoded
1083  *got_frame = 0;
1084  return buf_size;
1085  }
1086 
1087  /* skip droppable INTER frames if requested */
1088  if (ctx->frame_flags & BS_NONREF &&
1089  (avctx->skip_frame >= AVDISCARD_NONREF))
1090  return 0;
1091 
1092  /* skip INTER frames if requested */
1093  if (!(ctx->frame_flags & BS_KEYFRAME) && avctx->skip_frame >= AVDISCARD_NONKEY)
1094  return 0;
1095 
1096  /* use BS_BUFFER flag for buffer switching */
1097  ctx->buf_sel = (ctx->frame_flags >> BS_BUFFER) & 1;
1098 
1099  if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
1100  return res;
1101 
1102  /* decode luma plane */
1103  if ((res = decode_plane(ctx, avctx, ctx->planes, ctx->y_data_ptr, ctx->y_data_size, 40)))
1104  return res;
1105 
1106  /* decode chroma planes */
1107  if ((res = decode_plane(ctx, avctx, &ctx->planes[1], ctx->u_data_ptr, ctx->u_data_size, 10)))
1108  return res;
1109 
1110  if ((res = decode_plane(ctx, avctx, &ctx->planes[2], ctx->v_data_ptr, ctx->v_data_size, 10)))
1111  return res;
1112 
1113  output_plane(&ctx->planes[0], ctx->buf_sel,
1114  frame->data[0], frame->linesize[0],
1115  avctx->height);
1116  output_plane(&ctx->planes[1], ctx->buf_sel,
1117  frame->data[1], frame->linesize[1],
1118  (avctx->height + 3) >> 2);
1119  output_plane(&ctx->planes[2], ctx->buf_sel,
1120  frame->data[2], frame->linesize[2],
1121  (avctx->height + 3) >> 2);
1122 
1123  *got_frame = 1;
1124 
1125  return buf_size;
1126 }
1127 
1128 
1130 {
1131  free_frame_buffers(avctx->priv_data);
1132 
1133  return 0;
1134 }
1135 
1137  .name = "indeo3",
1138  .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 3"),
1139  .type = AVMEDIA_TYPE_VIDEO,
1140  .id = AV_CODEC_ID_INDEO3,
1141  .priv_data_size = sizeof(Indeo3DecodeContext),
1142  .init = decode_init,
1143  .close = decode_close,
1144  .decode = decode_frame,
1145  .capabilities = AV_CODEC_CAP_DR1,
1147 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
AVCodec
AVCodec.
Definition: codec.h:202
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
APPLY_DELTA_8
#define APPLY_DELTA_8
Definition: indeo3.c:382
vq_tab
static const vqEntry vq_tab[24]
Definition: indeo3data.h:330
BS_NONREF
#define BS_NONREF
nonref (discardable) frame indicator
Definition: indeo3.c:61
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:850
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
Cell::height
int16_t height
cell height in 4x4 blocks
Definition: indeo3.c:79
IV3_UNSUPPORTED
@ IV3_UNSUPPORTED
Definition: indeo3.c:335
APPLY_DELTA_4
#define APPLY_DELTA_4
Definition: indeo3.c:369
GetByteContext
Definition: bytestream.h:33
OS_HDR_ID
#define OS_HDR_ID
Definition: indeo3.c:893
thread.h
RLE_ESC_FE
@ RLE_ESC_FE
apply null delta to all lines up to the 3rd line
Definition: indeo3.c:51
get_bits_count
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:220
decode_close
static av_cold int decode_close(AVCodecContext *avctx)
Definition: indeo3.c:1129
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
step
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about which is also called distortion Distortion can be quantified by almost any quality measurement one chooses the sum of squared differences is used but more complex methods that consider psychovisual effects can be used as well It makes no difference in this discussion First step
Definition: rate_distortion.txt:58
BS_MV_Y_HALF
#define BS_MV_Y_HALF
vertical mv halfpel resolution indicator
Definition: indeo3.c:59
w
uint8_t w
Definition: llviddspenc.c:38
AV_CODEC_ID_INDEO3
@ AV_CODEC_ID_INDEO3
Definition: codec_id.h:78
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
RLE_ESC_FC
@ RLE_ESC_FC
same as RLE_ESC_FD + do the same with next block
Definition: indeo3.c:49
data
const char data[16]
Definition: mxf.c:143
decode_frame_headers
static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const uint8_t *buf, int buf_size)
Definition: indeo3.c:895
Indeo3DecodeContext::alt_quant
const uint8_t * alt_quant
secondary VQ table set for the modes 1 and 4
Definition: indeo3.c:108
AV_WN32A
#define AV_WN32A(p, v)
Definition: intreadwrite.h:538
BS_MV_X_HALF
#define BS_MV_X_HALF
horizontal mv halfpel resolution indicator
Definition: indeo3.c:60
CELL_STACK_MAX
#define CELL_STACK_MAX
Definition: indeo3.c:73
decode_cell
static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, Cell *cell, const uint8_t *data_ptr, const uint8_t *last_ptr)
Decode a vector-quantized cell.
Definition: indeo3.c:582
Indeo3DecodeContext::mc_vectors
const int8_t * mc_vectors
Definition: indeo3.c:93
RLE_ESC_FB
@ RLE_ESC_FB
apply null delta to N blocks / skip N blocks
Definition: indeo3.c:48
init_get_bits
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:660
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
BUFFER_PRECHECK
#define BUFFER_PRECHECK
Definition: indeo3.c:340
init
static int init
Definition: av_tx.c:47
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:380
decode_cell_data
static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell, uint8_t *block, uint8_t *ref_block, ptrdiff_t row_offset, int h_zoom, int v_zoom, int mode, const vqEntry *delta[2], int swap_quads[2], const uint8_t **data_ptr, const uint8_t *last_ptr)
Definition: indeo3.c:426
Cell::xpos
int16_t xpos
cell coordinates in 4x4 blocks
Definition: indeo3.c:76
AVCodecContext::skip_frame
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition: avcodec.h:1673
IV3_BAD_COUNTER
@ IV3_BAD_COUNTER
Definition: indeo3.c:334
IV3_BAD_RLE
@ IV3_BAD_RLE
Definition: indeo3.c:332
GetBitContext
Definition: get_bits.h:62
requant_tab
static uint8_t requant_tab[8][128]
Definition: indeo3.c:113
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:463
BS_BUFFER
#define BS_BUFFER
indicates which of two frame buffers should be used
Definition: indeo3.c:62
ff_thread_once
static int ff_thread_once(char *control, void(*routine)(void))
Definition: thread.h:175
Indeo3DecodeContext::width
int16_t width
Definition: indeo3.c:96
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
build_requant_tab
static av_cold void build_requant_tab(void)
Definition: indeo3.c:120
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
width
#define width
intreadwrite.h
Indeo3DecodeContext::gb
GetBitContext gb
Definition: indeo3.c:88
offsets
static const int offsets[]
Definition: hevc_pel.c:34
Indeo3DecodeContext::buf_sel
uint8_t buf_sel
active frame buffer: 0 - primary, 1 -secondary
Definition: indeo3.c:101
copy_cell
static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into the cell(x,...
Definition: indeo3.c:232
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
RLE_ESC_FF
@ RLE_ESC_FF
apply null delta to all lines up to the 2nd line
Definition: indeo3.c:52
Indeo3DecodeContext::hdsp
HpelDSPContext hdsp
Definition: indeo3.c:86
UPDATE_BITPOS
#define UPDATE_BITPOS(n)
Definition: indeo3.c:733
RLE_LINES_COPY_M10
#define RLE_LINES_COPY_M10
Definition: indeo3.c:360
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode_init
static av_cold int decode_init(AVCodecContext *avctx)
Definition: indeo3.c:1051
Indeo3DecodeContext::v_data_size
int32_t v_data_size
Definition: indeo3.c:106
get_bits.h
BS_KEYFRAME
#define BS_KEYFRAME
intra frame indicator
Definition: indeo3.c:58
Plane::buffers
uint8_t * buffers[2]
Definition: indeo3.c:66
vqEntry
Definition: indeo3data.h:323
V_SPLIT
@ V_SPLIT
Definition: indeo3.c:725
ff_hpeldsp_init
av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
Definition: hpeldsp.c:338
parse_bintree
static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, int code, Cell *ref_cell, const int depth, const int strip_width)
Definition: indeo3.c:753
AV_ONCE_INIT
#define AV_ONCE_INIT
Definition: thread.h:173
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
decode_frame
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: indeo3.c:1067
Indeo3DecodeContext::y_data_ptr
const uint8_t * y_data_ptr
Definition: indeo3.c:102
Indeo3DecodeContext::next_cell_data
const uint8_t * next_cell_data
Definition: indeo3.c:91
ff_indeo3_decoder
const AVCodec ff_indeo3_decoder
Definition: indeo3.c:1136
src
#define src
Definition: vp8dsp.c:255
Indeo3DecodeContext::num_vectors
unsigned num_vectors
number of motion vectors in mc_vectors
Definition: indeo3.c:94
Indeo3DecodeContext::height
int16_t height
Definition: indeo3.c:96
Indeo3DecodeContext::u_data_ptr
const uint8_t * u_data_ptr
Definition: indeo3.c:104
Indeo3DecodeContext
Definition: indeo3.c:84
RLE_LINES_COPY
#define RLE_LINES_COPY
Definition: indeo3.c:357
Indeo3DecodeContext::last_byte
const uint8_t * last_byte
Definition: indeo3.c:92
Indeo3DecodeContext::planes
Plane planes[3]
Definition: indeo3.c:109
AVOnce
#define AVOnce
Definition: thread.h:172
SPLIT_CELL
#define SPLIT_CELL(size, new_size)
Definition: indeo3.c:731
ff_dlog
#define ff_dlog(a,...)
Definition: tableprint_vlc.h:29
HpelDSPContext
Half-pel DSP context.
Definition: hpeldsp.h:45
Cell
Definition: indeo3.c:75
Plane::pixels
uint8_t * pixels[2]
pointer to the actual pixel data of the buffers above
Definition: indeo3.c:67
Cell::width
int16_t width
cell width in 4x4 blocks
Definition: indeo3.c:78
AVDISCARD_NONKEY
@ AVDISCARD_NONKEY
discard all frames except keyframes
Definition: defs.h:53
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1652
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
H_SPLIT
@ H_SPLIT
Definition: indeo3.c:724
Plane::height
int height
Definition: cfhd.h:120
IV3_OUT_OF_DATA
@ IV3_OUT_OF_DATA
Definition: indeo3.c:336
Indeo3DecodeContext::cb_offset
uint8_t cb_offset
needed for selecting VQ tables
Definition: indeo3.c:100
decode_plane
static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, const uint8_t *data, int32_t data_size, int32_t strip_width)
Definition: indeo3.c:854
Indeo3DecodeContext::v_data_ptr
const uint8_t * v_data_ptr
Definition: indeo3.c:103
IV3_BAD_DATA
@ IV3_BAD_DATA
Definition: indeo3.c:333
Plane::pitch
ptrdiff_t pitch
Definition: indeo3.c:70
height
#define height
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
allocate_frame_buffers
static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, int luma_width, int luma_height)
Definition: indeo3.c:166
Plane::width
int width
Definition: cfhd.h:119
Cell::ypos
int16_t ypos
Definition: indeo3.c:77
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
line
Definition: graph2dot.c:48
indeo3data.h
Indeo3DecodeContext::avctx
AVCodecContext * avctx
Definition: indeo3.c:85
RLE_ESC_F9
@ RLE_ESC_F9
same as RLE_ESC_FA + do the same with next block
Definition: indeo3.c:46
Indeo3DecodeContext::u_data_size
int32_t u_data_size
Definition: indeo3.c:107
Indeo3DecodeContext::data_size
int data_size
size of the frame data in bytes
Definition: indeo3.c:98
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
copy_block.h
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:50
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
vqEntry::num_dyads
uint8_t num_dyads
number of two-pixel deltas
Definition: indeo3data.h:326
delta
float delta
Definition: vorbis_enc_data.h:430
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
RESYNC_BITSTREAM
#define RESYNC_BITSTREAM
Definition: indeo3.c:737
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
Cell::mv_ptr
const int8_t * mv_ptr
ptr to the motion vector if any
Definition: indeo3.c:81
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
Plane::width
uint32_t width
Definition: indeo3.c:68
avcodec.h
AV_RN32A
#define AV_RN32A(p)
Definition: intreadwrite.h:526
RLE_ESC_FA
@ RLE_ESC_FA
INTRA: skip block, INTER: copy data from reference.
Definition: indeo3.c:47
ret
ret
Definition: filter_design.txt:187
FFSWAP
#define FFSWAP(type, a, b)
Definition: macros.h:52
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
Indeo3DecodeContext::frame_num
uint32_t frame_num
current frame number (zero-based)
Definition: indeo3.c:97
Indeo3DecodeContext::y_data_size
int32_t y_data_size
Definition: indeo3.c:105
replicate64
static uint64_t replicate64(uint64_t a)
Definition: indeo3.c:297
free_frame_buffers
static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
Definition: indeo3.c:152
BS_8BIT_PEL
#define BS_8BIT_PEL
8-bit pixel bitdepth indicator
Definition: indeo3.c:57
AV_WN64A
#define AV_WN64A(p, v)
Definition: intreadwrite.h:542
RLE_ESC_FD
@ RLE_ESC_FD
apply null delta to all remaining lines of this block
Definition: indeo3.c:50
Plane::height
uint32_t height
Definition: indeo3.c:69
INTER_DATA
@ INTER_DATA
Definition: indeo3.c:727
AVCodecContext
main external API structure.
Definition: avcodec.h:383
Indeo3DecodeContext::skip_bits
int skip_bits
Definition: indeo3.c:90
CHECK_CELL
#define CHECK_CELL
Definition: indeo3.c:744
mode
mode
Definition: ebur128.h:83
APPLY_DELTA_1011_INTER
#define APPLY_DELTA_1011_INTER
Definition: indeo3.c:404
output_plane
static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst, ptrdiff_t dst_pitch, int dst_height)
Convert and output the current plane.
Definition: indeo3.c:1026
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
RLE_BLOCK_COPY_8
#define RLE_BLOCK_COPY_8
Definition: indeo3.c:348
Plane
Definition: cfhd.h:118
Cell::tree
uint8_t tree
tree id: 0- MC tree, 1 - VQ tree
Definition: indeo3.c:80
RLE_BLOCK_COPY
#define RLE_BLOCK_COPY
Definition: indeo3.c:344
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
ff_set_dimensions
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:86
avpriv_request_sample
#define avpriv_request_sample(...)
Definition: tableprint_vlc.h:37
replicate32
static uint32_t replicate32(uint32_t a)
Definition: indeo3.c:308
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
INTRA_NULL
@ INTRA_NULL
Definition: indeo3.c:726
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
int32_t
int32_t
Definition: audioconvert.c:56
bytestream.h
imgutils.h
hpeldsp.h
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
h
h
Definition: vp9dsp_template.c:2038
av_image_check_size
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:318
Indeo3DecodeContext::need_resync
int need_resync
Definition: indeo3.c:89
AVDISCARD_NONREF
@ AVDISCARD_NONREF
discard all non reference
Definition: defs.h:50
Indeo3DecodeContext::frame_flags
uint16_t frame_flags
frame properties
Definition: indeo3.c:99
IV3_NOERR
@ IV3_NOERR
Definition: indeo3.c:331
vqEntry::quad_exp
uint8_t quad_exp
log2 of four-pixel deltas
Definition: indeo3data.h:327
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
fill_64
static void fill_64(uint8_t *dst, const uint64_t pix, int32_t n, int32_t row_offset)
Definition: indeo3.c:321