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
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.
46 #include "libavutil/channel_layout.h"
47 #include "libavutil/common.h"
48 #include "libavutil/intreadwrite.h"
51 #include "bytestream.h"
53 #define VMD_HEADER_SIZE 0x330
54 #define PALETTE_COUNT 256
60 typedef struct VmdVideoContext {
62 AVCodecContext *avctx;
65 const unsigned char *buf;
68 unsigned char palette[PALETTE_COUNT * 4];
69 unsigned char *unpack_buffer;
70 int unpack_buffer_size;
75 #define QUEUE_SIZE 0x1000
76 #define QUEUE_MASK 0x0FFF
78 static void lz_unpack(const unsigned char *src, int src_len,
79 unsigned char *dest, int dest_len)
83 unsigned char queue[QUEUE_SIZE];
85 unsigned int dataleft;
86 unsigned int chainofs;
87 unsigned int chainlen;
93 bytestream2_init(&gb, src, src_len);
96 dataleft = bytestream2_get_le32(&gb);
97 memset(queue, 0x20, QUEUE_SIZE);
98 if (bytestream2_get_bytes_left(&gb) < 4)
100 if (bytestream2_peek_le32(&gb) == 0x56781234) {
101 bytestream2_get_le32(&gb);
106 speclen = 100; /* no speclen */
109 while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) {
110 tag = bytestream2_get_byteu(&gb);
111 if ((tag == 0xFF) && (dataleft > 8)) {
112 if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8)
114 for (i = 0; i < 8; i++) {
115 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
120 for (i = 0; i < 8; i++) {
124 if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1)
126 queue[qpos++] = *d++ = bytestream2_get_byte(&gb);
130 chainofs = bytestream2_get_byte(&gb);
131 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
132 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
133 if (chainlen == speclen) {
134 chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
136 if (d + chainlen > d_end)
138 for (j = 0; j < chainlen; j++) {
139 *d = queue[chainofs++ & QUEUE_MASK];
140 queue[qpos++] = *d++;
143 dataleft -= chainlen;
151 static int rle_unpack(const unsigned char *src, unsigned char *dest,
152 int src_count, int src_size, int dest_len)
156 unsigned char *dest_end = dest + dest_len;
159 bytestream2_init(&gb, src, src_size);
162 if (bytestream2_get_bytes_left(&gb) < 1)
164 *pd++ = bytestream2_get_byteu(&gb);
170 if (bytestream2_get_bytes_left(&gb) < 1)
172 l = bytestream2_get_byteu(&gb);
175 if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l)
176 return bytestream2_tell(&gb);
177 bytestream2_get_buffer(&gb, pd, l);
180 if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2)
181 return bytestream2_tell(&gb);
182 for (i = 0; i < l; i++) {
183 *pd++ = bytestream2_get_byteu(&gb);
184 *pd++ = bytestream2_get_byteu(&gb);
186 bytestream2_skip(&gb, 2);
189 } while (i < src_count);
191 return bytestream2_tell(&gb);
194 static void vmd_decode(VmdVideoContext *s, AVFrame *frame)
197 unsigned int *palette32;
198 unsigned char r, g, b;
203 unsigned char *dp; /* pointer to current frame */
204 unsigned char *pp; /* pointer to previous frame */
208 int frame_x, frame_y;
209 int frame_width, frame_height;
211 frame_x = AV_RL16(&s->buf[6]);
212 frame_y = AV_RL16(&s->buf[8]);
213 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
214 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
215 if (frame_x < 0 || frame_width < 0 ||
216 frame_x >= s->avctx->width ||
217 frame_width > s->avctx->width ||
218 frame_x + frame_width > s->avctx->width)
220 if (frame_y < 0 || frame_height < 0 ||
221 frame_y >= s->avctx->height ||
222 frame_height > s->avctx->height ||
223 frame_y + frame_height > s->avctx->height)
226 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
227 (frame_x || frame_y)) {
235 /* if only a certain region will be updated, copy the entire previous
236 * frame before the decode */
237 if (s->prev_frame.data[0] &&
238 (frame_x || frame_y || (frame_width != s->avctx->width) ||
239 (frame_height != s->avctx->height))) {
241 memcpy(frame->data[0], s->prev_frame.data[0],
242 s->avctx->height * frame->linesize[0]);
245 /* check if there is a new palette */
246 bytestream2_init(&gb, s->buf + 16, s->size - 16);
247 if (s->buf[15] & 0x02) {
248 bytestream2_skip(&gb, 2);
249 palette32 = (unsigned int *)s->palette;
250 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
251 for (i = 0; i < PALETTE_COUNT; i++) {
252 r = bytestream2_get_byteu(&gb) * 4;
253 g = bytestream2_get_byteu(&gb) * 4;
254 b = bytestream2_get_byteu(&gb) * 4;
255 palette32[i] = (r << 16) | (g << 8) | (b);
258 s->size -= (256 * 3 + 2);
261 /* originally UnpackFrame in VAG's code */
262 bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer);
263 if (bytestream2_get_bytes_left(&gb) < 1)
265 meth = bytestream2_get_byteu(&gb);
267 lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
268 s->unpack_buffer, s->unpack_buffer_size);
270 bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
273 dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
274 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
277 for (i = 0; i < frame_height; i++) {
280 len = bytestream2_get_byte(&gb);
282 len = (len & 0x7F) + 1;
283 if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len)
285 bytestream2_get_buffer(&gb, &dp[ofs], len);
288 /* interframe pixel copy */
289 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
291 memcpy(&dp[ofs], &pp[ofs], len + 1);
294 } while (ofs < frame_width);
295 if (ofs > frame_width) {
296 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
300 dp += frame->linesize[0];
301 pp += s->prev_frame.linesize[0];
306 for (i = 0; i < frame_height; i++) {
307 bytestream2_get_buffer(&gb, dp, frame_width);
308 dp += frame->linesize[0];
309 pp += s->prev_frame.linesize[0];
314 for (i = 0; i < frame_height; i++) {
317 len = bytestream2_get_byte(&gb);
319 len = (len & 0x7F) + 1;
320 if (bytestream2_get_byte(&gb) == 0xFF)
321 len = rle_unpack(gb.buffer, &dp[ofs],
322 len, bytestream2_get_bytes_left(&gb),
325 bytestream2_get_buffer(&gb, &dp[ofs], len);
326 bytestream2_skip(&gb, len);
328 /* interframe pixel copy */
329 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
331 memcpy(&dp[ofs], &pp[ofs], len + 1);
334 } while (ofs < frame_width);
335 if (ofs > frame_width) {
336 av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
339 dp += frame->linesize[0];
340 pp += s->prev_frame.linesize[0];
347 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
349 VmdVideoContext *s = avctx->priv_data;
351 unsigned int *palette32;
352 int palette_index = 0;
353 unsigned char r, g, b;
354 unsigned char *vmd_header;
355 unsigned char *raw_palette;
358 avctx->pix_fmt = AV_PIX_FMT_PAL8;
360 /* make sure the VMD header made it */
361 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
362 av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
366 vmd_header = (unsigned char *)avctx->extradata;
368 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
369 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
370 if (!s->unpack_buffer)
373 /* load up the initial palette */
374 raw_palette = &vmd_header[28];
375 palette32 = (unsigned int *)s->palette;
376 for (i = 0; i < PALETTE_COUNT; i++) {
377 r = raw_palette[palette_index++] * 4;
378 g = raw_palette[palette_index++] * 4;
379 b = raw_palette[palette_index++] * 4;
380 palette32[i] = (r << 16) | (g << 8) | (b);
386 static int vmdvideo_decode_frame(AVCodecContext *avctx,
387 void *data, int *got_frame,
390 const uint8_t *buf = avpkt->data;
391 int buf_size = avpkt->size;
392 VmdVideoContext *s = avctx->priv_data;
393 AVFrame *frame = data;
402 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) {
403 av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
407 vmd_decode(s, frame);
409 /* make the palette available on the way out */
410 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
413 av_frame_unref(&s->prev_frame);
414 if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
419 /* report that the buffer was completely consumed */
423 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
425 VmdVideoContext *s = avctx->priv_data;
427 av_frame_unref(&s->prev_frame);
428 av_free(s->unpack_buffer);
438 #define BLOCK_TYPE_AUDIO 1
439 #define BLOCK_TYPE_INITIAL 2
440 #define BLOCK_TYPE_SILENCE 3
442 typedef struct VmdAudioContext {
447 static const uint16_t vmdaudio_table[128] = {
448 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
449 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
450 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
451 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
452 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
453 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
454 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
455 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
456 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
457 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
458 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
459 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
460 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
463 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
465 VmdAudioContext *s = avctx->priv_data;
467 if (avctx->channels < 1 || avctx->channels > 2) {
468 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
469 return AVERROR(EINVAL);
471 if (avctx->block_align < 1) {
472 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
473 return AVERROR(EINVAL);
476 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
479 if (avctx->bits_per_coded_sample == 16)
480 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
482 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
483 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
485 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
487 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
488 "block align = %d, sample rate = %d\n",
489 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
495 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
499 const uint8_t *buf_end = buf + buf_size;
501 int st = channels - 1;
503 /* decode initial raw sample */
504 for (ch = 0; ch < channels; ch++) {
505 predictor[ch] = (int16_t)AV_RL16(buf);
507 *out++ = predictor[ch];
510 /* decode DPCM samples */
512 while (buf < buf_end) {
515 predictor[ch] -= vmdaudio_table[b & 0x7F];
517 predictor[ch] += vmdaudio_table[b];
518 predictor[ch] = av_clip_int16(predictor[ch]);
519 *out++ = predictor[ch];
524 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
525 int *got_frame_ptr, AVPacket *avpkt)
527 AVFrame *frame = data;
528 const uint8_t *buf = avpkt->data;
529 const uint8_t *buf_end;
530 int buf_size = avpkt->size;
531 VmdAudioContext *s = avctx->priv_data;
532 int block_type, silent_chunks, audio_chunks;
534 uint8_t *output_samples_u8;
535 int16_t *output_samples_s16;
538 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
544 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
545 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
546 return AVERROR(EINVAL);
551 /* get number of silent chunks */
553 if (block_type == BLOCK_TYPE_INITIAL) {
556 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
557 return AVERROR(EINVAL);
559 flags = AV_RB32(buf);
560 silent_chunks = av_popcount(flags);
563 } else if (block_type == BLOCK_TYPE_SILENCE) {
565 buf_size = 0; // should already be zero but set it just to be sure
568 /* ensure output buffer is large enough */
569 audio_chunks = buf_size / s->chunk_size;
571 /* get output buffer */
572 frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
574 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
575 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
578 output_samples_u8 = frame->data[0];
579 output_samples_s16 = (int16_t *)frame->data[0];
581 /* decode silent chunks */
582 if (silent_chunks > 0) {
583 int silent_size = avctx->block_align * silent_chunks;
584 if (s->out_bps == 2) {
585 memset(output_samples_s16, 0x00, silent_size * 2);
586 output_samples_s16 += silent_size;
588 memset(output_samples_u8, 0x80, silent_size);
589 output_samples_u8 += silent_size;
593 /* decode audio chunks */
594 if (audio_chunks > 0) {
595 buf_end = buf + buf_size;
596 while (buf + s->chunk_size <= buf_end) {
597 if (s->out_bps == 2) {
598 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
600 output_samples_s16 += avctx->block_align;
602 memcpy(output_samples_u8, buf, s->chunk_size);
603 output_samples_u8 += avctx->block_align;
605 buf += s->chunk_size;
616 * Public Data Structures
619 AVCodec ff_vmdvideo_decoder = {
621 .type = AVMEDIA_TYPE_VIDEO,
622 .id = AV_CODEC_ID_VMDVIDEO,
623 .priv_data_size = sizeof(VmdVideoContext),
624 .init = vmdvideo_decode_init,
625 .close = vmdvideo_decode_end,
626 .decode = vmdvideo_decode_frame,
627 .capabilities = CODEC_CAP_DR1,
628 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
631 AVCodec ff_vmdaudio_decoder = {
633 .type = AVMEDIA_TYPE_AUDIO,
634 .id = AV_CODEC_ID_VMDAUDIO,
635 .priv_data_size = sizeof(VmdAudioContext),
636 .init = vmdaudio_decode_init,
637 .decode = vmdaudio_decode_frame,
638 .capabilities = CODEC_CAP_DR1,
639 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),