Re: [FFmpeg-devel] [PATCH] avformat/westwood_aud: Adds PCM format demux.
On Wed, Feb 27, 2019 at 11:12:08PM +, Aidan R wrote: > PCM format AUD files are found in Westwood's Blade Runner game. > --- > libavformat/westwood_aud.c | 80 > -- > 1 file changed, 63 insertions(+), 17 deletions(-) > > diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c > index 9c2d35cb8a..5d7e827bc1 100644 > --- a/libavformat/westwood_aud.c > +++ b/libavformat/westwood_aud.c > @@ -41,6 +41,12 @@ > #define AUD_HEADER_SIZE 12 > #define AUD_CHUNK_PREAMBLE_SIZE 8 > #define AUD_CHUNK_SIGNATURE 0xDEAF > +#define AUD_PCM_CHUNK_SIZE 2048 /* arbitrary size to pull out of PCM data*/ > + > +typedef struct AUDDemuxContext { > +int size; > +int pos; > +} AUDDemuxContext; > > static int wsaud_probe(AVProbeData *p) > { > @@ -50,10 +56,10 @@ static int wsaud_probe(AVProbeData *p) > * so perform sanity checks on various header parameters: > * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers > * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers > - * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers > + * compression type (8 bits) = 0, 1 or 99 ==> 3 acceptable numbers > * first audio chunk signature (32 bits) ==> 1 acceptable number > - * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 = > - * 320008 acceptable number combinations. > + * The number space contains 2^64 numbers. There are 40001 * 4 * 3 * 1 = > + * 480012 acceptable number combinations. > */ > > if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE) > @@ -69,13 +75,22 @@ static int wsaud_probe(AVProbeData *p) > if (p->buf[10] & 0xFC) > return 0; > > -if (p->buf[11] != 99 && p->buf[11] != 1) > +/* valid format values are 99 == adpcm, 1 == snd1 and 0 == pcm */ > +if (p->buf[11] != 99 && p->buf[11] != 1 && p->buf[11] != 0) > return 0; > > -/* read ahead to the first audio chunk and validate the first header > signature */ > -if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) > +/* read ahead to the first audio chunk and validate the first header > + * signature pcm format does not use a chunk format, so don't check > + * for that codec */ > +if (p->buf[11] != 0 && AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) > return 0; > > +/* if we have pcm format then compressed size should equal > + * uncompressed size */ > +if (p->buf[11] == 0 && AV_RL32(&p->buf[2]) != AV_RL32(&p->buf[6])) { > +return 0; > +} > + > /* return 1/2 certainty since this file check is a little sketchy */ > return AVPROBE_SCORE_EXTENSION; > } this seems to break probetest tools/probetest 256 1024 testing size=1 testing size=2 testing size=4 testing size=8 testing size=16 testing size=32 Failure of wsaud probing code with score=50 type=0 p=EBC size=32 testing size=64 testing size=128 testing size=256 testing size=512 [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Freedom in capitalist society always remains about the same as it was in ancient Greek republics: Freedom for slave owners. -- Vladimir Lenin signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/westwood_aud: Adds PCM format demux.
ons 2019-02-27 klockan 23:12 + skrev Aidan R: > PCM format AUD files are found in Westwood's Blade Runner game. Do we have samples for this? > @@ -100,6 +119,15 @@ static int wsaud_read_header(AVFormatContext *s) > return AVERROR(ENOMEM); > > switch (codec) { > +case 0: > +if (bits_per_sample == 8) { > +st->codecpar->codec_id = AV_CODEC_ID_PCM_U8; > +} else { > +st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; > +} > +st->codecpar->bits_per_coded_sample = bits_per_sample; > +st->codecpar->bit_rate = channels * sample_rate * bits_per_sample; > +break; > case 1: > if (channels != 1) { > avpriv_request_sample(s, "Stereo WS-SND1"); > @@ -130,20 +158,24 @@ static int wsaud_read_packet(AVFormatContext *s, > AVPacket *pkt) > { > AVIOContext *pb = s->pb; > +AUDDemuxContext *aud = s->priv_data; > unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE]; > -unsigned int chunk_size; > +unsigned int chunk_size, bytes_per_sample; > int ret = 0; > AVStream *st = s->streams[0]; > > -if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != > -AUD_CHUNK_PREAMBLE_SIZE) > -return AVERROR(EIO); > +/* AUD files don't store PCM audio in chunks */ > +if (st->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE) { what about u8? /Tomas ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/westwood_aud: Adds PCM format demux.
PCM format AUD files are found in Westwood's Blade Runner game. --- libavformat/westwood_aud.c | 80 -- 1 file changed, 63 insertions(+), 17 deletions(-) diff --git a/libavformat/westwood_aud.c b/libavformat/westwood_aud.c index 9c2d35cb8a..5d7e827bc1 100644 --- a/libavformat/westwood_aud.c +++ b/libavformat/westwood_aud.c @@ -41,6 +41,12 @@ #define AUD_HEADER_SIZE 12 #define AUD_CHUNK_PREAMBLE_SIZE 8 #define AUD_CHUNK_SIGNATURE 0xDEAF +#define AUD_PCM_CHUNK_SIZE 2048 /* arbitrary size to pull out of PCM data*/ + +typedef struct AUDDemuxContext { +int size; +int pos; +} AUDDemuxContext; static int wsaud_probe(AVProbeData *p) { @@ -50,10 +56,10 @@ static int wsaud_probe(AVProbeData *p) * so perform sanity checks on various header parameters: * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers * flags <= 0x03 (2 LSBs are used) ==> 4 acceptable numbers - * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers + * compression type (8 bits) = 0, 1 or 99 ==> 3 acceptable numbers * first audio chunk signature (32 bits) ==> 1 acceptable number - * The number space contains 2^64 numbers. There are 40001 * 4 * 2 * 1 = - * 320008 acceptable number combinations. + * The number space contains 2^64 numbers. There are 40001 * 4 * 3 * 1 = + * 480012 acceptable number combinations. */ if (p->buf_size < AUD_HEADER_SIZE + AUD_CHUNK_PREAMBLE_SIZE) @@ -69,13 +75,22 @@ static int wsaud_probe(AVProbeData *p) if (p->buf[10] & 0xFC) return 0; -if (p->buf[11] != 99 && p->buf[11] != 1) +/* valid format values are 99 == adpcm, 1 == snd1 and 0 == pcm */ +if (p->buf[11] != 99 && p->buf[11] != 1 && p->buf[11] != 0) return 0; -/* read ahead to the first audio chunk and validate the first header signature */ -if (AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) +/* read ahead to the first audio chunk and validate the first header + * signature pcm format does not use a chunk format, so don't check + * for that codec */ +if (p->buf[11] != 0 && AV_RL32(&p->buf[16]) != AUD_CHUNK_SIGNATURE) return 0; +/* if we have pcm format then compressed size should equal + * uncompressed size */ +if (p->buf[11] == 0 && AV_RL32(&p->buf[2]) != AV_RL32(&p->buf[6])) { +return 0; +} + /* return 1/2 certainty since this file check is a little sketchy */ return AVPROBE_SCORE_EXTENSION; } @@ -83,16 +98,20 @@ static int wsaud_probe(AVProbeData *p) static int wsaud_read_header(AVFormatContext *s) { AVIOContext *pb = s->pb; +AUDDemuxContext *aud = s->priv_data; AVStream *st; unsigned char header[AUD_HEADER_SIZE]; -int sample_rate, channels, codec; +int sample_rate, channels, codec, bits_per_sample; if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) return AVERROR(EIO); sample_rate = AV_RL16(&header[0]); channels= (header[10] & 0x1) + 1; +bits_per_sample = (header[10] & 0x2) ? 16 : 8; codec = header[11]; +aud->size = AV_RL32(&header[2]); +aud->pos= 0; /* used to track position in a PCM stream */ /* initialize the audio decoder stream */ st = avformat_new_stream(s, NULL); @@ -100,6 +119,15 @@ static int wsaud_read_header(AVFormatContext *s) return AVERROR(ENOMEM); switch (codec) { +case 0: +if (bits_per_sample == 8) { +st->codecpar->codec_id = AV_CODEC_ID_PCM_U8; +} else { +st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; +} +st->codecpar->bits_per_coded_sample = bits_per_sample; +st->codecpar->bit_rate = channels * sample_rate * bits_per_sample; +break; case 1: if (channels != 1) { avpriv_request_sample(s, "Stereo WS-SND1"); @@ -130,20 +158,24 @@ static int wsaud_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; +AUDDemuxContext *aud = s->priv_data; unsigned char preamble[AUD_CHUNK_PREAMBLE_SIZE]; -unsigned int chunk_size; +unsigned int chunk_size, bytes_per_sample; int ret = 0; AVStream *st = s->streams[0]; -if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != -AUD_CHUNK_PREAMBLE_SIZE) -return AVERROR(EIO); +/* AUD files don't store PCM audio in chunks */ +if (st->codecpar->codec_id != AV_CODEC_ID_PCM_S16LE) { +if (avio_read(pb, preamble, AUD_CHUNK_PREAMBLE_SIZE) != +AUD_CHUNK_PREAMBLE_SIZE) +return AVERROR(EIO); -/* validate the chunk */ -if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE) -return AVERROR_INVALIDDATA; +/* validate the chunk */ +if (AV_RL32(&preamble[4]) != AUD_CHUNK_SIGNATURE) +return AVERROR_INVALIDDATA; -chunk_size = AV_RL16(&preamble[0]);