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