westwood.c
Go to the documentation of this file.
1 /*
2  * Westwood Studios Multimedia Formats Demuxer (VQA, AUD)
3  * Copyright (c) 2003 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 
36 #include "libavutil/intreadwrite.h"
37 #include "avformat.h"
38 #include "internal.h"
39 
40 #define AUD_HEADER_SIZE 12
41 #define AUD_CHUNK_PREAMBLE_SIZE 8
42 #define AUD_CHUNK_SIGNATURE 0x0000DEAF
43 
44 #define FORM_TAG MKBETAG('F', 'O', 'R', 'M')
45 #define WVQA_TAG MKBETAG('W', 'V', 'Q', 'A')
46 #define VQHD_TAG MKBETAG('V', 'Q', 'H', 'D')
47 #define FINF_TAG MKBETAG('F', 'I', 'N', 'F')
48 #define SND0_TAG MKBETAG('S', 'N', 'D', '0')
49 #define SND1_TAG MKBETAG('S', 'N', 'D', '1')
50 #define SND2_TAG MKBETAG('S', 'N', 'D', '2')
51 #define VQFR_TAG MKBETAG('V', 'Q', 'F', 'R')
52 
53 /* don't know what these tags are for, but acknowledge their existence */
54 #define CINF_TAG MKBETAG('C', 'I', 'N', 'F')
55 #define CINH_TAG MKBETAG('C', 'I', 'N', 'H')
56 #define CIND_TAG MKBETAG('C', 'I', 'N', 'D')
57 #define PINF_TAG MKBETAG('P', 'I', 'N', 'F')
58 #define PINH_TAG MKBETAG('P', 'I', 'N', 'H')
59 #define PIND_TAG MKBETAG('P', 'I', 'N', 'D')
60 #define CMDS_TAG MKBETAG('C', 'M', 'D', 'S')
61 
62 #define VQA_HEADER_SIZE 0x2A
63 #define VQA_FRAMERATE 15
64 #define VQA_PREAMBLE_SIZE 8
65 
66 typedef struct WsAudDemuxContext {
74 
75 typedef struct WsVqaDemuxContext {
79 
82 
85 
86 static int wsaud_probe(AVProbeData *p)
87 {
88  int field;
89 
90  /* Probabilistic content detection strategy: There is no file signature
91  * so perform sanity checks on various header parameters:
92  * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers
93  * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers
94  * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers
95  * first audio chunk signature (32 bits) ==> 1 acceptable number
96  * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
97  * 320008 acceptable number combinations.
98  */
99 
101  return 0;
102 
103  /* check sample rate */
104  field = AV_RL16(&p->buf[0]);
105  if ((field < 8000) || (field > 48000))
106  return 0;
107 
108  /* enforce the rule that the top 6 bits of this flags field are reserved (0);
109  * this might not be true, but enforce it until deemed unnecessary */
110  if (p->buf[10] & 0xFC)
111  return 0;
112 
113  /* note: only check for WS IMA (type 99) right now since there is no
114  * support for type 1 */
115  if (p->buf[11] != 99)
116  return 0;
117 
118  /* read ahead to the first audio chunk and validate the first header signature */
119  if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE)
120  return 0;
121 
122  /* return 1/2 certainty since this file check is a little sketchy */
123  return AVPROBE_SCORE_MAX / 2;
124 }
125 
127  AVFormatParameters *ap)
128 {
129  WsAudDemuxContext *wsaud = s->priv_data;
130  AVIOContext *pb = s->pb;
131  AVStream *st;
132  unsigned char header[AUD_HEADER_SIZE];
133 
134  if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
135  return AVERROR(EIO);
136  wsaud->audio_samplerate = AV_RL16(&header[0]);
137  if (header[11] == 99)
139  else
140  return AVERROR_INVALIDDATA;
141 
142  /* flag 0 indicates stereo */
143  wsaud->audio_channels = (header[10] & 0x1) + 1;
144  /* flag 1 indicates 16 bit audio */
145  wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
146 
147  /* initialize the audio decoder stream */
148  st = avformat_new_stream(s, NULL);
149  if (!st)
150  return AVERROR(ENOMEM);
151  avpriv_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
153  st->codec->codec_id = wsaud->audio_type;
154  st->codec->codec_tag = 0; /* no tag */
155  st->codec->channels = wsaud->audio_channels;
156  st->codec->sample_rate = wsaud->audio_samplerate;
157  st->codec->bits_per_coded_sample = wsaud->audio_bits;
158  st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
159  st->codec->bits_per_coded_sample / 4;
161 
162  wsaud->audio_stream_index = st->index;
163  wsaud->audio_frame_counter = 0;
164 
165  return 0;
166 }
167 
169  AVPacket *pkt)
170 {
171  WsAudDemuxContext *wsaud = s->priv_data;
172  AVIOContext *pb = s->pb;
173  unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
174  unsigned int chunk_size;
175  int ret = 0;
176 
177  if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
179  return AVERROR(EIO);
180 
181  /* validate the chunk */
182  if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
183  return AVERROR_INVALIDDATA;
184 
185  chunk_size = AV_RL16(&preamble[0]);
186  ret= av_get_packet(pb, pkt, chunk_size);
187  if (ret != chunk_size)
188  return AVERROR(EIO);
189  pkt->stream_index = wsaud->audio_stream_index;
190  pkt->pts = wsaud->audio_frame_counter;
191  pkt->pts /= wsaud->audio_samplerate;
192 
193  /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
194  wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels;
195 
196  return ret;
197 }
198 
199 static int wsvqa_probe(AVProbeData *p)
200 {
201  /* need 12 bytes to qualify */
202  if (p->buf_size < 12)
203  return 0;
204 
205  /* check for the VQA signatures */
206  if ((AV_RB32(&p->buf[0]) != FORM_TAG) ||
207  (AV_RB32(&p->buf[8]) != WVQA_TAG))
208  return 0;
209 
210  return AVPROBE_SCORE_MAX;
211 }
212 
214  AVFormatParameters *ap)
215 {
216  WsVqaDemuxContext *wsvqa = s->priv_data;
217  AVIOContext *pb = s->pb;
218  AVStream *st;
219  unsigned char *header;
220  unsigned char scratch[VQA_PREAMBLE_SIZE];
221  unsigned int chunk_tag;
222  unsigned int chunk_size;
223 
224  /* initialize the video decoder stream */
225  st = avformat_new_stream(s, NULL);
226  if (!st)
227  return AVERROR(ENOMEM);
229  wsvqa->video_stream_index = st->index;
232  st->codec->codec_tag = 0; /* no fourcc */
233 
234  /* skip to the start of the VQA header */
235  avio_seek(pb, 20, SEEK_SET);
236 
237  /* the VQA header needs to go to the decoder */
240  header = (unsigned char *)st->codec->extradata;
241  if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
242  VQA_HEADER_SIZE) {
243  av_free(st->codec->extradata);
244  return AVERROR(EIO);
245  }
246  st->codec->width = AV_RL16(&header[6]);
247  st->codec->height = AV_RL16(&header[8]);
248 
249  /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
250  if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
251  st = avformat_new_stream(s, NULL);
252  if (!st)
253  return AVERROR(ENOMEM);
256  if (AV_RL16(&header[0]) == 1)
258  else
260  st->codec->codec_tag = 0; /* no tag */
261  st->codec->sample_rate = AV_RL16(&header[24]);
262  if (!st->codec->sample_rate)
263  st->codec->sample_rate = 22050;
264  st->codec->channels = header[26];
265  if (!st->codec->channels)
266  st->codec->channels = 1;
267  st->codec->bits_per_coded_sample = 16;
268  st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
269  st->codec->bits_per_coded_sample / 4;
271 
272  wsvqa->audio_stream_index = st->index;
273  wsvqa->audio_samplerate = st->codec->sample_rate;
274  wsvqa->audio_channels = st->codec->channels;
275  wsvqa->audio_frame_counter = 0;
276  }
277 
278  /* there are 0 or more chunks before the FINF chunk; iterate until
279  * FINF has been skipped and the file will be ready to be demuxed */
280  do {
281  if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
282  av_free(st->codec->extradata);
283  return AVERROR(EIO);
284  }
285  chunk_tag = AV_RB32(&scratch[0]);
286  chunk_size = AV_RB32(&scratch[4]);
287 
288  /* catch any unknown header tags, for curiousity */
289  switch (chunk_tag) {
290  case CINF_TAG:
291  case CINH_TAG:
292  case CIND_TAG:
293  case PINF_TAG:
294  case PINH_TAG:
295  case PIND_TAG:
296  case FINF_TAG:
297  case CMDS_TAG:
298  break;
299 
300  default:
301  av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
302  scratch[0], scratch[1],
303  scratch[2], scratch[3]);
304  break;
305  }
306 
307  avio_skip(pb, chunk_size);
308  } while (chunk_tag != FINF_TAG);
309 
310  return 0;
311 }
312 
314  AVPacket *pkt)
315 {
316  WsVqaDemuxContext *wsvqa = s->priv_data;
317  AVIOContext *pb = s->pb;
318  int ret = -1;
319  unsigned char preamble[VQA_PREAMBLE_SIZE];
320  unsigned int chunk_type;
321  unsigned int chunk_size;
322  int skip_byte;
323 
324  while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
325  chunk_type = AV_RB32(&preamble[0]);
326  chunk_size = AV_RB32(&preamble[4]);
327  skip_byte = chunk_size & 0x01;
328 
329  if ((chunk_type == SND2_TAG || chunk_type == SND1_TAG) && wsvqa->audio_channels == 0) {
330  av_log(s, AV_LOG_ERROR, "audio chunk without any audio header information found\n");
331  return AVERROR_INVALIDDATA;
332  }
333 
334  if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
335 
336  if (av_new_packet(pkt, chunk_size))
337  return AVERROR(EIO);
338  ret = avio_read(pb, pkt->data, chunk_size);
339  if (ret != chunk_size) {
340  av_free_packet(pkt);
341  return AVERROR(EIO);
342  }
343 
344  if (chunk_type == SND2_TAG) {
345  pkt->stream_index = wsvqa->audio_stream_index;
346  /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
347  wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels;
348  } else if(chunk_type == SND1_TAG) {
349  pkt->stream_index = wsvqa->audio_stream_index;
350  /* unpacked size is stored in header */
351  wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels;
352  } else {
353  pkt->stream_index = wsvqa->video_stream_index;
354  }
355  /* stay on 16-bit alignment */
356  if (skip_byte)
357  avio_skip(pb, 1);
358 
359  return ret;
360  } else {
361  switch(chunk_type){
362  case CMDS_TAG:
363  case SND0_TAG:
364  break;
365  default:
366  av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type);
367  }
368  avio_skip(pb, chunk_size + skip_byte);
369  }
370  }
371 
372  return ret;
373 }
374 
375 #if CONFIG_WSAUD_DEMUXER
376 AVInputFormat ff_wsaud_demuxer = {
377  .name = "wsaud",
378  .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
379  .priv_data_size = sizeof(WsAudDemuxContext),
383 };
384 #endif
385 #if CONFIG_WSVQA_DEMUXER
386 AVInputFormat ff_wsvqa_demuxer = {
387  .name = "wsvqa",
388  .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
389  .priv_data_size = sizeof(WsVqaDemuxContext),
393 };
394 #endif