1/* 2 * Sierra VMD Audio & Video Decoders 3 * Copyright (C) 2004 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 libavcodec/vmdav.c 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#include <unistd.h> 46 47#include "libavutil/intreadwrite.h" 48#include "avcodec.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, unsigned char *dest, int dest_len) 77{ 78 const unsigned char *s; 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 90 s = src; 91 d = dest; 92 d_end = d + dest_len; 93 dataleft = AV_RL32(s); 94 s += 4; 95 memset(queue, 0x20, QUEUE_SIZE); 96 if (AV_RL32(s) == 0x56781234) { 97 s += 4; 98 qpos = 0x111; 99 speclen = 0xF + 3; 100 } else { 101 qpos = 0xFEE; 102 speclen = 100; /* no speclen */ 103 } 104 105 while (dataleft > 0) { 106 tag = *s++; 107 if ((tag == 0xFF) && (dataleft > 8)) { 108 if (d + 8 > d_end) 109 return; 110 for (i = 0; i < 8; i++) { 111 queue[qpos++] = *d++ = *s++; 112 qpos &= QUEUE_MASK; 113 } 114 dataleft -= 8; 115 } else { 116 for (i = 0; i < 8; i++) { 117 if (dataleft == 0) 118 break; 119 if (tag & 0x01) { 120 if (d + 1 > d_end) 121 return; 122 queue[qpos++] = *d++ = *s++; 123 qpos &= QUEUE_MASK; 124 dataleft--; 125 } else { 126 chainofs = *s++; 127 chainofs |= ((*s & 0xF0) << 4); 128 chainlen = (*s++ & 0x0F) + 3; 129 if (chainlen == speclen) 130 chainlen = *s++ + 0xF + 3; 131 if (d + chainlen > d_end) 132 return; 133 for (j = 0; j < chainlen; j++) { 134 *d = queue[chainofs++ & QUEUE_MASK]; 135 queue[qpos++] = *d++; 136 qpos &= QUEUE_MASK; 137 } 138 dataleft -= chainlen; 139 } 140 tag >>= 1; 141 } 142 } 143 } 144} 145 146static int rle_unpack(const unsigned char *src, unsigned char *dest, 147 int src_len, int dest_len) 148{ 149 const unsigned char *ps; 150 unsigned char *pd; 151 int i, l; 152 unsigned char *dest_end = dest + dest_len; 153 154 ps = src; 155 pd = dest; 156 if (src_len & 1) 157 *pd++ = *ps++; 158 159 src_len >>= 1; 160 i = 0; 161 do { 162 l = *ps++; 163 if (l & 0x80) { 164 l = (l & 0x7F) * 2; 165 if (pd + l > dest_end) 166 return ps - src; 167 memcpy(pd, ps, l); 168 ps += l; 169 pd += l; 170 } else { 171 if (pd + i > dest_end) 172 return ps - src; 173 for (i = 0; i < l; i++) { 174 *pd++ = ps[0]; 175 *pd++ = ps[1]; 176 } 177 ps += 2; 178 } 179 i += l; 180 } while (i < src_len); 181 182 return ps - src; 183} 184 185static void vmd_decode(VmdVideoContext *s) 186{ 187 int i; 188 unsigned int *palette32; 189 unsigned char r, g, b; 190 191 /* point to the start of the encoded data */ 192 const unsigned char *p = s->buf + 16; 193 194 const unsigned char *pb; 195 unsigned char meth; 196 unsigned char *dp; /* pointer to current frame */ 197 unsigned char *pp; /* pointer to previous frame */ 198 unsigned char len; 199 int ofs; 200 201 int frame_x, frame_y; 202 int frame_width, frame_height; 203 int dp_size; 204 205 frame_x = AV_RL16(&s->buf[6]); 206 frame_y = AV_RL16(&s->buf[8]); 207 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; 208 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; 209 210 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && 211 (frame_x || frame_y)) { 212 213 s->x_off = frame_x; 214 s->y_off = frame_y; 215 } 216 frame_x -= s->x_off; 217 frame_y -= s->y_off; 218 219 /* if only a certain region will be updated, copy the entire previous 220 * frame before the decode */ 221 if (frame_x || frame_y || (frame_width != s->avctx->width) || 222 (frame_height != s->avctx->height)) { 223 224 memcpy(s->frame.data[0], s->prev_frame.data[0], 225 s->avctx->height * s->frame.linesize[0]); 226 } 227 228 /* check if there is a new palette */ 229 if (s->buf[15] & 0x02) { 230 p += 2; 231 palette32 = (unsigned int *)s->palette; 232 for (i = 0; i < PALETTE_COUNT; i++) { 233 r = *p++ * 4; 234 g = *p++ * 4; 235 b = *p++ * 4; 236 palette32[i] = (r << 16) | (g << 8) | (b); 237 } 238 s->size -= (256 * 3 + 2); 239 } 240 if (s->size >= 0) { 241 /* originally UnpackFrame in VAG's code */ 242 pb = p; 243 meth = *pb++; 244 if (meth & 0x80) { 245 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); 246 meth &= 0x7F; 247 pb = s->unpack_buffer; 248 } 249 250 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 251 dp_size = s->frame.linesize[0] * s->avctx->height; 252 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 253 switch (meth) { 254 case 1: 255 for (i = 0; i < frame_height; i++) { 256 ofs = 0; 257 do { 258 len = *pb++; 259 if (len & 0x80) { 260 len = (len & 0x7F) + 1; 261 if (ofs + len > frame_width) 262 return; 263 memcpy(&dp[ofs], pb, len); 264 pb += len; 265 ofs += len; 266 } else { 267 /* interframe pixel copy */ 268 if (ofs + len + 1 > frame_width) 269 return; 270 memcpy(&dp[ofs], &pp[ofs], len + 1); 271 ofs += len + 1; 272 } 273 } while (ofs < frame_width); 274 if (ofs > frame_width) { 275 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 276 ofs, frame_width); 277 break; 278 } 279 dp += s->frame.linesize[0]; 280 pp += s->prev_frame.linesize[0]; 281 } 282 break; 283 284 case 2: 285 for (i = 0; i < frame_height; i++) { 286 memcpy(dp, pb, frame_width); 287 pb += frame_width; 288 dp += s->frame.linesize[0]; 289 pp += s->prev_frame.linesize[0]; 290 } 291 break; 292 293 case 3: 294 for (i = 0; i < frame_height; i++) { 295 ofs = 0; 296 do { 297 len = *pb++; 298 if (len & 0x80) { 299 len = (len & 0x7F) + 1; 300 if (*pb++ == 0xFF) 301 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); 302 else 303 memcpy(&dp[ofs], pb, len); 304 pb += len; 305 ofs += len; 306 } else { 307 /* interframe pixel copy */ 308 if (ofs + len + 1 > frame_width) 309 return; 310 memcpy(&dp[ofs], &pp[ofs], len + 1); 311 ofs += len + 1; 312 } 313 } while (ofs < frame_width); 314 if (ofs > frame_width) { 315 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 316 ofs, frame_width); 317 } 318 dp += s->frame.linesize[0]; 319 pp += s->prev_frame.linesize[0]; 320 } 321 break; 322 } 323 } 324} 325 326static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) 327{ 328 VmdVideoContext *s = avctx->priv_data; 329 int i; 330 unsigned int *palette32; 331 int palette_index = 0; 332 unsigned char r, g, b; 333 unsigned char *vmd_header; 334 unsigned char *raw_palette; 335 336 s->avctx = avctx; 337 avctx->pix_fmt = PIX_FMT_PAL8; 338 339 /* make sure the VMD header made it */ 340 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { 341 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", 342 VMD_HEADER_SIZE); 343 return -1; 344 } 345 vmd_header = (unsigned char *)avctx->extradata; 346 347 s->unpack_buffer_size = AV_RL32(&vmd_header[800]); 348 s->unpack_buffer = av_malloc(s->unpack_buffer_size); 349 if (!s->unpack_buffer) 350 return -1; 351 352 /* load up the initial palette */ 353 raw_palette = &vmd_header[28]; 354 palette32 = (unsigned int *)s->palette; 355 for (i = 0; i < PALETTE_COUNT; i++) { 356 r = raw_palette[palette_index++] * 4; 357 g = raw_palette[palette_index++] * 4; 358 b = raw_palette[palette_index++] * 4; 359 palette32[i] = (r << 16) | (g << 8) | (b); 360 } 361 362 s->frame.data[0] = s->prev_frame.data[0] = NULL; 363 364 return 0; 365} 366 367static int vmdvideo_decode_frame(AVCodecContext *avctx, 368 void *data, int *data_size, 369 const uint8_t *buf, int buf_size) 370{ 371 VmdVideoContext *s = avctx->priv_data; 372 373 s->buf = buf; 374 s->size = buf_size; 375 376 if (buf_size < 16) 377 return buf_size; 378 379 s->frame.reference = 1; 380 if (avctx->get_buffer(avctx, &s->frame)) { 381 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); 382 return -1; 383 } 384 385 vmd_decode(s); 386 387 /* make the palette available on the way out */ 388 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); 389 390 /* shuffle frames */ 391 FFSWAP(AVFrame, s->frame, s->prev_frame); 392 if (s->frame.data[0]) 393 avctx->release_buffer(avctx, &s->frame); 394 395 *data_size = sizeof(AVFrame); 396 *(AVFrame*)data = s->prev_frame; 397 398 /* report that the buffer was completely consumed */ 399 return buf_size; 400} 401 402static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) 403{ 404 VmdVideoContext *s = avctx->priv_data; 405 406 if (s->prev_frame.data[0]) 407 avctx->release_buffer(avctx, &s->prev_frame); 408 av_free(s->unpack_buffer); 409 410 return 0; 411} 412 413 414/* 415 * Audio Decoder 416 */ 417 418typedef struct VmdAudioContext { 419 AVCodecContext *avctx; 420 int channels; 421 int bits; 422 int block_align; 423 int predictors[2]; 424} VmdAudioContext; 425 426static const uint16_t vmdaudio_table[128] = { 427 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 428 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 429 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 430 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 431 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, 432 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, 433 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 434 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, 435 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, 436 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, 437 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 438 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, 439 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 440}; 441 442static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) 443{ 444 VmdAudioContext *s = avctx->priv_data; 445 446 s->avctx = avctx; 447 s->channels = avctx->channels; 448 s->bits = avctx->bits_per_coded_sample; 449 s->block_align = avctx->block_align; 450 avctx->sample_fmt = SAMPLE_FMT_S16; 451 452 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", 453 s->channels, s->bits, s->block_align, avctx->sample_rate); 454 455 return 0; 456} 457 458static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, 459 const uint8_t *buf, int buf_size, int stereo) 460{ 461 int i; 462 int chan = 0; 463 int16_t *out = (int16_t*)data; 464 465 for(i = 0; i < buf_size; i++) { 466 if(buf[i] & 0x80) 467 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; 468 else 469 s->predictors[chan] += vmdaudio_table[buf[i]]; 470 s->predictors[chan] = av_clip_int16(s->predictors[chan]); 471 out[i] = s->predictors[chan]; 472 chan ^= stereo; 473 } 474} 475 476static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, 477 const uint8_t *buf, int silence, int data_size) 478{ 479 int bytes_decoded = 0; 480 int i; 481 482// if (silence) 483// av_log(s->avctx, AV_LOG_INFO, "silent block!\n"); 484 if (s->channels == 2) { 485 486 /* stereo handling */ 487 if (silence) { 488 memset(data, 0, data_size * 2); 489 } else { 490 if (s->bits == 16) 491 vmdaudio_decode_audio(s, data, buf, data_size, 1); 492 else { 493 /* copy the data but convert it to signed */ 494 for (i = 0; i < data_size; i++){ 495 *data++ = buf[i] + 0x80; 496 *data++ = buf[i] + 0x80; 497 } 498 } 499 } 500 } else { 501 bytes_decoded = data_size * 2; 502 503 /* mono handling */ 504 if (silence) { 505 memset(data, 0, data_size * 2); 506 } else { 507 if (s->bits == 16) { 508 vmdaudio_decode_audio(s, data, buf, data_size, 0); 509 } else { 510 /* copy the data but convert it to signed */ 511 for (i = 0; i < data_size; i++){ 512 *data++ = buf[i] + 0x80; 513 *data++ = buf[i] + 0x80; 514 } 515 } 516 } 517 } 518 519 return data_size * 2; 520} 521 522static int vmdaudio_decode_frame(AVCodecContext *avctx, 523 void *data, int *data_size, 524 const uint8_t *buf, int buf_size) 525{ 526 VmdAudioContext *s = avctx->priv_data; 527 unsigned char *output_samples = (unsigned char *)data; 528 529 /* point to the start of the encoded data */ 530 const unsigned char *p = buf + 16; 531 532 if (buf_size < 16) 533 return buf_size; 534 535 if (buf[6] == 1) { 536 /* the chunk contains audio */ 537 *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16); 538 } else if (buf[6] == 2) { 539 /* initial chunk, may contain audio and silence */ 540 uint32_t flags = AV_RB32(p); 541 int raw_block_size = s->block_align * s->bits / 8; 542 int silent_chunks; 543 if(flags == 0xFFFFFFFF) 544 silent_chunks = 32; 545 else 546 silent_chunks = av_log2(flags + 1); 547 if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2) 548 return -1; 549 *data_size = 0; 550 memset(output_samples, 0, raw_block_size * silent_chunks); 551 output_samples += raw_block_size * silent_chunks; 552 *data_size = raw_block_size * silent_chunks; 553 *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20); 554 } else if (buf[6] == 3) { 555 /* silent chunk */ 556 *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0); 557 } 558 559 return buf_size; 560} 561 562 563/* 564 * Public Data Structures 565 */ 566 567AVCodec vmdvideo_decoder = { 568 "vmdvideo", 569 CODEC_TYPE_VIDEO, 570 CODEC_ID_VMDVIDEO, 571 sizeof(VmdVideoContext), 572 vmdvideo_decode_init, 573 NULL, 574 vmdvideo_decode_end, 575 vmdvideo_decode_frame, 576 CODEC_CAP_DR1, 577 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), 578}; 579 580AVCodec vmdaudio_decoder = { 581 "vmdaudio", 582 CODEC_TYPE_AUDIO, 583 CODEC_ID_VMDAUDIO, 584 sizeof(VmdAudioContext), 585 vmdaudio_decode_init, 586 NULL, 587 NULL, 588 vmdaudio_decode_frame, 589 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), 590}; 591