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