00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043 #include <string.h>
00044 #include <unistd.h>
00045
00046 #include "common.h"
00047 #include "avcodec.h"
00048 #include "dsputil.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 DSPContext dsp;
00061 AVFrame frame;
00062 AVFrame prev_frame;
00063
00064 unsigned char *buf;
00065 int size;
00066
00067 unsigned char palette[PALETTE_COUNT * 4];
00068 unsigned char *unpack_buffer;
00069
00070 } VmdVideoContext;
00071
00072 #define QUEUE_SIZE 0x1000
00073 #define QUEUE_MASK 0x0FFF
00074
00075 static void lz_unpack(unsigned char *src, unsigned char *dest)
00076 {
00077 unsigned char *s;
00078 unsigned char *d;
00079 unsigned char queue[QUEUE_SIZE];
00080 unsigned int qpos;
00081 unsigned int dataleft;
00082 unsigned int chainofs;
00083 unsigned int chainlen;
00084 unsigned int speclen;
00085 unsigned char tag;
00086 unsigned int i, j;
00087
00088 s = src;
00089 d = dest;
00090 dataleft = LE_32(s);
00091 s += 4;
00092 memset(queue, QUEUE_SIZE, 0x20);
00093 if (LE_32(s) == 0x56781234) {
00094 s += 4;
00095 qpos = 0x111;
00096 speclen = 0xF + 3;
00097 } else {
00098 qpos = 0xFEE;
00099 speclen = 100;
00100 }
00101
00102 while (dataleft > 0) {
00103 tag = *s++;
00104 if ((tag == 0xFF) && (dataleft > 8)) {
00105 for (i = 0; i < 8; i++) {
00106 queue[qpos++] = *d++ = *s++;
00107 qpos &= QUEUE_MASK;
00108 }
00109 dataleft -= 8;
00110 } else {
00111 for (i = 0; i < 8; i++) {
00112 if (dataleft == 0)
00113 break;
00114 if (tag & 0x01) {
00115 queue[qpos++] = *d++ = *s++;
00116 qpos &= QUEUE_MASK;
00117 dataleft--;
00118 } else {
00119 chainofs = *s++;
00120 chainofs |= ((*s & 0xF0) << 4);
00121 chainlen = (*s++ & 0x0F) + 3;
00122 if (chainlen == speclen)
00123 chainlen = *s++ + 0xF + 3;
00124 for (j = 0; j < chainlen; j++) {
00125 *d = queue[chainofs++ & QUEUE_MASK];
00126 queue[qpos++] = *d++;
00127 qpos &= QUEUE_MASK;
00128 }
00129 dataleft -= chainlen;
00130 }
00131 tag >>= 1;
00132 }
00133 }
00134 }
00135 }
00136
00137 static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
00138 {
00139 unsigned char *ps;
00140 unsigned char *pd;
00141 int i, l;
00142
00143 ps = src;
00144 pd = dest;
00145 if (len & 1)
00146 *pd++ = *ps++;
00147
00148 len >>= 1;
00149 i = 0;
00150 do {
00151 l = *ps++;
00152 if (l & 0x80) {
00153 l = (l & 0x7F) * 2;
00154 memcpy(pd, ps, l);
00155 ps += l;
00156 pd += l;
00157 } else {
00158 for (i = 0; i < l; i++) {
00159 *pd++ = ps[0];
00160 *pd++ = ps[1];
00161 }
00162 ps += 2;
00163 }
00164 i += l;
00165 } while (i < len);
00166
00167 return (ps - src);
00168 }
00169
00170 static void vmd_decode(VmdVideoContext *s)
00171 {
00172 int i;
00173 unsigned int *palette32;
00174 unsigned char r, g, b;
00175
00176
00177 unsigned char *p = s->buf + 16;
00178
00179 unsigned char *pb;
00180 unsigned char meth;
00181 unsigned char *dp;
00182 unsigned char *pp;
00183 unsigned char len;
00184 int ofs;
00185
00186 int frame_x, frame_y;
00187 int frame_width, frame_height;
00188
00189 frame_x = LE_16(&s->buf[6]);
00190 frame_y = LE_16(&s->buf[8]);
00191 frame_width = LE_16(&s->buf[10]) - frame_x + 1;
00192 frame_height = LE_16(&s->buf[12]) - frame_y + 1;
00193
00194
00195
00196 if (frame_x || frame_y || (frame_width != s->avctx->width) ||
00197 (frame_height != s->avctx->height)) {
00198
00199 memcpy(s->frame.data[0], s->prev_frame.data[0],
00200 s->avctx->height * s->frame.linesize[0]);
00201 }
00202
00203
00204 if (s->buf[15] & 0x02) {
00205 p += 2;
00206 palette32 = (unsigned int *)s->palette;
00207 for (i = 0; i < PALETTE_COUNT; i++) {
00208 r = *p++ * 4;
00209 g = *p++ * 4;
00210 b = *p++ * 4;
00211 palette32[i] = (r << 16) | (g << 8) | (b);
00212 }
00213 s->size -= (256 * 3 + 2);
00214 }
00215 if (s->size >= 0) {
00216
00217 pb = p;
00218 meth = *pb++;
00219 if (meth & 0x80) {
00220 lz_unpack(pb, s->unpack_buffer);
00221 meth &= 0x7F;
00222 pb = s->unpack_buffer;
00223 }
00224
00225 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
00226 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
00227 switch (meth) {
00228 case 1:
00229 for (i = 0; i < frame_height; i++) {
00230 ofs = 0;
00231 do {
00232 len = *pb++;
00233 if (len & 0x80) {
00234 len = (len & 0x7F) + 1;
00235 memcpy(&dp[ofs], pb, len);
00236 pb += len;
00237 ofs += len;
00238 } else {
00239
00240 memcpy(&dp[ofs], &pp[ofs], len + 1);
00241 ofs += len + 1;
00242 }
00243 } while (ofs < frame_width);
00244 if (ofs > frame_width) {
00245 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
00246 ofs, frame_width);
00247 break;
00248 }
00249 dp += s->frame.linesize[0];
00250 pp += s->prev_frame.linesize[0];
00251 }
00252 break;
00253
00254 case 2:
00255 for (i = 0; i < frame_height; i++) {
00256 memcpy(dp, pb, frame_width);
00257 pb += frame_width;
00258 dp += s->frame.linesize[0];
00259 pp += s->prev_frame.linesize[0];
00260 }
00261 break;
00262
00263 case 3:
00264 for (i = 0; i < frame_height; i++) {
00265 ofs = 0;
00266 do {
00267 len = *pb++;
00268 if (len & 0x80) {
00269 len = (len & 0x7F) + 1;
00270 if (*pb++ == 0xFF)
00271 len = rle_unpack(pb, &dp[ofs], len);
00272 else
00273 memcpy(&dp[ofs], pb, len);
00274 pb += len;
00275 ofs += len;
00276 } else {
00277
00278 memcpy(&dp[ofs], &pp[ofs], len + 1);
00279 ofs += len + 1;
00280 }
00281 } while (ofs < frame_width);
00282 if (ofs > frame_width) {
00283 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
00284 ofs, frame_width);
00285 }
00286 dp += s->frame.linesize[0];
00287 pp += s->prev_frame.linesize[0];
00288 }
00289 break;
00290 }
00291 }
00292 }
00293
00294 static int vmdvideo_decode_init(AVCodecContext *avctx)
00295 {
00296 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
00297 int i;
00298 unsigned int *palette32;
00299 int palette_index = 0;
00300 unsigned char r, g, b;
00301 unsigned char *vmd_header;
00302 unsigned char *raw_palette;
00303
00304 s->avctx = avctx;
00305 avctx->pix_fmt = PIX_FMT_PAL8;
00306 avctx->has_b_frames = 0;
00307 dsputil_init(&s->dsp, avctx);
00308
00309
00310 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
00311 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
00312 VMD_HEADER_SIZE);
00313 return -1;
00314 }
00315 vmd_header = (unsigned char *)avctx->extradata;
00316
00317 s->unpack_buffer = av_malloc(LE_32(&vmd_header[800]));
00318 if (!s->unpack_buffer)
00319 return -1;
00320
00321
00322 raw_palette = &vmd_header[28];
00323 palette32 = (unsigned int *)s->palette;
00324 for (i = 0; i < PALETTE_COUNT; i++) {
00325 r = raw_palette[palette_index++] * 4;
00326 g = raw_palette[palette_index++] * 4;
00327 b = raw_palette[palette_index++] * 4;
00328 palette32[i] = (r << 16) | (g << 8) | (b);
00329 }
00330
00331 s->frame.data[0] = s->prev_frame.data[0] = NULL;
00332
00333 return 0;
00334 }
00335
00336 static int vmdvideo_decode_frame(AVCodecContext *avctx,
00337 void *data, int *data_size,
00338 uint8_t *buf, int buf_size)
00339 {
00340 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
00341
00342 s->buf = buf;
00343 s->size = buf_size;
00344
00345 if (buf_size < 16)
00346 return buf_size;
00347
00348 s->frame.reference = 1;
00349 if (avctx->get_buffer(avctx, &s->frame)) {
00350 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
00351 return -1;
00352 }
00353
00354 vmd_decode(s);
00355
00356
00357 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
00358
00359 if (s->prev_frame.data[0])
00360 avctx->release_buffer(avctx, &s->prev_frame);
00361
00362
00363 s->prev_frame = s->frame;
00364
00365 *data_size = sizeof(AVFrame);
00366 *(AVFrame*)data = s->frame;
00367
00368
00369 return buf_size;
00370 }
00371
00372 static int vmdvideo_decode_end(AVCodecContext *avctx)
00373 {
00374 VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
00375
00376 if (s->prev_frame.data[0])
00377 avctx->release_buffer(avctx, &s->prev_frame);
00378 av_free(s->unpack_buffer);
00379
00380 return 0;
00381 }
00382
00383
00384
00385
00386
00387
00388 typedef struct VmdAudioContext {
00389 AVCodecContext *avctx;
00390 int channels;
00391 int bits;
00392 int block_align;
00393 unsigned char steps8[16];
00394 unsigned short steps16[16];
00395 unsigned short steps128[256];
00396 short predictors[2];
00397 } VmdAudioContext;
00398
00399 static int vmdaudio_decode_init(AVCodecContext *avctx)
00400 {
00401 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
00402 int i;
00403
00404 s->avctx = avctx;
00405 s->channels = avctx->channels;
00406 s->bits = avctx->bits_per_sample;
00407 s->block_align = avctx->block_align;
00408
00409 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
00410 s->channels, s->bits, s->block_align, avctx->sample_rate);
00411
00412
00413 for (i = 0; i < 8; i++) {
00414 if (i < 4)
00415 s->steps8[i] = i;
00416 else
00417 s->steps8[i] = s->steps8[i - 1] + i - 1;
00418
00419 if (i == 0)
00420 s->steps16[i] = 0;
00421 else if (i == 1)
00422 s->steps16[i] = 4;
00423 else if (i == 2)
00424 s->steps16[i] = 16;
00425 else
00426 s->steps16[i] = 1 << (i + 4);
00427 }
00428
00429
00430 s->steps128[0] = 0;
00431 s->steps128[1] = 8;
00432 for (i = 0x02; i <= 0x20; i++)
00433 s->steps128[i] = (i - 1) << 4;
00434 for (i = 0x21; i <= 0x60; i++)
00435 s->steps128[i] = (i + 0x1F) << 3;
00436 for (i = 0x61; i <= 0x70; i++)
00437 s->steps128[i] = (i - 0x51) << 6;
00438 for (i = 0x71; i <= 0x78; i++)
00439 s->steps128[i] = (i - 0x69) << 8;
00440 for (i = 0x79; i <= 0x7D; i++)
00441 s->steps128[i] = (i - 0x75) << 10;
00442 s->steps128[0x7E] = 0x3000;
00443 s->steps128[0x7F] = 0x4000;
00444
00445
00446 for (i = 0; i < 8; i++) {
00447 s->steps8[i + 8] = -s->steps8[i];
00448 s->steps16[i + 8] = -s->steps16[i];
00449 }
00450 for (i = 0; i < 128; i++)
00451 s->steps128[i + 128] = -s->steps128[i];
00452
00453 return 0;
00454 }
00455
00456 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
00457 uint8_t *buf, int ratio) {
00458
00459 }
00460
00461 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
00462 uint8_t *buf, int silence)
00463 {
00464 int bytes_decoded = 0;
00465 int i;
00466
00467 if (silence)
00468 av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
00469 if (s->channels == 2) {
00470
00471
00472 if ((s->block_align & 0x01) == 0) {
00473 if (silence)
00474 memset(data, 0, s->block_align * 2);
00475 else
00476 vmdaudio_decode_audio(s, data, buf, 1);
00477 } else {
00478 if (silence)
00479 memset(data, 0, s->block_align * 2);
00480 else
00481 vmdaudio_decode_audio(s, data, buf, 1);
00482 }
00483 } else {
00484
00485
00486 if (silence) {
00487 if (s->bits == 16) {
00488 memset(data, 0, s->block_align * 2);
00489 bytes_decoded = s->block_align * 2;
00490 } else {
00491
00492
00493 memset(data, 0x00, s->block_align * 2);
00494 bytes_decoded = s->block_align * 2;
00495 }
00496 } else {
00497
00498 for (i = 0; i < s->block_align; i++)
00499 data[i * 2 + 1] = buf[i] + 0x80;
00500 bytes_decoded = s->block_align * 2;
00501 }
00502 }
00503
00504 return bytes_decoded;
00505 }
00506
00507 static int vmdaudio_decode_frame(AVCodecContext *avctx,
00508 void *data, int *data_size,
00509 uint8_t *buf, int buf_size)
00510 {
00511 VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
00512 unsigned int sound_flags;
00513 unsigned char *output_samples = (unsigned char *)data;
00514
00515
00516 unsigned char *p = buf + 16;
00517 unsigned char *p_end = buf + buf_size;
00518
00519 if (buf_size < 16)
00520 return buf_size;
00521
00522 if (buf[6] == 1) {
00523
00524 *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
00525 } else if (buf[6] == 2) {
00526
00527 sound_flags = LE_32(p);
00528 p += 4;
00529
00530
00531
00532 while (p < p_end) {
00533 if (sound_flags & 0x01)
00534
00535 *data_size += vmdaudio_loadsound(s, output_samples, p, 1);
00536 else {
00537
00538 *data_size += vmdaudio_loadsound(s, output_samples, p, 0);
00539 p += s->block_align;
00540 }
00541 output_samples += (s->block_align * s->bits / 8);
00542 sound_flags >>= 1;
00543 }
00544 } else if (buf[6] == 3) {
00545
00546 *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
00547 }
00548
00549 return buf_size;
00550 }
00551
00552
00553
00554
00555
00556
00557 AVCodec vmdvideo_decoder = {
00558 "vmdvideo",
00559 CODEC_TYPE_VIDEO,
00560 CODEC_ID_VMDVIDEO,
00561 sizeof(VmdVideoContext),
00562 vmdvideo_decode_init,
00563 NULL,
00564 vmdvideo_decode_end,
00565 vmdvideo_decode_frame,
00566 CODEC_CAP_DR1,
00567 };
00568
00569 AVCodec vmdaudio_decoder = {
00570 "vmdaudio",
00571 CODEC_TYPE_AUDIO,
00572 CODEC_ID_VMDAUDIO,
00573 sizeof(VmdAudioContext),
00574 vmdaudio_decode_init,
00575 NULL,
00576 NULL,
00577 vmdaudio_decode_frame,
00578 };