1/* 2 * Sierra VMD Audio & Video Decoders 3 * Copyright (C) 2004 the ffmpeg project 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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 * Sierra VMD audio & video decoders 25 * by Vladimir "VAG" Gneushev (vagsoft at mail.ru) 26 * for more information on the Sierra VMD format, visit: 27 * http://www.pcisys.net/~melanson/codecs/ 28 * 29 * The video decoder outputs PAL8 colorspace data. The decoder expects 30 * a 0x330-byte VMD file header to be transmitted via extradata during 31 * codec initialization. Each encoded frame that is sent to this decoder 32 * is expected to be prepended with the appropriate 16-byte frame 33 * information record from the VMD file. 34 * 35 * The audio decoder, like the video decoder, expects each encoded data 36 * chunk to be prepended with the appropriate 16-byte frame information 37 * record from the VMD file. It does not require the 0x330-byte VMD file 38 * header, but it does need the audio setup parameters passed in through 39 * normal libavcodec API means. 40 */ 41 42#include <stdio.h> 43#include <stdlib.h> 44#include <string.h> 45 46#include "libavutil/intreadwrite.h" 47#include "avcodec.h" 48#include "bytestream.h" 49 50#define VMD_HEADER_SIZE 0x330 51#define PALETTE_COUNT 256 52 53/* 54 * Video Decoder 55 */ 56 57typedef struct VmdVideoContext { 58 59 AVCodecContext *avctx; 60 AVFrame frame; 61 AVFrame prev_frame; 62 63 const unsigned char *buf; 64 int size; 65 66 unsigned char palette[PALETTE_COUNT * 4]; 67 unsigned char *unpack_buffer; 68 int unpack_buffer_size; 69 70 int x_off, y_off; 71} VmdVideoContext; 72 73#define QUEUE_SIZE 0x1000 74#define QUEUE_MASK 0x0FFF 75 76static void lz_unpack(const unsigned char *src, int src_len, 77 unsigned char *dest, int dest_len) 78{ 79 unsigned char *d; 80 unsigned char *d_end; 81 unsigned char queue[QUEUE_SIZE]; 82 unsigned int qpos; 83 unsigned int dataleft; 84 unsigned int chainofs; 85 unsigned int chainlen; 86 unsigned int speclen; 87 unsigned char tag; 88 unsigned int i, j; 89 GetByteContext gb; 90 91 bytestream2_init(&gb, src, src_len); 92 d = dest; 93 d_end = d + dest_len; 94 dataleft = bytestream2_get_le32(&gb); 95 memset(queue, 0x20, QUEUE_SIZE); 96 if (bytestream2_get_bytes_left(&gb) < 4) 97 return; 98 if (bytestream2_peek_le32(&gb) == 0x56781234) { 99 bytestream2_get_le32(&gb); 100 qpos = 0x111; 101 speclen = 0xF + 3; 102 } else { 103 qpos = 0xFEE; 104 speclen = 100; /* no speclen */ 105 } 106 107 while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { 108 tag = bytestream2_get_byteu(&gb); 109 if ((tag == 0xFF) && (dataleft > 8)) { 110 if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8) 111 return; 112 for (i = 0; i < 8; i++) { 113 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); 114 qpos &= QUEUE_MASK; 115 } 116 dataleft -= 8; 117 } else { 118 for (i = 0; i < 8; i++) { 119 if (dataleft == 0) 120 break; 121 if (tag & 0x01) { 122 if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1) 123 return; 124 queue[qpos++] = *d++ = bytestream2_get_byte(&gb); 125 qpos &= QUEUE_MASK; 126 dataleft--; 127 } else { 128 chainofs = bytestream2_get_byte(&gb); 129 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); 130 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; 131 if (chainlen == speclen) { 132 chainlen = bytestream2_get_byte(&gb) + 0xF + 3; 133 } 134 if (d + chainlen > d_end) 135 return; 136 for (j = 0; j < chainlen; j++) { 137 *d = queue[chainofs++ & QUEUE_MASK]; 138 queue[qpos++] = *d++; 139 qpos &= QUEUE_MASK; 140 } 141 dataleft -= chainlen; 142 } 143 tag >>= 1; 144 } 145 } 146 } 147} 148 149static int rle_unpack(const unsigned char *src, unsigned char *dest, 150 int src_count, int src_size, int dest_len) 151{ 152 unsigned char *pd; 153 int i, l; 154 unsigned char *dest_end = dest + dest_len; 155 GetByteContext gb; 156 157 bytestream2_init(&gb, src, src_size); 158 pd = dest; 159 if (src_count & 1) { 160 if (bytestream2_get_bytes_left(&gb) < 1) 161 return 0; 162 *pd++ = bytestream2_get_byteu(&gb); 163 } 164 165 src_count >>= 1; 166 i = 0; 167 do { 168 if (bytestream2_get_bytes_left(&gb) < 1) 169 break; 170 l = bytestream2_get_byteu(&gb); 171 if (l & 0x80) { 172 l = (l & 0x7F) * 2; 173 if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l) 174 return bytestream2_tell(&gb); 175 bytestream2_get_buffer(&gb, pd, l); 176 pd += l; 177 } else { 178 if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2) 179 return bytestream2_tell(&gb); 180 for (i = 0; i < l; i++) { 181 *pd++ = bytestream2_get_byteu(&gb); 182 *pd++ = bytestream2_get_byteu(&gb); 183 } 184 bytestream2_skip(&gb, 2); 185 } 186 i += l; 187 } while (i < src_count); 188 189 return bytestream2_tell(&gb); 190} 191 192static void vmd_decode(VmdVideoContext *s) 193{ 194 int i; 195 unsigned int *palette32; 196 unsigned char r, g, b; 197 198 GetByteContext gb; 199 200 unsigned char meth; 201 unsigned char *dp; /* pointer to current frame */ 202 unsigned char *pp; /* pointer to previous frame */ 203 unsigned char len; 204 int ofs; 205 206 int frame_x, frame_y; 207 int frame_width, frame_height; 208 209 frame_x = AV_RL16(&s->buf[6]); 210 frame_y = AV_RL16(&s->buf[8]); 211 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; 212 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; 213 if (frame_x < 0 || frame_width < 0 || 214 frame_x >= s->avctx->width || 215 frame_width > s->avctx->width || 216 frame_x + frame_width > s->avctx->width) 217 return; 218 if (frame_y < 0 || frame_height < 0 || 219 frame_y >= s->avctx->height || 220 frame_height > s->avctx->height || 221 frame_y + frame_height > s->avctx->height) 222 return; 223 224 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && 225 (frame_x || frame_y)) { 226 227 s->x_off = frame_x; 228 s->y_off = frame_y; 229 } 230 frame_x -= s->x_off; 231 frame_y -= s->y_off; 232 233 /* if only a certain region will be updated, copy the entire previous 234 * frame before the decode */ 235 if (s->prev_frame.data[0] && 236 (frame_x || frame_y || (frame_width != s->avctx->width) || 237 (frame_height != s->avctx->height))) { 238 239 memcpy(s->frame.data[0], s->prev_frame.data[0], 240 s->avctx->height * s->frame.linesize[0]); 241 } 242 243 /* check if there is a new palette */ 244 bytestream2_init(&gb, s->buf + 16, s->size - 16); 245 if (s->buf[15] & 0x02) { 246 bytestream2_skip(&gb, 2); 247 palette32 = (unsigned int *)s->palette; 248 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { 249 for (i = 0; i < PALETTE_COUNT; i++) { 250 r = bytestream2_get_byteu(&gb) * 4; 251 g = bytestream2_get_byteu(&gb) * 4; 252 b = bytestream2_get_byteu(&gb) * 4; 253 palette32[i] = (r << 16) | (g << 8) | (b); 254 } 255 } 256 s->size -= (256 * 3 + 2); 257 } 258 if (s->size > 0) { 259 /* originally UnpackFrame in VAG's code */ 260 bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer); 261 if (bytestream2_get_bytes_left(&gb) < 1) 262 return; 263 meth = bytestream2_get_byteu(&gb); 264 if (meth & 0x80) { 265 lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), 266 s->unpack_buffer, s->unpack_buffer_size); 267 meth &= 0x7F; 268 bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); 269 } 270 271 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 272 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 273 switch (meth) { 274 case 1: 275 for (i = 0; i < frame_height; i++) { 276 ofs = 0; 277 do { 278 len = bytestream2_get_byte(&gb); 279 if (len & 0x80) { 280 len = (len & 0x7F) + 1; 281 if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len) 282 return; 283 bytestream2_get_buffer(&gb, &dp[ofs], len); 284 ofs += len; 285 } else { 286 /* interframe pixel copy */ 287 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) 288 return; 289 memcpy(&dp[ofs], &pp[ofs], len + 1); 290 ofs += len + 1; 291 } 292 } while (ofs < frame_width); 293 if (ofs > frame_width) { 294 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 295 ofs, frame_width); 296 break; 297 } 298 dp += s->frame.linesize[0]; 299 pp += s->prev_frame.linesize[0]; 300 } 301 break; 302 303 case 2: 304 for (i = 0; i < frame_height; i++) { 305 bytestream2_get_buffer(&gb, dp, frame_width); 306 dp += s->frame.linesize[0]; 307 pp += s->prev_frame.linesize[0]; 308 } 309 break; 310 311 case 3: 312 for (i = 0; i < frame_height; i++) { 313 ofs = 0; 314 do { 315 len = bytestream2_get_byte(&gb); 316 if (len & 0x80) { 317 len = (len & 0x7F) + 1; 318 if (bytestream2_get_byte(&gb) == 0xFF) 319 len = rle_unpack(gb.buffer, &dp[ofs], 320 len, bytestream2_get_bytes_left(&gb), 321 frame_width - ofs); 322 else 323 bytestream2_get_buffer(&gb, &dp[ofs], len); 324 bytestream2_skip(&gb, len); 325 } else { 326 /* interframe pixel copy */ 327 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) 328 return; 329 memcpy(&dp[ofs], &pp[ofs], len + 1); 330 ofs += len + 1; 331 } 332 } while (ofs < frame_width); 333 if (ofs > frame_width) { 334 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 335 ofs, frame_width); 336 } 337 dp += s->frame.linesize[0]; 338 pp += s->prev_frame.linesize[0]; 339 } 340 break; 341 } 342 } 343} 344 345static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) 346{ 347 VmdVideoContext *s = avctx->priv_data; 348 int i; 349 unsigned int *palette32; 350 int palette_index = 0; 351 unsigned char r, g, b; 352 unsigned char *vmd_header; 353 unsigned char *raw_palette; 354 355 s->avctx = avctx; 356 avctx->pix_fmt = PIX_FMT_PAL8; 357 358 /* make sure the VMD header made it */ 359 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { 360 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", 361 VMD_HEADER_SIZE); 362 return -1; 363 } 364 vmd_header = (unsigned char *)avctx->extradata; 365 366 s->unpack_buffer_size = AV_RL32(&vmd_header[800]); 367 s->unpack_buffer = av_malloc(s->unpack_buffer_size); 368 if (!s->unpack_buffer) 369 return -1; 370 371 /* load up the initial palette */ 372 raw_palette = &vmd_header[28]; 373 palette32 = (unsigned int *)s->palette; 374 for (i = 0; i < PALETTE_COUNT; i++) { 375 r = raw_palette[palette_index++] * 4; 376 g = raw_palette[palette_index++] * 4; 377 b = raw_palette[palette_index++] * 4; 378 palette32[i] = (r << 16) | (g << 8) | (b); 379 } 380 381 return 0; 382} 383 384static int vmdvideo_decode_frame(AVCodecContext *avctx, 385 void *data, int *data_size, 386 AVPacket *avpkt) 387{ 388 const uint8_t *buf = avpkt->data; 389 int buf_size = avpkt->size; 390 VmdVideoContext *s = avctx->priv_data; 391 392 s->buf = buf; 393 s->size = buf_size; 394 395 if (buf_size < 16) 396 return buf_size; 397 398 s->frame.reference = 1; 399 if (avctx->get_buffer(avctx, &s->frame)) { 400 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); 401 return -1; 402 } 403 404 vmd_decode(s); 405 406 /* make the palette available on the way out */ 407 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); 408 409 /* shuffle frames */ 410 FFSWAP(AVFrame, s->frame, s->prev_frame); 411 if (s->frame.data[0]) 412 avctx->release_buffer(avctx, &s->frame); 413 414 *data_size = sizeof(AVFrame); 415 *(AVFrame*)data = s->prev_frame; 416 417 /* report that the buffer was completely consumed */ 418 return buf_size; 419} 420 421static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) 422{ 423 VmdVideoContext *s = avctx->priv_data; 424 425 if (s->prev_frame.data[0]) 426 avctx->release_buffer(avctx, &s->prev_frame); 427 av_free(s->unpack_buffer); 428 429 return 0; 430} 431 432 433/* 434 * Audio Decoder 435 */ 436 437#define BLOCK_TYPE_AUDIO 1 438#define BLOCK_TYPE_INITIAL 2 439#define BLOCK_TYPE_SILENCE 3 440 441typedef struct VmdAudioContext { 442 AVFrame frame; 443 int out_bps; 444 int chunk_size; 445} VmdAudioContext; 446 447static const uint16_t vmdaudio_table[128] = { 448 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 449 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 450 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 451 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 452 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, 453 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, 454 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 455 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, 456 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, 457 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, 458 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 459 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, 460 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 461}; 462 463static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) 464{ 465 VmdAudioContext *s = avctx->priv_data; 466 467 if (avctx->channels < 1 || avctx->channels > 2) { 468 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n"); 469 return AVERROR(EINVAL); 470 } 471 if (avctx->block_align < 1) { 472 av_log(avctx, AV_LOG_ERROR, "invalid block align\n"); 473 return AVERROR(EINVAL); 474 } 475 476 if (avctx->bits_per_coded_sample == 16) 477 avctx->sample_fmt = AV_SAMPLE_FMT_S16; 478 else 479 avctx->sample_fmt = AV_SAMPLE_FMT_U8; 480 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); 481 482 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2); 483 484 avcodec_get_frame_defaults(&s->frame); 485 avctx->coded_frame = &s->frame; 486 487 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " 488 "block align = %d, sample rate = %d\n", 489 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, 490 avctx->sample_rate); 491 492 return 0; 493} 494 495static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size, 496 int channels) 497{ 498 int ch; 499 const uint8_t *buf_end = buf + buf_size; 500 int predictor[2]; 501 int st = channels - 1; 502 503 /* decode initial raw sample */ 504 for (ch = 0; ch < channels; ch++) { 505 predictor[ch] = (int16_t)AV_RL16(buf); 506 buf += 2; 507 *out++ = predictor[ch]; 508 } 509 510 /* decode DPCM samples */ 511 ch = 0; 512 while (buf < buf_end) { 513 uint8_t b = *buf++; 514 if (b & 0x80) 515 predictor[ch] -= vmdaudio_table[b & 0x7F]; 516 else 517 predictor[ch] += vmdaudio_table[b]; 518 predictor[ch] = av_clip_int16(predictor[ch]); 519 *out++ = predictor[ch]; 520 ch ^= st; 521 } 522} 523 524static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, 525 int *got_frame_ptr, AVPacket *avpkt) 526{ 527 const uint8_t *buf = avpkt->data; 528 const uint8_t *buf_end; 529 int buf_size = avpkt->size; 530 VmdAudioContext *s = avctx->priv_data; 531 int block_type, silent_chunks, audio_chunks; 532 int ret; 533 uint8_t *output_samples_u8; 534 int16_t *output_samples_s16; 535 536 if (buf_size < 16) { 537 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); 538 *got_frame_ptr = 0; 539 return buf_size; 540 } 541 542 block_type = buf[6]; 543 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) { 544 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type); 545 return AVERROR(EINVAL); 546 } 547 buf += 16; 548 buf_size -= 16; 549 550 /* get number of silent chunks */ 551 silent_chunks = 0; 552 if (block_type == BLOCK_TYPE_INITIAL) { 553 uint32_t flags; 554 if (buf_size < 4) { 555 av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); 556 return AVERROR(EINVAL); 557 } 558 flags = AV_RB32(buf); 559 silent_chunks = av_popcount(flags); 560 buf += 4; 561 buf_size -= 4; 562 } else if (block_type == BLOCK_TYPE_SILENCE) { 563 silent_chunks = 1; 564 buf_size = 0; // should already be zero but set it just to be sure 565 } 566 567 /* ensure output buffer is large enough */ 568 audio_chunks = buf_size / s->chunk_size; 569 570 /* get output buffer */ 571 s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; 572 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { 573 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 574 return ret; 575 } 576 output_samples_u8 = s->frame.data[0]; 577 output_samples_s16 = (int16_t *)s->frame.data[0]; 578 579 /* decode silent chunks */ 580 if (silent_chunks > 0) { 581 int silent_size = avctx->block_align * silent_chunks; 582 if (s->out_bps == 2) { 583 memset(output_samples_s16, 0x00, silent_size * 2); 584 output_samples_s16 += silent_size; 585 } else { 586 memset(output_samples_u8, 0x80, silent_size); 587 output_samples_u8 += silent_size; 588 } 589 } 590 591 /* decode audio chunks */ 592 if (audio_chunks > 0) { 593 buf_end = buf + buf_size; 594 while (buf + s->chunk_size <= buf_end) { 595 if (s->out_bps == 2) { 596 decode_audio_s16(output_samples_s16, buf, s->chunk_size, 597 avctx->channels); 598 output_samples_s16 += avctx->block_align; 599 } else { 600 memcpy(output_samples_u8, buf, s->chunk_size); 601 output_samples_u8 += avctx->block_align; 602 } 603 buf += s->chunk_size; 604 } 605 } 606 607 *got_frame_ptr = 1; 608 *(AVFrame *)data = s->frame; 609 610 return avpkt->size; 611} 612 613 614/* 615 * Public Data Structures 616 */ 617 618AVCodec ff_vmdvideo_decoder = { 619 .name = "vmdvideo", 620 .type = AVMEDIA_TYPE_VIDEO, 621 .id = CODEC_ID_VMDVIDEO, 622 .priv_data_size = sizeof(VmdVideoContext), 623 .init = vmdvideo_decode_init, 624 .close = vmdvideo_decode_end, 625 .decode = vmdvideo_decode_frame, 626 .capabilities = CODEC_CAP_DR1, 627 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), 628}; 629 630AVCodec ff_vmdaudio_decoder = { 631 .name = "vmdaudio", 632 .type = AVMEDIA_TYPE_AUDIO, 633 .id = CODEC_ID_VMDAUDIO, 634 .priv_data_size = sizeof(VmdAudioContext), 635 .init = vmdaudio_decode_init, 636 .decode = vmdaudio_decode_frame, 637 .capabilities = CODEC_CAP_DR1, 638 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), 639}; 640