changeset 84:0068a6902911 libavformat

correct AUDIO strf parsing patch by (Roman Shaposhnick <rvs at sun dot com>)
author michaelni
date Wed, 12 Mar 2003 01:35:47 +0000
parents 5e7f9b16e0a8
children 25062c9b1f86
files asf.c avi.h avidec.c wav.c
diffstat 4 files changed, 30 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/asf.c	Tue Mar 11 12:09:13 2003 +0000
+++ b/asf.c	Wed Mar 12 01:35:47 2003 +0000
@@ -806,7 +806,7 @@
 	    asf->packet_size = asf->hdr.max_pktsize;
             asf->nb_packets = asf->hdr.packets_count;
         } else if (!memcmp(&g, &stream_header, sizeof(GUID))) {
-            int type, total_size;
+            int type, total_size, type_specific_size;
             unsigned int tag1;
             int64_t pos1, pos2;
 
@@ -832,7 +832,7 @@
             }
             get_guid(pb, &g);
             total_size = get_le64(pb);
-            get_le32(pb);
+            type_specific_size = get_le32(pb);
             get_le32(pb);
 	    st->id = get_le16(pb) & 0x7f; /* stream id */
             // mapping of asf ID to AV stream ID;
@@ -842,7 +842,7 @@
 	    st->codec.codec_type = type;
             st->codec.frame_rate = 15 * s->pts_den / s->pts_num; // 15 fps default
             if (type == CODEC_TYPE_AUDIO) {
-                get_wav_header(pb, &st->codec, 1);
+                get_wav_header(pb, &st->codec, type_specific_size);
 		/* We have to init the frame size at some point .... */
 		pos2 = url_ftell(pb);
 		if (gsize > (pos2 + 8 - pos1 + 24)) {
--- a/avi.h	Tue Mar 11 12:09:13 2003 +0000
+++ b/avi.h	Wed Mar 12 01:35:47 2003 +0000
@@ -18,8 +18,7 @@
 void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf);
 int put_wav_header(ByteIOContext *pb, AVCodecContext *enc);
 int wav_codec_get_id(unsigned int tag, int bps);
-void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, 
-                    int has_extra_data);
+void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size); 
 
 extern const CodecTag codec_bmp_tags[];
 extern const CodecTag codec_wav_tags[];
--- a/avidec.c	Tue Mar 11 12:09:13 2003 +0000
+++ b/avidec.c	Wed Mar 12 01:35:47 2003 +0000
@@ -187,7 +187,7 @@
 //                    url_fskip(pb, size - 5 * 4);
                     break;
                 case CODEC_TYPE_AUDIO:
-                    get_wav_header(pb, &st->codec, (size >= 18));
+                    get_wav_header(pb, &st->codec, size);
                     if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
                         url_fskip(pb, 1);
                     break;
--- a/wav.c	Tue Mar 11 12:09:13 2003 +0000
+++ b/wav.c	Wed Mar 12 01:35:47 2003 +0000
@@ -103,26 +103,44 @@
     return hdrsize;
 }
 
-void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, 
-                    int has_extra_data)
+/* We could be given one of the three possible structures here:
+ * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure
+ * is an expansion of the previous one with the fields added
+ * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and
+ * WAVEFORMATEX adds 'WORD  cbSize' and basically makes itself
+ * an openended structure.
+ */
+void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size) 
 {
     int id;
 
     id = get_le16(pb);
+    codec->codec_id = wav_codec_get_id(id, codec->frame_bits);
     codec->codec_type = CODEC_TYPE_AUDIO;
     codec->codec_tag = id;
     codec->channels = get_le16(pb);
     codec->sample_rate = get_le32(pb);
     codec->bit_rate = get_le32(pb) * 8;
     codec->block_align = get_le16(pb);
-    codec->bits_per_sample = get_le16(pb); /* bits per sample */
-    codec->codec_id = wav_codec_get_id(id, codec->frame_bits);
-    if (has_extra_data) {
+    if (size == 14) {  /* We're dealing with plain vanilla WAVEFORMAT */
+        codec->bits_per_sample = 8;
+	return;
+    }
+    
+    codec->bits_per_sample = get_le16(pb);
+    if (size > 16) {  /* We're obviously dealing with WAVEFORMATEX */
 	codec->extradata_size = get_le16(pb);
 	if (codec->extradata_size > 0) {
+	    if (codec->extradata_size > size - 18)
+	        codec->extradata_size = size - 18;
             codec->extradata = av_mallocz(codec->extradata_size);
             get_buffer(pb, codec->extradata, codec->extradata_size);
-        }
+        } else
+	    codec->extradata_size = 0;
+	
+	/* It is possible for the chunk to contain garbage at the end */
+	if (size - codec->extradata_size - 18 > 0)
+	    url_fskip(pb, size - codec->extradata_size - 18);
     }
 }
 
@@ -259,7 +277,7 @@
     if (!st)
         return AVERROR_NOMEM;
 
-    get_wav_header(pb, &st->codec, (size >= 18));
+    get_wav_header(pb, &st->codec, size);
     
     size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
     if (size < 0)