]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/vmdav.c
Simplify AC-3 critical band end calculation (correctly this time).
[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
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
56 typedef 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
75 static 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
145 static 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
184 static 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
325 static 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
364 static 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
401 static 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
417 typedef struct VmdAudioContext {
418     AVCodecContext *avctx;
419     int channels;
420     int bits;
421     int block_align;
422     int predictors[2];
423 } VmdAudioContext;
424
425 static 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
441 static 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
457 static 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
475 static 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
521 static 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
568 AVCodec vmdvideo_decoder = {
569     "vmdvideo",
570     CODEC_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
581 AVCodec vmdaudio_decoder = {
582     "vmdaudio",
583     CODEC_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 };