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