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 #include "bytestream.h"
49 
50 #define VMD_HEADER_SIZE 0x330
51 #define PALETTE_COUNT 256
52 
53 /*
54  * Video Decoder
55  */
56 
57 typedef struct VmdVideoContext {
58 
62 
63  const unsigned char *buf;
64  int size;
65 
66  unsigned char palette[PALETTE_COUNT * 4];
67  unsigned char *unpack_buffer;
69 
70  int x_off, y_off;
72 
73 #define QUEUE_SIZE 0x1000
74 #define QUEUE_MASK 0x0FFF
75 
76 static void lz_unpack(const unsigned char *src, int src_len,
77  unsigned char *dest, int dest_len)
78 {
79  unsigned char *d;
80  unsigned char *d_end;
81  unsigned char queue[QUEUE_SIZE];
82  unsigned int qpos;
83  unsigned int dataleft;
84  unsigned int chainofs;
85  unsigned int chainlen;
86  unsigned int speclen;
87  unsigned char tag;
88  unsigned int i, j;
89  GetByteContext gb;
90 
91  bytestream2_init(&gb, src, src_len);
92  d = dest;
93  d_end = d + dest_len;
94  dataleft = bytestream2_get_le32(&gb);
95  memset(queue, 0x20, QUEUE_SIZE);
96  if (bytestream2_get_bytes_left(&gb) < 4)
97  return;
98  if (bytestream2_peek_le32(&gb) == 0x56781234) {
99  bytestream2_get_le32(&gb);
100  qpos = 0x111;
101  speclen = 0xF + 3;
102  } else {
103  qpos = 0xFEE;
104  speclen = 100; /* no speclen */
105  }
106 
107  while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) {
108  tag = bytestream2_get_byteu(&gb);
109  if ((tag == 0xFF) && (dataleft > 8)) {
110  if (d + 8 > d_end || bytestream2_get_bytes_left(&gb) < 8)
111  return;
112  for (i = 0; i < 8; i++) {
113  queue[qpos++] = *d++ = bytestream2_get_byteu(&gb);
114  qpos &= QUEUE_MASK;
115  }
116  dataleft -= 8;
117  } else {
118  for (i = 0; i < 8; i++) {
119  if (dataleft == 0)
120  break;
121  if (tag & 0x01) {
122  if (d + 1 > d_end || bytestream2_get_bytes_left(&gb) < 1)
123  return;
124  queue[qpos++] = *d++ = bytestream2_get_byte(&gb);
125  qpos &= QUEUE_MASK;
126  dataleft--;
127  } else {
128  chainofs = bytestream2_get_byte(&gb);
129  chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4);
130  chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3;
131  if (chainlen == speclen) {
132  chainlen = bytestream2_get_byte(&gb) + 0xF + 3;
133  }
134  if (d + chainlen > d_end)
135  return;
136  for (j = 0; j < chainlen; j++) {
137  *d = queue[chainofs++ & QUEUE_MASK];
138  queue[qpos++] = *d++;
139  qpos &= QUEUE_MASK;
140  }
141  dataleft -= chainlen;
142  }
143  tag >>= 1;
144  }
145  }
146  }
147 }
148 
149 static int rle_unpack(const unsigned char *src, unsigned char *dest,
150  int src_count, int src_size, int dest_len)
151 {
152  unsigned char *pd;
153  int i, l;
154  unsigned char *dest_end = dest + dest_len;
155  GetByteContext gb;
156 
157  bytestream2_init(&gb, src, src_size);
158  pd = dest;
159  if (src_count & 1) {
160  if (bytestream2_get_bytes_left(&gb) < 1)
161  return 0;
162  *pd++ = bytestream2_get_byteu(&gb);
163  }
164 
165  src_count >>= 1;
166  i = 0;
167  do {
168  if (bytestream2_get_bytes_left(&gb) < 1)
169  break;
170  l = bytestream2_get_byteu(&gb);
171  if (l & 0x80) {
172  l = (l & 0x7F) * 2;
173  if (pd + l > dest_end || bytestream2_get_bytes_left(&gb) < l)
174  return bytestream2_tell(&gb);
175  bytestream2_get_buffer(&gb, pd, l);
176  pd += l;
177  } else {
178  if (pd + i > dest_end || bytestream2_get_bytes_left(&gb) < 2)
179  return bytestream2_tell(&gb);
180  for (i = 0; i < l; i++) {
181  *pd++ = bytestream2_get_byteu(&gb);
182  *pd++ = bytestream2_get_byteu(&gb);
183  }
184  bytestream2_skip(&gb, 2);
185  }
186  i += l;
187  } while (i < src_count);
188 
189  return bytestream2_tell(&gb);
190 }
191 
193 {
194  int i;
195  unsigned int *palette32;
196  unsigned char r, g, b;
197 
198  GetByteContext gb;
199 
200  unsigned char meth;
201  unsigned char *dp; /* pointer to current frame */
202  unsigned char *pp; /* pointer to previous frame */
203  unsigned char len;
204  int ofs;
205 
206  int frame_x, frame_y;
208 
209  frame_x = AV_RL16(&s->buf[6]);
210  frame_y = AV_RL16(&s->buf[8]);
211  frame_width = AV_RL16(&s->buf[10]) - frame_x + 1;
212  frame_height = AV_RL16(&s->buf[12]) - frame_y + 1;
213  if (frame_x < 0 || frame_width < 0 ||
214  frame_x >= s->avctx->width ||
215  frame_width > s->avctx->width ||
216  frame_x + frame_width > s->avctx->width)
217  return;
218  if (frame_y < 0 || frame_height < 0 ||
219  frame_y >= s->avctx->height ||
220  frame_height > s->avctx->height ||
221  frame_y + frame_height > s->avctx->height)
222  return;
223 
224  if ((frame_width == s->avctx->width && frame_height == s->avctx->height) &&
225  (frame_x || frame_y)) {
226 
227  s->x_off = frame_x;
228  s->y_off = frame_y;
229  }
230  frame_x -= s->x_off;
231  frame_y -= s->y_off;
232 
233  /* if only a certain region will be updated, copy the entire previous
234  * frame before the decode */
235  if (s->prev_frame.data[0] &&
236  (frame_x || frame_y || (frame_width != s->avctx->width) ||
237  (frame_height != s->avctx->height))) {
238 
239  memcpy(s->frame.data[0], s->prev_frame.data[0],
240  s->avctx->height * s->frame.linesize[0]);
241  }
242 
243  /* check if there is a new palette */
244  bytestream2_init(&gb, s->buf + 16, s->size - 16);
245  if (s->buf[15] & 0x02) {
246  bytestream2_skip(&gb, 2);
247  palette32 = (unsigned int *)s->palette;
248  if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) {
249  for (i = 0; i < PALETTE_COUNT; i++) {
250  r = bytestream2_get_byteu(&gb) * 4;
251  g = bytestream2_get_byteu(&gb) * 4;
252  b = bytestream2_get_byteu(&gb) * 4;
253  palette32[i] = (r << 16) | (g << 8) | (b);
254  }
255  }
256  s->size -= (256 * 3 + 2);
257  }
258  if (s->size > 0) {
259  /* originally UnpackFrame in VAG's code */
260  bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer);
261  if (bytestream2_get_bytes_left(&gb) < 1)
262  return;
263  meth = bytestream2_get_byteu(&gb);
264  if (meth & 0x80) {
267  meth &= 0x7F;
269  }
270 
271  dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
272  pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
273  switch (meth) {
274  case 1:
275  for (i = 0; i < frame_height; i++) {
276  ofs = 0;
277  do {
278  len = bytestream2_get_byte(&gb);
279  if (len & 0x80) {
280  len = (len & 0x7F) + 1;
281  if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len)
282  return;
283  bytestream2_get_buffer(&gb, &dp[ofs], len);
284  ofs += len;
285  } else {
286  /* interframe pixel copy */
287  if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
288  return;
289  memcpy(&dp[ofs], &pp[ofs], len + 1);
290  ofs += len + 1;
291  }
292  } while (ofs < frame_width);
293  if (ofs > frame_width) {
294  av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
295  ofs, frame_width);
296  break;
297  }
298  dp += s->frame.linesize[0];
299  pp += s->prev_frame.linesize[0];
300  }
301  break;
302 
303  case 2:
304  for (i = 0; i < frame_height; i++) {
305  bytestream2_get_buffer(&gb, dp, frame_width);
306  dp += s->frame.linesize[0];
307  pp += s->prev_frame.linesize[0];
308  }
309  break;
310 
311  case 3:
312  for (i = 0; i < frame_height; i++) {
313  ofs = 0;
314  do {
315  len = bytestream2_get_byte(&gb);
316  if (len & 0x80) {
317  len = (len & 0x7F) + 1;
318  if (bytestream2_get_byte(&gb) == 0xFF)
319  len = rle_unpack(gb.buffer, &dp[ofs],
320  len, bytestream2_get_bytes_left(&gb),
321  frame_width - ofs);
322  else
323  bytestream2_get_buffer(&gb, &dp[ofs], len);
324  bytestream2_skip(&gb, len);
325  } else {
326  /* interframe pixel copy */
327  if (ofs + len + 1 > frame_width || !s->prev_frame.data[0])
328  return;
329  memcpy(&dp[ofs], &pp[ofs], len + 1);
330  ofs += len + 1;
331  }
332  } while (ofs < frame_width);
333  if (ofs > frame_width) {
334  av_log(s->avctx, AV_LOG_ERROR, "VMD video: offset > width (%d > %d)\n",
335  ofs, frame_width);
336  }
337  dp += s->frame.linesize[0];
338  pp += s->prev_frame.linesize[0];
339  }
340  break;
341  }
342  }
343 }
344 
346 {
347  VmdVideoContext *s = avctx->priv_data;
348  int i;
349  unsigned int *palette32;
350  int palette_index = 0;
351  unsigned char r, g, b;
352  unsigned char *vmd_header;
353  unsigned char *raw_palette;
354 
355  s->avctx = avctx;
356  avctx->pix_fmt = PIX_FMT_PAL8;
357 
358  /* make sure the VMD header made it */
359  if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
360  av_log(s->avctx, AV_LOG_ERROR, "VMD video: expected extradata size of %d\n",
362  return -1;
363  }
364  vmd_header = (unsigned char *)avctx->extradata;
365 
366  s->unpack_buffer_size = AV_RL32(&vmd_header[800]);
368  if (!s->unpack_buffer)
369  return -1;
370 
371  /* load up the initial palette */
372  raw_palette = &vmd_header[28];
373  palette32 = (unsigned int *)s->palette;
374  for (i = 0; i < PALETTE_COUNT; i++) {
375  r = raw_palette[palette_index++] * 4;
376  g = raw_palette[palette_index++] * 4;
377  b = raw_palette[palette_index++] * 4;
378  palette32[i] = (r << 16) | (g << 8) | (b);
379  }
380 
381  return 0;
382 }
383 
385  void *data, int *data_size,
386  AVPacket *avpkt)
387 {
388  const uint8_t *buf = avpkt->data;
389  int buf_size = avpkt->size;
390  VmdVideoContext *s = avctx->priv_data;
391 
392  s->buf = buf;
393  s->size = buf_size;
394 
395  if (buf_size < 16)
396  return buf_size;
397 
398  s->frame.reference = 1;
399  if (avctx->get_buffer(avctx, &s->frame)) {
400  av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n");
401  return -1;
402  }
403 
404  vmd_decode(s);
405 
406  /* make the palette available on the way out */
407  memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
408 
409  /* shuffle frames */
410  FFSWAP(AVFrame, s->frame, s->prev_frame);
411  if (s->frame.data[0])
412  avctx->release_buffer(avctx, &s->frame);
413 
414  *data_size = sizeof(AVFrame);
415  *(AVFrame*)data = s->prev_frame;
416 
417  /* report that the buffer was completely consumed */
418  return buf_size;
419 }
420 
422 {
423  VmdVideoContext *s = avctx->priv_data;
424 
425  if (s->prev_frame.data[0])
426  avctx->release_buffer(avctx, &s->prev_frame);
428 
429  return 0;
430 }
431 
432 
433 /*
434  * Audio Decoder
435  */
436 
437 #define BLOCK_TYPE_AUDIO 1
438 #define BLOCK_TYPE_INITIAL 2
439 #define BLOCK_TYPE_SILENCE 3
440 
441 typedef struct VmdAudioContext {
443  int out_bps;
446 
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
461 };
462 
464 {
465  VmdAudioContext *s = avctx->priv_data;
466 
467  if (avctx->channels < 1 || avctx->channels > 2) {
468  av_log(avctx, AV_LOG_ERROR, "invalid number of channels\n");
469  return AVERROR(EINVAL);
470  }
471  if (avctx->block_align < 1) {
472  av_log(avctx, AV_LOG_ERROR, "invalid block align\n");
473  return AVERROR(EINVAL);
474  }
475 
476  if (avctx->bits_per_coded_sample == 16)
477  avctx->sample_fmt = AV_SAMPLE_FMT_S16;
478  else
479  avctx->sample_fmt = AV_SAMPLE_FMT_U8;
481 
482  s->chunk_size = avctx->block_align + avctx->channels * (s->out_bps == 2);
483 
485  avctx->coded_frame = &s->frame;
486 
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,
490  avctx->sample_rate);
491 
492  return 0;
493 }
494 
495 static void decode_audio_s16(int16_t *out, const uint8_t *buf, int buf_size,
496  int channels)
497 {
498  int ch;
499  const uint8_t *buf_end = buf + buf_size;
500  int predictor[2];
501  int st = channels - 1;
502 
503  /* decode initial raw sample */
504  for (ch = 0; ch < channels; ch++) {
505  predictor[ch] = (int16_t)AV_RL16(buf);
506  buf += 2;
507  *out++ = predictor[ch];
508  }
509 
510  /* decode DPCM samples */
511  ch = 0;
512  while (buf < buf_end) {
513  uint8_t b = *buf++;
514  if (b & 0x80)
515  predictor[ch] -= vmdaudio_table[b & 0x7F];
516  else
517  predictor[ch] += vmdaudio_table[b];
518  predictor[ch] = av_clip_int16(predictor[ch]);
519  *out++ = predictor[ch];
520  ch ^= st;
521  }
522 }
523 
524 static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data,
525  int *got_frame_ptr, AVPacket *avpkt)
526 {
527  const uint8_t *buf = avpkt->data;
528  const uint8_t *buf_end;
529  int buf_size = avpkt->size;
530  VmdAudioContext *s = avctx->priv_data;
531  int block_type, silent_chunks, audio_chunks;
532  int ret;
533  uint8_t *output_samples_u8;
534  int16_t *output_samples_s16;
535 
536  if (buf_size < 16) {
537  av_log(avctx, AV_LOG_WARNING, "skipping small junk packet\n");
538  *got_frame_ptr = 0;
539  return buf_size;
540  }
541 
542  block_type = buf[6];
543  if (block_type < BLOCK_TYPE_AUDIO || block_type > BLOCK_TYPE_SILENCE) {
544  av_log(avctx, AV_LOG_ERROR, "unknown block type: %d\n", block_type);
545  return AVERROR(EINVAL);
546  }
547  buf += 16;
548  buf_size -= 16;
549 
550  /* get number of silent chunks */
551  silent_chunks = 0;
552  if (block_type == BLOCK_TYPE_INITIAL) {
553  uint32_t flags;
554  if (buf_size < 4) {
555  av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
556  return AVERROR(EINVAL);
557  }
558  flags = AV_RB32(buf);
559  silent_chunks = av_popcount(flags);
560  buf += 4;
561  buf_size -= 4;
562  } else if (block_type == BLOCK_TYPE_SILENCE) {
563  silent_chunks = 1;
564  buf_size = 0; // should already be zero but set it just to be sure
565  }
566 
567  /* ensure output buffer is large enough */
568  audio_chunks = buf_size / s->chunk_size;
569 
570  /* get output buffer */
571  s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels;
572  if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
573  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
574  return ret;
575  }
576  output_samples_u8 = s->frame.data[0];
577  output_samples_s16 = (int16_t *)s->frame.data[0];
578 
579  /* decode silent chunks */
580  if (silent_chunks > 0) {
581  int silent_size = avctx->block_align * silent_chunks;
582  if (s->out_bps == 2) {
583  memset(output_samples_s16, 0x00, silent_size * 2);
584  output_samples_s16 += silent_size;
585  } else {
586  memset(output_samples_u8, 0x80, silent_size);
587  output_samples_u8 += silent_size;
588  }
589  }
590 
591  /* decode audio chunks */
592  if (audio_chunks > 0) {
593  buf_end = buf + buf_size;
594  while (buf + s->chunk_size <= buf_end) {
595  if (s->out_bps == 2) {
596  decode_audio_s16(output_samples_s16, buf, s->chunk_size,
597  avctx->channels);
598  output_samples_s16 += avctx->block_align;
599  } else {
600  memcpy(output_samples_u8, buf, s->chunk_size);
601  output_samples_u8 += avctx->block_align;
602  }
603  buf += s->chunk_size;
604  }
605  }
606 
607  *got_frame_ptr = 1;
608  *(AVFrame *)data = s->frame;
609 
610  return avpkt->size;
611 }
612 
613 
614 /*
615  * Public Data Structures
616  */
617 
619  .name = "vmdvideo",
620  .type = AVMEDIA_TYPE_VIDEO,
621  .id = CODEC_ID_VMDVIDEO,
622  .priv_data_size = sizeof(VmdVideoContext),
626  .capabilities = CODEC_CAP_DR1,
627  .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD video"),
628 };
629 
631  .name = "vmdaudio",
632  .type = AVMEDIA_TYPE_AUDIO,
633  .id = CODEC_ID_VMDAUDIO,
634  .priv_data_size = sizeof(VmdAudioContext),
637  .capabilities = CODEC_CAP_DR1,
638  .long_name = NULL_IF_CONFIG_SMALL("Sierra VMD audio"),
639 };