• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/westwood_aud.c

Go to the documentation of this file.
00001 /*
00002  * Westwood Studios AUD Format Demuxer
00003  * Copyright (c) 2003 The ffmpeg Project
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00036 #include "libavutil/intreadwrite.h"
00037 #include "avformat.h"
00038 #include "internal.h"
00039 
00040 #define AUD_HEADER_SIZE 12
00041 #define AUD_CHUNK_PREAMBLE_SIZE 8
00042 #define AUD_CHUNK_SIGNATURE 0x0000DEAF
00043 
00044 static int wsaud_probe(AVProbeData *p)
00045 {
00046     int field;
00047 
00048     /* Probabilistic content detection strategy: There is no file signature
00049      * so perform sanity checks on various header parameters:
00050      *   8000 <= sample rate (16 bits) <= 48000  ==> 40001 acceptable numbers
00051      *   flags <= 0x03 (2 LSBs are used)         ==> 4 acceptable numbers
00052      *   compression type (8 bits) = 1 or 99     ==> 2 acceptable numbers
00053      *   first audio chunk signature (32 bits)   ==> 1 acceptable number
00054      * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
00055      * 320008 acceptable number combinations.
00056      */
00057 
00058     if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE)
00059         return 0;
00060 
00061     /* check sample rate */
00062     field = AV_RL16(&p->buf[0]);
00063     if ((field < 8000) || (field > 48000))
00064         return 0;
00065 
00066     /* enforce the rule that the top 6 bits of this flags field are reserved (0);
00067      * this might not be true, but enforce it until deemed unnecessary */
00068     if (p->buf[10] & 0xFC)
00069         return 0;
00070 
00071     /* note: only check for WS IMA (type 99) right now since there is no
00072      * support for type 1 */
00073     if (p->buf[11] != 99 && p->buf[11] != 1)
00074         return 0;
00075 
00076     /* read ahead to the first audio chunk and validate the first header signature */
00077     if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE)
00078         return 0;
00079 
00080     /* return 1/2 certainty since this file check is a little sketchy */
00081     return AVPROBE_SCORE_MAX / 2;
00082 }
00083 
00084 static int wsaud_read_header(AVFormatContext *s,
00085                              AVFormatParameters *ap)
00086 {
00087     AVIOContext *pb = s->pb;
00088     AVStream *st;
00089     unsigned char header[AUD_HEADER_SIZE];
00090     int sample_rate, channels, codec;
00091 
00092     if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
00093         return AVERROR(EIO);
00094 
00095     sample_rate = AV_RL16(&header[0]);
00096     channels    = (header[10] & 0x1) + 1;
00097     codec       = header[11];
00098 
00099     /* initialize the audio decoder stream */
00100     st = avformat_new_stream(s, NULL);
00101     if (!st)
00102         return AVERROR(ENOMEM);
00103 
00104     switch (codec) {
00105     case  1:
00106         if (channels != 1) {
00107             av_log_ask_for_sample(s, "Stereo WS-SND1 is not supported.\n");
00108             return AVERROR_PATCHWELCOME;
00109         }
00110         st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
00111         break;
00112     case 99:
00113         st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
00114         st->codec->bits_per_coded_sample = 4;
00115         st->codec->bit_rate = channels * sample_rate * 4;
00116         break;
00117     default:
00118         av_log_ask_for_sample(s, "Unknown codec: %d\n", codec);
00119         return AVERROR_PATCHWELCOME;
00120     }
00121     avpriv_set_pts_info(st, 64, 1, sample_rate);
00122     st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
00123     st->codec->channels    = channels;
00124     st->codec->sample_rate = sample_rate;
00125 
00126     return 0;
00127 }
00128 
00129 static int wsaud_read_packet(AVFormatContext *s,
00130                              AVPacket *pkt)
00131 {
00132     AVIOContext *pb = s->pb;
00133     unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
00134     unsigned int chunk_size;
00135     int ret = 0;
00136     AVStream *st = s->streams[0];
00137 
00138     if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
00139         AUD_CHUNK_PREAMBLE_SIZE)
00140         return AVERROR(EIO);
00141 
00142     /* validate the chunk */
00143     if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
00144         return AVERROR_INVALIDDATA;
00145 
00146     chunk_size = AV_RL16(&preamble[0]);
00147 
00148     if (st->codec->codec_id == CODEC_ID_WESTWOOD_SND1) {
00149         /* For Westwood SND1 audio we need to add the output size and input
00150            size to the start of the packet to match what is in VQA.
00151            Specifically, this is needed to signal when a packet should be
00152            decoding as raw 8-bit pcm or variable-size ADPCM. */
00153         int out_size = AV_RL16(&preamble[2]);
00154         if ((ret = av_new_packet(pkt, chunk_size + 4)))
00155             return ret;
00156         if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
00157             return ret < 0 ? ret : AVERROR(EIO);
00158         AV_WL16(&pkt->data[0], out_size);
00159         AV_WL16(&pkt->data[2], chunk_size);
00160 
00161         pkt->duration = out_size;
00162     } else {
00163         ret = av_get_packet(pb, pkt, chunk_size);
00164         if (ret != chunk_size)
00165             return AVERROR(EIO);
00166 
00167         /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
00168         pkt->duration = (chunk_size * 2) / st->codec->channels;
00169     }
00170     pkt->stream_index = st->index;
00171 
00172     return ret;
00173 }
00174 
00175 AVInputFormat ff_wsaud_demuxer = {
00176     .name           = "wsaud",
00177     .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
00178     .read_probe     = wsaud_probe,
00179     .read_header    = wsaud_read_header,
00180     .read_packet    = wsaud_read_packet,
00181 };
Generated on Fri Feb 1 2013 14:34:55 for FFmpeg by doxygen 1.7.1