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