]> 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] = (r << 16) | (g << 8) | (b);
268         }
269     }
270     if (p < p_end) {
271         /* originally UnpackFrame in VAG's code */
272         pb = p;
273         pb_end = p_end;
274         meth = *pb++;
275         if (meth & 0x80) {
276             lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size);
277             meth &= 0x7F;
278             pb = s->unpack_buffer;
279             pb_end = s->unpack_buffer + s->unpack_buffer_size;
280         }
281
282         dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
283         pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
284         switch (meth) {
285         case 1:
286             for (i = 0; i < frame_height; i++) {
287                 ofs = 0;
288                 do {
289                     if (pb_end - pb < 1)
290                         return;
291                     len = *pb++;
292                     if (len & 0x80) {
293                         len = (len & 0x7F) + 1;
294                         if (ofs + len > frame_width || pb_end - pb < len)
295                             return;
296                         memcpy(&dp[ofs], pb, len);
297                         pb += len;
298                         ofs += len;
299                     } else {
300                         /* interframe pixel copy */
301                         if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
302                             return;
303                         memcpy(&dp[ofs], &pp[ofs], len + 1);
304                         ofs += len + 1;
305                     }
306                 } while (ofs < frame_width);
307                 if (ofs > frame_width) {
308                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
309                         ofs, frame_width);
310                     break;
311                 }
312                 dp += s->frame.linesize[0];
313                 pp += s->prev_frame.linesize[0];
314             }
315             break;
316
317         case 2:
318             for (i = 0; i < frame_height; i++) {
319                 if (pb_end -pb < frame_width)
320                     return;
321                 memcpy(dp, pb, frame_width);
322                 pb += frame_width;
323                 dp += s->frame.linesize[0];
324                 pp += s->prev_frame.linesize[0];
325             }
326             break;
327
328         case 3:
329             for (i = 0; i < frame_height; i++) {
330                 ofs = 0;
331                 do {
332                     if (pb_end - pb < 1)
333                         return;
334                     len = *pb++;
335                     if (len & 0x80) {
336                         len = (len & 0x7F) + 1;
337                         if (pb_end - pb < 1)
338                             return;
339                         if (*pb++ == 0xFF)
340                             len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs);
341                         else {
342                         if (pb_end - pb < len)
343                             return;
344                             memcpy(&dp[ofs], pb, len);
345                         }
346                         pb += len;
347                         ofs += len;
348                     } else {
349                         /* interframe pixel copy */
350                         if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
351                             return;
352                         memcpy(&dp[ofs], &pp[ofs], len + 1);
353                         ofs += len + 1;
354                     }
355                 } while (ofs < frame_width);
356                 if (ofs > frame_width) {
357                     av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
358                         ofs, frame_width);
359                 }
360                 dp += s->frame.linesize[0];
361                 pp += s->prev_frame.linesize[0];
362             }
363             break;
364         }
365     }
366 }
367
368 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
369 {
370     VmdVideoContext *s = avctx->priv_data;
371     int i;
372     unsigned int *palette32;
373     int palette_index = 0;
374     unsigned char r, g, b;
375     unsigned char *vmd_header;
376     unsigned char *raw_palette;
377
378     s->avctx = avctx;
379     avctx->pix_fmt = PIX_FMT_PAL8;
380
381     /* make sure the VMD header made it */
382     if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
383         av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
384             VMD_HEADER_SIZE);
385         return -1;
386     }
387     vmd_header = (unsigned char *)avctx->extradata;
388
389     s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
390     s->unpack_buffer = av_malloc(s->unpack_buffer_size);
391     if (!s->unpack_buffer)
392         return -1;
393
394     /* load up the initial palette */
395     raw_palette = &vmd_header[28];
396     palette32 = (unsigned int *)s->palette;
397     for (i = 0; i < PALETTE_COUNT; i++) {
398         r = raw_palette[palette_index++] * 4;
399         g = raw_palette[palette_index++] * 4;
400         b = raw_palette[palette_index++] * 4;
401         palette32[i] = (r << 16) | (g << 8) | (b);
402     }
403
404     avcodec_get_frame_defaults(&s->frame);
405     avcodec_get_frame_defaults(&s->prev_frame);
406
407     return 0;
408 }
409
410 static int vmdvideo_decode_frame(AVCodecContext *avctx,
411                                  void *data, int *data_size,
412                                  AVPacket *avpkt)
413 {
414     const uint8_t *buf = avpkt->data;
415     int buf_size = avpkt->size;
416     VmdVideoContext *s = avctx->priv_data;
417
418     s->buf = buf;
419     s->size = buf_size;
420
421     if (buf_size < 16)
422         return buf_size;
423
424     s->frame.reference = 1;
425     if (avctx->get_buffer(avctx, &s->frame)) {
426         av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
427         return -1;
428     }
429
430     vmd_decode(s);
431
432     /* make the palette available on the way out */
433     memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
434
435     /* shuffle frames */
436     FFSWAP(AVFrame, s->frame, s->prev_frame);
437     if (s->frame.data[0])
438         avctx->release_buffer(avctx, &s->frame);
439
440     *data_size = sizeof(AVFrame);
441     *(AVFrame*)data = s->prev_frame;
442
443     /* report that the buffer was completely consumed */
444     return buf_size;
445 }
446
447 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
448 {
449     VmdVideoContext *s = avctx->priv_data;
450
451     if (s->prev_frame.data[0])
452         avctx->release_buffer(avctx, &s->prev_frame);
453     av_free(s->unpack_buffer);
454
455     return 0;
456 }
457
458
459 /*
460  * Audio Decoder
461  */
462
463 #define BLOCK_TYPE_AUDIO    1
464 #define BLOCK_TYPE_INITIAL  2
465 #define BLOCK_TYPE_SILENCE  3
466
467 typedef struct VmdAudioContext {
468     int out_bps;
469     int chunk_size;
470 } VmdAudioContext;
471
472 static const uint16_t vmdaudio_table[128] = {
473     0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
474     0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
475     0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
476     0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
477     0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
478     0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
479     0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
480     0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
481     0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
482     0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
483     0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
484     0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
485     0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
486 };
487
488 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
489 {
490     VmdAudioContext *s = avctx->priv_data;
491
492     if (avctx->channels < 1 || avctx->channels > 2) {
493         av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
494         return AVERROR(EINVAL);
495     }
496     if (avctx->block_align < 1) {
497         av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
498         return AVERROR(EINVAL);
499     }
500
501     if (avctx->bits_per_coded_sample == 16)
502         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
503     else
504         avctx->sample_fmt = AV_SAMPLE_FMT_U8;
505     s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
506
507     s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
508
509     av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
510            "block align = %d, sample rate = %d\n",
511            avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
512            avctx->sample_rate);
513
514     return 0;
515 }
516
517 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
518                              int channels)
519 {
520     int ch;
521     const uint8_t *buf_end = buf + buf_size;
522     int predictor[2];
523     int st = channels - 1;
524
525     /* decode initial raw sample */
526     for (ch = 0; ch < channels; ch++) {
527         predictor[ch] = (int16_t)AV_RL16(buf);
528         buf += 2;
529         *out++ = predictor[ch];
530     }
531
532     /* decode DPCM samples */
533     ch = 0;
534     while (buf < buf_end) {
535         uint8_t b = *buf++;
536         if (b & 0x80)
537             predictor[ch] -= vmdaudio_table[b & 0x7F];
538         else
539             predictor[ch] += vmdaudio_table[b];
540         predictor[ch] = av_clip_int16(predictor[ch]);
541         *out++ = predictor[ch];
542         ch ^= st;
543     }
544 }
545
546 static int vmdaudio_decode_frame(AVCodecContext *avctx,
547                                  void *data, int *data_size,
548                                  AVPacket *avpkt)
549 {
550     const uint8_t *buf = avpkt->data;
551     const uint8_t *buf_end;
552     int buf_size = avpkt->size;
553     VmdAudioContext *s = avctx->priv_data;
554     int block_type, silent_chunks, audio_chunks;
555     int nb_samples, out_size;
556     uint8_t *output_samples_u8  = data;
557     int16_t *output_samples_s16 = data;
558
559     if (buf_size < 16) {
560         av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
561         *data_size = 0;
562         return buf_size;
563     }
564
565     block_type = buf[6];
566     if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
567         av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
568         return AVERROR(EINVAL);
569     }
570     buf      += 16;
571     buf_size -= 16;
572
573     /* get number of silent chunks */
574     silent_chunks = 0;
575     if (block_type == BLOCK_TYPE_INITIAL) {
576         uint32_t flags;
577         if (buf_size < 4) {
578             av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
579             return AVERROR(EINVAL);
580         }
581         flags         = AV_RB32(buf);
582         silent_chunks = av_popcount(flags);
583         buf      += 4;
584         buf_size -= 4;
585     } else if (block_type == BLOCK_TYPE_SILENCE) {
586         silent_chunks = 1;
587         buf_size = 0; // should already be zero but set it just to be sure
588     }
589
590     /* ensure output buffer is large enough */
591     audio_chunks = buf_size / s->chunk_size;
592     nb_samples   = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
593     out_size     = nb_samples * avctx->channels * s->out_bps;
594     if (*data_size < out_size)
595         return -1;
596
597     /* decode silent chunks */
598     if (silent_chunks > 0) {
599         int silent_size = avctx->block_align * silent_chunks;
600         if (s->out_bps == 2) {
601             memset(output_samples_s16, 0x00, silent_size * 2);
602             output_samples_s16 += silent_size;
603         } else {
604             memset(output_samples_u8,  0x80, silent_size);
605             output_samples_u8 += silent_size;
606         }
607     }
608
609     /* decode audio chunks */
610     if (audio_chunks > 0) {
611         buf_end = buf + buf_size;
612         while (buf < buf_end) {
613             if (s->out_bps == 2) {
614                 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
615                                  avctx->channels);
616                 output_samples_s16 += avctx->block_align;
617             } else {
618                 memcpy(output_samples_u8, buf, s->chunk_size);
619                 output_samples_u8  += avctx->block_align;
620             }
621             buf += s->chunk_size;
622         }
623     }
624
625     *data_size = out_size;
626     return avpkt->size;
627 }
628
629
630 /*
631  * Public Data Structures
632  */
633
634 AVCodec ff_vmdvideo_decoder = {
635     .name           = "vmdvideo",
636     .type           = AVMEDIA_TYPE_VIDEO,
637     .id             = CODEC_ID_VMDVIDEO,
638     .priv_data_size = sizeof(VmdVideoContext),
639     .init           = vmdvideo_decode_init,
640     .close          = vmdvideo_decode_end,
641     .decode         = vmdvideo_decode_frame,
642     .capabilities   = CODEC_CAP_DR1,
643     .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
644 };
645
646 AVCodec ff_vmdaudio_decoder = {
647     .name           = "vmdaudio",
648     .type           = AVMEDIA_TYPE_AUDIO,
649     .id             = CODEC_ID_VMDAUDIO,
650     .priv_data_size = sizeof(VmdAudioContext),
651     .init           = vmdaudio_decode_init,
652     .decode         = vmdaudio_decode_frame,
653     .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
654 };