00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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 const unsigned char *s_end;
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_end = src + src_len;
00093 d = dest;
00094 d_end = d + dest_len;
00095
00096 if (s_end - s < 8)
00097 return;
00098 dataleft = AV_RL32(s);
00099 s += 4;
00100 memset(queue, 0x20, QUEUE_SIZE);
00101 if (AV_RL32(s) == 0x56781234) {
00102 s += 4;
00103 qpos = 0x111;
00104 speclen = 0xF + 3;
00105 } else {
00106 qpos = 0xFEE;
00107 speclen = 100;
00108 }
00109
00110 while (s_end - s > 0 && dataleft > 0) {
00111 tag = *s++;
00112 if ((tag == 0xFF) && (dataleft > 8)) {
00113 if (d_end - d < 8 || s_end - s < 8)
00114 return;
00115 for (i = 0; i < 8; i++) {
00116 queue[qpos++] = *d++ = *s++;
00117 qpos &= QUEUE_MASK;
00118 }
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_end - d < 1 || s_end - s < 1)
00126 return;
00127 queue[qpos++] = *d++ = *s++;
00128 qpos &= QUEUE_MASK;
00129 dataleft--;
00130 } else {
00131 if (s_end - s < 2)
00132 return;
00133 chainofs = *s++;
00134 chainofs |= ((*s & 0xF0) << 4);
00135 chainlen = (*s++ & 0x0F) + 3;
00136 if (chainlen == speclen) {
00137 if (s_end - s < 1)
00138 return;
00139 chainlen = *s++ + 0xF + 3;
00140 }
00141 if (d_end - d < chainlen)
00142 return;
00143 for (j = 0; j < chainlen; j++) {
00144 *d = queue[chainofs++ & QUEUE_MASK];
00145 queue[qpos++] = *d++;
00146 qpos &= QUEUE_MASK;
00147 }
00148 dataleft -= chainlen;
00149 }
00150 tag >>= 1;
00151 }
00152 }
00153 }
00154 }
00155
00156 static int rle_unpack(const unsigned char *src, int src_len, int src_count,
00157 unsigned char *dest, int dest_len)
00158 {
00159 const unsigned char *ps;
00160 const unsigned char *ps_end;
00161 unsigned char *pd;
00162 int i, l;
00163 unsigned char *dest_end = dest + dest_len;
00164
00165 ps = src;
00166 ps_end = src + src_len;
00167 pd = dest;
00168 if (src_count & 1) {
00169 if (ps_end - ps < 1)
00170 return 0;
00171 *pd++ = *ps++;
00172 }
00173
00174 src_count >>= 1;
00175 i = 0;
00176 do {
00177 if (ps_end - ps < 1)
00178 break;
00179 l = *ps++;
00180 if (l & 0x80) {
00181 l = (l & 0x7F) * 2;
00182 if (dest_end - pd < l || ps_end - ps < l)
00183 return ps - src;
00184 memcpy(pd, ps, l);
00185 ps += l;
00186 pd += l;
00187 } else {
00188 if (dest_end - pd < i || ps_end - ps < 2)
00189 return ps - src;
00190 for (i = 0; i < l; i++) {
00191 *pd++ = ps[0];
00192 *pd++ = ps[1];
00193 }
00194 ps += 2;
00195 }
00196 i += l;
00197 } while (i < src_count);
00198
00199 return ps - src;
00200 }
00201
00202 static void vmd_decode(VmdVideoContext *s)
00203 {
00204 int i;
00205 unsigned int *palette32;
00206 unsigned char r, g, b;
00207
00208
00209 const unsigned char *p = s->buf + 16;
00210 const unsigned char *p_end = s->buf + s->size;
00211
00212 const unsigned char *pb;
00213 const unsigned char *pb_end;
00214 unsigned char meth;
00215 unsigned char *dp;
00216 unsigned char *pp;
00217 unsigned char len;
00218 int ofs;
00219
00220 int frame_x, frame_y;
00221 int frame_width, frame_height;
00222
00223 frame_x = AV_RL16(&s->buf[6]);
00224 frame_y = AV_RL16(&s->buf[8]);
00225 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
00226 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
00227 if (frame_x < 0 || frame_width < 0 ||
00228 frame_x >= s->avctx->width ||
00229 frame_width > s->avctx->width ||
00230 frame_x + frame_width > s->avctx->width)
00231 return;
00232 if (frame_y < 0 || frame_height < 0 ||
00233 frame_y >= s->avctx->height ||
00234 frame_height > s->avctx->height ||
00235 frame_y + frame_height > s->avctx->height)
00236 return;
00237
00238 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
00239 (frame_x || frame_y)) {
00240
00241 s->x_off = frame_x;
00242 s->y_off = frame_y;
00243 }
00244 frame_x -= s->x_off;
00245 frame_y -= s->y_off;
00246
00247
00248
00249 if (s->prev_frame.data[0] &&
00250 (frame_x || frame_y || (frame_width != s->avctx->width) ||
00251 (frame_height != s->avctx->height))) {
00252
00253 memcpy(s->frame.data[0], s->prev_frame.data[0],
00254 s->avctx->height * s->frame.linesize[0]);
00255 }
00256
00257
00258 if (s->buf[15] & 0x02) {
00259 if (p_end - p < 2 + 3 * PALETTE_COUNT)
00260 return;
00261 p += 2;
00262 palette32 = (unsigned int *)s->palette;
00263 for (i = 0; i < PALETTE_COUNT; i++) {
00264 r = *p++ * 4;
00265 g = *p++ * 4;
00266 b = *p++ * 4;
00267 palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b;
00268 palette32[i] |= palette32[i] >> 6 & 0x30303;
00269 }
00270 }
00271 if (p < p_end) {
00272
00273 pb = p;
00274 pb_end = p_end;
00275 meth = *pb++;
00276 if (meth & 0x80) {
00277 lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
00278 meth &= 0x7F;
00279 pb = s->unpack_buffer;
00280 pb_end = s->unpack_buffer + s->unpack_buffer_size;
00281 }
00282
00283 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
00284 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
00285 switch (meth) {
00286 case 1:
00287 for (i = 0; i < frame_height; i++) {
00288 ofs = 0;
00289 do {
00290 if (pb_end - pb < 1)
00291 return;
00292 len = *pb++;
00293 if (len & 0x80) {
00294 len = (len & 0x7F) + 1;
00295 if (ofs + len > frame_width || pb_end - pb < len)
00296 return;
00297 memcpy(&dp[ofs], pb, len);
00298 pb += len;
00299 ofs += len;
00300 } else {
00301
00302 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
00303 return;
00304 memcpy(&dp[ofs], &pp[ofs], len + 1);
00305 ofs += len + 1;
00306 }
00307 } while (ofs < frame_width);
00308 if (ofs > frame_width) {
00309 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
00310 ofs, frame_width);
00311 break;
00312 }
00313 dp += s->frame.linesize[0];
00314 pp += s->prev_frame.linesize[0];
00315 }
00316 break;
00317
00318 case 2:
00319 for (i = 0; i < frame_height; i++) {
00320 if (pb_end -pb < frame_width)
00321 return;
00322 memcpy(dp, pb, frame_width);
00323 pb += frame_width;
00324 dp += s->frame.linesize[0];
00325 pp += s->prev_frame.linesize[0];
00326 }
00327 break;
00328
00329 case 3:
00330 for (i = 0; i < frame_height; i++) {
00331 ofs = 0;
00332 do {
00333 if (pb_end - pb < 1)
00334 return;
00335 len = *pb++;
00336 if (len & 0x80) {
00337 len = (len & 0x7F) + 1;
00338 if (pb_end - pb < 1)
00339 return;
00340 if (*pb++ == 0xFF)
00341 len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
00342 else {
00343 if (pb_end - pb < len)
00344 return;
00345 memcpy(&dp[ofs], pb, len);
00346 }
00347 pb += len;
00348 ofs += len;
00349 } else {
00350
00351 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
00352 return;
00353 memcpy(&dp[ofs], &pp[ofs], len + 1);
00354 ofs += len + 1;
00355 }
00356 } while (ofs < frame_width);
00357 if (ofs > frame_width) {
00358 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
00359 ofs, frame_width);
00360 }
00361 dp += s->frame.linesize[0];
00362 pp += s->prev_frame.linesize[0];
00363 }
00364 break;
00365 }
00366 }
00367 }
00368
00369 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
00370 {
00371 VmdVideoContext *s = avctx->priv_data;
00372 int i;
00373 unsigned int *palette32;
00374 int palette_index = 0;
00375 unsigned char r, g, b;
00376 unsigned char *vmd_header;
00377 unsigned char *raw_palette;
00378
00379 s->avctx = avctx;
00380 avctx->pix_fmt = PIX_FMT_PAL8;
00381
00382
00383 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
00384 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
00385 VMD_HEADER_SIZE);
00386 return -1;
00387 }
00388 vmd_header = (unsigned char *)avctx->extradata;
00389
00390 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
00391 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
00392 if (!s->unpack_buffer)
00393 return -1;
00394
00395
00396 raw_palette = &vmd_header[28];
00397 palette32 = (unsigned int *)s->palette;
00398 for (i = 0; i < PALETTE_COUNT; i++) {
00399 r = raw_palette[palette_index++] * 4;
00400 g = raw_palette[palette_index++] * 4;
00401 b = raw_palette[palette_index++] * 4;
00402 palette32[i] = (r << 16) | (g << 8) | (b);
00403 }
00404
00405 avcodec_get_frame_defaults(&s->frame);
00406 avcodec_get_frame_defaults(&s->prev_frame);
00407
00408 return 0;
00409 }
00410
00411 static int vmdvideo_decode_frame(AVCodecContext *avctx,
00412 void *data, int *data_size,
00413 AVPacket *avpkt)
00414 {
00415 const uint8_t *buf = avpkt->data;
00416 int buf_size = avpkt->size;
00417 VmdVideoContext *s = avctx->priv_data;
00418
00419 s->buf = buf;
00420 s->size = buf_size;
00421
00422 if (buf_size < 16)
00423 return buf_size;
00424
00425 s->frame.reference = 3;
00426 if (avctx->get_buffer(avctx, &s->frame)) {
00427 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
00428 return -1;
00429 }
00430
00431 vmd_decode(s);
00432
00433
00434 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
00435
00436
00437 FFSWAP(AVFrame, s->frame, s->prev_frame);
00438 if (s->frame.data[0])
00439 avctx->release_buffer(avctx, &s->frame);
00440
00441 *data_size = sizeof(AVFrame);
00442 *(AVFrame*)data = s->prev_frame;
00443
00444
00445 return buf_size;
00446 }
00447
00448 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
00449 {
00450 VmdVideoContext *s = avctx->priv_data;
00451
00452 if (s->prev_frame.data[0])
00453 avctx->release_buffer(avctx, &s->prev_frame);
00454 av_free(s->unpack_buffer);
00455
00456 return 0;
00457 }
00458
00459
00460
00461
00462
00463
00464 #define BLOCK_TYPE_AUDIO 1
00465 #define BLOCK_TYPE_INITIAL 2
00466 #define BLOCK_TYPE_SILENCE 3
00467
00468 typedef struct VmdAudioContext {
00469 AVFrame frame;
00470 int out_bps;
00471 int chunk_size;
00472 } VmdAudioContext;
00473
00474 static const uint16_t vmdaudio_table[128] = {
00475 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
00476 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
00477 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
00478 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
00479 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
00480 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
00481 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
00482 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
00483 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
00484 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
00485 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
00486 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
00487 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
00488 };
00489
00490 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
00491 {
00492 VmdAudioContext *s = avctx->priv_data;
00493
00494 if (avctx->channels < 1 || avctx->channels > 2) {
00495 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
00496 return AVERROR(EINVAL);
00497 }
00498 if (avctx->block_align < 1) {
00499 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
00500 return AVERROR(EINVAL);
00501 }
00502
00503 if (avctx->bits_per_coded_sample == 16)
00504 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00505 else
00506 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
00507 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
00508
00509 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
00510
00511 avcodec_get_frame_defaults(&s->frame);
00512 avctx->coded_frame = &s->frame;
00513
00514 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
00515 "block align = %d, sample rate = %d\n",
00516 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
00517 avctx->sample_rate);
00518
00519 return 0;
00520 }
00521
00522 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
00523 int channels)
00524 {
00525 int ch;
00526 const uint8_t *buf_end = buf + buf_size;
00527 int predictor[2];
00528 int st = channels - 1;
00529
00530
00531 for (ch = 0; ch < channels; ch++) {
00532 predictor[ch] = (int16_t)AV_RL16(buf);
00533 buf += 2;
00534 *out++ = predictor[ch];
00535 }
00536
00537
00538 ch = 0;
00539 while (buf < buf_end) {
00540 uint8_t b = *buf++;
00541 if (b & 0x80)
00542 predictor[ch] -= vmdaudio_table[b & 0x7F];
00543 else
00544 predictor[ch] += vmdaudio_table[b];
00545 predictor[ch] = av_clip_int16(predictor[ch]);
00546 *out++ = predictor[ch];
00547 ch ^= st;
00548 }
00549 }
00550
00551 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
00552 int *got_frame_ptr, AVPacket *avpkt)
00553 {
00554 const uint8_t *buf = avpkt->data;
00555 const uint8_t *buf_end;
00556 int buf_size = avpkt->size;
00557 VmdAudioContext *s = avctx->priv_data;
00558 int block_type, silent_chunks, audio_chunks;
00559 int ret;
00560 uint8_t *output_samples_u8;
00561 int16_t *output_samples_s16;
00562
00563 if (buf_size < 16) {
00564 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
00565 *got_frame_ptr = 0;
00566 return buf_size;
00567 }
00568
00569 block_type = buf[6];
00570 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
00571 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
00572 return AVERROR(EINVAL);
00573 }
00574 buf += 16;
00575 buf_size -= 16;
00576
00577
00578 silent_chunks = 0;
00579 if (block_type == BLOCK_TYPE_INITIAL) {
00580 uint32_t flags;
00581 if (buf_size < 4) {
00582 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
00583 return AVERROR(EINVAL);
00584 }
00585 flags = AV_RB32(buf);
00586 silent_chunks = av_popcount(flags);
00587 buf += 4;
00588 buf_size -= 4;
00589 } else if (block_type == BLOCK_TYPE_SILENCE) {
00590 silent_chunks = 1;
00591 buf_size = 0;
00592 }
00593
00594
00595 audio_chunks = buf_size / s->chunk_size;
00596
00597
00598 s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
00599 if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
00600 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00601 return ret;
00602 }
00603 output_samples_u8 = s->frame.data[0];
00604 output_samples_s16 = (int16_t *)s->frame.data[0];
00605
00606
00607 if (silent_chunks > 0) {
00608 int silent_size = avctx->block_align * silent_chunks;
00609 if (s->out_bps == 2) {
00610 memset(output_samples_s16, 0x00, silent_size * 2);
00611 output_samples_s16 += silent_size;
00612 } else {
00613 memset(output_samples_u8, 0x80, silent_size);
00614 output_samples_u8 += silent_size;
00615 }
00616 }
00617
00618
00619 if (audio_chunks > 0) {
00620 buf_end = buf + buf_size;
00621 while ( buf_end - buf >= s->chunk_size) {
00622 if (s->out_bps == 2) {
00623 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
00624 avctx->channels);
00625 output_samples_s16 += avctx->block_align;
00626 } else {
00627 memcpy(output_samples_u8, buf, s->chunk_size);
00628 output_samples_u8 += avctx->block_align;
00629 }
00630 buf += s->chunk_size;
00631 }
00632 }
00633
00634 *got_frame_ptr = 1;
00635 *(AVFrame *)data = s->frame;
00636
00637 return avpkt->size;
00638 }
00639
00640
00641
00642
00643
00644
00645 AVCodec ff_vmdvideo_decoder = {
00646 .name = "vmdvideo",
00647 .type = AVMEDIA_TYPE_VIDEO,
00648 .id = CODEC_ID_VMDVIDEO,
00649 .priv_data_size = sizeof(VmdVideoContext),
00650 .init = vmdvideo_decode_init,
00651 .close = vmdvideo_decode_end,
00652 .decode = vmdvideo_decode_frame,
00653 .capabilities = CODEC_CAP_DR1,
00654 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
00655 };
00656
00657 AVCodec ff_vmdaudio_decoder = {
00658 .name = "vmdaudio",
00659 .type = AVMEDIA_TYPE_AUDIO,
00660 .id = CODEC_ID_VMDAUDIO,
00661 .priv_data_size = sizeof(VmdAudioContext),
00662 .init = vmdaudio_decode_init,
00663 .decode = vmdaudio_decode_frame,
00664 .capabilities = CODEC_CAP_DR1,
00665 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
00666 };