]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/wav.c
os_support: fix poll() implementation
[ffmpeg] / libavformat / wav.c
index 5faa63edca7acd4e698b77e88bba96ee1b5744f4..4cf138c75440bff303a008d760d77ae37b9497d9 100644 (file)
@@ -23,7 +23,7 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
-#include "raw.h"
+#include "pcm.h"
 #include "riff.h"
 
 typedef struct {
@@ -95,6 +95,8 @@ static int wav_write_trailer(AVFormatContext *s)
     WAVContext    *wav = s->priv_data;
     int64_t file_size;
 
+    put_flush_packet(pb);
+
     if (!url_is_streamed(s->pb)) {
         ff_end_tag(pb, wav->data);
 
@@ -121,7 +123,7 @@ static int wav_write_trailer(AVFormatContext *s)
     return 0;
 }
 
-AVOutputFormat wav_muxer = {
+AVOutputFormat ff_wav_muxer = {
     "wav",
     NULL_IF_CONFIG_SMALL("WAV format"),
     "audio/x-wav",
@@ -138,6 +140,13 @@ AVOutputFormat wav_muxer = {
 
 
 #if CONFIG_WAV_DEMUXER
+
+static int64_t next_tag(ByteIOContext *pb, unsigned int *tag)
+{
+    *tag = get_le32(pb);
+    return get_le32(pb);
+}
+
 /* return the size of the found tag */
 static int64_t find_tag(ByteIOContext *pb, uint32_t tag1)
 {
@@ -147,8 +156,7 @@ static int64_t find_tag(ByteIOContext *pb, uint32_t tag1)
     for (;;) {
         if (url_feof(pb))
             return -1;
-        tag  = get_le32(pb);
-        size = get_le32(pb);
+        size = next_tag(pb, &tag);
         if (tag == tag1)
             break;
         url_fseek(pb, size, SEEK_CUR);
@@ -181,6 +189,7 @@ static int wav_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
 {
     int64_t size, av_uninit(data_size);
+    int64_t sample_count=0;
     int rf64;
     unsigned int tag;
     ByteIOContext *pb = s->pb;
@@ -206,6 +215,7 @@ static int wav_read_header(AVFormatContext *s,
             return -1;
         get_le64(pb); /* RIFF size */
         data_size = get_le64(pb);
+        sample_count = get_le64(pb);
         url_fskip(pb, size - 16); /* skip rest of ds64 chunk */
     }
 
@@ -222,7 +232,18 @@ static int wav_read_header(AVFormatContext *s,
 
     av_set_pts_info(st, 64, 1, st->codec->sample_rate);
 
-    size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
+    for (;;) {
+        if (url_feof(pb))
+            return -1;
+        size = next_tag(pb, &tag);
+        if (tag == MKTAG('d', 'a', 't', 'a')){
+            break;
+        }else if (tag == MKTAG('f','a','c','t') && !sample_count){
+            sample_count = get_le32(pb);
+            size -= 4;
+        }
+        url_fseek(pb, size, SEEK_CUR);
+    }
     if (rf64)
         size = data_size;
     if (size < 0)
@@ -230,7 +251,12 @@ static int wav_read_header(AVFormatContext *s,
     if (!size) {
         wav->data_end = INT64_MAX;
     } else
-    wav->data_end= url_ftell(pb) + size;
+        wav->data_end= url_ftell(pb) + size;
+
+    if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
+        sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+    if (sample_count)
+        st->duration = sample_count;
     return 0;
 }
 
@@ -314,7 +340,7 @@ static int wav_read_seek(AVFormatContext *s,
     return pcm_read_seek(s, stream_index, timestamp, flags);
 }
 
-AVInputFormat wav_demuxer = {
+AVInputFormat ff_wav_demuxer = {
     "wav",
     NULL_IF_CONFIG_SMALL("WAV format"),
     sizeof(WAVContext),
@@ -400,7 +426,7 @@ static int w64_read_header(AVFormatContext *s, AVFormatParameters *ap)
     return 0;
 }
 
-AVInputFormat w64_demuxer = {
+AVInputFormat ff_w64_demuxer = {
     "w64",
     NULL_IF_CONFIG_SMALL("Sony Wave64 format"),
     sizeof(WAVContext),