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 "avcodec.h"
42 #include "bytestream.h"
43 #include "hpeldsp.h"
44 #define BITSTREAM_READER_LE
45 #include "get_bits.h"
46 #include "internal.h"
47 
48 #define PALETTE_COUNT 256
49 
50 typedef struct IpvideoContext {
51 
56  const unsigned char *decoding_map;
58 
59  int is_16bpp;
61  unsigned char *pixel_ptr;
62  int line_inc;
63  int stride;
65 
66  uint32_t pal[256];
68 
69 static int copy_from(IpvideoContext *s, AVFrame *src, AVFrame *dst, int delta_x, int delta_y)
70 {
71  int current_offset = s->pixel_ptr - dst->data[0];
72  int motion_offset = current_offset + delta_y * dst->linesize[0]
73  + delta_x * (1 + s->is_16bpp);
74  if (motion_offset < 0) {
75  av_log(s->avctx, AV_LOG_ERROR, "motion offset < 0 (%d)\n", motion_offset);
76  return AVERROR_INVALIDDATA;
77  } else if (motion_offset > s->upper_motion_limit_offset) {
78  av_log(s->avctx, AV_LOG_ERROR, "motion offset above limit (%d >= %d)\n",
79  motion_offset, s->upper_motion_limit_offset);
80  return AVERROR_INVALIDDATA;
81  }
82  if (src->data[0] == NULL) {
83  av_log(s->avctx, AV_LOG_ERROR, "Invalid decode type, corrupted header?\n");
84  return AVERROR(EINVAL);
85  }
86  s->hdsp.put_pixels_tab[!s->is_16bpp][0](s->pixel_ptr, src->data[0] + motion_offset,
87  dst->linesize[0], 8);
88  return 0;
89 }
90 
92 {
93  return copy_from(s, s->last_frame, frame, 0, 0);
94 }
95 
97 {
98  return copy_from(s, s->second_last_frame, frame, 0, 0);
99 }
100 
102 {
103  unsigned char B;
104  int x, y;
105 
106  /* copy block from 2 frames ago using a motion vector; need 1 more byte */
107  if (!s->is_16bpp) {
108  B = bytestream2_get_byte(&s->stream_ptr);
109  } else {
110  B = bytestream2_get_byte(&s->mv_ptr);
111  }
112 
113  if (B < 56) {
114  x = 8 + (B % 7);
115  y = B / 7;
116  } else {
117  x = -14 + ((B - 56) % 29);
118  y = 8 + ((B - 56) / 29);
119  }
120 
121  av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
122  return copy_from(s, s->second_last_frame, frame, x, y);
123 }
124 
126 {
127  unsigned char B;
128  int x, y;
129 
130  /* copy 8x8 block from current frame from an up/left block */
131 
132  /* need 1 more byte for motion */
133  if (!s->is_16bpp) {
134  B = bytestream2_get_byte(&s->stream_ptr);
135  } else {
136  B = bytestream2_get_byte(&s->mv_ptr);
137  }
138 
139  if (B < 56) {
140  x = -(8 + (B % 7));
141  y = -(B / 7);
142  } else {
143  x = -(-14 + ((B - 56) % 29));
144  y = -( 8 + ((B - 56) / 29));
145  }
146 
147  av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
148  return copy_from(s, frame, frame, x, y);
149 }
150 
152 {
153  int x, y;
154  unsigned char B, BL, BH;
155 
156  /* copy a block from the previous frame; need 1 more byte */
157  if (!s->is_16bpp) {
158  B = bytestream2_get_byte(&s->stream_ptr);
159  } else {
160  B = bytestream2_get_byte(&s->mv_ptr);
161  }
162 
163  BL = B & 0x0F;
164  BH = (B >> 4) & 0x0F;
165  x = -8 + BL;
166  y = -8 + BH;
167 
168  av_dlog(s->avctx, "motion byte = %d, (x, y) = (%d, %d)\n", B, x, y);
169  return copy_from(s, s->last_frame, frame, x, y);
170 }
171 
173 {
174  signed char x, y;
175 
176  /* copy a block from the previous frame using an expanded range;
177  * need 2 more bytes */
178  x = bytestream2_get_byte(&s->stream_ptr);
179  y = bytestream2_get_byte(&s->stream_ptr);
180 
181  av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
182  return copy_from(s, s->last_frame, frame, x, y);
183 }
184 
186 {
187  /* mystery opcode? skip multiple blocks? */
188  av_log(s->avctx, AV_LOG_ERROR, "Help! Mystery opcode 0x6 seen\n");
189 
190  /* report success */
191  return 0;
192 }
193 
195 {
196  int x, y;
197  unsigned char P[2];
198  unsigned int flags;
199 
200  /* 2-color encoding */
201  P[0] = bytestream2_get_byte(&s->stream_ptr);
202  P[1] = bytestream2_get_byte(&s->stream_ptr);
203 
204  if (P[0] <= P[1]) {
205 
206  /* need 8 more bytes from the stream */
207  for (y = 0; y < 8; y++) {
208  flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
209  for (; flags != 1; flags >>= 1)
210  *s->pixel_ptr++ = P[flags & 1];
211  s->pixel_ptr += s->line_inc;
212  }
213 
214  } else {
215 
216  /* need 2 more bytes from the stream */
217  flags = bytestream2_get_le16(&s->stream_ptr);
218  for (y = 0; y < 8; y += 2) {
219  for (x = 0; x < 8; x += 2, flags >>= 1) {
220  s->pixel_ptr[x ] =
221  s->pixel_ptr[x + 1 ] =
222  s->pixel_ptr[x + s->stride] =
223  s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];
224  }
225  s->pixel_ptr += s->stride * 2;
226  }
227  }
228 
229  /* report success */
230  return 0;
231 }
232 
234 {
235  int x, y;
236  unsigned char P[4];
237  unsigned int flags = 0;
238 
239  /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
240  * either top and bottom or left and right halves */
241  P[0] = bytestream2_get_byte(&s->stream_ptr);
242  P[1] = bytestream2_get_byte(&s->stream_ptr);
243 
244  if (P[0] <= P[1]) {
245  for (y = 0; y < 16; y++) {
246  // new values for each 4x4 block
247  if (!(y & 3)) {
248  if (y) {
249  P[0] = bytestream2_get_byte(&s->stream_ptr);
250  P[1] = bytestream2_get_byte(&s->stream_ptr);
251  }
252  flags = bytestream2_get_le16(&s->stream_ptr);
253  }
254 
255  for (x = 0; x < 4; x++, flags >>= 1)
256  *s->pixel_ptr++ = P[flags & 1];
257  s->pixel_ptr += s->stride - 4;
258  // switch to right half
259  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
260  }
261 
262  } else {
263  flags = bytestream2_get_le32(&s->stream_ptr);
264  P[2] = bytestream2_get_byte(&s->stream_ptr);
265  P[3] = bytestream2_get_byte(&s->stream_ptr);
266 
267  if (P[2] <= P[3]) {
268 
269  /* vertical split; left & right halves are 2-color encoded */
270 
271  for (y = 0; y < 16; y++) {
272  for (x = 0; x < 4; x++, flags >>= 1)
273  *s->pixel_ptr++ = P[flags & 1];
274  s->pixel_ptr += s->stride - 4;
275  // switch to right half
276  if (y == 7) {
277  s->pixel_ptr -= 8 * s->stride - 4;
278  P[0] = P[2];
279  P[1] = P[3];
280  flags = bytestream2_get_le32(&s->stream_ptr);
281  }
282  }
283 
284  } else {
285 
286  /* horizontal split; top & bottom halves are 2-color encoded */
287 
288  for (y = 0; y < 8; y++) {
289  if (y == 4) {
290  P[0] = P[2];
291  P[1] = P[3];
292  flags = bytestream2_get_le32(&s->stream_ptr);
293  }
294 
295  for (x = 0; x < 8; x++, flags >>= 1)
296  *s->pixel_ptr++ = P[flags & 1];
297  s->pixel_ptr += s->line_inc;
298  }
299  }
300  }
301 
302  /* report success */
303  return 0;
304 }
305 
307 {
308  int x, y;
309  unsigned char P[4];
310 
311  /* 4-color encoding */
313 
314  if (P[0] <= P[1]) {
315  if (P[2] <= P[3]) {
316 
317  /* 1 of 4 colors for each pixel, need 16 more bytes */
318  for (y = 0; y < 8; y++) {
319  /* get the next set of 8 2-bit flags */
320  int flags = bytestream2_get_le16(&s->stream_ptr);
321  for (x = 0; x < 8; x++, flags >>= 2)
322  *s->pixel_ptr++ = P[flags & 0x03];
323  s->pixel_ptr += s->line_inc;
324  }
325 
326  } else {
327  uint32_t flags;
328 
329  /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
330  flags = bytestream2_get_le32(&s->stream_ptr);
331 
332  for (y = 0; y < 8; y += 2) {
333  for (x = 0; x < 8; x += 2, flags >>= 2) {
334  s->pixel_ptr[x ] =
335  s->pixel_ptr[x + 1 ] =
336  s->pixel_ptr[x + s->stride] =
337  s->pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
338  }
339  s->pixel_ptr += s->stride * 2;
340  }
341 
342  }
343  } else {
344  uint64_t flags;
345 
346  /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
347  flags = bytestream2_get_le64(&s->stream_ptr);
348  if (P[2] <= P[3]) {
349  for (y = 0; y < 8; y++) {
350  for (x = 0; x < 8; x += 2, flags >>= 2) {
351  s->pixel_ptr[x ] =
352  s->pixel_ptr[x + 1] = P[flags & 0x03];
353  }
354  s->pixel_ptr += s->stride;
355  }
356  } else {
357  for (y = 0; y < 8; y += 2) {
358  for (x = 0; x < 8; x++, flags >>= 2) {
359  s->pixel_ptr[x ] =
360  s->pixel_ptr[x + s->stride] = P[flags & 0x03];
361  }
362  s->pixel_ptr += s->stride * 2;
363  }
364  }
365  }
366 
367  /* report success */
368  return 0;
369 }
370 
372 {
373  int x, y;
374  unsigned char P[8];
375  int flags = 0;
376 
378 
379  /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
380  * either top and bottom or left and right halves */
381  if (P[0] <= P[1]) {
382 
383  /* 4-color encoding for each quadrant; need 32 bytes */
384  for (y = 0; y < 16; y++) {
385  // new values for each 4x4 block
386  if (!(y & 3)) {
387  if (y) bytestream2_get_buffer(&s->stream_ptr, P, 4);
388  flags = bytestream2_get_le32(&s->stream_ptr);
389  }
390 
391  for (x = 0; x < 4; x++, flags >>= 2)
392  *s->pixel_ptr++ = P[flags & 0x03];
393 
394  s->pixel_ptr += s->stride - 4;
395  // switch to right half
396  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
397  }
398 
399  } else {
400  // vertical split?
401  int vert;
402  uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
403 
404  bytestream2_get_buffer(&s->stream_ptr, P + 4, 4);
405  vert = P[4] <= P[5];
406 
407  /* 4-color encoding for either left and right or top and bottom
408  * halves */
409 
410  for (y = 0; y < 16; y++) {
411  for (x = 0; x < 4; x++, flags >>= 2)
412  *s->pixel_ptr++ = P[flags & 0x03];
413 
414  if (vert) {
415  s->pixel_ptr += s->stride - 4;
416  // switch to right half
417  if (y == 7) s->pixel_ptr -= 8 * s->stride - 4;
418  } else if (y & 1) s->pixel_ptr += s->line_inc;
419 
420  // load values for second half
421  if (y == 7) {
422  memcpy(P, P + 4, 4);
423  flags = bytestream2_get_le64(&s->stream_ptr);
424  }
425  }
426  }
427 
428  /* report success */
429  return 0;
430 }
431 
433 {
434  int y;
435 
436  /* 64-color encoding (each pixel in block is a different color) */
437  for (y = 0; y < 8; y++) {
439  s->pixel_ptr += s->stride;
440  }
441 
442  /* report success */
443  return 0;
444 }
445 
447 {
448  int x, y;
449 
450  /* 16-color block encoding: each 2x2 block is a different color */
451  for (y = 0; y < 8; y += 2) {
452  for (x = 0; x < 8; x += 2) {
453  s->pixel_ptr[x ] =
454  s->pixel_ptr[x + 1 ] =
455  s->pixel_ptr[x + s->stride] =
456  s->pixel_ptr[x + 1 + s->stride] = bytestream2_get_byte(&s->stream_ptr);
457  }
458  s->pixel_ptr += s->stride * 2;
459  }
460 
461  /* report success */
462  return 0;
463 }
464 
466 {
467  int y;
468  unsigned char P[2];
469 
470  /* 4-color block encoding: each 4x4 block is a different color */
471  for (y = 0; y < 8; y++) {
472  if (!(y & 3)) {
473  P[0] = bytestream2_get_byte(&s->stream_ptr);
474  P[1] = bytestream2_get_byte(&s->stream_ptr);
475  }
476  memset(s->pixel_ptr, P[0], 4);
477  memset(s->pixel_ptr + 4, P[1], 4);
478  s->pixel_ptr += s->stride;
479  }
480 
481  /* report success */
482  return 0;
483 }
484 
486 {
487  int y;
488  unsigned char pix;
489 
490  /* 1-color encoding: the whole block is 1 solid color */
491  pix = bytestream2_get_byte(&s->stream_ptr);
492 
493  for (y = 0; y < 8; y++) {
494  memset(s->pixel_ptr, pix, 8);
495  s->pixel_ptr += s->stride;
496  }
497 
498  /* report success */
499  return 0;
500 }
501 
503 {
504  int x, y;
505  unsigned char sample[2];
506 
507  /* dithered encoding */
508  sample[0] = bytestream2_get_byte(&s->stream_ptr);
509  sample[1] = bytestream2_get_byte(&s->stream_ptr);
510 
511  for (y = 0; y < 8; y++) {
512  for (x = 0; x < 8; x += 2) {
513  *s->pixel_ptr++ = sample[ y & 1 ];
514  *s->pixel_ptr++ = sample[!(y & 1)];
515  }
516  s->pixel_ptr += s->line_inc;
517  }
518 
519  /* report success */
520  return 0;
521 }
522 
524 {
525  signed char x, y;
526 
527  /* copy a block from the second last frame using an expanded range */
528  x = bytestream2_get_byte(&s->stream_ptr);
529  y = bytestream2_get_byte(&s->stream_ptr);
530 
531  av_dlog(s->avctx, "motion bytes = %d, %d\n", x, y);
532  return copy_from(s, s->second_last_frame, frame, x, y);
533 }
534 
536 {
537  int x, y;
538  uint16_t P[2];
539  unsigned int flags;
540  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
541 
542  /* 2-color encoding */
543  P[0] = bytestream2_get_le16(&s->stream_ptr);
544  P[1] = bytestream2_get_le16(&s->stream_ptr);
545 
546  if (!(P[0] & 0x8000)) {
547 
548  for (y = 0; y < 8; y++) {
549  flags = bytestream2_get_byte(&s->stream_ptr) | 0x100;
550  for (; flags != 1; flags >>= 1)
551  *pixel_ptr++ = P[flags & 1];
552  pixel_ptr += s->line_inc;
553  }
554 
555  } else {
556 
557  flags = bytestream2_get_le16(&s->stream_ptr);
558  for (y = 0; y < 8; y += 2) {
559  for (x = 0; x < 8; x += 2, flags >>= 1) {
560  pixel_ptr[x ] =
561  pixel_ptr[x + 1 ] =
562  pixel_ptr[x + s->stride] =
563  pixel_ptr[x + 1 + s->stride] = P[flags & 1];
564  }
565  pixel_ptr += s->stride * 2;
566  }
567  }
568 
569  return 0;
570 }
571 
573 {
574  int x, y;
575  uint16_t P[4];
576  unsigned int flags = 0;
577  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
578 
579  /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
580  * either top and bottom or left and right halves */
581  P[0] = bytestream2_get_le16(&s->stream_ptr);
582  P[1] = bytestream2_get_le16(&s->stream_ptr);
583 
584  if (!(P[0] & 0x8000)) {
585 
586  for (y = 0; y < 16; y++) {
587  // new values for each 4x4 block
588  if (!(y & 3)) {
589  if (y) {
590  P[0] = bytestream2_get_le16(&s->stream_ptr);
591  P[1] = bytestream2_get_le16(&s->stream_ptr);
592  }
593  flags = bytestream2_get_le16(&s->stream_ptr);
594  }
595 
596  for (x = 0; x < 4; x++, flags >>= 1)
597  *pixel_ptr++ = P[flags & 1];
598  pixel_ptr += s->stride - 4;
599  // switch to right half
600  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
601  }
602 
603  } else {
604 
605  flags = bytestream2_get_le32(&s->stream_ptr);
606  P[2] = bytestream2_get_le16(&s->stream_ptr);
607  P[3] = bytestream2_get_le16(&s->stream_ptr);
608 
609  if (!(P[2] & 0x8000)) {
610 
611  /* vertical split; left & right halves are 2-color encoded */
612 
613  for (y = 0; y < 16; y++) {
614  for (x = 0; x < 4; x++, flags >>= 1)
615  *pixel_ptr++ = P[flags & 1];
616  pixel_ptr += s->stride - 4;
617  // switch to right half
618  if (y == 7) {
619  pixel_ptr -= 8 * s->stride - 4;
620  P[0] = P[2];
621  P[1] = P[3];
622  flags = bytestream2_get_le32(&s->stream_ptr);
623  }
624  }
625 
626  } else {
627 
628  /* horizontal split; top & bottom halves are 2-color encoded */
629 
630  for (y = 0; y < 8; y++) {
631  if (y == 4) {
632  P[0] = P[2];
633  P[1] = P[3];
634  flags = bytestream2_get_le32(&s->stream_ptr);
635  }
636 
637  for (x = 0; x < 8; x++, flags >>= 1)
638  *pixel_ptr++ = P[flags & 1];
639  pixel_ptr += s->line_inc;
640  }
641  }
642  }
643 
644  /* report success */
645  return 0;
646 }
647 
649 {
650  int x, y;
651  uint16_t P[4];
652  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
653 
654  /* 4-color encoding */
655  for (x = 0; x < 4; x++)
656  P[x] = bytestream2_get_le16(&s->stream_ptr);
657 
658  if (!(P[0] & 0x8000)) {
659  if (!(P[2] & 0x8000)) {
660 
661  /* 1 of 4 colors for each pixel */
662  for (y = 0; y < 8; y++) {
663  /* get the next set of 8 2-bit flags */
664  int flags = bytestream2_get_le16(&s->stream_ptr);
665  for (x = 0; x < 8; x++, flags >>= 2)
666  *pixel_ptr++ = P[flags & 0x03];
667  pixel_ptr += s->line_inc;
668  }
669 
670  } else {
671  uint32_t flags;
672 
673  /* 1 of 4 colors for each 2x2 block */
674  flags = bytestream2_get_le32(&s->stream_ptr);
675 
676  for (y = 0; y < 8; y += 2) {
677  for (x = 0; x < 8; x += 2, flags >>= 2) {
678  pixel_ptr[x ] =
679  pixel_ptr[x + 1 ] =
680  pixel_ptr[x + s->stride] =
681  pixel_ptr[x + 1 + s->stride] = P[flags & 0x03];
682  }
683  pixel_ptr += s->stride * 2;
684  }
685 
686  }
687  } else {
688  uint64_t flags;
689 
690  /* 1 of 4 colors for each 2x1 or 1x2 block */
691  flags = bytestream2_get_le64(&s->stream_ptr);
692  if (!(P[2] & 0x8000)) {
693  for (y = 0; y < 8; y++) {
694  for (x = 0; x < 8; x += 2, flags >>= 2) {
695  pixel_ptr[x ] =
696  pixel_ptr[x + 1] = P[flags & 0x03];
697  }
698  pixel_ptr += s->stride;
699  }
700  } else {
701  for (y = 0; y < 8; y += 2) {
702  for (x = 0; x < 8; x++, flags >>= 2) {
703  pixel_ptr[x ] =
704  pixel_ptr[x + s->stride] = P[flags & 0x03];
705  }
706  pixel_ptr += s->stride * 2;
707  }
708  }
709  }
710 
711  /* report success */
712  return 0;
713 }
714 
716 {
717  int x, y;
718  uint16_t P[8];
719  int flags = 0;
720  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
721 
722  for (x = 0; x < 4; x++)
723  P[x] = bytestream2_get_le16(&s->stream_ptr);
724 
725  /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
726  * either top and bottom or left and right halves */
727  if (!(P[0] & 0x8000)) {
728 
729  /* 4-color encoding for each quadrant */
730  for (y = 0; y < 16; y++) {
731  // new values for each 4x4 block
732  if (!(y & 3)) {
733  if (y)
734  for (x = 0; x < 4; x++)
735  P[x] = bytestream2_get_le16(&s->stream_ptr);
736  flags = bytestream2_get_le32(&s->stream_ptr);
737  }
738 
739  for (x = 0; x < 4; x++, flags >>= 2)
740  *pixel_ptr++ = P[flags & 0x03];
741 
742  pixel_ptr += s->stride - 4;
743  // switch to right half
744  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
745  }
746 
747  } else {
748  // vertical split?
749  int vert;
750  uint64_t flags = bytestream2_get_le64(&s->stream_ptr);
751 
752  for (x = 4; x < 8; x++)
753  P[x] = bytestream2_get_le16(&s->stream_ptr);
754  vert = !(P[4] & 0x8000);
755 
756  /* 4-color encoding for either left and right or top and bottom
757  * halves */
758 
759  for (y = 0; y < 16; y++) {
760  for (x = 0; x < 4; x++, flags >>= 2)
761  *pixel_ptr++ = P[flags & 0x03];
762 
763  if (vert) {
764  pixel_ptr += s->stride - 4;
765  // switch to right half
766  if (y == 7) pixel_ptr -= 8 * s->stride - 4;
767  } else if (y & 1) pixel_ptr += s->line_inc;
768 
769  // load values for second half
770  if (y == 7) {
771  memcpy(P, P + 4, 8);
772  flags = bytestream2_get_le64(&s->stream_ptr);
773  }
774  }
775  }
776 
777  /* report success */
778  return 0;
779 }
780 
782 {
783  int x, y;
784  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
785 
786  /* 64-color encoding (each pixel in block is a different color) */
787  for (y = 0; y < 8; y++) {
788  for (x = 0; x < 8; x++)
789  pixel_ptr[x] = bytestream2_get_le16(&s->stream_ptr);
790  pixel_ptr += s->stride;
791  }
792 
793  /* report success */
794  return 0;
795 }
796 
798 {
799  int x, y;
800  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
801 
802  /* 16-color block encoding: each 2x2 block is a different color */
803  for (y = 0; y < 8; y += 2) {
804  for (x = 0; x < 8; x += 2) {
805  pixel_ptr[x ] =
806  pixel_ptr[x + 1 ] =
807  pixel_ptr[x + s->stride] =
808  pixel_ptr[x + 1 + s->stride] = bytestream2_get_le16(&s->stream_ptr);
809  }
810  pixel_ptr += s->stride * 2;
811  }
812 
813  /* report success */
814  return 0;
815 }
816 
818 {
819  int x, y;
820  uint16_t P[2];
821  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
822 
823  /* 4-color block encoding: each 4x4 block is a different color */
824  for (y = 0; y < 8; y++) {
825  if (!(y & 3)) {
826  P[0] = bytestream2_get_le16(&s->stream_ptr);
827  P[1] = bytestream2_get_le16(&s->stream_ptr);
828  }
829  for (x = 0; x < 8; x++)
830  pixel_ptr[x] = P[x >> 2];
831  pixel_ptr += s->stride;
832  }
833 
834  /* report success */
835  return 0;
836 }
837 
839 {
840  int x, y;
841  uint16_t pix;
842  uint16_t *pixel_ptr = (uint16_t*)s->pixel_ptr;
843 
844  /* 1-color encoding: the whole block is 1 solid color */
845  pix = bytestream2_get_le16(&s->stream_ptr);
846 
847  for (y = 0; y < 8; y++) {
848  for (x = 0; x < 8; x++)
849  pixel_ptr[x] = pix;
850  pixel_ptr += s->stride;
851  }
852 
853  /* report success */
854  return 0;
855 }
856 
857 static int (* const ipvideo_decode_block[])(IpvideoContext *s, AVFrame *frame) = {
866 };
867 
868 static int (* const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame) = {
877 };
878 
880 {
881  int x, y;
882  unsigned char opcode;
883  int ret;
884  GetBitContext gb;
885 
886  bytestream2_skip(&s->stream_ptr, 14); /* data starts 14 bytes in */
887  if (!s->is_16bpp) {
888  /* this is PAL8, so make the palette available */
889  memcpy(frame->data[1], s->pal, AVPALETTE_SIZE);
890 
891  s->stride = frame->linesize[0];
892  } else {
893  s->stride = frame->linesize[0] >> 1;
894  s->mv_ptr = s->stream_ptr;
895  bytestream2_skip(&s->mv_ptr, bytestream2_get_le16(&s->stream_ptr));
896  }
897  s->line_inc = s->stride - 8;
898  s->upper_motion_limit_offset = (s->avctx->height - 8) * frame->linesize[0]
899  + (s->avctx->width - 8) * (1 + s->is_16bpp);
900 
902  for (y = 0; y < s->avctx->height; y += 8) {
903  for (x = 0; x < s->avctx->width; x += 8) {
904  opcode = get_bits(&gb, 4);
905 
906  av_dlog(s->avctx,
907  " block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
908  x, y, opcode, bytestream2_tell(&s->stream_ptr));
909 
910  if (!s->is_16bpp) {
911  s->pixel_ptr = frame->data[0] + x
912  + y*frame->linesize[0];
913  ret = ipvideo_decode_block[opcode](s, frame);
914  } else {
915  s->pixel_ptr = frame->data[0] + x*2
916  + y*frame->linesize[0];
917  ret = ipvideo_decode_block16[opcode](s, frame);
918  }
919  if (ret != 0) {
920  av_log(s->avctx, AV_LOG_ERROR, "decode problem on frame %d, @ block (%d, %d)\n",
921  s->avctx->frame_number, x, y);
922  return;
923  }
924  }
925  }
926  if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) {
928  "decode finished with %d bytes left over\n",
930  }
931 }
932 
934 {
935  IpvideoContext *s = avctx->priv_data;
936 
937  s->avctx = avctx;
938 
939  s->is_16bpp = avctx->bits_per_coded_sample == 16;
941 
942  ff_hpeldsp_init(&s->hdsp, avctx->flags);
943 
944  s->last_frame = av_frame_alloc();
946  if (!s->last_frame || !s->second_last_frame) {
949  return AVERROR(ENOMEM);
950  }
951 
952  return 0;
953 }
954 
956  void *data, int *got_frame,
957  AVPacket *avpkt)
958 {
959  const uint8_t *buf = avpkt->data;
960  int buf_size = avpkt->size;
961  IpvideoContext *s = avctx->priv_data;
962  AVFrame *frame = data;
963  int ret;
964 
965  /* decoding map contains 4 bits of information per 8x8 block */
966  s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
967 
968  /* compressed buffer needs to be large enough to at least hold an entire
969  * decoding map */
970  if (buf_size < s->decoding_map_size)
971  return buf_size;
972 
976  }
977 
978  s->decoding_map = buf;
980  buf_size - s->decoding_map_size);
981 
982  if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
983  return ret;
984 
985  if (!s->is_16bpp) {
987  if (pal) {
988  frame->palette_has_changed = 1;
989  memcpy(s->pal, pal, AVPALETTE_SIZE);
990  }
991  }
992 
993  ipvideo_decode_opcodes(s, frame);
994 
995  *got_frame = 1;
996 
997  /* shuffle frames */
1000  if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
1001  return ret;
1002 
1003  /* report that the buffer was completely consumed */
1004  return buf_size;
1005 }
1006 
1008 {
1009  IpvideoContext *s = avctx->priv_data;
1010 
1013 
1014  return 0;
1015 }
1016 
1018  .name = "interplayvideo",
1019  .type = AVMEDIA_TYPE_VIDEO,
1021  .priv_data_size = sizeof(IpvideoContext),
1025  .capabilities = CODEC_CAP_DR1 | CODEC_CAP_PARAM_CHANGE,
1026  .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE video"),
1027 };
const char * s
Definition: avisynth_c.h:668
#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:76
const unsigned char * decoding_map
#define B
Definition: dsputil.c:2025
unsigned char * pixel_ptr
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static int ipvideo_decode_block_opcode_0x4(IpvideoContext *s, AVFrame *frame)
#define sample
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
static int(*const ipvideo_decode_block16[])(IpvideoContext *s, AVFrame *frame)
uint8_t
#define av_cold
Definition: attributes.h:78
static int ipvideo_decode_block_opcode_0xA(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0x2(IpvideoContext *s, AVFrame *frame)
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
static int ipvideo_decode_block_opcode_0x9(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0x7_16(IpvideoContext *s, AVFrame *frame)
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
bitstream reader API header.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
frame
Definition: stft.m:14
Discrete Time axis x
AVFrame * last_frame
static int ipvideo_decode_block_opcode_0x5(IpvideoContext *s, AVFrame *frame)
static int ipvideo_decode_block_opcode_0x8_16(IpvideoContext *s, AVFrame *frame)
#define CODEC_CAP_PARAM_CHANGE
Codec supports changed parameters at any point.
An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static int ipvideo_decode_block_opcode_0xD(IpvideoContext *s, AVFrame *frame)
Spectrum Plot time data
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:258
static int ipvideo_decode_block_opcode_0xE_16(IpvideoContext *s, AVFrame *frame)
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
int flags
CODEC_FLAG_*.
static av_cold int ipvideo_decode_end(AVCodecContext *avctx)
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
external API header
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)
av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
Definition: hpeldsp.c:37
Half-pel DSP context.
Definition: hpeldsp.h:45
static int ipvideo_decode_block_opcode_0x8(IpvideoContext *s, AVFrame *frame)
ret
Definition: avfilter.c:821
int width
picture width / height.
static int ipvideo_decode_block_opcode_0x3(IpvideoContext *s, AVFrame *frame)
struct IpvideoContext IpvideoContext
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 av_always_inline int bytestream2_tell(GetByteContext *g)
Definition: bytestream.h:183
NULL
Definition: eval.c:55
Half-pel DSP functions.
AVS_Value src
Definition: avisynth_c.h:523
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
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.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
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:594
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:379
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:280
static int ipvideo_decode_block_opcode_0x6_16(IpvideoContext *s, AVFrame *frame)
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:330
AVCodec ff_interplay_video_decoder
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
static int ipvideo_decode_block_opcode_0xB_16(IpvideoContext *s, AVFrame *frame)
static int flags
Definition: cpu.c:23
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
static int ipvideo_decode_block_opcode_0xE(IpvideoContext *s, AVFrame *frame)
uint32_t pal[256]
static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame)
common internal api header.
static int ipvideo_decode_block_opcode_0x9_16(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:108
int upper_motion_limit_offset
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:269
static int ipvideo_decode_block_opcode_0xF(IpvideoContext *s, AVFrame *frame)
function y
Definition: D.m:1
static int ipvideo_decode_block_opcode_0xB(IpvideoContext *s, AVFrame *frame)
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
static int ipvideo_decode_block_opcode_0xA_16(IpvideoContext *s, AVFrame *frame)
int frame_number
Frame counter, set by libavcodec.
static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s, AVFrame *frame)
uint8_t * av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:289
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
#define FFSWAP(type, a, b)
Definition: common.h:61
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.
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.
for(j=16;j >0;--j)