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