Libav
|
00001 /* 00002 * Sierra VMD Audio & Video Decoders 00003 * Copyright (C) 2004 the ffmpeg project 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00042 #include <stdio.h> 00043 #include <stdlib.h> 00044 #include <string.h> 00045 00046 #include "libavutil/intreadwrite.h" 00047 #include "avcodec.h" 00048 00049 #define VMD_HEADER_SIZE 0x330 00050 #define PALETTE_COUNT 256 00051 00052 /* 00053 * Video Decoder 00054 */ 00055 00056 typedef struct VmdVideoContext { 00057 00058 AVCodecContext *avctx; 00059 AVFrame frame; 00060 AVFrame prev_frame; 00061 00062 const unsigned char *buf; 00063 int size; 00064 00065 unsigned char palette[PALETTE_COUNT * 4]; 00066 unsigned char *unpack_buffer; 00067 int unpack_buffer_size; 00068 00069 int x_off, y_off; 00070 } VmdVideoContext; 00071 00072 #define QUEUE_SIZE 0x1000 00073 #define QUEUE_MASK 0x0FFF 00074 00075 static void lz_unpack(const unsigned char *src, int src_len, 00076 unsigned char *dest, int dest_len) 00077 { 00078 const unsigned char *s; 00079 unsigned int s_len; 00080 unsigned char *d; 00081 unsigned char *d_end; 00082 unsigned char queue[QUEUE_SIZE]; 00083 unsigned int qpos; 00084 unsigned int dataleft; 00085 unsigned int chainofs; 00086 unsigned int chainlen; 00087 unsigned int speclen; 00088 unsigned char tag; 00089 unsigned int i, j; 00090 00091 s = src; 00092 s_len = src_len; 00093 d = dest; 00094 d_end = d + dest_len; 00095 dataleft = AV_RL32(s); 00096 s += 4; s_len -= 4; 00097 memset(queue, 0x20, QUEUE_SIZE); 00098 if (s_len < 4) 00099 return; 00100 if (AV_RL32(s) == 0x56781234) { 00101 s += 4; s_len -= 4; 00102 qpos = 0x111; 00103 speclen = 0xF + 3; 00104 } else { 00105 qpos = 0xFEE; 00106 speclen = 100; /* no speclen */ 00107 } 00108 00109 while (dataleft > 0 && s_len > 0) { 00110 tag = *s++; s_len--; 00111 if ((tag == 0xFF) && (dataleft > 8)) { 00112 if (d + 8 > d_end || s_len < 8) 00113 return; 00114 for (i = 0; i < 8; i++) { 00115 queue[qpos++] = *d++ = *s++; 00116 qpos &= QUEUE_MASK; 00117 } 00118 s_len -= 8; 00119 dataleft -= 8; 00120 } else { 00121 for (i = 0; i < 8; i++) { 00122 if (dataleft == 0) 00123 break; 00124 if (tag & 0x01) { 00125 if (d + 1 > d_end || s_len < 1) 00126 return; 00127 queue[qpos++] = *d++ = *s++; 00128 qpos &= QUEUE_MASK; 00129 dataleft--; 00130 s_len--; 00131 } else { 00132 if (s_len < 2) 00133 return; 00134 chainofs = *s++; 00135 chainofs |= ((*s & 0xF0) << 4); 00136 chainlen = (*s++ & 0x0F) + 3; 00137 s_len -= 2; 00138 if (chainlen == speclen) { 00139 if (s_len < 1) 00140 return; 00141 chainlen = *s++ + 0xF + 3; 00142 s_len--; 00143 } 00144 if (d + chainlen > d_end) 00145 return; 00146 for (j = 0; j < chainlen; j++) { 00147 *d = queue[chainofs++ & QUEUE_MASK]; 00148 queue[qpos++] = *d++; 00149 qpos &= QUEUE_MASK; 00150 } 00151 dataleft -= chainlen; 00152 } 00153 tag >>= 1; 00154 } 00155 } 00156 } 00157 } 00158 00159 static int rle_unpack(const unsigned char *src, unsigned char *dest, 00160 int src_count, int src_size, int dest_len) 00161 { 00162 const unsigned char *ps; 00163 unsigned char *pd; 00164 int i, l; 00165 unsigned char *dest_end = dest + dest_len; 00166 00167 ps = src; 00168 pd = dest; 00169 if (src_count & 1) { 00170 if (src_size < 1) 00171 return 0; 00172 *pd++ = *ps++; 00173 src_size--; 00174 } 00175 00176 src_count >>= 1; 00177 i = 0; 00178 do { 00179 if (src_size < 1) 00180 break; 00181 l = *ps++; 00182 src_size--; 00183 if (l & 0x80) { 00184 l = (l & 0x7F) * 2; 00185 if (pd + l > dest_end || src_size < l) 00186 return ps - src; 00187 memcpy(pd, ps, l); 00188 ps += l; 00189 src_size -= l; 00190 pd += l; 00191 } else { 00192 if (pd + i > dest_end || src_size < 2) 00193 return ps - src; 00194 for (i = 0; i < l; i++) { 00195 *pd++ = ps[0]; 00196 *pd++ = ps[1]; 00197 } 00198 ps += 2; 00199 src_size -= 2; 00200 } 00201 i += l; 00202 } while (i < src_count); 00203 00204 return ps - src; 00205 } 00206 00207 static void vmd_decode(VmdVideoContext *s) 00208 { 00209 int i; 00210 unsigned int *palette32; 00211 unsigned char r, g, b; 00212 00213 /* point to the start of the encoded data */ 00214 const unsigned char *p = s->buf + 16; 00215 00216 const unsigned char *pb; 00217 unsigned int pb_size; 00218 unsigned char meth; 00219 unsigned char *dp; /* pointer to current frame */ 00220 unsigned char *pp; /* pointer to previous frame */ 00221 unsigned char len; 00222 int ofs; 00223 00224 int frame_x, frame_y; 00225 int frame_width, frame_height; 00226 int dp_size; 00227 00228 frame_x = AV_RL16(&s->buf[6]); 00229 frame_y = AV_RL16(&s->buf[8]); 00230 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; 00231 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; 00232 if (frame_x < 0 || frame_width < 0 || 00233 frame_x >= s->avctx->width || 00234 frame_width > s->avctx->width || 00235 frame_x + frame_width > s->avctx->width) 00236 return; 00237 if (frame_y < 0 || frame_height < 0 || 00238 frame_y >= s->avctx->height || 00239 frame_height > s->avctx->height || 00240 frame_y + frame_height > s->avctx->height) 00241 return; 00242 00243 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && 00244 (frame_x || frame_y)) { 00245 00246 s->x_off = frame_x; 00247 s->y_off = frame_y; 00248 } 00249 frame_x -= s->x_off; 00250 frame_y -= s->y_off; 00251 00252 /* if only a certain region will be updated, copy the entire previous 00253 * frame before the decode */ 00254 if (s->prev_frame.data[0] && 00255 (frame_x || frame_y || (frame_width != s->avctx->width) || 00256 (frame_height != s->avctx->height))) { 00257 00258 memcpy(s->frame.data[0], s->prev_frame.data[0], 00259 s->avctx->height * s->frame.linesize[0]); 00260 } 00261 00262 /* check if there is a new palette */ 00263 if (s->buf[15] & 0x02) { 00264 p += 2; 00265 palette32 = (unsigned int *)s->palette; 00266 for (i = 0; i < PALETTE_COUNT; i++) { 00267 r = *p++ * 4; 00268 g = *p++ * 4; 00269 b = *p++ * 4; 00270 palette32[i] = (r << 16) | (g << 8) | (b); 00271 } 00272 s->size -= (256 * 3 + 2); 00273 } 00274 if (s->size > 0) { 00275 /* originally UnpackFrame in VAG's code */ 00276 pb = p; 00277 pb_size = s->buf + s->size - pb; 00278 if (pb_size < 1) 00279 return; 00280 meth = *pb++; pb_size--; 00281 if (meth & 0x80) { 00282 lz_unpack(pb, pb_size, 00283 s->unpack_buffer, s->unpack_buffer_size); 00284 meth &= 0x7F; 00285 pb = s->unpack_buffer; 00286 pb_size = s->unpack_buffer_size; 00287 } 00288 00289 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 00290 dp_size = s->frame.linesize[0] * s->avctx->height; 00291 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 00292 switch (meth) { 00293 case 1: 00294 for (i = 0; i < frame_height; i++) { 00295 ofs = 0; 00296 do { 00297 if (pb_size < 1) 00298 return; 00299 len = *pb++; 00300 pb_size--; 00301 if (len & 0x80) { 00302 len = (len & 0x7F) + 1; 00303 if (ofs + len > frame_width || pb_size < len) 00304 return; 00305 memcpy(&dp[ofs], pb, len); 00306 pb += len; 00307 pb_size -= len; 00308 ofs += len; 00309 } else { 00310 /* interframe pixel copy */ 00311 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) 00312 return; 00313 memcpy(&dp[ofs], &pp[ofs], len + 1); 00314 ofs += len + 1; 00315 } 00316 } while (ofs < frame_width); 00317 if (ofs > frame_width) { 00318 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00319 ofs, frame_width); 00320 break; 00321 } 00322 dp += s->frame.linesize[0]; 00323 pp += s->prev_frame.linesize[0]; 00324 } 00325 break; 00326 00327 case 2: 00328 for (i = 0; i < frame_height; i++) { 00329 if (pb_size < frame_width) 00330 return; 00331 memcpy(dp, pb, frame_width); 00332 pb += frame_width; 00333 pb_size -= frame_width; 00334 dp += s->frame.linesize[0]; 00335 pp += s->prev_frame.linesize[0]; 00336 } 00337 break; 00338 00339 case 3: 00340 for (i = 0; i < frame_height; i++) { 00341 ofs = 0; 00342 do { 00343 if (pb_size < 1) 00344 return; 00345 len = *pb++; 00346 pb_size--; 00347 if (len & 0x80) { 00348 len = (len & 0x7F) + 1; 00349 if (pb_size < 1) 00350 return; 00351 if (*pb++ == 0xFF) 00352 len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs); 00353 else { 00354 if (pb_size < len) 00355 return; 00356 memcpy(&dp[ofs], pb, len); 00357 } 00358 pb += len; 00359 pb_size -= 1 + len; 00360 ofs += len; 00361 } else { 00362 /* interframe pixel copy */ 00363 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) 00364 return; 00365 memcpy(&dp[ofs], &pp[ofs], len + 1); 00366 ofs += len + 1; 00367 } 00368 } while (ofs < frame_width); 00369 if (ofs > frame_width) { 00370 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00371 ofs, frame_width); 00372 } 00373 dp += s->frame.linesize[0]; 00374 pp += s->prev_frame.linesize[0]; 00375 } 00376 break; 00377 } 00378 } 00379 } 00380 00381 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) 00382 { 00383 VmdVideoContext *s = avctx->priv_data; 00384 int i; 00385 unsigned int *palette32; 00386 int palette_index = 0; 00387 unsigned char r, g, b; 00388 unsigned char *vmd_header; 00389 unsigned char *raw_palette; 00390 00391 s->avctx = avctx; 00392 avctx->pix_fmt = PIX_FMT_PAL8; 00393 00394 /* make sure the VMD header made it */ 00395 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { 00396 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", 00397 VMD_HEADER_SIZE); 00398 return -1; 00399 } 00400 vmd_header = (unsigned char *)avctx->extradata; 00401 00402 s->unpack_buffer_size = AV_RL32(&vmd_header[800]); 00403 s->unpack_buffer = av_malloc(s->unpack_buffer_size); 00404 if (!s->unpack_buffer) 00405 return -1; 00406 00407 /* load up the initial palette */ 00408 raw_palette = &vmd_header[28]; 00409 palette32 = (unsigned int *)s->palette; 00410 for (i = 0; i < PALETTE_COUNT; i++) { 00411 r = raw_palette[palette_index++] * 4; 00412 g = raw_palette[palette_index++] * 4; 00413 b = raw_palette[palette_index++] * 4; 00414 palette32[i] = (r << 16) | (g << 8) | (b); 00415 } 00416 00417 return 0; 00418 } 00419 00420 static int vmdvideo_decode_frame(AVCodecContext *avctx, 00421 void *data, int *data_size, 00422 AVPacket *avpkt) 00423 { 00424 const uint8_t *buf = avpkt->data; 00425 int buf_size = avpkt->size; 00426 VmdVideoContext *s = avctx->priv_data; 00427 00428 s->buf = buf; 00429 s->size = buf_size; 00430 00431 if (buf_size < 16) 00432 return buf_size; 00433 00434 s->frame.reference = 1; 00435 if (avctx->get_buffer(avctx, &s->frame)) { 00436 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); 00437 return -1; 00438 } 00439 00440 vmd_decode(s); 00441 00442 /* make the palette available on the way out */ 00443 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); 00444 00445 /* shuffle frames */ 00446 FFSWAP(AVFrame, s->frame, s->prev_frame); 00447 if (s->frame.data[0]) 00448 avctx->release_buffer(avctx, &s->frame); 00449 00450 *data_size = sizeof(AVFrame); 00451 *(AVFrame*)data = s->prev_frame; 00452 00453 /* report that the buffer was completely consumed */ 00454 return buf_size; 00455 } 00456 00457 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) 00458 { 00459 VmdVideoContext *s = avctx->priv_data; 00460 00461 if (s->prev_frame.data[0]) 00462 avctx->release_buffer(avctx, &s->prev_frame); 00463 av_free(s->unpack_buffer); 00464 00465 return 0; 00466 } 00467 00468 00469 /* 00470 * Audio Decoder 00471 */ 00472 00473 typedef struct VmdAudioContext { 00474 AVCodecContext *avctx; 00475 int channels; 00476 int bits; 00477 int block_align; 00478 int predictors[2]; 00479 } VmdAudioContext; 00480 00481 static const uint16_t vmdaudio_table[128] = { 00482 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 00483 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 00484 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 00485 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 00486 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, 00487 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, 00488 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 00489 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, 00490 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, 00491 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, 00492 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 00493 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, 00494 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 00495 }; 00496 00497 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) 00498 { 00499 VmdAudioContext *s = avctx->priv_data; 00500 00501 s->avctx = avctx; 00502 s->channels = avctx->channels; 00503 s->bits = avctx->bits_per_coded_sample; 00504 s->block_align = avctx->block_align; 00505 avctx->sample_fmt = SAMPLE_FMT_S16; 00506 00507 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", 00508 s->channels, s->bits, s->block_align, avctx->sample_rate); 00509 00510 return 0; 00511 } 00512 00513 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, 00514 const uint8_t *buf, int buf_size, int stereo) 00515 { 00516 int i; 00517 int chan = 0; 00518 int16_t *out = (int16_t*)data; 00519 00520 for(i = 0; i < buf_size; i++) { 00521 if(buf[i] & 0x80) 00522 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; 00523 else 00524 s->predictors[chan] += vmdaudio_table[buf[i]]; 00525 s->predictors[chan] = av_clip_int16(s->predictors[chan]); 00526 out[i] = s->predictors[chan]; 00527 chan ^= stereo; 00528 } 00529 } 00530 00531 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, 00532 const uint8_t *buf, int silence, int data_size) 00533 { 00534 int bytes_decoded = 0; 00535 int i; 00536 00537 // if (silence) 00538 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n"); 00539 if (s->channels == 2) { 00540 00541 /* stereo handling */ 00542 if (silence) { 00543 memset(data, 0, data_size * 2); 00544 } else { 00545 if (s->bits == 16) 00546 vmdaudio_decode_audio(s, data, buf, data_size, 1); 00547 else { 00548 /* copy the data but convert it to signed */ 00549 for (i = 0; i < data_size; i++){ 00550 *data++ = buf[i] + 0x80; 00551 *data++ = buf[i] + 0x80; 00552 } 00553 } 00554 } 00555 } else { 00556 bytes_decoded = data_size * 2; 00557 00558 /* mono handling */ 00559 if (silence) { 00560 memset(data, 0, data_size * 2); 00561 } else { 00562 if (s->bits == 16) { 00563 vmdaudio_decode_audio(s, data, buf, data_size, 0); 00564 } else { 00565 /* copy the data but convert it to signed */ 00566 for (i = 0; i < data_size; i++){ 00567 *data++ = buf[i] + 0x80; 00568 *data++ = buf[i] + 0x80; 00569 } 00570 } 00571 } 00572 } 00573 00574 return data_size * 2; 00575 } 00576 00577 static int vmdaudio_decode_frame(AVCodecContext *avctx, 00578 void *data, int *data_size, 00579 AVPacket *avpkt) 00580 { 00581 const uint8_t *buf = avpkt->data; 00582 int buf_size = avpkt->size; 00583 VmdAudioContext *s = avctx->priv_data; 00584 unsigned char *output_samples = (unsigned char *)data; 00585 00586 /* point to the start of the encoded data */ 00587 const unsigned char *p = buf + 16; 00588 00589 if (buf_size < 16) 00590 return buf_size; 00591 00592 if (buf[6] == 1) { 00593 /* the chunk contains audio */ 00594 *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16); 00595 } else if (buf[6] == 2) { 00596 /* initial chunk, may contain audio and silence */ 00597 uint32_t flags = AV_RB32(p); 00598 int raw_block_size = s->block_align * s->bits / 8; 00599 int silent_chunks; 00600 if(flags == 0xFFFFFFFF) 00601 silent_chunks = 32; 00602 else 00603 silent_chunks = av_log2(flags + 1); 00604 if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2) 00605 return -1; 00606 *data_size = 0; 00607 memset(output_samples, 0, raw_block_size * silent_chunks); 00608 output_samples += raw_block_size * silent_chunks; 00609 *data_size = raw_block_size * silent_chunks; 00610 *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20); 00611 } else if (buf[6] == 3) { 00612 /* silent chunk */ 00613 *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0); 00614 } 00615 00616 return buf_size; 00617 } 00618 00619 00620 /* 00621 * Public Data Structures 00622 */ 00623 00624 AVCodec vmdvideo_decoder = { 00625 "vmdvideo", 00626 AVMEDIA_TYPE_VIDEO, 00627 CODEC_ID_VMDVIDEO, 00628 sizeof(VmdVideoContext), 00629 vmdvideo_decode_init, 00630 NULL, 00631 vmdvideo_decode_end, 00632 vmdvideo_decode_frame, 00633 CODEC_CAP_DR1, 00634 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), 00635 }; 00636 00637 AVCodec vmdaudio_decoder = { 00638 "vmdaudio", 00639 AVMEDIA_TYPE_AUDIO, 00640 CODEC_ID_VMDAUDIO, 00641 sizeof(VmdAudioContext), 00642 vmdaudio_decode_init, 00643 NULL, 00644 NULL, 00645 vmdaudio_decode_frame, 00646 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), 00647 };