2 * Sierra VMD Audio & Video Decoders
3 * Copyright (C) 2004 the ffmpeg project
5 * This file is part of FFmpeg.
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.
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.
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
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/avassert.h"
47 #include "libavutil/channel_layout.h"
48 #include "libavutil/common.h"
49 #include "libavutil/intreadwrite.h"
52 #include "bytestream.h"
54 #define VMD_HEADER_SIZE 0x330
55 #define PALETTE_COUNT 256
61 typedef struct VmdVideoContext {
63 AVCodecContext *avctx;
66 const unsigned char *buf;
69 unsigned char palette[PALETTE_COUNT * 4];
70 unsigned char *unpack_buffer;
71 int unpack_buffer_size;
76 #define QUEUE_SIZE 0x1000
77 #define QUEUE_MASK 0x0FFF
79 static void lz_unpack(const unsigned char *src, int src_len,
80 unsigned char *dest, int dest_len)
84 unsigned char queue[QUEUE_SIZE];
86 unsigned int dataleft;
87 unsigned int chainofs;
88 unsigned int chainlen;
94 bytestream2_init(&gb, src, src_len);
97 dataleft = bytestream2_get_le32(&gb);
98 memset(queue, 0x20, QUEUE_SIZE);
99 if (bytestream2_get_bytes_left(&gb) < 4)
101 if (bytestream2_peek_le32(&gb) == 0x56781234) {
102 bytestream2_skipu(&gb, 4);
107 speclen = 100; /* no speclen */
110 while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) {
111 tag = bytestream2_get_byteu(&gb);
112 if ((tag == 0xFF) && (dataleft > 8)) {
113 if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8)
115 for (i = 0; i < 8; i++) {
116 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
121 for (i = 0; i < 8; i++) {
125 if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1)
127 queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
131 chainofs = bytestream2_get_byte(&gb);
132 chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
133 chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
134 if (chainlen == speclen) {
135 chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
137 if (d_end - d < chainlen)
139 for (j = 0; j < chainlen; j++) {
140 *d = queue[chainofs++ & QUEUE_MASK];
141 queue[qpos++] = *d++;
144 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 (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l)
176 return bytestream2_tell(&gb);
177 bytestream2_get_bufferu(&gb, pd, l);
181 if (dest_end - pd < 2*l || bytestream2_get_bytes_left(&gb) < 2)
182 return bytestream2_tell(&gb);
183 ps[0] = bytestream2_get_byteu(&gb);
184 ps[1] = bytestream2_get_byteu(&gb);
185 for (j = 0; j < l; j++) {
191 } while (i < src_count);
193 return bytestream2_tell(&gb);
196 static int vmd_decode(VmdVideoContext *s, AVFrame *frame)
199 unsigned int *palette32;
200 unsigned char r, g, b;
205 unsigned char *dp; /* pointer to current frame */
206 unsigned char *pp; /* pointer to previous frame */
210 int frame_x, frame_y;
211 int frame_width, frame_height;
213 frame_x = AV_RL16(&s->buf[6]);
214 frame_y = AV_RL16(&s->buf[8]);
215 frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
216 frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
218 if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
219 (frame_x || frame_y)) {
227 if (frame_x < 0 || frame_width < 0 ||
228 frame_x >= s->avctx->width ||
229 frame_width > s->avctx->width ||
230 frame_x + frame_width > s->avctx->width) {
231 av_log(s->avctx, AV_LOG_ERROR,
232 "Invalid horizontal range %d-%d\n",
233 frame_x, frame_width);
234 return AVERROR_INVALIDDATA;
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 av_log(s->avctx, AV_LOG_ERROR,
241 "Invalid vertical range %d-%d\n",
242 frame_x, frame_width);
243 return AVERROR_INVALIDDATA;
246 /* if only a certain region will be updated, copy the entire previous
247 * frame before the decode */
248 if (s->prev_frame.data[0] &&
249 (frame_x || frame_y || (frame_width != s->avctx->width) ||
250 (frame_height != s->avctx->height))) {
252 memcpy(frame->data[0], s->prev_frame.data[0],
253 s->avctx->height * frame->linesize[0]);
256 /* check if there is a new palette */
257 bytestream2_init(&gb, s->buf + 16, s->size - 16);
258 if (s->buf[15] & 0x02) {
259 bytestream2_skip(&gb, 2);
260 palette32 = (unsigned int *)s->palette;
261 if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
262 for (i = 0; i < PALETTE_COUNT; i++) {
263 r = bytestream2_get_byteu(&gb) * 4;
264 g = bytestream2_get_byteu(&gb) * 4;
265 b = bytestream2_get_byteu(&gb) * 4;
266 palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b);
267 palette32[i] |= palette32[i] >> 6 & 0x30303;
270 av_log(s->avctx, AV_LOG_ERROR, "Incomplete palette\n");
271 return AVERROR_INVALIDDATA;
278 /* originally UnpackFrame in VAG's code */
279 if (bytestream2_get_bytes_left(&gb) < 1)
280 return AVERROR_INVALIDDATA;
281 meth = bytestream2_get_byteu(&gb);
283 lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb),
284 s->unpack_buffer, s->unpack_buffer_size);
286 bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size);
289 dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x];
290 pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
293 for (i = 0; i < frame_height; i++) {
296 len = bytestream2_get_byte(&gb);
298 len = (len & 0x7F) + 1;
299 if (ofs + len > frame_width ||
300 bytestream2_get_bytes_left(&gb) < len)
301 return AVERROR_INVALIDDATA;
302 bytestream2_get_bufferu(&gb, &dp[ofs], len);
305 /* interframe pixel copy */
306 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
307 return AVERROR_INVALIDDATA;
308 memcpy(&dp[ofs], &pp[ofs], len + 1);
311 } while (ofs < frame_width);
312 if (ofs > frame_width) {
313 av_log(s->avctx, AV_LOG_ERROR,
314 "offset > width (%d > %d)\n",
316 return AVERROR_INVALIDDATA;
318 dp += frame->linesize[0];
319 pp += s->prev_frame.linesize[0];
324 for (i = 0; i < frame_height; i++) {
325 bytestream2_get_buffer(&gb, dp, frame_width);
326 dp += frame->linesize[0];
327 pp += s->prev_frame.linesize[0];
332 for (i = 0; i < frame_height; i++) {
335 len = bytestream2_get_byte(&gb);
337 len = (len & 0x7F) + 1;
338 if (bytestream2_get_byte(&gb) == 0xFF)
339 len = rle_unpack(gb.buffer, &dp[ofs],
340 len, bytestream2_get_bytes_left(&gb),
343 bytestream2_get_buffer(&gb, &dp[ofs], len);
344 bytestream2_skip(&gb, len);
346 /* interframe pixel copy */
347 if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
348 return AVERROR_INVALIDDATA;
349 memcpy(&dp[ofs], &pp[ofs], len + 1);
352 } while (ofs < frame_width);
353 if (ofs > frame_width) {
354 av_log(s->avctx, AV_LOG_ERROR,
355 "offset > width (%d > %d)\n",
357 return AVERROR_INVALIDDATA;
359 dp += frame->linesize[0];
360 pp += s->prev_frame.linesize[0];
367 static av_cold int vmdvideo_decode_init(AVCodecContext *avctx)
369 VmdVideoContext *s = avctx->priv_data;
371 unsigned int *palette32;
372 int palette_index = 0;
373 unsigned char r, g, b;
374 unsigned char *vmd_header;
375 unsigned char *raw_palette;
378 avctx->pix_fmt = AV_PIX_FMT_PAL8;
380 /* make sure the VMD header made it */
381 if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
382 av_log(s->avctx, AV_LOG_ERROR, "expected extradata size of %d\n",
384 return AVERROR_INVALIDDATA;
386 vmd_header = (unsigned char *)avctx->extradata;
388 s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
389 s->unpack_buffer = av_malloc(s->unpack_buffer_size);
390 if (!s->unpack_buffer)
391 return AVERROR(ENOMEM);
393 /* load up the initial palette */
394 raw_palette = &vmd_header[28];
395 palette32 = (unsigned int *)s->palette;
396 for (i = 0; i < PALETTE_COUNT; i++) {
397 r = raw_palette[palette_index++] * 4;
398 g = raw_palette[palette_index++] * 4;
399 b = raw_palette[palette_index++] * 4;
400 palette32[i] = (r << 16) | (g << 8) | (b);
403 avcodec_get_frame_defaults(&s->prev_frame);
408 static int vmdvideo_decode_frame(AVCodecContext *avctx,
409 void *data, int *got_frame,
412 const uint8_t *buf = avpkt->data;
413 int buf_size = avpkt->size;
414 VmdVideoContext *s = avctx->priv_data;
415 AVFrame *frame = data;
422 return AVERROR_INVALIDDATA;
424 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
427 if ((ret = vmd_decode(s, frame)) < 0)
430 /* make the palette available on the way out */
431 memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4);
434 av_frame_unref(&s->prev_frame);
435 if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0)
440 /* report that the buffer was completely consumed */
444 static av_cold int vmdvideo_decode_end(AVCodecContext *avctx)
446 VmdVideoContext *s = avctx->priv_data;
448 av_frame_unref(&s->prev_frame);
449 av_free(s->unpack_buffer);
459 #define BLOCK_TYPE_AUDIO 1
460 #define BLOCK_TYPE_INITIAL 2
461 #define BLOCK_TYPE_SILENCE 3
463 typedef struct VmdAudioContext {
468 static const uint16_t vmdaudio_table[128] = {
469 0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
470 0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
471 0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
472 0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
473 0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
474 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
475 0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
476 0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
477 0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
478 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
479 0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
480 0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
481 0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
484 static av_cold int vmdaudio_decode_init(AVCodecContext *avctx)
486 VmdAudioContext *s = avctx->priv_data;
488 if (avctx->channels < 1 || avctx->channels > 2) {
489 av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
490 return AVERROR(EINVAL);
492 if (avctx->block_align < 1 || avctx->block_align % avctx->channels) {
493 av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
494 return AVERROR(EINVAL);
497 avctx->channel_layout = avctx->channels == 1 ? AV_CH_LAYOUT_MONO :
500 if (avctx->bits_per_coded_sample == 16)
501 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
503 avctx->sample_fmt = AV_SAMPLE_FMT_U8;
504 s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt);
506 s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
508 av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, "
509 "block align = %d, sample rate = %d\n",
510 avctx->channels, avctx->bits_per_coded_sample, avctx->block_align,
516 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
520 const uint8_t *buf_end = buf + buf_size;
522 int st = channels - 1;
524 /* decode initial raw sample */
525 for (ch = 0; ch < channels; ch++) {
526 predictor[ch] = (int16_t)AV_RL16(buf);
528 *out++ = predictor[ch];
531 /* decode DPCM samples */
533 while (buf < buf_end) {
536 predictor[ch] -= vmdaudio_table[b & 0x7F];
538 predictor[ch] += vmdaudio_table[b];
539 predictor[ch] = av_clip_int16(predictor[ch]);
540 *out++ = predictor[ch];
545 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
546 int *got_frame_ptr, AVPacket *avpkt)
548 AVFrame *frame = data;
549 const uint8_t *buf = avpkt->data;
550 const uint8_t *buf_end;
551 int buf_size = avpkt->size;
552 VmdAudioContext *s = avctx->priv_data;
553 int block_type, silent_chunks, audio_chunks;
555 uint8_t *output_samples_u8;
556 int16_t *output_samples_s16;
559 av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
565 if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
566 av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
567 return AVERROR(EINVAL);
572 /* get number of silent chunks */
574 if (block_type == BLOCK_TYPE_INITIAL) {
577 av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
578 return AVERROR(EINVAL);
580 flags = AV_RB32(buf);
581 silent_chunks = av_popcount(flags);
584 } else if (block_type == BLOCK_TYPE_SILENCE) {
586 buf_size = 0; // should already be zero but set it just to be sure
589 /* ensure output buffer is large enough */
590 audio_chunks = buf_size / s->chunk_size;
592 /* drop incomplete chunks */
593 buf_size = audio_chunks * s->chunk_size;
595 /* get output buffer */
596 frame->nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) /
598 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
600 output_samples_u8 = frame->data[0];
601 output_samples_s16 = (int16_t *)frame->data[0];
603 /* decode silent chunks */
604 if (silent_chunks > 0) {
605 int silent_size = avctx->block_align * silent_chunks;
606 av_assert0(avctx->block_align * silent_chunks <= frame->nb_samples * avctx->channels);
608 if (s->out_bps == 2) {
609 memset(output_samples_s16, 0x00, silent_size * 2);
610 output_samples_s16 += silent_size;
612 memset(output_samples_u8, 0x80, silent_size);
613 output_samples_u8 += silent_size;
617 /* decode audio chunks */
618 if (audio_chunks > 0) {
619 buf_end = buf + buf_size;
620 av_assert0((buf_size & (avctx->channels > 1)) == 0);
621 while (buf_end - buf >= s->chunk_size) {
622 if (s->out_bps == 2) {
623 decode_audio_s16(output_samples_s16, buf, s->chunk_size,
625 output_samples_s16 += avctx->block_align;
627 memcpy(output_samples_u8, buf, s->chunk_size);
628 output_samples_u8 += avctx->block_align;
630 buf += s->chunk_size;
641 * Public Data Structures
644 AVCodec ff_vmdvideo_decoder = {
646 .type = AVMEDIA_TYPE_VIDEO,
647 .id = AV_CODEC_ID_VMDVIDEO,
648 .priv_data_size = sizeof(VmdVideoContext),
649 .init = vmdvideo_decode_init,
650 .close = vmdvideo_decode_end,
651 .decode = vmdvideo_decode_frame,
652 .capabilities = CODEC_CAP_DR1,
653 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
656 AVCodec ff_vmdaudio_decoder = {
658 .type = AVMEDIA_TYPE_AUDIO,
659 .id = AV_CODEC_ID_VMDAUDIO,
660 .priv_data_size = sizeof(VmdAudioContext),
661 .init = vmdaudio_decode_init,
662 .decode = vmdaudio_decode_frame,
663 .capabilities = CODEC_CAP_DR1,
664 .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),