LCOV - code coverage report
Current view: top level - libavformat - westwood_aud.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 47 72 65.3 %
Date: 2017-12-17 11:58:42 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Westwood Studios AUD Format Demuxer
       3             :  * Copyright (c) 2003 The FFmpeg project
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg 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             :  * FFmpeg 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 FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Westwood Studios AUD file demuxer
      25             :  * by Mike Melanson (melanson@pcisys.net)
      26             :  * for more information on the Westwood file formats, visit:
      27             :  *   http://www.pcisys.net/~melanson/codecs/
      28             :  *   http://www.geocities.com/SiliconValley/8682/aud3.txt
      29             :  *
      30             :  * Implementation note: There is no definite file signature for AUD files.
      31             :  * The demuxer uses a probabilistic strategy for content detection. This
      32             :  * entails performing sanity checks on certain header values in order to
      33             :  * qualify a file. Refer to wsaud_probe() for the precise parameters.
      34             :  */
      35             : 
      36             : #include "libavutil/channel_layout.h"
      37             : #include "libavutil/intreadwrite.h"
      38             : #include "avformat.h"
      39             : #include "internal.h"
      40             : 
      41             : #define AUD_HEADER_SIZE 12
      42             : #define AUD_CHUNK_PREAMBLE_SIZE 8
      43             : #define AUD_CHUNK_SIGNATURE 0x0000DEAF
      44             : 
      45        6130 : static int wsaud_probe(AVProbeData *p)
      46             : {
      47             :     int field;
      48             : 
      49             :     /* Probabilistic content detection strategy: There is no file signature
      50             :      * so perform sanity checks on various header parameters:
      51             :      *   8000 <= sample rate (16 bits) <= 48000  ==> 40001 acceptable numbers
      52             :      *   flags <= 0x03 (2 LSBs are used)         ==> 4 acceptable numbers
      53             :      *   compression type (8 bits) = 1 or 99     ==> 2 acceptable numbers
      54             :      *   first audio chunk signature (32 bits)   ==> 1 acceptable number
      55             :      * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 =
      56             :      * 320008 acceptable number combinations.
      57             :      */
      58             : 
      59        6130 :     if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE)
      60           0 :         return 0;
      61             : 
      62             :     /* check sample rate */
      63        6130 :     field = AV_RL16(&p->buf[0]);
      64        6130 :     if ((field < 8000) || (field > 48000))
      65        1662 :         return 0;
      66             : 
      67             :     /* enforce the rule that the top 6 bits of this flags field are reserved (0);
      68             :      * this might not be true, but enforce it until deemed unnecessary */
      69        4468 :     if (p->buf[10] & 0xFC)
      70        3872 :         return 0;
      71             : 
      72         596 :     if (p->buf[11] != 99 && p->buf[11] != 1)
      73         588 :         return 0;
      74             : 
      75             :     /* read ahead to the first audio chunk and validate the first header signature */
      76           8 :     if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE)
      77           7 :         return 0;
      78             : 
      79             :     /* return 1/2 certainty since this file check is a little sketchy */
      80           1 :     return AVPROBE_SCORE_EXTENSION;
      81             : }
      82             : 
      83           1 : static int wsaud_read_header(AVFormatContext *s)
      84             : {
      85           1 :     AVIOContext *pb = s->pb;
      86             :     AVStream *st;
      87             :     unsigned char header[AUD_HEADER_SIZE];
      88             :     int sample_rate, channels, codec;
      89             : 
      90           1 :     if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
      91           0 :         return AVERROR(EIO);
      92             : 
      93           1 :     sample_rate = AV_RL16(&header[0]);
      94           1 :     channels    = (header[10] & 0x1) + 1;
      95           1 :     codec       = header[11];
      96             : 
      97             :     /* initialize the audio decoder stream */
      98           1 :     st = avformat_new_stream(s, NULL);
      99           1 :     if (!st)
     100           0 :         return AVERROR(ENOMEM);
     101             : 
     102           1 :     switch (codec) {
     103           0 :     case  1:
     104           0 :         if (channels != 1) {
     105           0 :             avpriv_request_sample(s, "Stereo WS-SND1");
     106           0 :             return AVERROR_PATCHWELCOME;
     107             :         }
     108           0 :         st->codecpar->codec_id = AV_CODEC_ID_WESTWOOD_SND1;
     109           0 :         break;
     110           1 :     case 99:
     111           1 :         st->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_WS;
     112           1 :         st->codecpar->bits_per_coded_sample = 4;
     113           1 :         st->codecpar->bit_rate = channels * sample_rate * 4;
     114           1 :         break;
     115           0 :     default:
     116           0 :         avpriv_request_sample(s, "Unknown codec: %d", codec);
     117           0 :         return AVERROR_PATCHWELCOME;
     118             :     }
     119           1 :     avpriv_set_pts_info(st, 64, 1, sample_rate);
     120           1 :     st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
     121           1 :     st->codecpar->channels    = channels;
     122           1 :     st->codecpar->channel_layout = channels == 1 ? AV_CH_LAYOUT_MONO :
     123             :                                                    AV_CH_LAYOUT_STEREO;
     124           1 :     st->codecpar->sample_rate = sample_rate;
     125             : 
     126           1 :     return 0;
     127             : }
     128             : 
     129          13 : static int wsaud_read_packet(AVFormatContext *s,
     130             :                              AVPacket *pkt)
     131             : {
     132          13 :     AVIOContext *pb = s->pb;
     133             :     unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
     134             :     unsigned int chunk_size;
     135          13 :     int ret = 0;
     136          13 :     AVStream *st = s->streams[0];
     137             : 
     138          13 :     if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
     139             :         AUD_CHUNK_PREAMBLE_SIZE)
     140           2 :         return AVERROR(EIO);
     141             : 
     142             :     /* validate the chunk */
     143          11 :     if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE)
     144           0 :         return AVERROR_INVALIDDATA;
     145             : 
     146          11 :     chunk_size = AV_RL16(&preamble[0]);
     147             : 
     148          11 :     if (st->codecpar->codec_id == AV_CODEC_ID_WESTWOOD_SND1) {
     149             :         /* For Westwood SND1 audio we need to add the output size and input
     150             :            size to the start of the packet to match what is in VQA.
     151             :            Specifically, this is needed to signal when a packet should be
     152             :            decoding as raw 8-bit pcm or variable-size ADPCM. */
     153           0 :         int out_size = AV_RL16(&preamble[2]);
     154           0 :         if ((ret = av_new_packet(pkt, chunk_size + 4)) < 0)
     155           0 :             return ret;
     156           0 :         if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
     157           0 :             return ret < 0 ? ret : AVERROR(EIO);
     158           0 :         AV_WL16(&pkt->data[0], out_size);
     159           0 :         AV_WL16(&pkt->data[2], chunk_size);
     160             : 
     161           0 :         pkt->duration = out_size;
     162             :     } else {
     163          11 :         ret = av_get_packet(pb, pkt, chunk_size);
     164          11 :         if (ret != chunk_size)
     165           0 :             return AVERROR(EIO);
     166             : 
     167          11 :         if (st->codecpar->channels <= 0) {
     168           0 :             av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n",
     169           0 :                    st->codecpar->channels);
     170           0 :             return AVERROR_INVALIDDATA;
     171             :         }
     172             : 
     173             :         /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
     174          11 :         pkt->duration = (chunk_size * 2) / st->codecpar->channels;
     175             :     }
     176          11 :     pkt->stream_index = st->index;
     177             : 
     178          11 :     return ret;
     179             : }
     180             : 
     181             : AVInputFormat ff_wsaud_demuxer = {
     182             :     .name           = "wsaud",
     183             :     .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios audio"),
     184             :     .read_probe     = wsaud_probe,
     185             :     .read_header    = wsaud_read_header,
     186             :     .read_packet    = wsaud_read_packet,
     187             : };

Generated by: LCOV version 1.13