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