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