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