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