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  return AVERROR(EIO);
244  }
245  st->codec->width = AV_RL16(&header[6]);
246  st->codec->height = AV_RL16(&header[8]);
247 
248  /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
249  if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
250  st = avformat_new_stream(s, NULL);
251  if (!st)
252  return AVERROR(ENOMEM);
255  if (AV_RL16(&header[0]) == 1)
257  else
259  st->codec->codec_tag = 0; /* no tag */
260  st->codec->sample_rate = AV_RL16(&header[24]);
261  if (!st->codec->sample_rate)
262  st->codec->sample_rate = 22050;
263  st->codec->channels = header[26];
264  if (!st->codec->channels)
265  st->codec->channels = 1;
266  st->codec->bits_per_coded_sample = 16;
267  st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
268  st->codec->bits_per_coded_sample / 4;
270 
271  wsvqa->audio_stream_index = st->index;
272  wsvqa->audio_samplerate = st->codec->sample_rate;
273  wsvqa->audio_channels = st->codec->channels;
274  wsvqa->audio_frame_counter = 0;
275  }
276 
277  /* there are 0 or more chunks before the FINF chunk; iterate until
278  * FINF has been skipped and the file will be ready to be demuxed */
279  do {
280  if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) {
281  return AVERROR(EIO);
282  }
283  chunk_tag = AV_RB32(&scratch[0]);
284  chunk_size = AV_RB32(&scratch[4]);
285 
286  /* catch any unknown header tags, for curiousity */
287  switch (chunk_tag) {
288  case CINF_TAG:
289  case CINH_TAG:
290  case CIND_TAG:
291  case PINF_TAG:
292  case PINH_TAG:
293  case PIND_TAG:
294  case FINF_TAG:
295  case CMDS_TAG:
296  break;
297 
298  default:
299  av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
300  scratch[0], scratch[1],
301  scratch[2], scratch[3]);
302  break;
303  }
304 
305  avio_skip(pb, chunk_size);
306  } while (chunk_tag != FINF_TAG);
307 
308  return 0;
309 }
310 
312  AVPacket *pkt)
313 {
314  WsVqaDemuxContext *wsvqa = s->priv_data;
315  AVIOContext *pb = s->pb;
316  int ret = -1;
317  unsigned char preamble[VQA_PREAMBLE_SIZE];
318  unsigned int chunk_type;
319  unsigned int chunk_size;
320  int skip_byte;
321 
322  while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) {
323  chunk_type = AV_RB32(&preamble[0]);
324  chunk_size = AV_RB32(&preamble[4]);
325  skip_byte = chunk_size & 0x01;
326 
327  if ((chunk_type == SND2_TAG || chunk_type == SND1_TAG) && wsvqa->audio_channels == 0) {
328  av_log(s, AV_LOG_ERROR, "audio chunk without any audio header information found\n");
329  return AVERROR_INVALIDDATA;
330  }
331 
332  if ((chunk_type == SND1_TAG) || (chunk_type == SND2_TAG) || (chunk_type == VQFR_TAG)) {
333 
334  if (av_new_packet(pkt, chunk_size))
335  return AVERROR(EIO);
336  ret = avio_read(pb, pkt->data, chunk_size);
337  if (ret != chunk_size) {
338  av_free_packet(pkt);
339  return AVERROR(EIO);
340  }
341 
342  if (chunk_type == SND2_TAG) {
343  pkt->stream_index = wsvqa->audio_stream_index;
344  /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
345  wsvqa->audio_frame_counter += (chunk_size * 2) / wsvqa->audio_channels;
346  } else if(chunk_type == SND1_TAG) {
347  pkt->stream_index = wsvqa->audio_stream_index;
348  /* unpacked size is stored in header */
349  wsvqa->audio_frame_counter += AV_RL16(pkt->data) / wsvqa->audio_channels;
350  } else {
351  pkt->stream_index = wsvqa->video_stream_index;
352  }
353  /* stay on 16-bit alignment */
354  if (skip_byte)
355  avio_skip(pb, 1);
356 
357  return ret;
358  } else {
359  switch(chunk_type){
360  case CMDS_TAG:
361  case SND0_TAG:
362  break;
363  default:
364  av_log(s, AV_LOG_INFO, "Skipping unknown chunk 0x%08X\n", chunk_type);
365  }
366  avio_skip(pb, chunk_size + skip_byte);
367  }
368  }
369 
370  return ret;
371 }
372 
373 #if CONFIG_WSAUD_DEMUXER
374 AVInputFormat ff_wsaud_demuxer = {
375  .name = "wsaud",
376  .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
377  .priv_data_size = sizeof(WsAudDemuxContext),
381 };
382 #endif
383 #if CONFIG_WSVQA_DEMUXER
384 AVInputFormat ff_wsvqa_demuxer = {
385  .name = "wsvqa",
386  .long_name = NULL_IF_CONFIG_SMALL("Westwood Studios VQA format"),
387  .priv_data_size = sizeof(WsVqaDemuxContext),
391 };
392 #endif