lavc decoders: work with refcounted frames.
[FFMpeg-mirror/mplayer-patches.git] / libavcodec / vmdav.c
blobb5b5524919c4fde5ee4882bfd7e70557cc686e52
1 /*
2 * Sierra VMD Audio & Video Decoders
3 * Copyright (C) 2004 the ffmpeg project
5 * This file is part of Libav.
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.
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.
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
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/
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.
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.
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
46 #include "libavutil/channel_layout.h"
47 #include "libavutil/common.h"
48 #include "libavutil/intreadwrite.h"
49 #include "avcodec.h"
50 #include "internal.h"
52 #define VMD_HEADER_SIZE 0x330
53 #define PALETTE_COUNT 256
56 * Video Decoder
59 typedef struct VmdVideoContext {
61 AVCodecContext *avctx;
62 AVFrame prev_frame;
64 const unsigned char *buf;
65 int size;
67 unsigned char palette[PALETTE_COUNT * 4];
68 unsigned char *unpack_buffer;
69 int unpack_buffer_size;
71 int x_off, y_off;
72 } VmdVideoContext;
74 #define QUEUE_SIZE 0x1000
75 #define QUEUE_MASK 0x0FFF
77 static void lz_unpack(const unsigned char *src, int src_len,
78 unsigned char *dest, int dest_len)
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;
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 */
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;
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--;
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;
153 dataleft -= chainlen;
155 tag >>= 1;
161 static int rle_unpack(const unsigned char *src, unsigned char *dest,
162 int src_count, int src_size, int dest_len)
164 const unsigned char *ps;
165 unsigned char *pd;
166 int i, l;
167 unsigned char *dest_end = dest + dest_len;
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--;
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];
200 ps += 2;
201 src_size -= 2;
203 i += l;
204 } while (i < src_count);
206 return ps - src;
209 static void vmd_decode(VmdVideoContext *s, AVFrame *frame)
211 int i;
212 unsigned int *palette32;
213 unsigned char r, g, b;
215 /* point to the start of the encoded data */
216 const unsigned char *p = s->buf + 16;
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;
226 int frame_x, frame_y;
227 int frame_width, frame_height;
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;
244 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
245 (frame_x || frame_y)) {
247 s->x_off = frame_x;
248 s->y_off = frame_y;
250 frame_x -= s->x_off;
251 frame_y -= s->y_off;
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))) {
259 memcpy(frame->data[0], s->prev_frame.data[0],
260 s->avctx->height * frame->linesize[0]);
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);
273 s->size -= (256 * 3 + 2);
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;
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;
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;
322 dp += frame->linesize[0];
323 pp += s->prev_frame.linesize[0];
325 break;
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];
337 break;
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);
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;
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);
373 dp += frame->linesize[0];
374 pp += s->prev_frame.linesize[0];
376 break;
381 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
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;
391 s->avctx = avctx;
392 avctx->pix_fmt = AV_PIX_FMT_PAL8;
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;
400 vmd_header = (unsigned char *)avctx->extradata;
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;
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);
417 return 0;
420 static int vmdvideo_decode_frame(AVCodecContext *avctx,
421 void *data, int *got_frame,
422 AVPacket *avpkt)
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;
430 s->buf = buf;
431 s->size = buf_size;
433 if (buf_size < 16)
434 return buf_size;
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;
441 vmd_decode(s, frame);
443 /* make the palette available on the way out */
444 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
446 /* shuffle frames */
447 av_frame_unref(&s->prev_frame);
448 if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
449 return ret;
451 *got_frame = 1;
453 /* report that the buffer was completely consumed */
454 return buf_size;
457 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
459 VmdVideoContext *s = avctx->priv_data;
461 av_frame_unref(&s->prev_frame);
462 av_free(s->unpack_buffer);
464 return 0;
469 * Audio Decoder
472 #define BLOCK_TYPE_AUDIO 1
473 #define BLOCK_TYPE_INITIAL 2
474 #define BLOCK_TYPE_SILENCE 3
476 typedef struct VmdAudioContext {
477 int out_bps;
478 int chunk_size;
479 } VmdAudioContext;
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
497 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
499 VmdAudioContext *s = avctx->priv_data;
501 if (avctx->channels < 1 || avctx->channels > 2) {
502 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
503 return AVERROR(EINVAL);
505 if (avctx->block_align < 1) {
506 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
507 return AVERROR(EINVAL);
510 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
511 AV_CH_LAYOUT_STEREO;
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);
519 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
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);
526 return 0;
529 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
530 int channels)
532 int ch;
533 const uint8_t *buf_end = buf + buf_size;
534 int predictor[2];
535 int st = channels - 1;
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];
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;
558 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
559 int *got_frame_ptr, AVPacket *avpkt)
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;
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;
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);
582 buf += 16;
583 buf_size -= 16;
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);
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
602 /* ensure output buffer is large enough */
603 audio_chunks = buf_size / s->chunk_size;
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;
612 output_samples_u8 = frame->data[0];
613 output_samples_s16 = (int16_t *)frame->data[0];
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;
627 /* decode audio chunks */
628 if (audio_chunks > 0) {
629 buf_end = buf + buf_size;
630 while (buf < 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;
639 buf += s->chunk_size;
643 *got_frame_ptr = 1;
645 return avpkt->size;
650 * Public Data Structures
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"),
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"),