]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/wav.c
os_support: fix poll() implementation
[ffmpeg] / libavformat / wav.c
index 80915d56e61480eca12b85b4ec22b202be4cb7fb..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);
@@ -163,17 +171,17 @@ static int wav_probe(AVProbeData *p)
         return 0;
     if (!memcmp(p->buf + 8, "WAVE", 4)) {
         if (!memcmp(p->buf, "RIFF", 4))
-        /*
-          Since ACT demuxer has standard WAV header at top of it's own,
-          returning score is decreased to avoid probe conflict
-          between ACT and WAV.
-        */
-        return AVPROBE_SCORE_MAX - 1;
+            /*
+              Since ACT demuxer has standard WAV header at top of it's own,
+              returning score is decreased to avoid probe conflict
+              between ACT and WAV.
+            */
+            return AVPROBE_SCORE_MAX - 1;
         else if (!memcmp(p->buf,      "RF64", 4) &&
                  !memcmp(p->buf + 12, "ds64", 4))
             return AVPROBE_SCORE_MAX;
     }
-        return 0;
+    return 0;
 }
 
 /* wav input */
@@ -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,12 +232,31 @@ 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)
         return -1;
-    wav->data_end= url_ftell(pb) + size;
+    if (!size) {
+        wav->data_end = INT64_MAX;
+    } else
+        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;
 }
 
@@ -311,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),
@@ -397,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),