[FFmpeg-cvslog] aud: support Westwood SND1 audio in AUD files.

Justin Ruggles git at videolan.org
Tue Jan 24 23:12:54 CET 2012


ffmpeg | branch: master | Justin Ruggles <justin.ruggles at gmail.com> | Tue Jan 24 11:09:05 2012 -0500| [d481227c549aece0bc4a05819a771806b6cd7507] | committer: Justin Ruggles

aud: support Westwood SND1 audio in AUD files.

Fixes decoding of the handful of "death scream" samples from
"Command and Conquer" that use SND1. e.g.
http://samples.libav.org/game-formats/westwood-aud/nuyell1.aud
http://samples.libav.org/game-formats/westwood-aud/nuyell7.aud

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=d481227c549aece0bc4a05819a771806b6cd7507
---

 libavformat/westwood_aud.c |   32 ++++++++++++++++++++++++++------
 1 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c
index b1eb768..652045f 100644
--- a/libavformat/westwood_aud.c
+++ b/libavformat/westwood_aud.c
@@ -79,7 +79,7 @@ static int wsaud_probe(AVProbeData *p)
 
     /* note: only check for WS IMA (type 99) right now since there is no
      * support for type 1 */
-    if (p->buf[11] != 99)
+    if (p->buf[11] != 99 && p->buf[11] != 1)
         return 0;
 
     /* read ahead to the first audio chunk and validate the first header signature */
@@ -103,6 +103,8 @@ static int wsaud_read_header(AVFormatContext *s,
     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;
 
@@ -121,10 +123,10 @@ static int wsaud_read_header(AVFormatContext *s,
     st->codec->codec_tag = 0;  /* no tag */
     st->codec->channels = wsaud->audio_channels;
     st->codec->sample_rate = wsaud->audio_samplerate;
-    st->codec->bits_per_coded_sample = wsaud->audio_bits;
-    st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
-        st->codec->bits_per_coded_sample / 4;
-    st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
+    if (st->codec->codec_id == CODEC_ID_ADPCM_IMA_WS) {
+        st->codec->bits_per_coded_sample = 4;
+        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * 4;
+    }
 
     wsaud->audio_stream_index = st->index;
     wsaud->audio_frame_counter = 0;
@@ -140,6 +142,7 @@ static int wsaud_read_packet(AVFormatContext *s,
     unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE];
     unsigned int chunk_size;
     int ret = 0;
+    AVStream *st = s->streams[wsaud->audio_stream_index];
 
     if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) !=
         AUD_CHUNK_PREAMBLE_SIZE)
@@ -150,15 +153,32 @@ static int wsaud_read_packet(AVFormatContext *s,
         return AVERROR_INVALIDDATA;
 
     chunk_size = AV_RL16(&preamble[0]);
+
+    if (st->codec->codec_id == 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)))
+            return ret;
+        if ((ret = avio_read(pb, &pkt->data[4], chunk_size)) != chunk_size)
+            return ret < 0 ? ret : AVERROR(EIO);
+        AV_WL16(&pkt->data[0], out_size);
+        AV_WL16(&pkt->data[2], chunk_size);
+
+        pkt->duration = out_size;
+    } else {
     ret= av_get_packet(pb, pkt, chunk_size);
     if (ret != chunk_size)
         return AVERROR(EIO);
-    pkt->stream_index = wsaud->audio_stream_index;
     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->stream_index = st->index;
 
     return ret;
 }



More information about the ffmpeg-cvslog mailing list