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 <string.h>
39
41
42 #define BITSTREAM_READER_LE
49
50 #define PALETTE_COUNT 256
51
53
58
59 /* For format 0x10 */
62
67
74
77
79 {
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) {
91 }
else if (motion_offset >
s->upper_motion_limit_offset) {
93 motion_offset,
s->upper_motion_limit_offset);
95 }
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 {
108 }
109
111 {
113 }
114
116 {
118 int x, y;
119
120 /* copy block from 2 frames ago using a motion vector; need 1 more byte */
122 B = bytestream2_get_byte(&
s->stream_ptr);
123 } else {
124 B = bytestream2_get_byte(&
s->mv_ptr);
125 }
126
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);
137 }
138
140 {
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 */
148 B = bytestream2_get_byte(&
s->stream_ptr);
149 } else {
150 B = bytestream2_get_byte(&
s->mv_ptr);
151 }
152
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);
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 */
172 B = bytestream2_get_byte(&
s->stream_ptr);
173 } else {
174 B = bytestream2_get_byte(&
s->mv_ptr);
175 }
176
178 BH = (
B >> 4) & 0x0F;
180 y = -8 + BH;
181
182 ff_tlog(
s->avctx,
"motion byte = %d, (x, y) = (%d, %d)\n",
B, 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);
197 }
198
200 {
201 /* mystery opcode? skip multiple blocks? */
203
204 /* report success */
205 return 0;
206 }
207
209 {
210 int x, y;
213
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
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;
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) {
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;
256 unsigned int flags = 0;
257
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
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
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
301 s->pixel_ptr -= 8 *
s->stride - 4;
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) {
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;
334
338 }
339
340 /* 4-color encoding */
342
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 {
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) {
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 {
374
375 /* 1 of 4 colors for each 2x1 or 1x2 block, need 8 more bytes */
376 flags = bytestream2_get_le64(&
s->stream_ptr);
378 for (y = 0; y < 8; y++) {
379 for (x = 0; x < 8; x += 2, flags >>= 2) {
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) {
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;
405
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 */
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)) {
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
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
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) {
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) {
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;
503
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;
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);
572 }
573
575 {
576 int x, y;
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;
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;
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;
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) {
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;
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 {
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 {
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;
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) {
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;
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
919 {
921
922 if (!opcode) {
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_num > 2)
931 }
932 }
933
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;
942 } else if (opcode > 0) {
943 off_x = ((uint16_t)opcode - 0x4000) %
frame->width;
944 off_y = ((uint16_t)opcode - 0x4000) /
frame->width;
946 }
947 }
948
951 };
952
954 {
955 int pass, x, y;
956 int16_t opcode;
958
959 /* this is PAL8, so make the palette available */
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
968
969 for (pass = 0; pass < 2; ++pass) {
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
976 " block @ (%3d, %3d): opcode 0x%X, data ptr offset %d\n",
978
979 s->pixel_ptr =
frame->data[0] + x + y *
frame->linesize[0];
981 }
982 }
983 }
984
987 "decode finished with %d bytes left over\n",
989 }
990 }
991
993 {
995
996 if (!opcode) {
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
1021 };
1022
1024 {
1025 int pass, x, y, changed_block;
1026 int16_t opcode,
skip;
1029
1031
1032 /* this is PAL8, so make the palette available */
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
1042
1043 for (pass = 0; pass < 2; ++pass) {
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
1054 opcode = bytestream2_get_le16(&decoding_map_ptr);
1056 break;
1057 }
1059 return;
1060 skip = bytestream2_get_le16(&skip_map_ptr);
1061 }
1063 }
1064 }
1065 }
1066
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
1076 changed_block = 1;
1077 break;
1078 }
1080 return;
1081 skip = bytestream2_get_le16(&skip_map_ptr);
1082 }
1083
1084 if (changed_block) {
1086 } else {
1087 /* Don't try to copy last_frame data on the first frame */
1088 if (
s->avctx->frame_num)
1090 }
1092 }
1093 }
1094
1096
1099 "decode finished with %d bytes left over\n",
1101 }
1102 }
1103
1105 {
1106 int x, y;
1107 unsigned char opcode;
1110
1113 /* this is PAL8, so make the palette available */
1115
1116 s->stride =
frame->linesize[0];
1117 } else {
1118 s->stride =
frame->linesize[0] >> 1;
1119 s->mv_ptr =
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
1127 for (y = 0; y <
s->avctx->height; y += 8) {
1128 for (x = 0; x <
s->avctx->width; x += 8) {
1130 return;
1132
1134 " block @ (%3d, %3d): encoding 0x%X, data ptr offset %d\n",
1136
1138 s->pixel_ptr =
frame->data[0] + x
1139 + y*
frame->linesize[0];
1141 } else {
1142 s->pixel_ptr =
frame->data[0] + x*2
1143 + y*
frame->linesize[0];
1145 }
1148 s->avctx->frame_num, x, y);
1149 return;
1150 }
1151 }
1152 }
1155 "decode finished with %d bytes left over\n",
1157 }
1158 }
1159
1161 {
1163
1165
1168
1170
1175 if (!
s->last_frame || !
s->second_last_frame ||
1176 !
s->cur_decode_frame || !
s->prev_decode_frame) {
1178 }
1179
1180 s->cur_decode_frame->width = avctx->
width;
1181 s->prev_decode_frame->width = avctx->
width;
1182 s->cur_decode_frame->height = avctx->
height;
1183 s->prev_decode_frame->height = avctx->
height;
1184 s->cur_decode_frame->format = avctx->
pix_fmt;
1185 s->prev_decode_frame->format = avctx->
pix_fmt;
1186
1187 return 0;
1188 }
1189
1192 {
1193 const uint8_t *buf = avpkt->
data;
1194 int buf_size = avpkt->
size;
1197 int send_buffer;
1198 int frame_format;
1199 int video_data_size;
1200
1206 }
1207
1208 if (!
s->cur_decode_frame->data[0]) {
1212
1217 }
1218 }
1219
1220 if (buf_size < 8)
1222
1223 frame_format =
AV_RL8(buf);
1224 send_buffer =
AV_RL8(buf + 1);
1225 video_data_size =
AV_RL16(buf + 2);
1226 s->decoding_map_size =
AV_RL16(buf + 4);
1227 s->skip_map_size =
AV_RL16(buf + 6);
1228
1229 switch (frame_format) {
1230 case 0x06:
1231 if (
s->decoding_map_size) {
1234 }
1235
1236 if (
s->skip_map_size) {
1239 }
1240
1244 }
1245
1246 /* Decoding map for 0x06 frame format is at the top of pixeldata */
1247 s->decoding_map_size = ((
s->avctx->width / 8) * (
s->avctx->height / 8)) * 2;
1248 s->decoding_map = buf + 8 + 14;
/* 14 bits of op data */
1249 video_data_size -=
s->decoding_map_size + 14;
1250 if (video_data_size <= 0 || s->decoding_map_size == 0)
1252
1253 if (buf_size < 8 + s->decoding_map_size + 14 + video_data_size)
1255
1256 bytestream2_init(&
s->stream_ptr, buf + 8 +
s->decoding_map_size + 14, video_data_size);
1257
1258 break;
1259
1260 case 0x10:
1261 if (!
s->decoding_map_size) {
1264 }
1265
1266 if (!
s->skip_map_size) {
1269 }
1270
1274 }
1275
1276 if (buf_size < 8 + video_data_size + s->decoding_map_size +
s->skip_map_size)
1278
1280 s->decoding_map = buf + 8 + video_data_size;
1281 s->skip_map = buf + 8 + video_data_size +
s->decoding_map_size;
1282
1283 break;
1284
1285 case 0x11:
1286 if (!
s->decoding_map_size) {
1289 }
1290
1291 if (
s->skip_map_size) {
1294 }
1295
1296 if (buf_size < 8 + video_data_size + s->decoding_map_size)
1298
1300 s->decoding_map = buf + 8 + video_data_size;
1301
1302 break;
1303
1304 default:
1306 }
1307
1308 /* ensure we can't overread the packet */
1309 if (buf_size < 8 + s->decoding_map_size + video_data_size +
s->skip_map_size) {
1312 }
1313
1316
1318 #if FF_API_PALETTE_HAS_CHANGED
1320 frame->palette_has_changed =
1321 #endif
1323 #if FF_API_PALETTE_HAS_CHANGED
1325 #endif
1326 }
1327
1328 switch (frame_format) {
1329 case 0x06:
1331 break;
1332 case 0x10:
1334 break;
1335 case 0x11:
1337 break;
1338 }
1339
1340 *got_frame = send_buffer;
1341
1342 /* shuffle frames */
1346
1347 /* report that the buffer was completely consumed */
1348 return buf_size;
1349 }
1350
1352 {
1354
1359
1360 return 0;
1361 }
1362
1364 .
p.
name =
"interplayvideo",
1374 };