Libav
|
00001 /* 00002 * Sierra VMD Audio & Video Decoders 00003 * Copyright (C) 2004 the ffmpeg project 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 int dp_size; 00203 00204 frame_x = AV_RL16(&s->buf[6]); 00205 frame_y = AV_RL16(&s->buf[8]); 00206 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; 00207 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; 00208 00209 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && 00210 (frame_x || frame_y)) { 00211 00212 s->x_off = frame_x; 00213 s->y_off = frame_y; 00214 } 00215 frame_x -= s->x_off; 00216 frame_y -= s->y_off; 00217 00218 /* if only a certain region will be updated, copy the entire previous 00219 * frame before the decode */ 00220 if (frame_x || frame_y || (frame_width != s->avctx->width) || 00221 (frame_height != s->avctx->height)) { 00222 00223 memcpy(s->frame.data[0], s->prev_frame.data[0], 00224 s->avctx->height * s->frame.linesize[0]); 00225 } 00226 00227 /* check if there is a new palette */ 00228 if (s->buf[15] & 0x02) { 00229 p += 2; 00230 palette32 = (unsigned int *)s->palette; 00231 for (i = 0; i < PALETTE_COUNT; i++) { 00232 r = *p++ * 4; 00233 g = *p++ * 4; 00234 b = *p++ * 4; 00235 palette32[i] = (r << 16) | (g << 8) | (b); 00236 } 00237 s->size -= (256 * 3 + 2); 00238 } 00239 if (s->size >= 0) { 00240 /* originally UnpackFrame in VAG's code */ 00241 pb = p; 00242 meth = *pb++; 00243 if (meth & 0x80) { 00244 lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); 00245 meth &= 0x7F; 00246 pb = s->unpack_buffer; 00247 } 00248 00249 dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; 00250 dp_size = s->frame.linesize[0] * s->avctx->height; 00251 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; 00252 switch (meth) { 00253 case 1: 00254 for (i = 0; i < frame_height; i++) { 00255 ofs = 0; 00256 do { 00257 len = *pb++; 00258 if (len & 0x80) { 00259 len = (len & 0x7F) + 1; 00260 if (ofs + len > frame_width) 00261 return; 00262 memcpy(&dp[ofs], pb, len); 00263 pb += len; 00264 ofs += len; 00265 } else { 00266 /* interframe pixel copy */ 00267 if (ofs + len + 1 > frame_width) 00268 return; 00269 memcpy(&dp[ofs], &pp[ofs], len + 1); 00270 ofs += len + 1; 00271 } 00272 } while (ofs < frame_width); 00273 if (ofs > frame_width) { 00274 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00275 ofs, frame_width); 00276 break; 00277 } 00278 dp += s->frame.linesize[0]; 00279 pp += s->prev_frame.linesize[0]; 00280 } 00281 break; 00282 00283 case 2: 00284 for (i = 0; i < frame_height; i++) { 00285 memcpy(dp, pb, frame_width); 00286 pb += frame_width; 00287 dp += s->frame.linesize[0]; 00288 pp += s->prev_frame.linesize[0]; 00289 } 00290 break; 00291 00292 case 3: 00293 for (i = 0; i < frame_height; i++) { 00294 ofs = 0; 00295 do { 00296 len = *pb++; 00297 if (len & 0x80) { 00298 len = (len & 0x7F) + 1; 00299 if (*pb++ == 0xFF) 00300 len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); 00301 else 00302 memcpy(&dp[ofs], pb, len); 00303 pb += len; 00304 ofs += len; 00305 } else { 00306 /* interframe pixel copy */ 00307 if (ofs + len + 1 > frame_width) 00308 return; 00309 memcpy(&dp[ofs], &pp[ofs], len + 1); 00310 ofs += len + 1; 00311 } 00312 } while (ofs < frame_width); 00313 if (ofs > frame_width) { 00314 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n", 00315 ofs, frame_width); 00316 } 00317 dp += s->frame.linesize[0]; 00318 pp += s->prev_frame.linesize[0]; 00319 } 00320 break; 00321 } 00322 } 00323 } 00324 00325 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) 00326 { 00327 VmdVideoContext *s = avctx->priv_data; 00328 int i; 00329 unsigned int *palette32; 00330 int palette_index = 0; 00331 unsigned char r, g, b; 00332 unsigned char *vmd_header; 00333 unsigned char *raw_palette; 00334 00335 s->avctx = avctx; 00336 avctx->pix_fmt = PIX_FMT_PAL8; 00337 00338 /* make sure the VMD header made it */ 00339 if (s->avctx->extradata_size != VMD_HEADER_SIZE) { 00340 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n", 00341 VMD_HEADER_SIZE); 00342 return -1; 00343 } 00344 vmd_header = (unsigned char *)avctx->extradata; 00345 00346 s->unpack_buffer_size = AV_RL32(&vmd_header[800]); 00347 s->unpack_buffer = av_malloc(s->unpack_buffer_size); 00348 if (!s->unpack_buffer) 00349 return -1; 00350 00351 /* load up the initial palette */ 00352 raw_palette = &vmd_header[28]; 00353 palette32 = (unsigned int *)s->palette; 00354 for (i = 0; i < PALETTE_COUNT; i++) { 00355 r = raw_palette[palette_index++] * 4; 00356 g = raw_palette[palette_index++] * 4; 00357 b = raw_palette[palette_index++] * 4; 00358 palette32[i] = (r << 16) | (g << 8) | (b); 00359 } 00360 00361 return 0; 00362 } 00363 00364 static int vmdvideo_decode_frame(AVCodecContext *avctx, 00365 void *data, int *data_size, 00366 AVPacket *avpkt) 00367 { 00368 const uint8_t *buf = avpkt->data; 00369 int buf_size = avpkt->size; 00370 VmdVideoContext *s = avctx->priv_data; 00371 00372 s->buf = buf; 00373 s->size = buf_size; 00374 00375 if (buf_size < 16) 00376 return buf_size; 00377 00378 s->frame.reference = 1; 00379 if (avctx->get_buffer(avctx, &s->frame)) { 00380 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); 00381 return -1; 00382 } 00383 00384 vmd_decode(s); 00385 00386 /* make the palette available on the way out */ 00387 memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); 00388 00389 /* shuffle frames */ 00390 FFSWAP(AVFrame, s->frame, s->prev_frame); 00391 if (s->frame.data[0]) 00392 avctx->release_buffer(avctx, &s->frame); 00393 00394 *data_size = sizeof(AVFrame); 00395 *(AVFrame*)data = s->prev_frame; 00396 00397 /* report that the buffer was completely consumed */ 00398 return buf_size; 00399 } 00400 00401 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) 00402 { 00403 VmdVideoContext *s = avctx->priv_data; 00404 00405 if (s->prev_frame.data[0]) 00406 avctx->release_buffer(avctx, &s->prev_frame); 00407 av_free(s->unpack_buffer); 00408 00409 return 0; 00410 } 00411 00412 00413 /* 00414 * Audio Decoder 00415 */ 00416 00417 typedef struct VmdAudioContext { 00418 AVCodecContext *avctx; 00419 int channels; 00420 int bits; 00421 int block_align; 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 s->channels = avctx->channels; 00447 s->bits = avctx->bits_per_coded_sample; 00448 s->block_align = avctx->block_align; 00449 avctx->sample_fmt = SAMPLE_FMT_S16; 00450 00451 av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n", 00452 s->channels, s->bits, s->block_align, avctx->sample_rate); 00453 00454 return 0; 00455 } 00456 00457 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data, 00458 const uint8_t *buf, int buf_size, int stereo) 00459 { 00460 int i; 00461 int chan = 0; 00462 int16_t *out = (int16_t*)data; 00463 00464 for(i = 0; i < buf_size; i++) { 00465 if(buf[i] & 0x80) 00466 s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F]; 00467 else 00468 s->predictors[chan] += vmdaudio_table[buf[i]]; 00469 s->predictors[chan] = av_clip_int16(s->predictors[chan]); 00470 out[i] = s->predictors[chan]; 00471 chan ^= stereo; 00472 } 00473 } 00474 00475 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data, 00476 const uint8_t *buf, int silence, int data_size) 00477 { 00478 int bytes_decoded = 0; 00479 int i; 00480 00481 // if (silence) 00482 // av_log(s->avctx, AV_LOG_INFO, "silent block!\n"); 00483 if (s->channels == 2) { 00484 00485 /* stereo handling */ 00486 if (silence) { 00487 memset(data, 0, data_size * 2); 00488 } else { 00489 if (s->bits == 16) 00490 vmdaudio_decode_audio(s, data, buf, data_size, 1); 00491 else { 00492 /* copy the data but convert it to signed */ 00493 for (i = 0; i < data_size; i++){ 00494 *data++ = buf[i] + 0x80; 00495 *data++ = buf[i] + 0x80; 00496 } 00497 } 00498 } 00499 } else { 00500 bytes_decoded = data_size * 2; 00501 00502 /* mono handling */ 00503 if (silence) { 00504 memset(data, 0, data_size * 2); 00505 } else { 00506 if (s->bits == 16) { 00507 vmdaudio_decode_audio(s, data, buf, data_size, 0); 00508 } else { 00509 /* copy the data but convert it to signed */ 00510 for (i = 0; i < data_size; i++){ 00511 *data++ = buf[i] + 0x80; 00512 *data++ = buf[i] + 0x80; 00513 } 00514 } 00515 } 00516 } 00517 00518 return data_size * 2; 00519 } 00520 00521 static int vmdaudio_decode_frame(AVCodecContext *avctx, 00522 void *data, int *data_size, 00523 AVPacket *avpkt) 00524 { 00525 const uint8_t *buf = avpkt->data; 00526 int buf_size = avpkt->size; 00527 VmdAudioContext *s = avctx->priv_data; 00528 unsigned char *output_samples = (unsigned char *)data; 00529 00530 /* point to the start of the encoded data */ 00531 const unsigned char *p = buf + 16; 00532 00533 if (buf_size < 16) 00534 return buf_size; 00535 00536 if (buf[6] == 1) { 00537 /* the chunk contains audio */ 00538 *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16); 00539 } else if (buf[6] == 2) { 00540 /* initial chunk, may contain audio and silence */ 00541 uint32_t flags = AV_RB32(p); 00542 int raw_block_size = s->block_align * s->bits / 8; 00543 int silent_chunks; 00544 if(flags == 0xFFFFFFFF) 00545 silent_chunks = 32; 00546 else 00547 silent_chunks = av_log2(flags + 1); 00548 if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2) 00549 return -1; 00550 *data_size = 0; 00551 memset(output_samples, 0, raw_block_size * silent_chunks); 00552 output_samples += raw_block_size * silent_chunks; 00553 *data_size = raw_block_size * silent_chunks; 00554 *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20); 00555 } else if (buf[6] == 3) { 00556 /* silent chunk */ 00557 *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0); 00558 } 00559 00560 return buf_size; 00561 } 00562 00563 00564 /* 00565 * Public Data Structures 00566 */ 00567 00568 AVCodec vmdvideo_decoder = { 00569 "vmdvideo", 00570 AVMEDIA_TYPE_VIDEO, 00571 CODEC_ID_VMDVIDEO, 00572 sizeof(VmdVideoContext), 00573 vmdvideo_decode_init, 00574 NULL, 00575 vmdvideo_decode_end, 00576 vmdvideo_decode_frame, 00577 CODEC_CAP_DR1, 00578 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"), 00579 }; 00580 00581 AVCodec vmdaudio_decoder = { 00582 "vmdaudio", 00583 AVMEDIA_TYPE_AUDIO, 00584 CODEC_ID_VMDAUDIO, 00585 sizeof(VmdAudioContext), 00586 vmdaudio_decode_init, 00587 NULL, 00588 NULL, 00589 vmdaudio_decode_frame, 00590 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"), 00591 };