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