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
42
43 #define BITSTREAM_READER_LE
50
51 #define PALETTE_COUNT 256
52
54
59
60 /* For format 0x10 */
63
68
75
78
80 {
82 int current_offset =
s->pixel_ptr - dst->
data[0];
83 int x = (current_offset % dst->
linesize[0]) / (1 +
s->is_16bpp);
84 int y = current_offset / dst->
linesize[0];
85 int dx = delta_x + x - ((delta_x + x >=
width) - (delta_x + x < 0)) *
width;
86 int dy = delta_y + y + (delta_x + x >=
width) - (delta_x + x < 0);
87 int motion_offset = dy *
src->linesize[0] + dx * (1 +
s->is_16bpp);
88
89 if (motion_offset < 0) {
92 }
else if (motion_offset >
s->upper_motion_limit_offset) {
94 motion_offset,
s->upper_motion_limit_offset);
96 }
100 }
101 s->hdsp.put_pixels_tab[!
s->is_16bpp][0](
s->pixel_ptr,
src->data[0] + motion_offset,
103 return 0;
104 }
105
107 {
109 }
110
112 {
114 }
115
117 {
119 int x, y;
120
121 /* copy block from 2 frames ago using a motion vector; need 1 more byte */
123 B = bytestream2_get_byte(&
s->stream_ptr);
124 } else {
125 B = bytestream2_get_byte(&
s->mv_ptr);
126 }
127
131 } else {
132 x = -14 + ((
B - 56) % 29);
133 y = 8 + ((
B - 56) / 29);
134 }
135
136 ff_tlog(
s->avctx,
"motion byte = %d, (x, y) = (%d, %d)\n",
B, x, y);
138 }
139
141 {
143 int x, y;
144
145 /* copy 8x8 block from current frame from an up/left block */
146
147 /* need 1 more byte for motion */
149 B = bytestream2_get_byte(&
s->stream_ptr);
150 } else {
151 B = bytestream2_get_byte(&
s->mv_ptr);
152 }
153
157 } else {
158 x = -(-14 + ((
B - 56) % 29));
159 y = -( 8 + ((
B - 56) / 29));
160 }
161
162 ff_tlog(
s->avctx,
"motion byte = %d, (x, y) = (%d, %d)\n",
B, x, y);
164 }
165
167 {
168 int x, y;
169 unsigned char B,
BL, BH;
170
171 /* copy a block from the previous frame; need 1 more byte */
173 B = bytestream2_get_byte(&
s->stream_ptr);
174 } else {
175 B = bytestream2_get_byte(&
s->mv_ptr);
176 }
177
179 BH = (
B >> 4) & 0x0F;
181 y = -8 + BH;
182
183 ff_tlog(
s->avctx,
"motion byte = %d, (x, y) = (%d, %d)\n",
B, x, y);
185 }
186
188 {
189 signed char x, y;
190
191 /* copy a block from the previous frame using an expanded range;
192 * need 2 more bytes */
193 x = bytestream2_get_byte(&
s->stream_ptr);
194 y = bytestream2_get_byte(&
s->stream_ptr);
195
196 ff_tlog(
s->avctx,
"motion bytes = %d, %d\n", x, y);
198 }
199
201 {
202 /* mystery opcode? skip multiple blocks? */
204
205 /* report success */
206 return 0;
207 }
208
210 {
211 int x, y;
214
218 }
219
220 /* 2-color encoding */
221 P[0] = bytestream2_get_byte(&
s->stream_ptr);
222 P[1] = bytestream2_get_byte(&
s->stream_ptr);
223
225
226 /* need 8 more bytes from the stream */
227 for (y = 0; y < 8; y++) {
228 flags = bytestream2_get_byte(&
s->stream_ptr) | 0x100;
230 *
s->pixel_ptr++ =
P[
flags & 1];
231 s->pixel_ptr +=
s->line_inc;
232 }
233
234 } else {
235
236 /* need 2 more bytes from the stream */
237 flags = bytestream2_get_le16(&
s->stream_ptr);
238 for (y = 0; y < 8; y += 2) {
239 for (x = 0; x < 8; x += 2, flags >>= 1) {
241 s->pixel_ptr[x + 1 ] =
242 s->pixel_ptr[x +
s->stride] =
243 s->pixel_ptr[x + 1 +
s->stride] =
P[
flags & 1];
244 }
245 s->pixel_ptr +=
s->stride * 2;
246 }
247 }
248
249 /* report success */
250 return 0;
251 }
252
254 {
255 int x, y;
257 unsigned int flags = 0;
258
262 }
263
264 /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
265 * either top and bottom or left and right halves */
266 P[0] = bytestream2_get_byte(&
s->stream_ptr);
267 P[1] = bytestream2_get_byte(&
s->stream_ptr);
268
270 for (y = 0; y < 16; y++) {
271 // new values for each 4x4 block
272 if (!(y & 3)) {
273 if (y) {
274 P[0] = bytestream2_get_byte(&
s->stream_ptr);
275 P[1] = bytestream2_get_byte(&
s->stream_ptr);
276 }
277 flags = bytestream2_get_le16(&
s->stream_ptr);
278 }
279
280 for (x = 0; x < 4; x++, flags >>= 1)
281 *
s->pixel_ptr++ =
P[
flags & 1];
282 s->pixel_ptr +=
s->stride - 4;
283 // switch to right half
284 if (y == 7)
s->pixel_ptr -= 8 *
s->stride - 4;
285 }
286
287 } else {
288 flags = bytestream2_get_le32(&
s->stream_ptr);
289 P[2] = bytestream2_get_byte(&
s->stream_ptr);
290 P[3] = bytestream2_get_byte(&
s->stream_ptr);
291
293
294 /* vertical split; left & right halves are 2-color encoded */
295
296 for (y = 0; y < 16; y++) {
297 for (x = 0; x < 4; x++, flags >>= 1)
298 *
s->pixel_ptr++ =
P[
flags & 1];
299 s->pixel_ptr +=
s->stride - 4;
300 // switch to right half
302 s->pixel_ptr -= 8 *
s->stride - 4;
305 flags = bytestream2_get_le32(&
s->stream_ptr);
306 }
307 }
308
309 } else {
310
311 /* horizontal split; top & bottom halves are 2-color encoded */
312
313 for (y = 0; y < 8; y++) {
314 if (y == 4) {
317 flags = bytestream2_get_le32(&
s->stream_ptr);
318 }
319
320 for (x = 0; x < 8; x++, flags >>= 1)
321 *
s->pixel_ptr++ =
P[
flags & 1];
322 s->pixel_ptr +=
s->line_inc;
323 }
324 }
325 }
326
327 /* report success */
328 return 0;
329 }
330
332 {
333 int x, y;
335
339 }
340
341 /* 4-color encoding */
343
346
347 /* 1 of 4 colors for each pixel, need 16 more bytes */
348 for (y = 0; y < 8; y++) {
349 /* get the next set of 8 2-bit flags */
350 int flags = bytestream2_get_le16(&
s->stream_ptr);
351 for (x = 0; x < 8; x++, flags >>= 2)
352 *
s->pixel_ptr++ =
P[
flags & 0x03];
353 s->pixel_ptr +=
s->line_inc;
354 }
355
356 } else {
358
359 /* 1 of 4 colors for each 2x2 block, need 4 more bytes */
360 flags = bytestream2_get_le32(&
s->stream_ptr);
361
362 for (y = 0; y < 8; y += 2) {
363 for (x = 0; x < 8; x += 2, flags >>= 2) {
365 s->pixel_ptr[x + 1 ] =
366 s->pixel_ptr[x +
s->stride] =
367 s->pixel_ptr[x + 1 +
s->stride] =
P[
flags & 0x03];
368 }
369 s->pixel_ptr +=
s->stride * 2;
370 }
371
372 }
373 } else {
375
376 /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
377 flags = bytestream2_get_le64(&
s->stream_ptr);
379 for (y = 0; y < 8; y++) {
380 for (x = 0; x < 8; x += 2, flags >>= 2) {
382 s->pixel_ptr[x + 1] =
P[
flags & 0x03];
383 }
384 s->pixel_ptr +=
s->stride;
385 }
386 } else {
387 for (y = 0; y < 8; y += 2) {
388 for (x = 0; x < 8; x++, flags >>= 2) {
390 s->pixel_ptr[x +
s->stride] =
P[
flags & 0x03];
391 }
392 s->pixel_ptr +=
s->stride * 2;
393 }
394 }
395 }
396
397 /* report success */
398 return 0;
399 }
400
402 {
403 int x, y;
406
410 }
411
413
414 /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
415 * either top and bottom or left and right halves */
417
418 /* 4-color encoding for each quadrant; need 32 bytes */
419 for (y = 0; y < 16; y++) {
420 // new values for each 4x4 block
421 if (!(y & 3)) {
423 flags = bytestream2_get_le32(&
s->stream_ptr);
424 }
425
426 for (x = 0; x < 4; x++, flags >>= 2)
427 *
s->pixel_ptr++ =
P[
flags & 0x03];
428
429 s->pixel_ptr +=
s->stride - 4;
430 // switch to right half
431 if (y == 7)
s->pixel_ptr -= 8 *
s->stride - 4;
432 }
433
434 } else {
435 // vertical split?
436 int vert;
437 uint64_t
flags = bytestream2_get_le64(&
s->stream_ptr);
438
441
442 /* 4-color encoding for either left and right or top and bottom
443 * halves */
444
445 for (y = 0; y < 16; y++) {
446 for (x = 0; x < 4; x++, flags >>= 2)
447 *
s->pixel_ptr++ =
P[
flags & 0x03];
448
450 s->pixel_ptr +=
s->stride - 4;
451 // switch to right half
452 if (y == 7)
s->pixel_ptr -= 8 *
s->stride - 4;
453 }
else if (y & 1)
s->pixel_ptr +=
s->line_inc;
454
455 // load values for second half
456 if (y == 7) {
458 flags = bytestream2_get_le64(&
s->stream_ptr);
459 }
460 }
461 }
462
463 /* report success */
464 return 0;
465 }
466
468 {
469 int y;
470
471 /* 64-color encoding (each pixel in block is a different color) */
472 for (y = 0; y < 8; y++) {
474 s->pixel_ptr +=
s->stride;
475 }
476
477 /* report success */
478 return 0;
479 }
480
482 {
483 int x, y;
484
485 /* 16-color block encoding: each 2x2 block is a different color */
486 for (y = 0; y < 8; y += 2) {
487 for (x = 0; x < 8; x += 2) {
489 s->pixel_ptr[x + 1 ] =
490 s->pixel_ptr[x +
s->stride] =
491 s->pixel_ptr[x + 1 +
s->stride] = bytestream2_get_byte(&
s->stream_ptr);
492 }
493 s->pixel_ptr +=
s->stride * 2;
494 }
495
496 /* report success */
497 return 0;
498 }
499
501 {
502 int y;
504
508 }
509
510 /* 4-color block encoding: each 4x4 block is a different color */
511 for (y = 0; y < 8; y++) {
512 if (!(y & 3)) {
513 P[0] = bytestream2_get_byte(&
s->stream_ptr);
514 P[1] = bytestream2_get_byte(&
s->stream_ptr);
515 }
516 memset(
s->pixel_ptr,
P[0], 4);
517 memset(
s->pixel_ptr + 4,
P[1], 4);
518 s->pixel_ptr +=
s->stride;
519 }
520
521 /* report success */
522 return 0;
523 }
524
526 {
527 int y;
528 unsigned char pix;
529
530 /* 1-color encoding: the whole block is 1 solid color */
531 pix = bytestream2_get_byte(&
s->stream_ptr);
532
533 for (y = 0; y < 8; y++) {
534 memset(
s->pixel_ptr, pix, 8);
535 s->pixel_ptr +=
s->stride;
536 }
537
538 /* report success */
539 return 0;
540 }
541
543 {
544 int x, y;
546
547 /* dithered encoding */
548 sample[0] = bytestream2_get_byte(&
s->stream_ptr);
549 sample[1] = bytestream2_get_byte(&
s->stream_ptr);
550
551 for (y = 0; y < 8; y++) {
552 for (x = 0; x < 8; x += 2) {
553 *
s->pixel_ptr++ =
sample[ y & 1 ];
554 *
s->pixel_ptr++ =
sample[!(y & 1)];
555 }
556 s->pixel_ptr +=
s->line_inc;
557 }
558
559 /* report success */
560 return 0;
561 }
562
564 {
565 signed char x, y;
566
567 /* copy a block from the second last frame using an expanded range */
568 x = bytestream2_get_byte(&
s->stream_ptr);
569 y = bytestream2_get_byte(&
s->stream_ptr);
570
571 ff_tlog(
s->avctx,
"motion bytes = %d, %d\n", x, y);
573 }
574
576 {
577 int x, y;
580 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
581
582 /* 2-color encoding */
583 P[0] = bytestream2_get_le16(&
s->stream_ptr);
584 P[1] = bytestream2_get_le16(&
s->stream_ptr);
585
586 if (!(
P[0] & 0x8000)) {
587
588 for (y = 0; y < 8; y++) {
589 flags = bytestream2_get_byte(&
s->stream_ptr) | 0x100;
591 *pixel_ptr++ =
P[
flags & 1];
592 pixel_ptr +=
s->line_inc;
593 }
594
595 } else {
596
597 flags = bytestream2_get_le16(&
s->stream_ptr);
598 for (y = 0; y < 8; y += 2) {
599 for (x = 0; x < 8; x += 2, flags >>= 1) {
600 pixel_ptr[x ] =
601 pixel_ptr[x + 1 ] =
602 pixel_ptr[x +
s->stride] =
603 pixel_ptr[x + 1 +
s->stride] =
P[
flags & 1];
604 }
605 pixel_ptr +=
s->stride * 2;
606 }
607 }
608
609 return 0;
610 }
611
613 {
614 int x, y;
616 unsigned int flags = 0;
617 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
618
619 /* 2-color encoding for each 4x4 quadrant, or 2-color encoding on
620 * either top and bottom or left and right halves */
621 P[0] = bytestream2_get_le16(&
s->stream_ptr);
622 P[1] = bytestream2_get_le16(&
s->stream_ptr);
623
624 if (!(
P[0] & 0x8000)) {
625
626 for (y = 0; y < 16; y++) {
627 // new values for each 4x4 block
628 if (!(y & 3)) {
629 if (y) {
630 P[0] = bytestream2_get_le16(&
s->stream_ptr);
631 P[1] = bytestream2_get_le16(&
s->stream_ptr);
632 }
633 flags = bytestream2_get_le16(&
s->stream_ptr);
634 }
635
636 for (x = 0; x < 4; x++, flags >>= 1)
637 *pixel_ptr++ =
P[
flags & 1];
638 pixel_ptr +=
s->stride - 4;
639 // switch to right half
640 if (y == 7) pixel_ptr -= 8 *
s->stride - 4;
641 }
642
643 } else {
644
645 flags = bytestream2_get_le32(&
s->stream_ptr);
646 P[2] = bytestream2_get_le16(&
s->stream_ptr);
647 P[3] = bytestream2_get_le16(&
s->stream_ptr);
648
649 if (!(
P[2] & 0x8000)) {
650
651 /* vertical split; left & right halves are 2-color encoded */
652
653 for (y = 0; y < 16; y++) {
654 for (x = 0; x < 4; x++, flags >>= 1)
655 *pixel_ptr++ =
P[
flags & 1];
656 pixel_ptr +=
s->stride - 4;
657 // switch to right half
658 if (y == 7) {
659 pixel_ptr -= 8 *
s->stride - 4;
662 flags = bytestream2_get_le32(&
s->stream_ptr);
663 }
664 }
665
666 } else {
667
668 /* horizontal split; top & bottom halves are 2-color encoded */
669
670 for (y = 0; y < 8; y++) {
671 if (y == 4) {
674 flags = bytestream2_get_le32(&
s->stream_ptr);
675 }
676
677 for (x = 0; x < 8; x++, flags >>= 1)
678 *pixel_ptr++ =
P[
flags & 1];
679 pixel_ptr +=
s->line_inc;
680 }
681 }
682 }
683
684 /* report success */
685 return 0;
686 }
687
689 {
690 int x, y;
692 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
693
694 /* 4-color encoding */
695 for (x = 0; x < 4; x++)
696 P[x] = bytestream2_get_le16(&
s->stream_ptr);
697
698 if (!(
P[0] & 0x8000)) {
699 if (!(
P[2] & 0x8000)) {
700
701 /* 1 of 4 colors for each pixel */
702 for (y = 0; y < 8; y++) {
703 /* get the next set of 8 2-bit flags */
704 int flags = bytestream2_get_le16(&
s->stream_ptr);
705 for (x = 0; x < 8; x++, flags >>= 2)
706 *pixel_ptr++ =
P[
flags & 0x03];
707 pixel_ptr +=
s->line_inc;
708 }
709
710 } else {
712
713 /* 1 of 4 colors for each 2x2 block */
714 flags = bytestream2_get_le32(&
s->stream_ptr);
715
716 for (y = 0; y < 8; y += 2) {
717 for (x = 0; x < 8; x += 2, flags >>= 2) {
718 pixel_ptr[x ] =
719 pixel_ptr[x + 1 ] =
720 pixel_ptr[x +
s->stride] =
721 pixel_ptr[x + 1 +
s->stride] =
P[
flags & 0x03];
722 }
723 pixel_ptr +=
s->stride * 2;
724 }
725
726 }
727 } else {
729
730 /* 1 of 4 colors for each 2x1 or 1x2 block */
731 flags = bytestream2_get_le64(&
s->stream_ptr);
732 if (!(
P[2] & 0x8000)) {
733 for (y = 0; y < 8; y++) {
734 for (x = 0; x < 8; x += 2, flags >>= 2) {
735 pixel_ptr[x ] =
736 pixel_ptr[x + 1] =
P[
flags & 0x03];
737 }
738 pixel_ptr +=
s->stride;
739 }
740 } else {
741 for (y = 0; y < 8; y += 2) {
742 for (x = 0; x < 8; x++, flags >>= 2) {
743 pixel_ptr[x ] =
744 pixel_ptr[x +
s->stride] =
P[
flags & 0x03];
745 }
746 pixel_ptr +=
s->stride * 2;
747 }
748 }
749 }
750
751 /* report success */
752 return 0;
753 }
754
756 {
757 int x, y;
760 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
761
762 for (x = 0; x < 4; x++)
763 P[x] = bytestream2_get_le16(&
s->stream_ptr);
764
765 /* 4-color encoding for each 4x4 quadrant, or 4-color encoding on
766 * either top and bottom or left and right halves */
767 if (!(
P[0] & 0x8000)) {
768
769 /* 4-color encoding for each quadrant */
770 for (y = 0; y < 16; y++) {
771 // new values for each 4x4 block
772 if (!(y & 3)) {
773 if (y)
774 for (x = 0; x < 4; x++)
775 P[x] = bytestream2_get_le16(&
s->stream_ptr);
776 flags = bytestream2_get_le32(&
s->stream_ptr);
777 }
778
779 for (x = 0; x < 4; x++, flags >>= 2)
780 *pixel_ptr++ =
P[
flags & 0x03];
781
782 pixel_ptr +=
s->stride - 4;
783 // switch to right half
784 if (y == 7) pixel_ptr -= 8 *
s->stride - 4;
785 }
786
787 } else {
788 // vertical split?
789 int vert;
790 uint64_t
flags = bytestream2_get_le64(&
s->stream_ptr);
791
792 for (x = 4; x < 8; x++)
793 P[x] = bytestream2_get_le16(&
s->stream_ptr);
794 vert = !(
P[4] & 0x8000);
795
796 /* 4-color encoding for either left and right or top and bottom
797 * halves */
798
799 for (y = 0; y < 16; y++) {
800 for (x = 0; x < 4; x++, flags >>= 2)
801 *pixel_ptr++ =
P[
flags & 0x03];
802
803 if (vert) {
804 pixel_ptr +=
s->stride - 4;
805 // switch to right half
806 if (y == 7) pixel_ptr -= 8 *
s->stride - 4;
807 }
else if (y & 1) pixel_ptr +=
s->line_inc;
808
809 // load values for second half
810 if (y == 7) {
812 flags = bytestream2_get_le64(&
s->stream_ptr);
813 }
814 }
815 }
816
817 /* report success */
818 return 0;
819 }
820
822 {
823 int x, y;
824 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
825
826 /* 64-color encoding (each pixel in block is a different color) */
827 for (y = 0; y < 8; y++) {
828 for (x = 0; x < 8; x++)
829 pixel_ptr[x] = bytestream2_get_le16(&
s->stream_ptr);
830 pixel_ptr +=
s->stride;
831 }
832
833 /* report success */
834 return 0;
835 }
836
838 {
839 int x, y;
840 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
841
842 /* 16-color block encoding: each 2x2 block is a different color */
843 for (y = 0; y < 8; y += 2) {
844 for (x = 0; x < 8; x += 2) {
845 pixel_ptr[x ] =
846 pixel_ptr[x + 1 ] =
847 pixel_ptr[x +
s->stride] =
848 pixel_ptr[x + 1 +
s->stride] = bytestream2_get_le16(&
s->stream_ptr);
849 }
850 pixel_ptr +=
s->stride * 2;
851 }
852
853 /* report success */
854 return 0;
855 }
856
858 {
859 int x, y;
861 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
862
863 /* 4-color block encoding: each 4x4 block is a different color */
864 for (y = 0; y < 8; y++) {
865 if (!(y & 3)) {
866 P[0] = bytestream2_get_le16(&
s->stream_ptr);
867 P[1] = bytestream2_get_le16(&
s->stream_ptr);
868 }
869 for (x = 0; x < 8; x++)
870 pixel_ptr[x] =
P[x >> 2];
871 pixel_ptr +=
s->stride;
872 }
873
874 /* report success */
875 return 0;
876 }
877
879 {
880 int x, y;
881 uint16_t pix;
882 uint16_t *pixel_ptr = (uint16_t*)
s->pixel_ptr;
883
884 /* 1-color encoding: the whole block is 1 solid color */
885 pix = bytestream2_get_le16(&
s->stream_ptr);
886
887 for (y = 0; y < 8; y++) {
888 for (x = 0; x < 8; x++)
889 pixel_ptr[x] = pix;
890 pixel_ptr +=
s->stride;
891 }
892
893 /* report success */
894 return 0;
895 }
896
906 };
907
917 };
918
920 {
922
923 if (!opcode) {
926 s->pixel_ptr +=
s->stride;
927 }
928 } else {
929 /* Don't try to copy second_last_frame data on the first frames */
930 if (
s->avctx->frame_number > 2)
932 }
933 }
934
936 {
937 int off_x, off_y;
938
939 if (opcode < 0) {
940 off_x = ((uint16_t)opcode - 0xC000) %
frame->width;
941 off_y = ((uint16_t)opcode - 0xC000) /
frame->width;
943 } else if (opcode > 0) {
944 off_x = ((uint16_t)opcode - 0x4000) %
frame->width;
945 off_y = ((uint16_t)opcode - 0x4000) /
frame->width;
947 }
948 }
949
952 };
953
955 {
957 int16_t opcode;
959
960 /* this is PAL8, so make the palette available */
962 s->stride =
frame->linesize[0];
963
964 s->line_inc =
s->stride - 8;
965 s->upper_motion_limit_offset = (
s->avctx->height - 8) *
frame->linesize[0]
966 + (
s->avctx->width - 8) * (1 +
s->is_16bpp);
967
969
972 for (y = 0; y <
s->avctx->height; y += 8) {
973 for (x = 0; x <
s->avctx->width; x += 8) {
974 opcode = bytestream2_get_le16(&decoding_map_ptr);
975
977 " block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
979
980 s->pixel_ptr =
frame->data[0] + x + y *
frame->linesize[0];
982 }
983 }
984 }
985
988 "decode finished with %d bytes left over\n",
990 }
991 }
992
994 {
996
997 if (!opcode) {
1000 s->pixel_ptr +=
s->stride;
1001 }
1002 }
1003 }
1004
1006 {
1007 int off_x, off_y;
1008
1009 if (opcode < 0) {
1010 off_x = ((uint16_t)opcode - 0xC000) %
s->cur_decode_frame->width;
1011 off_y = ((uint16_t)opcode - 0xC000) /
s->cur_decode_frame->width;
1012 copy_from(
s,
s->prev_decode_frame,
s->cur_decode_frame, off_x, off_y);
1013 } else if (opcode > 0) {
1014 off_x = ((uint16_t)opcode - 0x4000) %
s->cur_decode_frame->width;
1015 off_y = ((uint16_t)opcode - 0x4000) /
s->cur_decode_frame->width;
1016 copy_from(
s,
s->cur_decode_frame,
s->cur_decode_frame, off_x, off_y);
1017 }
1018 }
1019
1022 };
1023
1025 {
1026 int pass, x, y, changed_block;
1027 int16_t opcode, skip;
1030
1032
1033 /* this is PAL8, so make the palette available */
1035 s->stride =
frame->linesize[0];
1036
1037 s->line_inc =
s->stride - 8;
1038 s->upper_motion_limit_offset = (
s->avctx->height - 8) *
frame->linesize[0]
1039 + (
s->avctx->width - 8) * (1 +
s->is_16bpp);
1040
1043
1047 skip = bytestream2_get_le16(&skip_map_ptr);
1048
1049 for (y = 0; y <
s->avctx->height; y += 8) {
1050 for (x = 0; x <
s->avctx->width; x += 8) {
1051 s->pixel_ptr =
s->cur_decode_frame->data[0] + x + y *
s->cur_decode_frame->linesize[0];
1052
1053 while (skip <= 0) {
1054 if (skip != -0x8000 && skip) {
1055 opcode = bytestream2_get_le16(&decoding_map_ptr);
1057 break;
1058 }
1060 return;
1061 skip = bytestream2_get_le16(&skip_map_ptr);
1062 }
1063 skip *= 2;
1064 }
1065 }
1066 }
1067
1069 skip = bytestream2_get_le16(&skip_map_ptr);
1070 for (y = 0; y <
s->avctx->height; y += 8) {
1071 for (x = 0; x <
s->avctx->width; x += 8) {
1072 changed_block = 0;
1073 s->pixel_ptr =
frame->data[0] + x + y*
frame->linesize[0];
1074
1075 while (skip <= 0) {
1076 if (skip != -0x8000 && skip) {
1077 changed_block = 1;
1078 break;
1079 }
1081 return;
1082 skip = bytestream2_get_le16(&skip_map_ptr);
1083 }
1084
1085 if (changed_block) {
1087 } else {
1088 /* Don't try to copy last_frame data on the first frame */
1089 if (
s->avctx->frame_number)
1091 }
1092 skip *= 2;
1093 }
1094 }
1095
1097
1100 "decode finished with %d bytes left over\n",
1102 }
1103 }
1104
1106 {
1107 int x, y;
1108 unsigned char opcode;
1111
1114 /* this is PAL8, so make the palette available */
1116
1117 s->stride =
frame->linesize[0];
1118 } else {
1119 s->stride =
frame->linesize[0] >> 1;
1120 s->mv_ptr =
s->stream_ptr;
1122 }
1123 s->line_inc =
s->stride - 8;
1124 s->upper_motion_limit_offset = (
s->avctx->height - 8) *
frame->linesize[0]
1125 + (
s->avctx->width - 8) * (1 +
s->is_16bpp);
1126
1128 for (y = 0; y <
s->avctx->height; y += 8) {
1129 for (x = 0; x <
s->avctx->width; x += 8) {
1131 return;
1133
1135 " block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
1137
1139 s->pixel_ptr =
frame->data[0] + x
1140 + y*
frame->linesize[0];
1142 } else {
1143 s->pixel_ptr =
frame->data[0] + x*2
1144 + y*
frame->linesize[0];
1146 }
1149 s->avctx->frame_number, x, y);
1150 return;
1151 }
1152 }
1153 }
1156 "decode finished with %d bytes left over\n",
1158 }
1159 }
1160
1162 {
1164
1166
1169
1171
1176 if (!
s->last_frame || !
s->second_last_frame ||
1177 !
s->cur_decode_frame || !
s->prev_decode_frame) {
1179 }
1180
1181 s->cur_decode_frame->width = avctx->
width;
1182 s->prev_decode_frame->width = avctx->
width;
1183 s->cur_decode_frame->height = avctx->
height;
1184 s->prev_decode_frame->height = avctx->
height;
1185 s->cur_decode_frame->format = avctx->
pix_fmt;
1186 s->prev_decode_frame->format = avctx->
pix_fmt;
1187
1188 return 0;
1189 }
1190
1192 void *
data,
int *got_frame,
1194 {
1195 const uint8_t *buf = avpkt->
data;
1196 int buf_size = avpkt->
size;
1200 int send_buffer;
1201 int frame_format;
1202 int video_data_size;
1203
1209 }
1210
1211 if (!
s->cur_decode_frame->data[0]) {
1215
1220 }
1221 }
1222
1223 if (buf_size < 8)
1225
1226 frame_format =
AV_RL8(buf);
1227 send_buffer =
AV_RL8(buf + 1);
1228 video_data_size =
AV_RL16(buf + 2);
1229 s->decoding_map_size =
AV_RL16(buf + 4);
1230 s->skip_map_size =
AV_RL16(buf + 6);
1231
1232 switch (frame_format) {
1233 case 0x06:
1234 if (
s->decoding_map_size) {
1237 }
1238
1239 if (
s->skip_map_size) {
1242 }
1243
1247 }
1248
1249 /* Decoding map for 0x06 frame format is at the top of pixeldata */
1250 s->decoding_map_size = ((
s->avctx->width / 8) * (
s->avctx->height / 8)) * 2;
1251 s->decoding_map = buf + 8 + 14;
/* 14 bits of op data */
1252 video_data_size -=
s->decoding_map_size + 14;
1253 if (video_data_size <= 0 || s->decoding_map_size == 0)
1255
1256 if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
1258
1259 bytestream2_init(&
s->stream_ptr, buf + 8 +
s->decoding_map_size + 14, video_data_size);
1260
1261 break;
1262
1263 case 0x10:
1264 if (!
s->decoding_map_size) {
1267 }
1268
1269 if (!
s->skip_map_size) {
1272 }
1273
1277 }
1278
1279 if (buf_size < 8 + video_data_size + s->decoding_map_size +
s->skip_map_size)
1281
1283 s->decoding_map = buf + 8 + video_data_size;
1284 s->skip_map = buf + 8 + video_data_size +
s->decoding_map_size;
1285
1286 break;
1287
1288 case 0x11:
1289 if (!
s->decoding_map_size) {
1292 }
1293
1294 if (
s->skip_map_size) {
1297 }
1298
1299 if (buf_size < 8 + video_data_size + s->decoding_map_size)
1301
1303 s->decoding_map = buf + 8 + video_data_size;
1304
1305 break;
1306
1307 default:
1309 }
1310
1311 /* ensure we can't overread the packet */
1312 if (buf_size < 8 + s->decoding_map_size + video_data_size +
s->skip_map_size) {
1315 }
1316
1319
1322 }
1323
1324 switch (frame_format) {
1325 case 0x06:
1327 break;
1328 case 0x10:
1330 break;
1331 case 0x11:
1333 break;
1334 }
1335
1336 *got_frame = send_buffer;
1337
1338 /* shuffle frames */
1343
1344 /* report that the buffer was completely consumed */
1345 return buf_size;
1346 }
1347
1349 {
1351
1356
1357 return 0;
1358 }
1359
1361 .
name =
"interplayvideo",
1371 };