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