FFmpeg
interplayvideo.c
Go to the documentation of this file.
1 /*
2  * Interplay MVE Video Decoder
3  * Copyright (C) 2003 The FFmpeg project
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  * Interplay MVE Video Decoder by Mike Melanson (melanson@pcisys.net)
25  * For more information about the Interplay MVE format, visit:
26  * http://www.pcisys.net/~melanson/codecs/interplay-mve.txt
27  * This code is written in such a way that the identifiers match up
28  * with the encoding descriptions in the document.
29  *
30  * This decoder presently only supports a PAL8 output colorspace.
31  *
32  * An Interplay video frame consists of 2 parts: The decoding map and
33  * the video data. A demuxer must load these 2 parts together in a single
34  * buffer before sending it through the stream to this decoder.
35  */
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 
41 #include "libavutil/intreadwrite.h"
42 
43 #define BITSTREAM_READER_LE
44 #include "avcodec.h"
45 #include "bytestream.h"
46 #include "get_bits.h"
47 #include "hpeldsp.h"
48 #include "internal.h"
49 
50 #define PALETTE_COUNT 256
51 
52 typedef struct IpvideoContext {
53 
58 
59  /* For format 0x10 */
62 
63  const unsigned char *decoding_map;
65  const unsigned char *skip_map;
67 
68  int is_16bpp;
70  unsigned char *pixel_ptr;
71  int line_inc;
72  int stride;
74 
75  uint32_t pal[256];
77 
78 static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
79 {
80  int width = dst->width;
81  int current_offset = s->pixel_ptr - dst->data[0];
82  int x = (current_offset % dst->linesize[0]) / (1 + s->is_16bpp);
83  int y = current_offset / dst->linesize[0];
84  int dx = delta_x + x - ((delta_x + x >= width) - (delta_x + x < 0)) * width;
85  int dy = delta_y + y + (delta_x + x >= width) - (delta_x + x < 0);
86  int motion_offset = dy * src->linesize[0] + dx * (1 + s->is_16bpp);
87 
88  if (motion_offset < 0) {
89  av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
90  return AVERROR_INVALIDDATA;
91  } else if (motion_offset > s->upper_motion_limit_offset) {
92  av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
93  motion_offset, s->upper_motion_limit_offset);
94  return AVERROR_INVALIDDATA;
95  }
96  if (!src->data[0]) {
97  av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
98  return AVERROR(EINVAL);
99  }
100  s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
101  dst->linesize[0], 8);
102  return 0;
103 }
104 
106 {
107  return copy_from(s, s->last_frame, frame, 0, 0);
108 }
109 
111 {
112  return copy_from(s, s->second_last_frame, frame, 0, 0);
113 }
114 
116 {
117  unsigned char B;
118  int x, y;
119 
120  /* copy block from 2 frames ago using a motion vector; need 1 more byte */
121  if (!s->is_16bpp) {
122  B = bytestream2_get_byte(&s->stream_ptr);
123  } else {
124  B = bytestream2_get_byte(&s->mv_ptr);
125  }
126 
127  if (B < 56) {
128  x = 8 + (B % 7);
129  y = B / 7;
130  } else {
131  x = -14 + ((B - 56) % 29);
132  y = 8 + ((B - 56) / 29);
133  }
134 
135  ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
136  return copy_from(s, s->second_last_frame, frame, x, y);
137 }
138 
140 {
141  unsigned char B;
142  int x, y;
143 
144  /* copy 8x8 block from current frame from an up/left block */
145 
146  /* need 1 more byte for motion */
147  if (!s->is_16bpp) {
148  B = bytestream2_get_byte(&s->stream_ptr);
149  } else {
150  B = bytestream2_get_byte(&s->mv_ptr);
151  }
152 
153  if (B < 56) {
154  x = -(8 + (B % 7));
155  y = -(B / 7);
156  } else {
157  x = -(-14 + ((B - 56) % 29));
158  y = -( 8 + ((B - 56) / 29));
159  }
160 
161  ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
162  return copy_from(s, frame, frame, x, y);
163 }
164 
166 {
167  int x, y;
168  unsigned char B, BL, BH;
169 
170  /* copy a block from the previous frame; need 1 more byte */
171  if (!s->is_16bpp) {
172  B = bytestream2_get_byte(&s->stream_ptr);
173  } else {
174  B = bytestream2_get_byte(&s->mv_ptr);
175  }
176 
177  BL = B & 0x0F;
178  BH = (B >> 4) & 0x0F;
179  x = -8 + BL;
180  y = -8 + BH;
181 
182  ff_tlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
183  return copy_from(s, s->last_frame, frame, x, y);
184 }
185 
187 {
188  signed char x, y;
189 
190  /* copy a block from the previous frame using an expanded range;
191  * need 2 more bytes */
192  x = bytestream2_get_byte(&s->stream_ptr);
193  y = bytestream2_get_byte(&s->stream_ptr);
194 
195  ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
196  return copy_from(s, s->last_frame, frame, x, y);
197 }
198 
200 {
201  /* mystery opcode? skip multiple blocks? */
202  av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
203 
204  /* report success */
205  return 0;
206 }
207 
209 {
210  int x, y;
211  unsigned char P[2];
212  unsigned int flags;
213 
214  if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
215  av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x7\n");
216  return AVERROR_INVALIDDATA;
217  }
218 
219  /* 2-color encoding */
220  P[0] = bytestream2_get_byte(&s->stream_ptr);
221  P[1] = bytestream2_get_byte(&s->stream_ptr);
222 
223  if (P[0] <= P[1]) {
224 
225  /* need 8 more bytes from the stream */
226  for (y = 0; y < 8; y++) {
227  flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
228  for (; flags != 1; flags >>= 1)
229  *s->pixel_ptr++ = P[flags & 1];
230  s->pixel_ptr += s->line_inc;
231  }
232 
233  } else {
234 
235  /* need 2 more bytes from the stream */
236  flags = bytestream2_get_le16(&s->stream_ptr);
237  for (y = 0; y < 8; y += 2) {
238  for (x = 0; x < 8; x += 2, flags >>= 1) {
239  s->pixel_ptr[x ] =
240  s->pixel_ptr[x + 1 ] =
241  s->pixel_ptr[x + s->stride] =
242  s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
243  }
244  s->pixel_ptr += s->stride * 2;
245  }
246  }
247 
248  /* report success */
249  return 0;
250 }
251 
253 {
254  int x, y;
255  unsigned char P[4];
256  unsigned int flags = 0;
257 
258  if (bytestream2_get_bytes_left(&s->stream_ptr) < 12) {
259  av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x8\n");
260  return AVERROR_INVALIDDATA;
261  }
262 
263  /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
264  * either top and bottom or left and right halves */
265  P[0] = bytestream2_get_byte(&s->stream_ptr);
266  P[1] = bytestream2_get_byte(&s->stream_ptr);
267 
268  if (P[0] <= P[1]) {
269  for (y = 0; y < 16; y++) {
270  // new values for each 4x4 block
271  if (!(y & 3)) {
272  if (y) {
273  P[0] = bytestream2_get_byte(&s->stream_ptr);
274  P[1] = bytestream2_get_byte(&s->stream_ptr);
275  }
276  flags = bytestream2_get_le16(&s->stream_ptr);
277  }
278 
279  for (x = 0; x < 4; x++, flags >>= 1)
280  *s->pixel_ptr++ = P[flags & 1];
281  s->pixel_ptr += s->stride - 4;
282  // switch to right half
283  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
284  }
285 
286  } else {
287  flags = bytestream2_get_le32(&s->stream_ptr);
288  P[2] = bytestream2_get_byte(&s->stream_ptr);
289  P[3] = bytestream2_get_byte(&s->stream_ptr);
290 
291  if (P[2] <= P[3]) {
292 
293  /* vertical split; left & right halves are 2-color encoded */
294 
295  for (y = 0; y < 16; y++) {
296  for (x = 0; x < 4; x++, flags >>= 1)
297  *s->pixel_ptr++ = P[flags & 1];
298  s->pixel_ptr += s->stride - 4;
299  // switch to right half
300  if (y == 7) {
301  s->pixel_ptr -= 8 * s->stride - 4;
302  P[0] = P[2];
303  P[1] = P[3];
304  flags = bytestream2_get_le32(&s->stream_ptr);
305  }
306  }
307 
308  } else {
309 
310  /* horizontal split; top & bottom halves are 2-color encoded */
311 
312  for (y = 0; y < 8; y++) {
313  if (y == 4) {
314  P[0] = P[2];
315  P[1] = P[3];
316  flags = bytestream2_get_le32(&s->stream_ptr);
317  }
318 
319  for (x = 0; x < 8; x++, flags >>= 1)
320  *s->pixel_ptr++ = P[flags & 1];
321  s->pixel_ptr += s->line_inc;
322  }
323  }
324  }
325 
326  /* report success */
327  return 0;
328 }
329 
331 {
332  int x, y;
333  unsigned char P[4];
334 
335  if (bytestream2_get_bytes_left(&s->stream_ptr) < 8) {
336  av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0x9\n");
337  return AVERROR_INVALIDDATA;
338  }
339 
340  /* 4-color encoding */
342 
343  if (P[0] <= P[1]) {
344  if (P[2] <= P[3]) {
345 
346  /* 1 of 4 colors for each pixel, need 16 more bytes */
347  for (y = 0; y < 8; y++) {
348  /* get the next set of 8 2-bit flags */
349  int flags = bytestream2_get_le16(&s->stream_ptr);
350  for (x = 0; x < 8; x++, flags >>= 2)
351  *s->pixel_ptr++ = P[flags & 0x03];
352  s->pixel_ptr += s->line_inc;
353  }
354 
355  } else {
356  uint32_t flags;
357 
358  /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
359  flags = bytestream2_get_le32(&s->stream_ptr);
360 
361  for (y = 0; y < 8; y += 2) {
362  for (x = 0; x < 8; x += 2, flags >>= 2) {
363  s->pixel_ptr[x ] =
364  s->pixel_ptr[x + 1 ] =
365  s->pixel_ptr[x + s->stride] =
366  s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
367  }
368  s->pixel_ptr += s->stride * 2;
369  }
370 
371  }
372  } else {
373  uint64_t flags;
374 
375  /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
376  flags = bytestream2_get_le64(&s->stream_ptr);
377  if (P[2] <= P[3]) {
378  for (y = 0; y < 8; y++) {
379  for (x = 0; x < 8; x += 2, flags >>= 2) {
380  s->pixel_ptr[x ] =
381  s->pixel_ptr[x + 1] = P[flags & 0x03];
382  }
383  s->pixel_ptr += s->stride;
384  }
385  } else {
386  for (y = 0; y < 8; y += 2) {
387  for (x = 0; x < 8; x++, flags >>= 2) {
388  s->pixel_ptr[x ] =
389  s->pixel_ptr[x + s->stride] = P[flags & 0x03];
390  }
391  s->pixel_ptr += s->stride * 2;
392  }
393  }
394  }
395 
396  /* report success */
397  return 0;
398 }
399 
401 {
402  int x, y;
403  unsigned char P[8];
404  int flags = 0;
405 
406  if (bytestream2_get_bytes_left(&s->stream_ptr) < 16) {
407  av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xA\n");
408  return AVERROR_INVALIDDATA;
409  }
410 
412 
413  /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
414  * either top and bottom or left and right halves */
415  if (P[0] <= P[1]) {
416 
417  /* 4-color encoding for each quadrant; need 32 bytes */
418  for (y = 0; y < 16; y++) {
419  // new values for each 4x4 block
420  if (!(y & 3)) {
421  if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
422  flags = bytestream2_get_le32(&s->stream_ptr);
423  }
424 
425  for (x = 0; x < 4; x++, flags >>= 2)
426  *s->pixel_ptr++ = P[flags & 0x03];
427 
428  s->pixel_ptr += s->stride - 4;
429  // switch to right half
430  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
431  }
432 
433  } else {
434  // vertical split?
435  int vert;
436  uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
437 
438  bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
439  vert = P[4] <= P[5];
440 
441  /* 4-color encoding for either left and right or top and bottom
442  * halves */
443 
444  for (y = 0; y < 16; y++) {
445  for (x = 0; x < 4; x++, flags >>= 2)
446  *s->pixel_ptr++ = P[flags & 0x03];
447 
448  if (vert) {
449  s->pixel_ptr += s->stride - 4;
450  // switch to right half
451  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
452  } else if (y & 1) s->pixel_ptr += s->line_inc;
453 
454  // load values for second half
455  if (y == 7) {
456  memcpy(P, P + 4, 4);
457  flags = bytestream2_get_le64(&s->stream_ptr);
458  }
459  }
460  }
461 
462  /* report success */
463  return 0;
464 }
465 
467 {
468  int y;
469 
470  /* 64-color encoding (each pixel in block is a different color) */
471  for (y = 0; y < 8; y++) {
473  s->pixel_ptr += s->stride;
474  }
475 
476  /* report success */
477  return 0;
478 }
479 
481 {
482  int x, y;
483 
484  /* 16-color block encoding: each 2x2 block is a different color */
485  for (y = 0; y < 8; y += 2) {
486  for (x = 0; x < 8; x += 2) {
487  s->pixel_ptr[x ] =
488  s->pixel_ptr[x + 1 ] =
489  s->pixel_ptr[x + s->stride] =
490  s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
491  }
492  s->pixel_ptr += s->stride * 2;
493  }
494 
495  /* report success */
496  return 0;
497 }
498 
500 {
501  int y;
502  unsigned char P[2];
503 
504  if (bytestream2_get_bytes_left(&s->stream_ptr) < 4) {
505  av_log(s->avctx, AV_LOG_ERROR, "too little data for opcode 0xD\n");
506  return AVERROR_INVALIDDATA;
507  }
508 
509  /* 4-color block encoding: each 4x4 block is a different color */
510  for (y = 0; y < 8; y++) {
511  if (!(y & 3)) {
512  P[0] = bytestream2_get_byte(&s->stream_ptr);
513  P[1] = bytestream2_get_byte(&s->stream_ptr);
514  }
515  memset(s->pixel_ptr, P[0], 4);
516  memset(s->pixel_ptr + 4, P[1], 4);
517  s->pixel_ptr += s->stride;
518  }
519 
520  /* report success */
521  return 0;
522 }
523 
525 {
526  int y;
527  unsigned char pix;
528 
529  /* 1-color encoding: the whole block is 1 solid color */
530  pix = bytestream2_get_byte(&s->stream_ptr);
531 
532  for (y = 0; y < 8; y++) {
533  memset(s->pixel_ptr, pix, 8);
534  s->pixel_ptr += s->stride;
535  }
536 
537  /* report success */
538  return 0;
539 }
540 
542 {
543  int x, y;
544  unsigned char sample[2];
545 
546  /* dithered encoding */
547  sample[0] = bytestream2_get_byte(&s->stream_ptr);
548  sample[1] = bytestream2_get_byte(&s->stream_ptr);
549 
550  for (y = 0; y < 8; y++) {
551  for (x = 0; x < 8; x += 2) {
552  *s->pixel_ptr++ = sample[ y & 1 ];
553  *s->pixel_ptr++ = sample[!(y & 1)];
554  }
555  s->pixel_ptr += s->line_inc;
556  }
557 
558  /* report success */
559  return 0;
560 }
561 
563 {
564  signed char x, y;
565 
566  /* copy a block from the second last frame using an expanded range */
567  x = bytestream2_get_byte(&s->stream_ptr);
568  y = bytestream2_get_byte(&s->stream_ptr);
569 
570  ff_tlog(s->avctx, "motion bytes = %d, %d\n", x, y);
571  return copy_from(s, s->second_last_frame, frame, x, y);
572 }
573 
575 {
576  int x, y;
577  uint16_t P[2];
578  unsigned int flags;
579  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
580 
581  /* 2-color encoding */
582  P[0] = bytestream2_get_le16(&s->stream_ptr);
583  P[1] = bytestream2_get_le16(&s->stream_ptr);
584 
585  if (!(P[0] & 0x8000)) {
586 
587  for (y = 0; y < 8; y++) {
588  flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
589  for (; flags != 1; flags >>= 1)
590  *pixel_ptr++ = P[flags & 1];
591  pixel_ptr += s->line_inc;
592  }
593 
594  } else {
595 
596  flags = bytestream2_get_le16(&s->stream_ptr);
597  for (y = 0; y < 8; y += 2) {
598  for (x = 0; x < 8; x += 2, flags >>= 1) {
599  pixel_ptr[x ] =
600  pixel_ptr[x + 1 ] =
601  pixel_ptr[x + s->stride] =
602  pixel_ptr[x + 1 + s->stride] = P[flags & 1];
603  }
604  pixel_ptr += s->stride * 2;
605  }
606  }
607 
608  return 0;
609 }
610 
612 {
613  int x, y;
614  uint16_t P[4];
615  unsigned int flags = 0;
616  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
617 
618  /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
619  * either top and bottom or left and right halves */
620  P[0] = bytestream2_get_le16(&s->stream_ptr);
621  P[1] = bytestream2_get_le16(&s->stream_ptr);
622 
623  if (!(P[0] & 0x8000)) {
624 
625  for (y = 0; y < 16; y++) {
626  // new values for each 4x4 block
627  if (!(y & 3)) {
628  if (y) {
629  P[0] = bytestream2_get_le16(&s->stream_ptr);
630  P[1] = bytestream2_get_le16(&s->stream_ptr);
631  }
632  flags = bytestream2_get_le16(&s->stream_ptr);
633  }
634 
635  for (x = 0; x < 4; x++, flags >>= 1)
636  *pixel_ptr++ = P[flags & 1];
637  pixel_ptr += s->stride - 4;
638  // switch to right half
639  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
640  }
641 
642  } else {
643 
644  flags = bytestream2_get_le32(&s->stream_ptr);
645  P[2] = bytestream2_get_le16(&s->stream_ptr);
646  P[3] = bytestream2_get_le16(&s->stream_ptr);
647 
648  if (!(P[2] & 0x8000)) {
649 
650  /* vertical split; left & right halves are 2-color encoded */
651 
652  for (y = 0; y < 16; y++) {
653  for (x = 0; x < 4; x++, flags >>= 1)
654  *pixel_ptr++ = P[flags & 1];
655  pixel_ptr += s->stride - 4;
656  // switch to right half
657  if (y == 7) {
658  pixel_ptr -= 8 * s->stride - 4;
659  P[0] = P[2];
660  P[1] = P[3];
661  flags = bytestream2_get_le32(&s->stream_ptr);
662  }
663  }
664 
665  } else {
666 
667  /* horizontal split; top & bottom halves are 2-color encoded */
668 
669  for (y = 0; y < 8; y++) {
670  if (y == 4) {
671  P[0] = P[2];
672  P[1] = P[3];
673  flags = bytestream2_get_le32(&s->stream_ptr);
674  }
675 
676  for (x = 0; x < 8; x++, flags >>= 1)
677  *pixel_ptr++ = P[flags & 1];
678  pixel_ptr += s->line_inc;
679  }
680  }
681  }
682 
683  /* report success */
684  return 0;
685 }
686 
688 {
689  int x, y;
690  uint16_t P[4];
691  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
692 
693  /* 4-color encoding */
694  for (x = 0; x < 4; x++)
695  P[x] = bytestream2_get_le16(&s->stream_ptr);
696 
697  if (!(P[0] & 0x8000)) {
698  if (!(P[2] & 0x8000)) {
699 
700  /* 1 of 4 colors for each pixel */
701  for (y = 0; y < 8; y++) {
702  /* get the next set of 8 2-bit flags */
703  int flags = bytestream2_get_le16(&s->stream_ptr);
704  for (x = 0; x < 8; x++, flags >>= 2)
705  *pixel_ptr++ = P[flags & 0x03];
706  pixel_ptr += s->line_inc;
707  }
708 
709  } else {
710  uint32_t flags;
711 
712  /* 1 of 4 colors for each 2x2 block */
713  flags = bytestream2_get_le32(&s->stream_ptr);
714 
715  for (y = 0; y < 8; y += 2) {
716  for (x = 0; x < 8; x += 2, flags >>= 2) {
717  pixel_ptr[x ] =
718  pixel_ptr[x + 1 ] =
719  pixel_ptr[x + s->stride] =
720  pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
721  }
722  pixel_ptr += s->stride * 2;
723  }
724 
725  }
726  } else {
727  uint64_t flags;
728 
729  /* 1 of 4 colors for each 2x1 or 1x2 block */
730  flags = bytestream2_get_le64(&s->stream_ptr);
731  if (!(P[2] & 0x8000)) {
732  for (y = 0; y < 8; y++) {
733  for (x = 0; x < 8; x += 2, flags >>= 2) {
734  pixel_ptr[x ] =
735  pixel_ptr[x + 1] = P[flags & 0x03];
736  }
737  pixel_ptr += s->stride;
738  }
739  } else {
740  for (y = 0; y < 8; y += 2) {
741  for (x = 0; x < 8; x++, flags >>= 2) {
742  pixel_ptr[x ] =
743  pixel_ptr[x + s->stride] = P[flags & 0x03];
744  }
745  pixel_ptr += s->stride * 2;
746  }
747  }
748  }
749 
750  /* report success */
751  return 0;
752 }
753 
755 {
756  int x, y;
757  uint16_t P[8];
758  int flags = 0;
759  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
760 
761  for (x = 0; x < 4; x++)
762  P[x] = bytestream2_get_le16(&s->stream_ptr);
763 
764  /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
765  * either top and bottom or left and right halves */
766  if (!(P[0] & 0x8000)) {
767 
768  /* 4-color encoding for each quadrant */
769  for (y = 0; y < 16; y++) {
770  // new values for each 4x4 block
771  if (!(y & 3)) {
772  if (y)
773  for (x = 0; x < 4; x++)
774  P[x] = bytestream2_get_le16(&s->stream_ptr);
775  flags = bytestream2_get_le32(&s->stream_ptr);
776  }
777 
778  for (x = 0; x < 4; x++, flags >>= 2)
779  *pixel_ptr++ = P[flags & 0x03];
780 
781  pixel_ptr += s->stride - 4;
782  // switch to right half
783  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
784  }
785 
786  } else {
787  // vertical split?
788  int vert;
789  uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
790 
791  for (x = 4; x < 8; x++)
792  P[x] = bytestream2_get_le16(&s->stream_ptr);
793  vert = !(P[4] & 0x8000);
794 
795  /* 4-color encoding for either left and right or top and bottom
796  * halves */
797 
798  for (y = 0; y < 16; y++) {
799  for (x = 0; x < 4; x++, flags >>= 2)
800  *pixel_ptr++ = P[flags & 0x03];
801 
802  if (vert) {
803  pixel_ptr += s->stride - 4;
804  // switch to right half
805  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
806  } else if (y & 1) pixel_ptr += s->line_inc;
807 
808  // load values for second half
809  if (y == 7) {
810  memcpy(P, P + 4, 8);
811  flags = bytestream2_get_le64(&s->stream_ptr);
812  }
813  }
814  }
815 
816  /* report success */
817  return 0;
818 }
819 
821 {
822  int x, y;
823  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
824 
825  /* 64-color encoding (each pixel in block is a different color) */
826  for (y = 0; y < 8; y++) {
827  for (x = 0; x < 8; x++)
828  pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
829  pixel_ptr += s->stride;
830  }
831 
832  /* report success */
833  return 0;
834 }
835 
837 {
838  int x, y;
839  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
840 
841  /* 16-color block encoding: each 2x2 block is a different color */
842  for (y = 0; y < 8; y += 2) {
843  for (x = 0; x < 8; x += 2) {
844  pixel_ptr[x ] =
845  pixel_ptr[x + 1 ] =
846  pixel_ptr[x + s->stride] =
847  pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
848  }
849  pixel_ptr += s->stride * 2;
850  }
851 
852  /* report success */
853  return 0;
854 }
855 
857 {
858  int x, y;
859  uint16_t P[2];
860  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
861 
862  /* 4-color block encoding: each 4x4 block is a different color */
863  for (y = 0; y < 8; y++) {
864  if (!(y & 3)) {
865  P[0] = bytestream2_get_le16(&s->stream_ptr);
866  P[1] = bytestream2_get_le16(&s->stream_ptr);
867  }
868  for (x = 0; x < 8; x++)
869  pixel_ptr[x] = P[x >> 2];
870  pixel_ptr += s->stride;
871  }
872 
873  /* report success */
874  return 0;
875 }
876 
878 {
879  int x, y;
880  uint16_t pix;
881  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
882 
883  /* 1-color encoding: the whole block is 1 solid color */
884  pix = bytestream2_get_le16(&s->stream_ptr);
885 
886  for (y = 0; y < 8; y++) {
887  for (x = 0; x < 8; x++)
888  pixel_ptr[x] = pix;
889  pixel_ptr += s->stride;
890  }
891 
892  /* report success */
893  return 0;
894 }
895 
905 };
906 
916 };
917 
918 static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
919 {
920  int line;
921 
922  if (!opcode) {
923  for (line = 0; line < 8; ++line) {
925  s->pixel_ptr += s->stride;
926  }
927  } else {
928  /* Don't try to copy second_last_frame data on the first frames */
929  if (s->avctx->frame_number > 2)
930  copy_from(s, s->second_last_frame, frame, 0, 0);
931  }
932 }
933 
934 static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
935 {
936  int off_x, off_y;
937 
938  if (opcode < 0) {
939  off_x = ((uint16_t)opcode - 0xC000) % frame->width;
940  off_y = ((uint16_t)opcode - 0xC000) / frame->width;
941  copy_from(s, s->last_frame, frame, off_x, off_y);
942  } else if (opcode > 0) {
943  off_x = ((uint16_t)opcode - 0x4000) % frame->width;
944  off_y = ((uint16_t)opcode - 0x4000) / frame->width;
945  copy_from(s, frame, frame, off_x, off_y);
946  }
947 }
948 
949 static void (* const ipvideo_format_06_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
951 };
952 
954 {
955  int pass, x, y;
956  int16_t opcode;
957  GetByteContext decoding_map_ptr;
958 
959  /* this is PAL8, so make the palette available */
960  memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
961  s->stride = frame->linesize[0];
962 
963  s->line_inc = s->stride - 8;
964  s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
965  + (s->avctx->width - 8) * (1 + s->is_16bpp);
966 
967  bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
968 
969  for (pass = 0; pass < 2; ++pass) {
970  bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
971  for (y = 0; y < s->avctx->height; y += 8) {
972  for (x = 0; x < s->avctx->width; x += 8) {
973  opcode = bytestream2_get_le16(&decoding_map_ptr);
974 
975  ff_tlog(s->avctx,
976  " block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
977  x, y, opcode, bytestream2_tell(&s->stream_ptr));
978 
979  s->pixel_ptr = frame->data[0] + x + y * frame->linesize[0];
981  }
982  }
983  }
984 
985  if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
987  "decode finished with %d bytes left over\n",
989  }
990 }
991 
992 static void ipvideo_format_10_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
993 {
994  int line;
995 
996  if (!opcode) {
997  for (line = 0; line < 8; ++line) {
999  s->pixel_ptr += s->stride;
1000  }
1001  }
1002 }
1003 
1005 {
1006  int off_x, off_y;
1007 
1008  if (opcode < 0) {
1009  off_x = ((uint16_t)opcode - 0xC000) % s->cur_decode_frame->width;
1010  off_y = ((uint16_t)opcode - 0xC000) / s->cur_decode_frame->width;
1011  copy_from(s, s->prev_decode_frame, s->cur_decode_frame, off_x, off_y);
1012  } else if (opcode > 0) {
1013  off_x = ((uint16_t)opcode - 0x4000) % s->cur_decode_frame->width;
1014  off_y = ((uint16_t)opcode - 0x4000) / s->cur_decode_frame->width;
1015  copy_from(s, s->cur_decode_frame, s->cur_decode_frame, off_x, off_y);
1016  }
1017 }
1018 
1019 static void (* const ipvideo_format_10_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op) = {
1021 };
1022 
1024 {
1025  int pass, x, y, changed_block;
1026  int16_t opcode, skip;
1027  GetByteContext decoding_map_ptr;
1028  GetByteContext skip_map_ptr;
1029 
1030  bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1031 
1032  /* this is PAL8, so make the palette available */
1033  memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1034  s->stride = frame->linesize[0];
1035 
1036  s->line_inc = s->stride - 8;
1037  s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1038  + (s->avctx->width - 8) * (1 + s->is_16bpp);
1039 
1040  bytestream2_init(&decoding_map_ptr, s->decoding_map, s->decoding_map_size);
1041  bytestream2_init(&skip_map_ptr, s->skip_map, s->skip_map_size);
1042 
1043  for (pass = 0; pass < 2; ++pass) {
1044  bytestream2_seek(&decoding_map_ptr, 0, SEEK_SET);
1045  bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1046  skip = bytestream2_get_le16(&skip_map_ptr);
1047 
1048  for (y = 0; y < s->avctx->height; y += 8) {
1049  for (x = 0; x < s->avctx->width; x += 8) {
1050  s->pixel_ptr = s->cur_decode_frame->data[0] + x + y * s->cur_decode_frame->linesize[0];
1051 
1052  while (skip <= 0) {
1053  if (skip != -0x8000 && skip) {
1054  opcode = bytestream2_get_le16(&decoding_map_ptr);
1055  ipvideo_format_10_passes[pass](s, frame, opcode);
1056  break;
1057  }
1058  if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1059  return;
1060  skip = bytestream2_get_le16(&skip_map_ptr);
1061  }
1062  skip *= 2;
1063  }
1064  }
1065  }
1066 
1067  bytestream2_seek(&skip_map_ptr, 0, SEEK_SET);
1068  skip = bytestream2_get_le16(&skip_map_ptr);
1069  for (y = 0; y < s->avctx->height; y += 8) {
1070  for (x = 0; x < s->avctx->width; x += 8) {
1071  changed_block = 0;
1072  s->pixel_ptr = frame->data[0] + x + y*frame->linesize[0];
1073 
1074  while (skip <= 0) {
1075  if (skip != -0x8000 && skip) {
1076  changed_block = 1;
1077  break;
1078  }
1079  if (bytestream2_get_bytes_left(&skip_map_ptr) < 2)
1080  return;
1081  skip = bytestream2_get_le16(&skip_map_ptr);
1082  }
1083 
1084  if (changed_block) {
1085  copy_from(s, s->cur_decode_frame, frame, 0, 0);
1086  } else {
1087  /* Don't try to copy last_frame data on the first frame */
1088  if (s->avctx->frame_number)
1089  copy_from(s, s->last_frame, frame, 0, 0);
1090  }
1091  skip *= 2;
1092  }
1093  }
1094 
1096 
1097  if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1099  "decode finished with %d bytes left over\n",
1101  }
1102 }
1103 
1105 {
1106  int x, y;
1107  unsigned char opcode;
1108  int ret;
1109  GetBitContext gb;
1110 
1111  bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
1112  if (!s->is_16bpp) {
1113  /* this is PAL8, so make the palette available */
1114  memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
1115 
1116  s->stride = frame->linesize[0];
1117  } else {
1118  s->stride = frame->linesize[0] >> 1;
1119  s->mv_ptr = s->stream_ptr;
1120  bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
1121  }
1122  s->line_inc = s->stride - 8;
1123  s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
1124  + (s->avctx->width - 8) * (1 + s->is_16bpp);
1125 
1126  init_get_bits(&gb, s->decoding_map, s->decoding_map_size * 8);
1127  for (y = 0; y < s->avctx->height; y += 8) {
1128  for (x = 0; x < s->avctx->width; x += 8) {
1129  if (get_bits_left(&gb) < 4)
1130  return;
1131  opcode = get_bits(&gb, 4);
1132 
1133  ff_tlog(s->avctx,
1134  " block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
1135  x, y, opcode, bytestream2_tell(&s->stream_ptr));
1136 
1137  if (!s->is_16bpp) {
1138  s->pixel_ptr = frame->data[0] + x
1139  + y*frame->linesize[0];
1140  ret = ipvideo_decode_block[opcode](s, frame);
1141  } else {
1142  s->pixel_ptr = frame->data[0] + x*2
1143  + y*frame->linesize[0];
1144  ret = ipvideo_decode_block16[opcode](s, frame);
1145  }
1146  if (ret != 0) {
1147  av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
1148  s->avctx->frame_number, x, y);
1149  return;
1150  }
1151  }
1152  }
1153  if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
1155  "decode finished with %d bytes left over\n",
1157  }
1158 }
1159 
1161 {
1162  IpvideoContext *s = avctx->priv_data;
1163  int ret;
1164 
1165  s->avctx = avctx;
1166 
1167  s->is_16bpp = avctx->bits_per_coded_sample == 16;
1169 
1170  ff_hpeldsp_init(&s->hdsp, avctx->flags);
1171 
1172  s->last_frame = av_frame_alloc();
1176  if (!s->last_frame || !s->second_last_frame ||
1177  !s->cur_decode_frame || !s->prev_decode_frame) {
1178  ret = AVERROR(ENOMEM);
1179  goto error;
1180  }
1181 
1182  s->cur_decode_frame->width = avctx->width;
1183  s->prev_decode_frame->width = avctx->width;
1184  s->cur_decode_frame->height = avctx->height;
1185  s->prev_decode_frame->height = avctx->height;
1186  s->cur_decode_frame->format = avctx->pix_fmt;
1187  s->prev_decode_frame->format = avctx->pix_fmt;
1188 
1189  return 0;
1190 error:
1195  return ret;
1196 }
1197 
1199  void *data, int *got_frame,
1200  AVPacket *avpkt)
1201 {
1202  const uint8_t *buf = avpkt->data;
1203  int buf_size = avpkt->size;
1204  IpvideoContext *s = avctx->priv_data;
1205  AVFrame *frame = data;
1206  int ret;
1207  int send_buffer;
1208  int frame_format;
1209  int video_data_size;
1210 
1216  }
1217 
1218  if (!s->cur_decode_frame->data[0]) {
1219  ret = ff_get_buffer(avctx, s->cur_decode_frame, 0);
1220  if (ret < 0)
1221  return ret;
1222 
1223  ret = ff_get_buffer(avctx, s->prev_decode_frame, 0);
1224  if (ret < 0) {
1226  return ret;
1227  }
1228  }
1229 
1230  if (buf_size < 8)
1231  return AVERROR_INVALIDDATA;
1232 
1233  frame_format = AV_RL8(buf);
1234  send_buffer = AV_RL8(buf + 1);
1235  video_data_size = AV_RL16(buf + 2);
1236  s->decoding_map_size = AV_RL16(buf + 4);
1237  s->skip_map_size = AV_RL16(buf + 6);
1238 
1239  switch (frame_format) {
1240  case 0x06:
1241  if (s->decoding_map_size) {
1242  av_log(avctx, AV_LOG_ERROR, "Decoding map for format 0x06\n");
1243  return AVERROR_INVALIDDATA;
1244  }
1245 
1246  if (s->skip_map_size) {
1247  av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x06\n");
1248  return AVERROR_INVALIDDATA;
1249  }
1250 
1251  if (s->is_16bpp) {
1252  av_log(avctx, AV_LOG_ERROR, "Video format 0x06 does not support 16bpp movies\n");
1253  return AVERROR_INVALIDDATA;
1254  }
1255 
1256  /* Decoding map for 0x06 frame format is at the top of pixeldata */
1257  s->decoding_map_size = ((s->avctx->width / 8) * (s->avctx->height / 8)) * 2;
1258  s->decoding_map = buf + 8 + 14; /* 14 bits of op data */
1259  video_data_size -= s->decoding_map_size + 14;
1260  if (video_data_size <= 0 || s->decoding_map_size == 0)
1261  return AVERROR_INVALIDDATA;
1262 
1263  if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
1264  return AVERROR_INVALIDDATA;
1265 
1266  bytestream2_init(&s->stream_ptr, buf + 8 + s->decoding_map_size + 14, video_data_size);
1267 
1268  break;
1269 
1270  case 0x10:
1271  if (! s->decoding_map_size) {
1272  av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x10\n");
1273  return AVERROR_INVALIDDATA;
1274  }
1275 
1276  if (! s->skip_map_size) {
1277  av_log(avctx, AV_LOG_ERROR, "Empty skip map for format 0x10\n");
1278  return AVERROR_INVALIDDATA;
1279  }
1280 
1281  if (s->is_16bpp) {
1282  av_log(avctx, AV_LOG_ERROR, "Video format 0x10 does not support 16bpp movies\n");
1283  return AVERROR_INVALIDDATA;
1284  }
1285 
1286  if (buf_size < 8 + video_data_size + s->decoding_map_size + s->skip_map_size)
1287  return AVERROR_INVALIDDATA;
1288 
1289  bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1290  s->decoding_map = buf + 8 + video_data_size;
1291  s->skip_map = buf + 8 + video_data_size + s->decoding_map_size;
1292 
1293  break;
1294 
1295  case 0x11:
1296  if (! s->decoding_map_size) {
1297  av_log(avctx, AV_LOG_ERROR, "Empty decoding map for format 0x11\n");
1298  return AVERROR_INVALIDDATA;
1299  }
1300 
1301  if (s->skip_map_size) {
1302  av_log(avctx, AV_LOG_ERROR, "Skip map for format 0x11\n");
1303  return AVERROR_INVALIDDATA;
1304  }
1305 
1306  if (buf_size < 8 + video_data_size + s->decoding_map_size)
1307  return AVERROR_INVALIDDATA;
1308 
1309  bytestream2_init(&s->stream_ptr, buf + 8, video_data_size);
1310  s->decoding_map = buf + 8 + video_data_size;
1311 
1312  break;
1313 
1314  default:
1315  av_log(avctx, AV_LOG_ERROR, "Frame type 0x%02X unsupported\n", frame_format);
1316  }
1317 
1318  /* ensure we can't overread the packet */
1319  if (buf_size < 8 + s->decoding_map_size + video_data_size + s->skip_map_size) {
1320  av_log(avctx, AV_LOG_ERROR, "Invalid IP packet size\n");
1321  return AVERROR_INVALIDDATA;
1322  }
1323 
1324  if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
1325  return ret;
1326 
1327  if (!s->is_16bpp) {
1328  int size;
1329  const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
1330  if (pal && size == AVPALETTE_SIZE) {
1331  frame->palette_has_changed = 1;
1332  memcpy(s->pal, pal, AVPALETTE_SIZE);
1333  } else if (pal) {
1334  av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
1335  }
1336  }
1337 
1338  switch (frame_format) {
1339  case 0x06:
1341  break;
1342  case 0x10:
1344  break;
1345  case 0x11:
1347  break;
1348  }
1349 
1350  *got_frame = send_buffer;
1351 
1352  /* shuffle frames */
1355  if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
1356  return ret;
1357 
1358  /* report that the buffer was completely consumed */
1359  return buf_size;
1360 }
1361 
1363 {
1364  IpvideoContext *s = avctx->priv_data;
1365 
1370 
1371  return 0;
1372 }
1373 
1375  .name = "interplayvideo",
1376  .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
1377  .type = AVMEDIA_TYPE_VIDEO,
1379  .priv_data_size = sizeof(IpvideoContext),
1381  .close = ipvideo_decode_end,
1383  .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_PARAM_CHANGE,
1384 };
#define ff_tlog(ctx,...)
Definition: internal.h:75
#define NULL
Definition: coverity.c:32
#define P
#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
const unsigned char * decoding_map
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static void ipvideo_format_06_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
unsigned char * pixel_ptr
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static void(*const ipvideo_format_06_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op)
int size
Definition: avcodec.h:1481
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:133
static void(*const ipvideo_format_10_passes[])(IpvideoContext *s, AVFrame *frame, int16_t op)
static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
#define src
Definition: vp8dsp.c:254
#define sample
AVCodec.
Definition: avcodec.h:3492
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_RL16
Definition: bytestream.h:87
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static void ipvideo_decode_format_11_opcodes(IpvideoContext *s, AVFrame *frame)
static int(*const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame)
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
static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
8 bits with AV_PIX_FMT_RGB32 palette
Definition: pixfmt.h:77
#define AVPALETTE_SIZE
Definition: pixfmt.h:32
static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
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
static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
static void ipvideo_format_10_secondpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
uint8_t * data
Definition: avcodec.h:1480
bitstream reader API header.
static void ipvideo_format_06_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
ptrdiff_t size
Definition: opengl_enc.c:100
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2792
#define av_log(a,...)
#define AV_RL8(x)
Definition: intreadwrite.h:398
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
AVFrame * last_frame
static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette...
Definition: avcodec.h:1193
An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
Definition: avcodec.h:1219
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:164
uint8_t * av_packet_get_side_data(const AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:350
static void ipvideo_decode_format_10_opcodes(IpvideoContext *s, AVFrame *frame)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define B
Definition: huffyuvdsp.h:32
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:263
static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:154
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1648
static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
static void ipvideo_decode_format_06_opcodes(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0xC_16(IpvideoContext *s, AVFrame *frame)
GetByteContext stream_ptr
static int ipvideo_decode_block_opcode_0x0(IpvideoContext *s, AVFrame *frame)
#define pass
Definition: fft_template.c:619
av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
Definition: hpeldsp.c:338
Half-pel DSP context.
Definition: hpeldsp.h:45
static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
#define width
int width
picture width / height.
Definition: avcodec.h:1741
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
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
static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
#define s(width, name)
Definition: cbs_vp9.c:257
static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
static int ipvideo_decode_block_opcode_0x1(IpvideoContext *s, AVFrame *frame)
AVFrame * second_last_frame
static void error(const char *err)
if(ret)
static av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:188
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
Half-pel DSP functions.
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
main external API structure.
Definition: avcodec.h:1568
static int ipvideo_decode_block_opcode_0x6(IpvideoContext *s, AVFrame *frame)
GetByteContext mv_ptr
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1968
op_pixels_func put_pixels_tab[4][4]
Halfpel motion compensation with rounding (a+b+1)>>1.
Definition: hpeldsp.h:56
HpelDSPContext hdsp
void * buf
Definition: avisynth_c.h:766
static int ipvideo_decode_block_opcode_0xD_16(IpvideoContext *s, AVFrame *frame)
AVCodecContext * avctx
static av_cold int ipvideo_decode_init(AVCodecContext *avctx)
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:452
AVFrame * cur_decode_frame
static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
static void ipvideo_format_10_firstpass(IpvideoContext *s, AVFrame *frame, int16_t opcode)
AVCodec ff_interplay_video_decoder
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
#define flags(name, subs,...)
Definition: cbs_av1.c:561
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:78
uint32_t pal[256]
int
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:33
common internal api header.
static int ipvideo_decode_block_opcode_0x9_16(IpvideoContext *s, AVFrame *frame)
#define AV_CODEC_CAP_PARAM_CHANGE
Codec supports changed parameters at any point.
Definition: avcodec.h:1048
int upper_motion_limit_offset
AVFrame * prev_decode_frame
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:375
static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
void * priv_data
Definition: avcodec.h:1595
const unsigned char * skip_map
static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:208
static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
int frame_number
Frame counter, set by libavcodec.
Definition: avcodec.h:2259
int height
Definition: frame.h:353
static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
#define FFSWAP(type, a, b)
Definition: common.h:99
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
static int(*const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0xC(IpvideoContext *s, AVFrame *frame)
This structure stores compressed data.
Definition: avcodec.h:1457
static int ipvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
Definition: avcodec.h:1179
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: avcodec.h:984
for(j=16;j >0;--j)