Libav 0.7.1
|
00001 /* 00002 * Sierra VMD Audio & Video Decoders 00003 * Copyright (C) 2004 the ffmpeg project 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 * Video Decoder 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, unsigned char *dest, int dest_len) 00076 { 00077 const unsigned char *s; 00078 unsigned char *d; 00079 unsigned char *d_end; 00080 unsigned char queue[QUEUE_SIZE]; 00081 unsigned int qpos; 00082 unsigned int dataleft; 00083 unsigned int chainofs; 00084 unsigned int chainlen; 00085 unsigned int speclen; 00086 unsigned char tag; 00087 unsigned int i, j; 00088 00089 s = src; 00090 d = dest; 00091 d_end = d + dest_len; 00092 dataleft = AV_RL32(s); 00093 s += 4; 00094 memset(queue, 0x20, QUEUE_SIZE); 00095 if (AV_RL32(s) == 0x56781234) { 00096 s += 4; 00097 qpos = 0x111; 00098 speclen = 0xF + 3; 00099 } else { 00100 qpos = 0xFEE; 00101 speclen = 100; /* no speclen */ 00102 } 00103 00104 while (dataleft > 0) { 00105 tag = *s++; 00106 if ((tag == 0xFF) && (dataleft > 8)) { 00107 if (d + 8 > d_end) 00108 return; 00109 for (i = 0; i < 8; i++) { 00110 queue[qpos++] = *d++ = *s++; 00111 qpos &= QUEUE_MASK; 00112 } 00113 dataleft -= 8; 00114 } else { 00115 for (i = 0; i < 8; i++) { 00116 if (dataleft == 0) 00117 break; 00118 if (tag & 0x01) { 00119 if (d + 1 > d_end) 00120 return; 00121 queue[qpos++] = *d++ = *s++; 00122 qpos &= QUEUE_MASK; 00123 dataleft--; 00124 } else { 00125 chainofs = *s++; 00126 chainofs |= ((*s & 0xF0) << 4); 00127 chainlen = (*s++ & 0x0F) + 3; 00128 if (chainlen == speclen) 00129 chainlen = *s++ + 0xF + 3; 00130 if (d + chainlen > d_end) 00131 return; 00132 for (j = 0; j < chainlen; j++) { 00133 *d = queue[chainofs++ & QUEUE_MASK]; 00134 queue[qpos++] = *d++; 00135 qpos &= QUEUE_MASK; 00136 } 00137 dataleft -= chainlen; 00138 } 00139 tag >>= 1; 00140 } 00141 } 00142 } 00143 } 00144 00145 static int rle_unpack(const unsigned char *src, unsigned char *dest, 00146 int src_len, int dest_len) 00147 { 00148 const unsigned char *ps; 00149 unsigned char *pd; 00150 int i, l; 00151 unsigned char *dest_end = dest + dest_len; 00152 00153 ps = src; 00154 pd = dest; 00155 if (src_len & 1) 00156 *pd++ = *ps++; 00157 00158 src_len >>= 1; 00159 i = 0; 00160 do { 00161 l = *ps++; 00162 if (l & 0x80) { 00163 l = (l & 0x7F) * 2; 00164 if (pd + l > dest_end) 00165 return ps - src; 00166 memcpy(pd, ps, l); 00167 ps += l; 00168 pd += l; 00169 } else { 00170 if (pd + i > dest_end) 00171 return ps - src; 00172 for (i = 0; i < l; i++) { 00173 *pd++ = ps[0]; 00174 *pd++ = ps[1]; 00175 } 00176 ps += 2; 00177 } 00178 i += l; 00179 } while (i < src_len); 00180 00181 return ps - src; 00182 } 00183 00184 static void vmd_decode(VmdVideoContext *s) 00185 { 00186 int i; 00187 unsigned int *palette32; 00188 unsigned char r, g, b; 00189 00190 /* point to the start of the encoded data */ 00191 const unsigned char *p = s->buf + 16; 00192 00193 const unsigned char *pb; 00194 unsigned char meth; 00195 unsigned char *dp; /* pointer to current frame */ 00196 unsigned char *pp; /* pointer to previous frame */ 00197 unsigned char len; 00198 int ofs; 00199 00200 int frame_x, frame_y; 00201 int frame_width, frame_height; 00202 00203 frame_x = AV_RL16(&s->buf[6]); 00204 frame_y = AV_RL16(&s->buf[8]); 00205 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; 00206 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; 00207 00208 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && 00209 (frame_x || frame_y)) { 00210 00211 s->x_off = frame_x; 00212 s->y_off = frame_y; 00213 } 00214 frame_x -= s->x_off; 00215 frame_y -= s->y_off; 00216 00217 /* if only a certain region will be updated, copy the entire previous 00218 * frame before the decode */ 00219 if (frame_x || frame_y || (frame_width != s->avctx->width) || 00220 (frame_height != s->avctx->height)) { 00221 00222 memcpy(s->frame.data[0], s->prev_frame.data[0], 00223 s->avctx->height * s->frame.linesize[0]); 00224 } 00225 00226 /* check if there is a new palette */ 00227 if (s->buf[15] & 0x02) { 00228 p += 2; 00229 palette32 = (unsigned int *)s->palette; 00230 for (i = 0; i < PALETTE_COUNT; i++) { 00231 r = *p++ * 4; 00232 g = *p++ * 4; 00233 b = *p++ * 4; 00234 palette32[i] = (r << 16) | (g << 8) | (b); 00235 } 00236 s->size -= (256 * 3 + 2); 00237 } 00238 if (s->size >= 0) { 00239 /* originally UnpackFrame in VAG's code */ 00240 pb = p; 00241 meth = *pb++; 00242 if (meth & 0x80) { 00243 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); 00244 meth &= 0x7F; 00245 pb = s->unpack_buffer; 00246 } 00247 00248 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 00249 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 00250 switch (meth) { 00251 case 1: 00252 for (i = 0; i < frame_height; i++) { 00253 ofs = 0; 00254 do { 00255 len = *pb++; 00256 if (len & 0x80) { 00257 len = (len & 0x7F) + 1; 00258 if (ofs + len > frame_width) 00259 return; 00260 memcpy(&dp[ofs], pb, len); 00261 pb += len; 00262 ofs += len; 00263 } else { 00264 /* interframe pixel copy */ 00265 if (ofs + len + 1 > frame_width) 00266 return; 00267 memcpy(&dp[ofs], &pp[ofs], len + 1); 00268 ofs += len + 1; 00269 } 00270 } while (ofs < frame_width); 00271 if (ofs > frame_width) { 00272 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00273 ofs, frame_width); 00274 break; 00275 } 00276 dp += s->frame.linesize[0]; 00277 pp += s->prev_frame.linesize[0]; 00278 } 00279 break; 00280 00281 case 2: 00282 for (i = 0; i < frame_height; i++) { 00283 memcpy(dp, pb, frame_width); 00284 pb += frame_width; 00285 dp += s->frame.linesize[0]; 00286 pp += s->prev_frame.linesize[0]; 00287 } 00288 break; 00289 00290 case 3: 00291 for (i = 0; i < frame_height; i++) { 00292 ofs = 0; 00293 do { 00294 len = *pb++; 00295 if (len & 0x80) { 00296 len = (len & 0x7F) + 1; 00297 if (*pb++ == 0xFF) 00298 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); 00299 else 00300 memcpy(&dp[ofs], pb, len); 00301 pb += len; 00302 ofs += len; 00303 } else { 00304 /* interframe pixel copy */ 00305 if (ofs + len + 1 > frame_width) 00306 return; 00307 memcpy(&dp[ofs], &pp[ofs], len + 1); 00308 ofs += len + 1; 00309 } 00310 } while (ofs < frame_width); 00311 if (ofs > frame_width) { 00312 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00313 ofs, frame_width); 00314 } 00315 dp += s->frame.linesize[0]; 00316 pp += s->prev_frame.linesize[0]; 00317 } 00318 break; 00319 } 00320 } 00321 } 00322 00323 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) 00324 { 00325 VmdVideoContext *s = avctx->priv_data; 00326 int i; 00327 unsigned int *palette32; 00328 int palette_index = 0; 00329 unsigned char r, g, b; 00330 unsigned char *vmd_header; 00331 unsigned char *raw_palette; 00332 00333 s->avctx = avctx; 00334 avctx->pix_fmt = PIX_FMT_PAL8; 00335 00336 /* make sure the VMD header made it */ 00337 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { 00338 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", 00339 VMD_HEADER_SIZE); 00340 return -1; 00341 } 00342 vmd_header = (unsigned char *)avctx->extradata; 00343 00344 s->unpack_buffer_size = AV_RL32(&vmd_header[800]); 00345 s->unpack_buffer = av_malloc(s->unpack_buffer_size); 00346 if (!s->unpack_buffer) 00347 return -1; 00348 00349 /* load up the initial palette */ 00350 raw_palette = &vmd_header[28]; 00351 palette32 = (unsigned int *)s->palette; 00352 for (i = 0; i < PALETTE_COUNT; i++) { 00353 r = raw_palette[palette_index++] * 4; 00354 g = raw_palette[palette_index++] * 4; 00355 b = raw_palette[palette_index++] * 4; 00356 palette32[i] = (r << 16) | (g << 8) | (b); 00357 } 00358 00359 return 0; 00360 } 00361 00362 static int vmdvideo_decode_frame(AVCodecContext *avctx, 00363 void *data, int *data_size, 00364 AVPacket *avpkt) 00365 { 00366 const uint8_t *buf = avpkt->data; 00367 int buf_size = avpkt->size; 00368 VmdVideoContext *s = avctx->priv_data; 00369 00370 s->buf = buf; 00371 s->size = buf_size; 00372 00373 if (buf_size < 16) 00374 return buf_size; 00375 00376 s->frame.reference = 1; 00377 if (avctx->get_buffer(avctx, &s->frame)) { 00378 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); 00379 return -1; 00380 } 00381 00382 vmd_decode(s); 00383 00384 /* make the palette available on the way out */ 00385 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); 00386 00387 /* shuffle frames */ 00388 FFSWAP(AVFrame, s->frame, s->prev_frame); 00389 if (s->frame.data[0]) 00390 avctx->release_buffer(avctx, &s->frame); 00391 00392 *data_size = sizeof(AVFrame); 00393 *(AVFrame*)data = s->prev_frame; 00394 00395 /* report that the buffer was completely consumed */ 00396 return buf_size; 00397 } 00398 00399 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) 00400 { 00401 VmdVideoContext *s = avctx->priv_data; 00402 00403 if (s->prev_frame.data[0]) 00404 avctx->release_buffer(avctx, &s->prev_frame); 00405 av_free(s->unpack_buffer); 00406 00407 return 0; 00408 } 00409 00410 00411 /* 00412 * Audio Decoder 00413 */ 00414 00415 #define BLOCK_TYPE_AUDIO 1 00416 #define BLOCK_TYPE_INITIAL 2 00417 #define BLOCK_TYPE_SILENCE 3 00418 00419 typedef struct VmdAudioContext { 00420 AVCodecContext *avctx; 00421 int out_bps; 00422 int predictors[2]; 00423 } VmdAudioContext; 00424 00425 static const uint16_t vmdaudio_table[128] = { 00426 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080, 00427 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120, 00428 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0, 00429 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 00430 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280, 00431 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0, 00432 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320, 00433 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, 00434 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0, 00435 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480, 00436 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700, 00437 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00, 00438 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 00439 }; 00440 00441 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) 00442 { 00443 VmdAudioContext *s = avctx->priv_data; 00444 00445 s->avctx = avctx; 00446 if (avctx->bits_per_coded_sample == 16) 00447 avctx->sample_fmt = AV_SAMPLE_FMT_S16; 00448 else 00449 avctx->sample_fmt = AV_SAMPLE_FMT_U8; 00450 s->out_bps = av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3; 00451 00452 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " 00453 "block align = %d, sample rate = %d\n", 00454 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align, 00455 avctx->sample_rate); 00456 00457 return 0; 00458 } 00459 00460 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, 00461 const uint8_t *buf, int buf_size, int stereo) 00462 { 00463 int i; 00464 int chan = 0; 00465 int16_t *out = (int16_t*)data; 00466 00467 for(i = 0; i < buf_size; i++) { 00468 if(buf[i] & 0x80) 00469 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; 00470 else 00471 s->predictors[chan] += vmdaudio_table[buf[i]]; 00472 s->predictors[chan] = av_clip_int16(s->predictors[chan]); 00473 out[i] = s->predictors[chan]; 00474 chan ^= stereo; 00475 } 00476 } 00477 00478 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, 00479 const uint8_t *buf, int silent_chunks, int data_size) 00480 { 00481 int silent_size = s->avctx->block_align * silent_chunks * s->out_bps; 00482 00483 if (silent_chunks) { 00484 memset(data, s->out_bps == 2 ? 0x00 : 0x80, silent_size); 00485 data += silent_size; 00486 } 00487 if (s->avctx->bits_per_coded_sample == 16) 00488 vmdaudio_decode_audio(s, data, buf, data_size, s->avctx->channels == 2); 00489 else { 00490 /* just copy the data */ 00491 memcpy(data, buf, data_size); 00492 } 00493 00494 return silent_size + data_size * s->out_bps; 00495 } 00496 00497 static int vmdaudio_decode_frame(AVCodecContext *avctx, 00498 void *data, int *data_size, 00499 AVPacket *avpkt) 00500 { 00501 const uint8_t *buf = avpkt->data; 00502 int buf_size = avpkt->size; 00503 VmdAudioContext *s = avctx->priv_data; 00504 int block_type, silent_chunks; 00505 unsigned char *output_samples = (unsigned char *)data; 00506 00507 if (buf_size < 16) { 00508 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n"); 00509 *data_size = 0; 00510 return buf_size; 00511 } 00512 00513 block_type = buf[6]; 00514 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) { 00515 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type); 00516 return AVERROR(EINVAL); 00517 } 00518 buf += 16; 00519 buf_size -= 16; 00520 00521 silent_chunks = 0; 00522 if (block_type == BLOCK_TYPE_INITIAL) { 00523 uint32_t flags = AV_RB32(buf); 00524 silent_chunks = av_popcount(flags); 00525 buf += 4; 00526 buf_size -= 4; 00527 } else if (block_type == BLOCK_TYPE_SILENCE) { 00528 silent_chunks = 1; 00529 buf_size = 0; // should already be zero but set it just to be sure 00530 } 00531 00532 /* ensure output buffer is large enough */ 00533 if (*data_size < (avctx->block_align*silent_chunks + buf_size) * s->out_bps) 00534 return -1; 00535 00536 *data_size = vmdaudio_loadsound(s, output_samples, buf, silent_chunks, buf_size); 00537 00538 return avpkt->size; 00539 } 00540 00541 00542 /* 00543 * Public Data Structures 00544 */ 00545 00546 AVCodec ff_vmdvideo_decoder = { 00547 "vmdvideo", 00548 AVMEDIA_TYPE_VIDEO, 00549 CODEC_ID_VMDVIDEO, 00550 sizeof(VmdVideoContext), 00551 vmdvideo_decode_init, 00552 NULL, 00553 vmdvideo_decode_end, 00554 vmdvideo_decode_frame, 00555 CODEC_CAP_DR1, 00556 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), 00557 }; 00558 00559 AVCodec ff_vmdaudio_decoder = { 00560 "vmdaudio", 00561 AVMEDIA_TYPE_AUDIO, 00562 CODEC_ID_VMDAUDIO, 00563 sizeof(VmdAudioContext), 00564 vmdaudio_decode_init, 00565 NULL, 00566 NULL, 00567 vmdaudio_decode_frame, 00568 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), 00569 };