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 
46 #include "libavutil/intreadwrite.h"
47 #include "avcodec.h"
48 
49 #define VMD_HEADER_SIZE 0x330
50 #define PALETTE_COUNT 256
51 
52 /*
53  * Video Decoder
54  */
55 
56 typedef struct VmdVideoContext {
57 
61 
62  const unsigned char *buf;
63  int size;
64 
65  unsigned char palette[PALETTE_COUNT * 4];
66  unsigned char *unpack_buffer;
68 
69  int x_off, y_off;
71 
72 #define QUEUE_SIZE 0x1000
73 #define QUEUE_MASK 0x0FFF
74 
75 static void lz_unpack(const unsigned char *src, int src_len,
76  unsigned char *dest, int dest_len)
77 {
78  const unsigned char *s;
79  unsigned int s_len;
80  unsigned char *d;
81  unsigned char *d_end;
82  unsigned char queue[QUEUE_SIZE];
83  unsigned int qpos;
84  unsigned int dataleft;
85  unsigned int chainofs;
86  unsigned int chainlen;
87  unsigned int speclen;
88  unsigned char tag;
89  unsigned int i, j;
90 
91  s = src;
92  s_len = src_len;
93  d = dest;
94  d_end = d + dest_len;
95  dataleft = AV_RL32(s);
96  s += 4; s_len -= 4;
97  memset(queue, 0x20, QUEUE_SIZE);
98  if (s_len < 4)
99  return;
100  if (AV_RL32(s) == 0x56781234) {
101  s += 4; s_len -= 4;
102  qpos = 0x111;
103  speclen = 0xF + 3;
104  } else {
105  qpos = 0xFEE;
106  speclen = 100; /* no speclen */
107  }
108 
109  while (dataleft > 0 && s_len > 0) {
110  tag = *s++; s_len--;
111  if ((tag == 0xFF) && (dataleft > 8)) {
112  if (d + 8 > d_end || s_len < 8)
113  return;
114  for (i = 0; i < 8; i++) {
115  queue[qpos++] = *d++ = *s++;
116  qpos &= QUEUE_MASK;
117  }
118  s_len -= 8;
119  dataleft -= 8;
120  } else {
121  for (i = 0; i < 8; i++) {
122  if (dataleft == 0)
123  break;
124  if (tag & 0x01) {
125  if (d + 1 > d_end || s_len < 1)
126  return;
127  queue[qpos++] = *d++ = *s++;
128  qpos &= QUEUE_MASK;
129  dataleft--;
130  s_len--;
131  } else {
132  if (s_len < 2)
133  return;
134  chainofs = *s++;
135  chainofs |= ((*s & 0xF0) << 4);
136  chainlen = (*s++ & 0x0F) + 3;
137  s_len -= 2;
138  if (chainlen == speclen) {
139  if (s_len < 1)
140  return;
141  chainlen = *s++ + 0xF + 3;
142  s_len--;
143  }
144  if (d + chainlen > d_end)
145  return;
146  for (j = 0; j < chainlen; j++) {
147  *d = queue[chainofs++ & QUEUE_MASK];
148  queue[qpos++] = *d++;
149  qpos &= QUEUE_MASK;
150  }
151  dataleft -= chainlen;
152  }
153  tag >>= 1;
154  }
155  }
156  }
157 }
158 
159 static int rle_unpack(const unsigned char *src, unsigned char *dest,
160  int src_count, int src_size, int dest_len)
161 {
162  const unsigned char *ps;
163  unsigned char *pd;
164  int i, l;
165  unsigned char *dest_end = dest + dest_len;
166 
167  ps = src;
168  pd = dest;
169  if (src_count & 1) {
170  if (src_size < 1)
171  return 0;
172  *pd++ = *ps++;
173  src_size--;
174  }
175 
176  src_count >>= 1;
177  i = 0;
178  do {
179  if (src_size < 1)
180  break;
181  l = *ps++;
182  src_size--;
183  if (l & 0x80) {
184  l = (l & 0x7F) * 2;
185  if (pd + l > dest_end || src_size < l)
186  return ps - src;
187  memcpy(pd, ps, l);
188  ps += l;
189  src_size -= l;
190  pd += l;
191  } else {
192  if (pd + i > dest_end || src_size < 2)
193  return ps - src;
194  for (i = 0; i < l; i++) {
195  *pd++ = ps[0];
196  *pd++ = ps[1];
197  }
198  ps += 2;
199  src_size -= 2;
200  }
201  i += l;
202  } while (i < src_count);
203 
204  return ps - src;
205 }
206 
208 {
209  int i;
210  unsigned int *palette32;
211  unsigned char r, g, b;
212 
213  /* point to the start of the encoded data */
214  const unsigned char *p = s->buf + 16;
215 
216  const unsigned char *pb;
217  unsigned int pb_size;
218  unsigned char meth;
219  unsigned char *dp; /* pointer to current frame */
220  unsigned char *pp; /* pointer to previous frame */
221  unsigned char len;
222  int ofs;
223 
224  int frame_x, frame_y;
226 
227  frame_x = AV_RL16(&s->buf[6]);
228  frame_y = AV_RL16(&s->buf[8]);
229  frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
230  frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
231  if (frame_x < 0 || frame_width < 0 ||
232  frame_x >= s->avctx->width ||
233  frame_width > s->avctx->width ||
234  frame_x + frame_width > s->avctx->width)
235  return;
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  return;
241 
242  if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
243  (frame_x || frame_y)) {
244 
245  s->x_off = frame_x;
246  s->y_off = frame_y;
247  }
248  frame_x -= s->x_off;
249  frame_y -= s->y_off;
250 
251  /* if only a certain region will be updated, copy the entire previous
252  * frame before the decode */
253  if (s->prev_frame.data[0] &&
254  (frame_x || frame_y || (frame_width != s->avctx->width) ||
255  (frame_height != s->avctx->height))) {
256 
257  memcpy(s->frame.data[0], s->prev_frame.data[0],
258  s->avctx->height * s->frame.linesize[0]);
259  }
260 
261  /* check if there is a new palette */
262  if (s->buf[15] & 0x02) {
263  p += 2;
264  palette32 = (unsigned int *)s->palette;
265  for (i = 0; i < PALETTE_COUNT; i++) {
266  r = *p++ * 4;
267  g = *p++ * 4;
268  b = *p++ * 4;
269  palette32[i] = (r << 16) | (g << 8) | (b);
270  }
271  s->size -= (256 * 3 + 2);
272  }
273  if (s->size > 0) {
274  /* originally UnpackFrame in VAG's code */
275  pb = p;
276  pb_size = s->buf + s->size - pb;
277  if (pb_size < 1)
278  return;
279  meth = *pb++; pb_size--;
280  if (meth & 0x80) {
281  lz_unpack(pb, pb_size,
283  meth &= 0x7F;
284  pb = s->unpack_buffer;
285  pb_size = s->unpack_buffer_size;
286  }
287 
288  dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
289  pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
290  switch (meth) {
291  case 1:
292  for (i = 0; i < frame_height; i++) {
293  ofs = 0;
294  do {
295  if (pb_size < 1)
296  return;
297  len = *pb++;
298  pb_size--;
299  if (len & 0x80) {
300  len = (len & 0x7F) + 1;
301  if (ofs + len > frame_width || pb_size < len)
302  return;
303  memcpy(&dp[ofs], pb, len);
304  pb += len;
305  pb_size -= len;
306  ofs += len;
307  } else {
308  /* interframe pixel copy */
309  if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
310  return;
311  memcpy(&dp[ofs], &pp[ofs], len + 1);
312  ofs += len + 1;
313  }
314  } while (ofs < frame_width);
315  if (ofs > frame_width) {
316  av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
317  ofs, frame_width);
318  break;
319  }
320  dp += s->frame.linesize[0];
321  pp += s->prev_frame.linesize[0];
322  }
323  break;
324 
325  case 2:
326  for (i = 0; i < frame_height; i++) {
327  if (pb_size < frame_width)
328  return;
329  memcpy(dp, pb, frame_width);
330  pb += frame_width;
331  pb_size -= frame_width;
332  dp += s->frame.linesize[0];
333  pp += s->prev_frame.linesize[0];
334  }
335  break;
336 
337  case 3:
338  for (i = 0; i < frame_height; i++) {
339  ofs = 0;
340  do {
341  if (pb_size < 1)
342  return;
343  len = *pb++;
344  pb_size--;
345  if (len & 0x80) {
346  len = (len & 0x7F) + 1;
347  if (pb_size < 1)
348  return;
349  if (*pb++ == 0xFF)
350  len = rle_unpack(pb, &dp[ofs], len, pb_size, frame_width - ofs);
351  else {
352  if (pb_size < len)
353  return;
354  memcpy(&dp[ofs], pb, len);
355  }
356  pb += len;
357  pb_size -= 1 + len;
358  ofs += len;
359  } else {
360  /* interframe pixel copy */
361  if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
362  return;
363  memcpy(&dp[ofs], &pp[ofs], len + 1);
364  ofs += len + 1;
365  }
366  } while (ofs < frame_width);
367  if (ofs > frame_width) {
368  av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
369  ofs, frame_width);
370  }
371  dp += s->frame.linesize[0];
372  pp += s->prev_frame.linesize[0];
373  }
374  break;
375  }
376  }
377 }
378 
380 {
381  VmdVideoContext *s = avctx->priv_data;
382  int i;
383  unsigned int *palette32;
384  int palette_index = 0;
385  unsigned char r, g, b;
386  unsigned char *vmd_header;
387  unsigned char *raw_palette;
388 
389  s->avctx = avctx;
390  avctx->pix_fmt = PIX_FMT_PAL8;
391 
392  /* make sure the VMD header made it */
393  if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
394  av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
396  return -1;
397  }
398  vmd_header = (unsigned char *)avctx->extradata;
399 
400  s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
402  if (!s->unpack_buffer)
403  return -1;
404 
405  /* load up the initial palette */
406  raw_palette = &vmd_header[28];
407  palette32 = (unsigned int *)s->palette;
408  for (i = 0; i < PALETTE_COUNT; i++) {
409  r = raw_palette[palette_index++] * 4;
410  g = raw_palette[palette_index++] * 4;
411  b = raw_palette[palette_index++] * 4;
412  palette32[i] = (r << 16) | (g << 8) | (b);
413  }
414 
415  return 0;
416 }
417 
419  void *data, int *data_size,
420  AVPacket *avpkt)
421 {
422  const uint8_t *buf = avpkt->data;
423  int buf_size = avpkt->size;
424  VmdVideoContext *s = avctx->priv_data;
425 
426  s->buf = buf;
427  s->size = buf_size;
428 
429  if (buf_size < 16)
430  return buf_size;
431 
432  s->frame.reference = 1;
433  if (avctx->get_buffer(avctx, &s->frame)) {
434  av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
435  return -1;
436  }
437 
438  vmd_decode(s);
439 
440  /* make the palette available on the way out */
441  memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
442 
443  /* shuffle frames */
444  FFSWAP(AVFrame, s->frame, s->prev_frame);
445  if (s->frame.data[0])
446  avctx->release_buffer(avctx, &s->frame);
447 
448  *data_size = sizeof(AVFrame);
449  *(AVFrame*)data = s->prev_frame;
450 
451  /* report that the buffer was completely consumed */
452  return buf_size;
453 }
454 
456 {
457  VmdVideoContext *s = avctx->priv_data;
458 
459  if (s->prev_frame.data[0])
460  avctx->release_buffer(avctx, &s->prev_frame);
462 
463  return 0;
464 }
465 
466 
467 /*
468  * Audio Decoder
469  */
470 
471 #define BLOCK_TYPE_AUDIO 1
472 #define BLOCK_TYPE_INITIAL 2
473 #define BLOCK_TYPE_SILENCE 3
474 
475 typedef struct VmdAudioContext {
477  int out_bps;
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 
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  if (avctx->bits_per_coded_sample == 16)
511  avctx->sample_fmt = AV_SAMPLE_FMT_S16;
512  else
513  avctx->sample_fmt = AV_SAMPLE_FMT_U8;
515 
516  s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
517 
519  avctx->coded_frame = &s->frame;
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  const uint8_t *buf = avpkt->data;
562  const uint8_t *buf_end;
563  int buf_size = avpkt->size;
564  VmdAudioContext *s = avctx->priv_data;
565  int block_type, silent_chunks, audio_chunks;
566  int ret;
567  uint8_t *output_samples_u8;
568  int16_t *output_samples_s16;
569 
570  if (buf_size < 16) {
571  av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
572  *got_frame_ptr = 0;
573  return buf_size;
574  }
575 
576  block_type = buf[6];
577  if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
578  av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
579  return AVERROR(EINVAL);
580  }
581  buf += 16;
582  buf_size -= 16;
583 
584  /* get number of silent chunks */
585  silent_chunks = 0;
586  if (block_type == BLOCK_TYPE_INITIAL) {
587  uint32_t flags;
588  if (buf_size < 4) {
589  av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
590  return AVERROR(EINVAL);
591  }
592  flags = AV_RB32(buf);
593  silent_chunks = av_popcount(flags);
594  buf += 4;
595  buf_size -= 4;
596  } else if (block_type == BLOCK_TYPE_SILENCE) {
597  silent_chunks = 1;
598  buf_size = 0; // should already be zero but set it just to be sure
599  }
600 
601  /* ensure output buffer is large enough */
602  audio_chunks = buf_size / s->chunk_size;
603 
604  /* get output buffer */
605  s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
606  if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
607  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
608  return ret;
609  }
610  output_samples_u8 = s->frame.data[0];
611  output_samples_s16 = (int16_t *)s->frame.data[0];
612 
613  /* decode silent chunks */
614  if (silent_chunks > 0) {
615  int silent_size = avctx->block_align * silent_chunks;
616  if (s->out_bps == 2) {
617  memset(output_samples_s16, 0x00, silent_size * 2);
618  output_samples_s16 += silent_size;
619  } else {
620  memset(output_samples_u8, 0x80, silent_size);
621  output_samples_u8 += silent_size;
622  }
623  }
624 
625  /* decode audio chunks */
626  if (audio_chunks > 0) {
627  buf_end = buf + buf_size;
628  while (buf < buf_end) {
629  if (s->out_bps == 2) {
630  decode_audio_s16(output_samples_s16, buf, s->chunk_size,
631  avctx->channels);
632  output_samples_s16 += avctx->block_align;
633  } else {
634  memcpy(output_samples_u8, buf, s->chunk_size);
635  output_samples_u8 += avctx->block_align;
636  }
637  buf += s->chunk_size;
638  }
639  }
640 
641  *got_frame_ptr = 1;
642  *(AVFrame *)data = s->frame;
643 
644  return avpkt->size;
645 }
646 
647 
648 /*
649  * Public Data Structures
650  */
651 
653  .name = "vmdvideo",
654  .type = AVMEDIA_TYPE_VIDEO,
655  .id = CODEC_ID_VMDVIDEO,
656  .priv_data_size = sizeof(VmdVideoContext),
660  .capabilities = CODEC_CAP_DR1,
661  .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
662 };
663 
665  .name = "vmdaudio",
666  .type = AVMEDIA_TYPE_AUDIO,
667  .id = CODEC_ID_VMDAUDIO,
668  .priv_data_size = sizeof(VmdAudioContext),
671  .capabilities = CODEC_CAP_DR1,
672  .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
673 };