]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/vmdav.c
indent
[frescor/ffmpeg.git] / libavcodec / vmdav.c
1 /*
2  * Sierra VMD Audio & Video Decoders
3  * Copyright (C) 2004 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file libavcodec/vmdav.c
24  * Sierra VMD audio & video decoders
25  * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
26  * for more information on the Sierra VMD format, visit:
27  *   http://www.pcisys.net/~melanson/codecs/
28  *
29  * The video decoder outputs PAL8 colorspace data. The decoder expects
30  * a 0x330-byte VMD file header to be transmitted via extradata during
31  * codec initialization. Each encoded frame that is sent to this decoder
32  * is expected to be prepended with the appropriate 16-byte frame
33  * information record from the VMD file.
34  *
35  * The audio decoder, like the video decoder, expects each encoded data
36  * chunk to be prepended with the appropriate 16-byte frame information
37  * record from the VMD file. It does not require the 0x330-byte VMD file
38  * header, but it does need the audio setup parameters passed in through
39  * normal libavcodec API means.
40  */
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46
47 #include "libavutil/intreadwrite.h"
48 #include "avcodec.h"
49
50 #define VMD_HEADER_SIZE 0x330
51 #define PALETTE_COUNT 256
52
53 /*
54  * Video Decoder
55  */
56
57 typedef struct VmdVideoContext {
58
59     AVCodecContext *avctx;
60     AVFrame frame;
61     AVFrame prev_frame;
62
63     const unsigned char *buf;
64     int size;
65
66     unsigned char palette[PALETTE_COUNT * 4];
67     unsigned char *unpack_buffer;
68     int unpack_buffer_size;
69
70     int x_off, y_off;
71 } VmdVideoContext;
72
73 #define QUEUE_SIZE 0x1000
74 #define QUEUE_MASK 0x0FFF
75
76 static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len)
77 {
78     const unsigned char *s;
79     unsigned char *d;
80     unsigned char *d_end;
81     unsigned char queue[QUEUE_SIZE];
82     unsigned int qpos;
83     unsigned int dataleft;
84     unsigned int chainofs;
85     unsigned int chainlen;
86     unsigned int speclen;
87     unsigned char tag;
88     unsigned int i, j;
89
90     s = src;
91     d = dest;
92     d_end = d + dest_len;
93     dataleft = AV_RL32(s);
94     s += 4;
95     memset(queue, 0x20, QUEUE_SIZE);
96     if (AV_RL32(s) == 0x56781234) {
97         s += 4;
98         qpos = 0x111;
99         speclen = 0xF + 3;
100     } else {
101         qpos = 0xFEE;
102         speclen = 100;  /* no speclen */
103     }
104
105     while (dataleft > 0) {
106         tag = *s++;
107         if ((tag == 0xFF) && (dataleft > 8)) {
108             if (d + 8 > d_end)
109                 return;
110             for (i = 0; i < 8; i++) {
111                 queue[qpos++] = *d++ = *s++;
112                 qpos &= QUEUE_MASK;
113             }
114             dataleft -= 8;
115         } else {
116             for (i = 0; i < 8; i++) {
117                 if (dataleft == 0)
118                     break;
119                 if (tag & 0x01) {
120                     if (d + 1 > d_end)
121                         return;
122                     queue[qpos++] = *d++ = *s++;
123                     qpos &= QUEUE_MASK;
124                     dataleft--;
125                 } else {
126                     chainofs = *s++;
127                     chainofs |= ((*s & 0xF0) << 4);
128                     chainlen = (*s++ & 0x0F) + 3;
129                     if (chainlen == speclen)
130                         chainlen = *s++ + 0xF + 3;
131                     if (d + chainlen > d_end)
132                         return;
133                     for (j = 0; j < chainlen; j++) {
134                         *d = queue[chainofs++ & QUEUE_MASK];
135                         queue[qpos++] = *d++;
136                         qpos &= QUEUE_MASK;
137                     }
138                     dataleft -= chainlen;
139                 }
140                 tag >>= 1;
141             }
142         }
143     }
144 }
145
146 static int rle_unpack(const unsigned char *src, unsigned char *dest,
147     int src_len, int dest_len)
148 {
149     const unsigned char *ps;
150     unsigned char *pd;
151     int i, l;
152     unsigned char *dest_end = dest + dest_len;
153
154     ps = src;
155     pd = dest;
156     if (src_len & 1)
157         *pd++ = *ps++;
158
159     src_len >>= 1;
160     i = 0;
161     do {
162         l = *ps++;
163         if (l & 0x80) {
164             l = (l & 0x7F) * 2;
165             if (pd + l > dest_end)
166                 return ps - src;
167             memcpy(pd, ps, l);
168             ps += l;
169             pd += l;
170         } else {
171             if (pd + i > dest_end)
172                 return ps - src;
173             for (i = 0; i < l; i++) {
174                 *pd++ = ps[0];
175                 *pd++ = ps[1];
176             }
177             ps += 2;
178         }
179         i += l;
180     } while (i < src_len);
181
182     return ps - src;
183 }
184
185 static void vmd_decode(VmdVideoContext *s)
186 {
187     int i;
188     unsigned int *palette32;
189     unsigned char r, g, b;
190
191     /* point to the start of the encoded data */
192     const unsigned char *p = s->buf + 16;
193
194     const unsigned char *pb;
195     unsigned char meth;
196     unsigned char *dp;   /* pointer to current frame */
197     unsigned char *pp;   /* pointer to previous frame */
198     unsigned char len;
199     int ofs;
200
201     int frame_x, frame_y;
202     int frame_width, frame_height;
203     int dp_size;
204
205     frame_x = AV_RL16(&s->buf[6]);
206     frame_y = AV_RL16(&s->buf[8]);
207     frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
208     frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
209
210     if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
211         (frame_x || frame_y)) {
212
213         s->x_off = frame_x;
214         s->y_off = frame_y;
215     }
216     frame_x -= s->x_off;
217     frame_y -= s->y_off;
218
219     /* if only a certain region will be updated, copy the entire previous
220      * frame before the decode */
221     if (frame_x || frame_y || (frame_width != s->avctx->width) ||
222         (frame_height != s->avctx->height)) {
223
224         memcpy(s->frame.data[0], s->prev_frame.data[0],
225             s->avctx->height * s->frame.linesize[0]);
226     }
227
228     /* check if there is a new palette */
229     if (s->buf[15] & 0x02) {
230         p += 2;
231         palette32 = (unsigned int *)s->palette;
232         for (i = 0; i < PALETTE_COUNT; i++) {
233             r = *p++ * 4;
234             g = *p++ * 4;
235             b = *p++ * 4;
236             palette32[i] = (r << 16) | (g << 8) | (b);
237         }
238         s->size -= (256 * 3 + 2);
239     }
240     if (s->size >= 0) {
241         /* originally UnpackFrame in VAG's code */
242         pb = p;
243         meth = *pb++;
244         if (meth & 0x80) {
245             lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
246             meth &= 0x7F;
247             pb = s->unpack_buffer;
248         }
249
250         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
251         dp_size = s->frame.linesize[0] * s->avctx->height;
252         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
253         switch (meth) {
254         case 1:
255             for (i = 0; i < frame_height; i++) {
256                 ofs = 0;
257                 do {
258                     len = *pb++;
259                     if (len & 0x80) {
260                         len = (len & 0x7F) + 1;
261                         if (ofs + len > frame_width)
262                             return;
263                         memcpy(&dp[ofs], pb, len);
264                         pb += len;
265                         ofs += len;
266                     } else {
267                         /* interframe pixel copy */
268                         if (ofs + len + 1 > frame_width)
269                             return;
270                         memcpy(&dp[ofs], &pp[ofs], len + 1);
271                         ofs += len + 1;
272                     }
273                 } while (ofs < frame_width);
274                 if (ofs > frame_width) {
275                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
276                         ofs, frame_width);
277                     break;
278                 }
279                 dp += s->frame.linesize[0];
280                 pp += s->prev_frame.linesize[0];
281             }
282             break;
283
284         case 2:
285             for (i = 0; i < frame_height; i++) {
286                 memcpy(dp, pb, frame_width);
287                 pb += frame_width;
288                 dp += s->frame.linesize[0];
289                 pp += s->prev_frame.linesize[0];
290             }
291             break;
292
293         case 3:
294             for (i = 0; i < frame_height; i++) {
295                 ofs = 0;
296                 do {
297                     len = *pb++;
298                     if (len & 0x80) {
299                         len = (len & 0x7F) + 1;
300                         if (*pb++ == 0xFF)
301                             len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
302                         else
303                             memcpy(&dp[ofs], pb, len);
304                         pb += len;
305                         ofs += len;
306                     } else {
307                         /* interframe pixel copy */
308                         if (ofs + len + 1 > frame_width)
309                             return;
310                         memcpy(&dp[ofs], &pp[ofs], len + 1);
311                         ofs += len + 1;
312                     }
313                 } while (ofs < frame_width);
314                 if (ofs > frame_width) {
315                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
316                         ofs, frame_width);
317                 }
318                 dp += s->frame.linesize[0];
319                 pp += s->prev_frame.linesize[0];
320             }
321             break;
322         }
323     }
324 }
325
326 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
327 {
328     VmdVideoContext *s = avctx->priv_data;
329     int i;
330     unsigned int *palette32;
331     int palette_index = 0;
332     unsigned char r, g, b;
333     unsigned char *vmd_header;
334     unsigned char *raw_palette;
335
336     s->avctx = avctx;
337     avctx->pix_fmt = PIX_FMT_PAL8;
338
339     /* make sure the VMD header made it */
340     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
341         av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
342             VMD_HEADER_SIZE);
343         return -1;
344     }
345     vmd_header = (unsigned char *)avctx->extradata;
346
347     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
348     s->unpack_buffer = av_malloc(s->unpack_buffer_size);
349     if (!s->unpack_buffer)
350         return -1;
351
352     /* load up the initial palette */
353     raw_palette = &vmd_header[28];
354     palette32 = (unsigned int *)s->palette;
355     for (i = 0; i < PALETTE_COUNT; i++) {
356         r = raw_palette[palette_index++] * 4;
357         g = raw_palette[palette_index++] * 4;
358         b = raw_palette[palette_index++] * 4;
359         palette32[i] = (r << 16) | (g << 8) | (b);
360     }
361
362     s->frame.data[0] = s->prev_frame.data[0] = NULL;
363
364     return 0;
365 }
366
367 static int vmdvideo_decode_frame(AVCodecContext *avctx,
368                                  void *data, int *data_size,
369                                  AVPacket *avpkt)
370 {
371     const uint8_t *buf = avpkt->data;
372     int buf_size = avpkt->size;
373     VmdVideoContext *s = avctx->priv_data;
374
375     s->buf = buf;
376     s->size = buf_size;
377
378     if (buf_size < 16)
379         return buf_size;
380
381     s->frame.reference = 1;
382     if (avctx->get_buffer(avctx, &s->frame)) {
383         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
384         return -1;
385     }
386
387     vmd_decode(s);
388
389     /* make the palette available on the way out */
390     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
391
392     /* shuffle frames */
393     FFSWAP(AVFrame, s->frame, s->prev_frame);
394     if (s->frame.data[0])
395         avctx->release_buffer(avctx, &s->frame);
396
397     *data_size = sizeof(AVFrame);
398     *(AVFrame*)data = s->prev_frame;
399
400     /* report that the buffer was completely consumed */
401     return buf_size;
402 }
403
404 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
405 {
406     VmdVideoContext *s = avctx->priv_data;
407
408     if (s->prev_frame.data[0])
409         avctx->release_buffer(avctx, &s->prev_frame);
410     av_free(s->unpack_buffer);
411
412     return 0;
413 }
414
415
416 /*
417  * Audio Decoder
418  */
419
420 typedef struct VmdAudioContext {
421     AVCodecContext *avctx;
422     int channels;
423     int bits;
424     int block_align;
425     int predictors[2];
426 } VmdAudioContext;
427
428 static const uint16_t vmdaudio_table[128] = {
429     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
430     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
431     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
432     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
433     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
434     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
435     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
436     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
437     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
438     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
439     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
440     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
441     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
442 };
443
444 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
445 {
446     VmdAudioContext *s = avctx->priv_data;
447
448     s->avctx = avctx;
449     s->channels = avctx->channels;
450     s->bits = avctx->bits_per_coded_sample;
451     s->block_align = avctx->block_align;
452     avctx->sample_fmt = SAMPLE_FMT_S16;
453
454     av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
455             s->channels, s->bits, s->block_align, avctx->sample_rate);
456
457     return 0;
458 }
459
460 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
461     const uint8_t *buf, int buf_size, int stereo)
462 {
463     int i;
464     int chan = 0;
465     int16_t *out = (int16_t*)data;
466
467     for(i = 0; i < buf_size; i++) {
468         if(buf[i] & 0x80)
469             s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
470         else
471             s->predictors[chan] += vmdaudio_table[buf[i]];
472         s->predictors[chan] = av_clip_int16(s->predictors[chan]);
473         out[i] = s->predictors[chan];
474         chan ^= stereo;
475     }
476 }
477
478 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
479     const uint8_t *buf, int silence, int data_size)
480 {
481     int bytes_decoded = 0;
482     int i;
483
484 //    if (silence)
485 //        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
486     if (s->channels == 2) {
487
488         /* stereo handling */
489         if (silence) {
490             memset(data, 0, data_size * 2);
491         } else {
492             if (s->bits == 16)
493                 vmdaudio_decode_audio(s, data, buf, data_size, 1);
494             else {
495                 /* copy the data but convert it to signed */
496                 for (i = 0; i < data_size; i++){
497                     *data++ = buf[i] + 0x80;
498                     *data++ = buf[i] + 0x80;
499                 }
500             }
501         }
502     } else {
503         bytes_decoded = data_size * 2;
504
505         /* mono handling */
506         if (silence) {
507             memset(data, 0, data_size * 2);
508         } else {
509             if (s->bits == 16) {
510                 vmdaudio_decode_audio(s, data, buf, data_size, 0);
511             } else {
512                 /* copy the data but convert it to signed */
513                 for (i = 0; i < data_size; i++){
514                     *data++ = buf[i] + 0x80;
515                     *data++ = buf[i] + 0x80;
516                 }
517             }
518         }
519     }
520
521     return data_size * 2;
522 }
523
524 static int vmdaudio_decode_frame(AVCodecContext *avctx,
525                                  void *data, int *data_size,
526                                  AVPacket *avpkt)
527 {
528     const uint8_t *buf = avpkt->data;
529     int buf_size = avpkt->size;
530     VmdAudioContext *s = avctx->priv_data;
531     unsigned char *output_samples = (unsigned char *)data;
532
533     /* point to the start of the encoded data */
534     const unsigned char *p = buf + 16;
535
536     if (buf_size < 16)
537         return buf_size;
538
539     if (buf[6] == 1) {
540         /* the chunk contains audio */
541         *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
542     } else if (buf[6] == 2) {
543         /* initial chunk, may contain audio and silence */
544         uint32_t flags = AV_RB32(p);
545         int raw_block_size = s->block_align * s->bits / 8;
546         int silent_chunks;
547         if(flags == 0xFFFFFFFF)
548             silent_chunks = 32;
549         else
550             silent_chunks = av_log2(flags + 1);
551         if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
552             return -1;
553         *data_size = 0;
554         memset(output_samples, 0, raw_block_size * silent_chunks);
555         output_samples += raw_block_size * silent_chunks;
556         *data_size = raw_block_size * silent_chunks;
557         *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
558     } else if (buf[6] == 3) {
559         /* silent chunk */
560         *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0);
561     }
562
563     return buf_size;
564 }
565
566
567 /*
568  * Public Data Structures
569  */
570
571 AVCodec vmdvideo_decoder = {
572     "vmdvideo",
573     CODEC_TYPE_VIDEO,
574     CODEC_ID_VMDVIDEO,
575     sizeof(VmdVideoContext),
576     vmdvideo_decode_init,
577     NULL,
578     vmdvideo_decode_end,
579     vmdvideo_decode_frame,
580     CODEC_CAP_DR1,
581     .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
582 };
583
584 AVCodec vmdaudio_decoder = {
585     "vmdaudio",
586     CODEC_TYPE_AUDIO,
587     CODEC_ID_VMDAUDIO,
588     sizeof(VmdAudioContext),
589     vmdaudio_decode_init,
590     NULL,
591     NULL,
592     vmdaudio_decode_frame,
593     .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
594 };