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