avformat/riffdec: Initialize bitrate
[ffmpeg.git] / libavformat / westwood_aud.c
index 21d16f7..6d8dbdb 100644 (file)
@@ -1,21 +1,21 @@
 /*
  * Westwood Studios AUD Format Demuxer
- * Copyright (c) 2003 The ffmpeg Project
+ * Copyright (c) 2003 The FFmpeg Project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -33,6 +33,7 @@
  * qualify a file. Refer to wsaud_probe() for the precise parameters.
  */
 
+#include "libavutil/channel_layout.h"
 #include "libavutil/intreadwrite.h"
 #include "avformat.h"
 #include "internal.h"
 #define AUD_CHUNK_PREAMBLE_SIZE 8
 #define AUD_CHUNK_SIGNATURE 0x0000DEAF
 
-typedef struct WsAudDemuxContext {
-    int audio_samplerate;
-    int audio_channels;
-    int audio_bits;
-    enum CodecID audio_type;
-    int audio_stream_index;
-    int64_t audio_frame_counter;
-} WsAudDemuxContext;
-
 static int wsaud_probe(AVProbeData *p)
 {
     int field;
@@ -77,8 +69,6 @@ static int wsaud_probe(AVProbeData *p)
     if (p->buf[10] & 0xFC)
         return 0;
 
-    /* note: only check for WS IMA (type 99) right now since there is no
-     * support for type 1 */
     if (p->buf[11] != 99 && p->buf[11] != 1)
         return 0;
 
@@ -87,49 +77,51 @@ static int wsaud_probe(AVProbeData *p)
         return 0;
 
     /* return 1/2 certainty since this file check is a little sketchy */
-    return AVPROBE_SCORE_MAX / 2;
+    return AVPROBE_SCORE_EXTENSION;
 }
 
-static int wsaud_read_header(AVFormatContext *s,
-                             AVFormatParameters *ap)
+static int wsaud_read_header(AVFormatContext *s)
 {
-    WsAudDemuxContext *wsaud = s->priv_data;
     AVIOContext *pb = s->pb;
     AVStream *st;
     unsigned char header[AUD_HEADER_SIZE];
+    int sample_rate, channels, codec;
 
     if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
         return AVERROR(EIO);
-    wsaud->audio_samplerate = AV_RL16(&header[0]);
-    if (header[11] == 99)
-        wsaud->audio_type = CODEC_ID_ADPCM_IMA_WS;
-    else if (header[11] == 1)
-        wsaud->audio_type = CODEC_ID_WESTWOOD_SND1;
-    else
-        return AVERROR_INVALIDDATA;
 
-    /* flag 0 indicates stereo */
-    wsaud->audio_channels = (header[10] & 0x1) + 1;
-    /* flag 1 indicates 16 bit audio */
-    wsaud->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8;
+    sample_rate = AV_RL16(&header[0]);
+    channels    = (header[10] & 0x1) + 1;
+    codec       = header[11];
 
     /* initialize the audio decoder stream */
     st = avformat_new_stream(s, NULL);
     if (!st)
         return AVERROR(ENOMEM);
-    avpriv_set_pts_info(st, 33, 1, wsaud->audio_samplerate);
-    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
-    st->codec->codec_id = wsaud->audio_type;
-    st->codec->codec_tag = 0;  /* no tag */
-    st->codec->channels = wsaud->audio_channels;
-    st->codec->sample_rate = wsaud->audio_samplerate;
-    if (st->codec->codec_id == CODEC_ID_ADPCM_IMA_WS) {
+
+    switch (codec) {
+    case  1:
+        if (channels != 1) {
+            avpriv_request_sample(s, "Stereo WS-SND1");
+            return AVERROR_PATCHWELCOME;
+        }
+        st->codec->codec_id = AV_CODEC_ID_WESTWOOD_SND1;
+        break;
+    case 99:
+        st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_WS;
         st->codec->bits_per_coded_sample = 4;
-        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 4;
+        st->codec->bit_rate = channels * sample_rate * 4;
+        break;
+    default:
+        avpriv_request_sample(s, "Unknown codec: %d", codec);
+        return AVERROR_PATCHWELCOME;
     }
-
-    wsaud->audio_stream_index = st->index;
-    wsaud->audio_frame_counter = 0;
+    avpriv_set_pts_info(st, 64, 1, sample_rate);
+    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
+    st->codec->channels    = channels;
+    st->codec->channel_layout = channels == 1 ? AV_CH_LAYOUT_MONO :
+                                                AV_CH_LAYOUT_STEREO;
+    st->codec->sample_rate = sample_rate;
 
     return 0;
 }
@@ -137,12 +129,11 @@ static int wsaud_read_header(AVFormatContext *s,
 static int wsaud_read_packet(AVFormatContext *s,
                              AVPacket *pkt)
 {
-    WsAudDemuxContext *wsaud = s->priv_data;
     AVIOContext *pb = s->pb;
     unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
     unsigned int chunk_size;
     int ret = 0;
-    AVStream *st = s->streams[wsaud->audio_stream_index];
+    AVStream *st = s->streams[0];
 
     if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
         AUD_CHUNK_PREAMBLE_SIZE)
@@ -154,13 +145,13 @@ static int wsaud_read_packet(AVFormatContext *s,
 
     chunk_size = AV_RL16(&preamble[0]);
 
-    if (st->codec->codec_id == CODEC_ID_WESTWOOD_SND1) {
+    if (st->codec->codec_id == AV_CODEC_ID_WESTWOOD_SND1) {
         /* For Westwood SND1 audio we need to add the output size and input
            size to the start of the packet to match what is in VQA.
            Specifically, this is needed to signal when a packet should be
            decoding as raw 8-bit pcm or variable-size ADPCM. */
         int out_size = AV_RL16(&preamble[2]);
-        if ((ret = av_new_packet(pkt, chunk_size + 4)))
+        if ((ret = av_new_packet(pkt, chunk_size + 4)) < 0)
             return ret;
         if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
             return ret < 0 ? ret : AVERROR(EIO);
@@ -172,11 +163,9 @@ static int wsaud_read_packet(AVFormatContext *s,
         ret = av_get_packet(pb, pkt, chunk_size);
         if (ret != chunk_size)
             return AVERROR(EIO);
-        pkt->pts = wsaud->audio_frame_counter;
-        pkt->pts /= wsaud->audio_samplerate;
 
         /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */
-        wsaud->audio_frame_counter += (chunk_size * 2) / wsaud->audio_channels;
+        pkt->duration = (chunk_size * 2) / st->codec->channels;
     }
     pkt->stream_index = st->index;
 
@@ -185,8 +174,7 @@ static int wsaud_read_packet(AVFormatContext *s,
 
 AVInputFormat ff_wsaud_demuxer = {
     .name           = "wsaud",
-    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios audio format"),
-    .priv_data_size = sizeof(WsAudDemuxContext),
+    .long_name      = NULL_IF_CONFIG_SMALL("Westwood Studios audio"),
     .read_probe     = wsaud_probe,
     .read_header    = wsaud_read_header,
     .read_packet    = wsaud_read_packet,