]> git.sesse.net Git - ffmpeg/blob - libavcodec/vmdav.c
10l to Benoit, poll.h is already included below, and this broke compilation on mingw
[ffmpeg] / 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 vmdvideo.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 "avcodec.h"
48 #include "dsputil.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     DSPContext dsp;
61     AVFrame frame;
62     AVFrame prev_frame;
63
64     unsigned char *buf;
65     int size;
66
67     unsigned char palette[PALETTE_COUNT * 4];
68     unsigned char *unpack_buffer;
69     int unpack_buffer_size;
70
71 } VmdVideoContext;
72
73 #define QUEUE_SIZE 0x1000
74 #define QUEUE_MASK 0x0FFF
75
76 static void lz_unpack(unsigned char *src, unsigned char *dest, int dest_len)
77 {
78     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(unsigned char *src, unsigned char *dest,
147     int src_len, int dest_len)
148 {
149     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     unsigned char *p = s->buf + 16;
193
194     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 only a certain region will be updated, copy the entire previous
211      * frame before the decode */
212     if (frame_x || frame_y || (frame_width != s->avctx->width) ||
213         (frame_height != s->avctx->height)) {
214
215         memcpy(s->frame.data[0], s->prev_frame.data[0],
216             s->avctx->height * s->frame.linesize[0]);
217     }
218
219     /* check if there is a new palette */
220     if (s->buf[15] & 0x02) {
221         p += 2;
222         palette32 = (unsigned int *)s->palette;
223         for (i = 0; i < PALETTE_COUNT; i++) {
224             r = *p++ * 4;
225             g = *p++ * 4;
226             b = *p++ * 4;
227             palette32[i] = (r << 16) | (g << 8) | (b);
228         }
229         s->size -= (256 * 3 + 2);
230     }
231     if (s->size >= 0) {
232         /* originally UnpackFrame in VAG's code */
233         pb = p;
234         meth = *pb++;
235         if (meth & 0x80) {
236             lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size);
237             meth &= 0x7F;
238             pb = s->unpack_buffer;
239         }
240
241         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
242         dp_size = s->frame.linesize[0] * s->avctx->height;
243         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
244         switch (meth) {
245         case 1:
246             for (i = 0; i < frame_height; i++) {
247                 ofs = 0;
248                 do {
249                     len = *pb++;
250                     if (len & 0x80) {
251                         len = (len & 0x7F) + 1;
252                         if (ofs + len > frame_width)
253                             return;
254                         memcpy(&dp[ofs], pb, len);
255                         pb += len;
256                         ofs += len;
257                     } else {
258                         /* interframe pixel copy */
259                         if (ofs + len + 1 > frame_width)
260                             return;
261                         memcpy(&dp[ofs], &pp[ofs], len + 1);
262                         ofs += len + 1;
263                     }
264                 } while (ofs < frame_width);
265                 if (ofs > frame_width) {
266                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
267                         ofs, frame_width);
268                     break;
269                 }
270                 dp += s->frame.linesize[0];
271                 pp += s->prev_frame.linesize[0];
272             }
273             break;
274
275         case 2:
276             for (i = 0; i < frame_height; i++) {
277                 memcpy(dp, pb, frame_width);
278                 pb += frame_width;
279                 dp += s->frame.linesize[0];
280                 pp += s->prev_frame.linesize[0];
281             }
282             break;
283
284         case 3:
285             for (i = 0; i < frame_height; i++) {
286                 ofs = 0;
287                 do {
288                     len = *pb++;
289                     if (len & 0x80) {
290                         len = (len & 0x7F) + 1;
291                         if (*pb++ == 0xFF)
292                             len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs);
293                         else
294                             memcpy(&dp[ofs], pb, len);
295                         pb += len;
296                         ofs += len;
297                     } else {
298                         /* interframe pixel copy */
299                         if (ofs + len + 1 > frame_width)
300                             return;
301                         memcpy(&dp[ofs], &pp[ofs], len + 1);
302                         ofs += len + 1;
303                     }
304                 } while (ofs < frame_width);
305                 if (ofs > frame_width) {
306                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
307                         ofs, frame_width);
308                 }
309                 dp += s->frame.linesize[0];
310                 pp += s->prev_frame.linesize[0];
311             }
312             break;
313         }
314     }
315 }
316
317 static int vmdvideo_decode_init(AVCodecContext *avctx)
318 {
319     VmdVideoContext *s = avctx->priv_data;
320     int i;
321     unsigned int *palette32;
322     int palette_index = 0;
323     unsigned char r, g, b;
324     unsigned char *vmd_header;
325     unsigned char *raw_palette;
326
327     s->avctx = avctx;
328     avctx->pix_fmt = PIX_FMT_PAL8;
329     dsputil_init(&s->dsp, avctx);
330
331     /* make sure the VMD header made it */
332     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
333         av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
334             VMD_HEADER_SIZE);
335         return -1;
336     }
337     vmd_header = (unsigned char *)avctx->extradata;
338
339     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
340     s->unpack_buffer = av_malloc(s->unpack_buffer_size);
341     if (!s->unpack_buffer)
342         return -1;
343
344     /* load up the initial palette */
345     raw_palette = &vmd_header[28];
346     palette32 = (unsigned int *)s->palette;
347     for (i = 0; i < PALETTE_COUNT; i++) {
348         r = raw_palette[palette_index++] * 4;
349         g = raw_palette[palette_index++] * 4;
350         b = raw_palette[palette_index++] * 4;
351         palette32[i] = (r << 16) | (g << 8) | (b);
352     }
353
354     s->frame.data[0] = s->prev_frame.data[0] = NULL;
355
356     return 0;
357 }
358
359 static int vmdvideo_decode_frame(AVCodecContext *avctx,
360                                  void *data, int *data_size,
361                                  uint8_t *buf, int buf_size)
362 {
363     VmdVideoContext *s = avctx->priv_data;
364
365     s->buf = buf;
366     s->size = buf_size;
367
368     if (buf_size < 16)
369         return buf_size;
370
371     s->frame.reference = 1;
372     if (avctx->get_buffer(avctx, &s->frame)) {
373         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
374         return -1;
375     }
376
377     vmd_decode(s);
378
379     /* make the palette available on the way out */
380     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
381
382     /* shuffle frames */
383     FFSWAP(AVFrame, s->frame, s->prev_frame);
384     if (s->frame.data[0])
385         avctx->release_buffer(avctx, &s->frame);
386
387     *data_size = sizeof(AVFrame);
388     *(AVFrame*)data = s->prev_frame;
389
390     /* report that the buffer was completely consumed */
391     return buf_size;
392 }
393
394 static int vmdvideo_decode_end(AVCodecContext *avctx)
395 {
396     VmdVideoContext *s = avctx->priv_data;
397
398     if (s->prev_frame.data[0])
399         avctx->release_buffer(avctx, &s->prev_frame);
400     av_free(s->unpack_buffer);
401
402     return 0;
403 }
404
405
406 /*
407  * Audio Decoder
408  */
409
410 typedef struct VmdAudioContext {
411     AVCodecContext *avctx;
412     int channels;
413     int bits;
414     int block_align;
415     int predictors[2];
416 } VmdAudioContext;
417
418 static uint16_t vmdaudio_table[128] = {
419     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
420     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
421     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
422     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
423     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
424     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
425     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
426     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
427     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
428     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
429     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
430     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
431     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
432 };
433
434 static int vmdaudio_decode_init(AVCodecContext *avctx)
435 {
436     VmdAudioContext *s = avctx->priv_data;
437
438     s->avctx = avctx;
439     s->channels = avctx->channels;
440     s->bits = avctx->bits_per_sample;
441     s->block_align = avctx->block_align;
442
443     av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
444             s->channels, s->bits, s->block_align, avctx->sample_rate);
445
446     return 0;
447 }
448
449 static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
450     uint8_t *buf, int stereo)
451 {
452     int i;
453     int chan = 0;
454     int16_t *out = (int16_t*)data;
455
456     for(i = 0; i < s->block_align; i++) {
457         if(buf[i] & 0x80)
458             s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
459         else
460             s->predictors[chan] += vmdaudio_table[buf[i]];
461         s->predictors[chan] = av_clip(s->predictors[chan], -32768, 32767);
462         out[i] = s->predictors[chan];
463         chan ^= stereo;
464     }
465 }
466
467 static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
468     uint8_t *buf, int silence)
469 {
470     int bytes_decoded = 0;
471     int i;
472
473 //    if (silence)
474 //        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
475     if (s->channels == 2) {
476
477         /* stereo handling */
478         if (silence) {
479             memset(data, 0, s->block_align * 2);
480         } else {
481             if (s->bits == 16)
482                 vmdaudio_decode_audio(s, data, buf, 1);
483             else {
484                 /* copy the data but convert it to signed */
485                 for (i = 0; i < s->block_align; i++){
486                     *data++ = buf[i] + 0x80;
487                     *data++ = buf[i] + 0x80;
488                 }
489             }
490         }
491     } else {
492         bytes_decoded = s->block_align * 2;
493
494         /* mono handling */
495         if (silence) {
496             memset(data, 0, s->block_align * 2);
497         } else {
498             if (s->bits == 16) {
499                 vmdaudio_decode_audio(s, data, buf, 0);
500             } else {
501                 /* copy the data but convert it to signed */
502                 for (i = 0; i < s->block_align; i++){
503                     *data++ = buf[i] + 0x80;
504                     *data++ = buf[i] + 0x80;
505                 }
506             }
507         }
508     }
509
510     return s->block_align * 2;
511 }
512
513 static int vmdaudio_decode_frame(AVCodecContext *avctx,
514                                  void *data, int *data_size,
515                                  uint8_t *buf, int buf_size)
516 {
517     VmdAudioContext *s = avctx->priv_data;
518     unsigned char *output_samples = (unsigned char *)data;
519
520     /* point to the start of the encoded data */
521     unsigned char *p = buf + 16;
522
523     if (buf_size < 16)
524         return buf_size;
525
526     if (buf[6] == 1) {
527         /* the chunk contains audio */
528         *data_size = vmdaudio_loadsound(s, output_samples, p, 0);
529     } else if (buf[6] == 2) {
530         /* the chunk may contain audio */
531         p += 4;
532         *data_size = vmdaudio_loadsound(s, output_samples, p, (buf_size == 16));
533         output_samples += (s->block_align * s->bits / 8);
534     } else if (buf[6] == 3) {
535         /* silent chunk */
536         *data_size = vmdaudio_loadsound(s, output_samples, p, 1);
537     }
538
539     return buf_size;
540 }
541
542
543 /*
544  * Public Data Structures
545  */
546
547 AVCodec vmdvideo_decoder = {
548     "vmdvideo",
549     CODEC_TYPE_VIDEO,
550     CODEC_ID_VMDVIDEO,
551     sizeof(VmdVideoContext),
552     vmdvideo_decode_init,
553     NULL,
554     vmdvideo_decode_end,
555     vmdvideo_decode_frame,
556     CODEC_CAP_DR1,
557 };
558
559 AVCodec vmdaudio_decoder = {
560     "vmdaudio",
561     CODEC_TYPE_AUDIO,
562     CODEC_ID_VMDAUDIO,
563     sizeof(VmdAudioContext),
564     vmdaudio_decode_init,
565     NULL,
566     NULL,
567     vmdaudio_decode_frame,
568 };