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
57typedef 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
76static 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
146static 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
185static 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
326static 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
367static int vmdvideo_decode_frame(AVCodecContext *avctx,
368                                 void *data, int *data_size,
369                                 const uint8_t *buf, int buf_size)
370{
371    VmdVideoContext *s = avctx->priv_data;
372
373    s->buf = buf;
374    s->size = buf_size;
375
376    if (buf_size < 16)
377        return buf_size;
378
379    s->frame.reference = 1;
380    if (avctx->get_buffer(avctx, &s->frame)) {
381        av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
382        return -1;
383    }
384
385    vmd_decode(s);
386
387    /* make the palette available on the way out */
388    memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
389
390    /* shuffle frames */
391    FFSWAP(AVFrame, s->frame, s->prev_frame);
392    if (s->frame.data[0])
393        avctx->release_buffer(avctx, &s->frame);
394
395    *data_size = sizeof(AVFrame);
396    *(AVFrame*)data = s->prev_frame;
397
398    /* report that the buffer was completely consumed */
399    return buf_size;
400}
401
402static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
403{
404    VmdVideoContext *s = avctx->priv_data;
405
406    if (s->prev_frame.data[0])
407        avctx->release_buffer(avctx, &s->prev_frame);
408    av_free(s->unpack_buffer);
409
410    return 0;
411}
412
413
414/*
415 * Audio Decoder
416 */
417
418typedef struct VmdAudioContext {
419    AVCodecContext *avctx;
420    int channels;
421    int bits;
422    int block_align;
423    int predictors[2];
424} VmdAudioContext;
425
426static const uint16_t vmdaudio_table[128] = {
427    0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
428    0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
429    0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
430    0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
431    0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
432    0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
433    0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
434    0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
435    0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
436    0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
437    0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
438    0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
439    0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
440};
441
442static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
443{
444    VmdAudioContext *s = avctx->priv_data;
445
446    s->avctx = avctx;
447    s->channels = avctx->channels;
448    s->bits = avctx->bits_per_coded_sample;
449    s->block_align = avctx->block_align;
450    avctx->sample_fmt = SAMPLE_FMT_S16;
451
452    av_log(s->avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, block align = %d, sample rate = %d\n",
453            s->channels, s->bits, s->block_align, avctx->sample_rate);
454
455    return 0;
456}
457
458static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
459    const uint8_t *buf, int buf_size, int stereo)
460{
461    int i;
462    int chan = 0;
463    int16_t *out = (int16_t*)data;
464
465    for(i = 0; i < buf_size; i++) {
466        if(buf[i] & 0x80)
467            s->predictors[chan] -= vmdaudio_table[buf[i] & 0x7F];
468        else
469            s->predictors[chan] += vmdaudio_table[buf[i]];
470        s->predictors[chan] = av_clip_int16(s->predictors[chan]);
471        out[i] = s->predictors[chan];
472        chan ^= stereo;
473    }
474}
475
476static int vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
477    const uint8_t *buf, int silence, int data_size)
478{
479    int bytes_decoded = 0;
480    int i;
481
482//    if (silence)
483//        av_log(s->avctx, AV_LOG_INFO, "silent block!\n");
484    if (s->channels == 2) {
485
486        /* stereo handling */
487        if (silence) {
488            memset(data, 0, data_size * 2);
489        } else {
490            if (s->bits == 16)
491                vmdaudio_decode_audio(s, data, buf, data_size, 1);
492            else {
493                /* copy the data but convert it to signed */
494                for (i = 0; i < data_size; i++){
495                    *data++ = buf[i] + 0x80;
496                    *data++ = buf[i] + 0x80;
497                }
498            }
499        }
500    } else {
501        bytes_decoded = data_size * 2;
502
503        /* mono handling */
504        if (silence) {
505            memset(data, 0, data_size * 2);
506        } else {
507            if (s->bits == 16) {
508                vmdaudio_decode_audio(s, data, buf, data_size, 0);
509            } else {
510                /* copy the data but convert it to signed */
511                for (i = 0; i < data_size; i++){
512                    *data++ = buf[i] + 0x80;
513                    *data++ = buf[i] + 0x80;
514                }
515            }
516        }
517    }
518
519    return data_size * 2;
520}
521
522static int vmdaudio_decode_frame(AVCodecContext *avctx,
523                                 void *data, int *data_size,
524                                 const uint8_t *buf, int buf_size)
525{
526    VmdAudioContext *s = avctx->priv_data;
527    unsigned char *output_samples = (unsigned char *)data;
528
529    /* point to the start of the encoded data */
530    const unsigned char *p = buf + 16;
531
532    if (buf_size < 16)
533        return buf_size;
534
535    if (buf[6] == 1) {
536        /* the chunk contains audio */
537        *data_size = vmdaudio_loadsound(s, output_samples, p, 0, buf_size - 16);
538    } else if (buf[6] == 2) {
539        /* initial chunk, may contain audio and silence */
540        uint32_t flags = AV_RB32(p);
541        int raw_block_size = s->block_align * s->bits / 8;
542        int silent_chunks;
543        if(flags == 0xFFFFFFFF)
544            silent_chunks = 32;
545        else
546            silent_chunks = av_log2(flags + 1);
547        if(*data_size < (s->block_align*silent_chunks + buf_size - 20) * 2)
548            return -1;
549        *data_size = 0;
550        memset(output_samples, 0, raw_block_size * silent_chunks);
551        output_samples += raw_block_size * silent_chunks;
552        *data_size = raw_block_size * silent_chunks;
553        *data_size += vmdaudio_loadsound(s, output_samples, p + 4, 0, buf_size - 20);
554    } else if (buf[6] == 3) {
555        /* silent chunk */
556        *data_size = vmdaudio_loadsound(s, output_samples, p, 1, 0);
557    }
558
559    return buf_size;
560}
561
562
563/*
564 * Public Data Structures
565 */
566
567AVCodec vmdvideo_decoder = {
568    "vmdvideo",
569    CODEC_TYPE_VIDEO,
570    CODEC_ID_VMDVIDEO,
571    sizeof(VmdVideoContext),
572    vmdvideo_decode_init,
573    NULL,
574    vmdvideo_decode_end,
575    vmdvideo_decode_frame,
576    CODEC_CAP_DR1,
577    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
578};
579
580AVCodec vmdaudio_decoder = {
581    "vmdaudio",
582    CODEC_TYPE_AUDIO,
583    CODEC_ID_VMDAUDIO,
584    sizeof(VmdAudioContext),
585    vmdaudio_decode_init,
586    NULL,
587    NULL,
588    vmdaudio_decode_frame,
589    .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
590};
591