Re: [FFmpeg-devel] [PATCH] avformat/westwood_aud: Adds PCM format demux.

2019-02-28 Thread Michael Niedermayer
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.

2019-02-28 Thread Tomas Härdin
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.

2019-02-27 Thread Aidan R
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]);