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