Anton Khirnov skrev 2011-07-09 11:20:
From: Tomas Härdin<[email protected]>

Signed-off-by: Anton Khirnov<[email protected]>
---
  libavformat/wav.c |   49 +++++++++++++++++++++++++++++++++----------------
  1 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/libavformat/wav.c b/libavformat/wav.c
index 8a8c0b4..35ec4fb 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -298,7 +298,7 @@ static int wav_read_header(AVFormatContext *s,
      AVStream *st;
      WAVContext *wav = s->priv_data;
      int ret, got_fmt = 0;
-    int64_t next_tag_ofs;
+    int64_t next_tag_ofs, data_ofs = -1;

      /* check RIFF header */
      tag = avio_rl32(pb);
@@ -329,13 +329,13 @@ static int wav_read_header(AVFormatContext *s,
          avio_skip(pb, size - 16); /* skip rest of ds64 chunk */
      }

-
      for (;;) {
-        if (pb->eof_reached)
-            return -1;
          size = next_tag(pb,&tag);
          next_tag_ofs = avio_tell(pb) + size;

+        if (pb->eof_reached)
+            break;
+
          switch (tag) {
          case MKTAG('f', 'm', 't', ' '):
              /* only parse the first 'fmt ' tag found */
@@ -352,26 +352,43 @@ static int wav_read_header(AVFormatContext *s,
                  return AVERROR_INVALIDDATA;
              }

-            goto break_loop;
+            if (rf64) {
+                next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
+            } else {
+                data_size = size;
+                next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
+            }
+
+            data_ofs = avio_tell(pb);
+
+            /* don't look for footer metadata if we can't seek or if we don't
+             * know where the data tag ends
+             */
+            if (!pb->seekable || (!rf64&&  !size))
+                goto break_loop;
+            break;
          case MKTAG('f','a','c','t'):
              if(!sample_count)
-            sample_count = avio_rl32(pb);
+                sample_count = avio_rl32(pb);
+            break;
+        }
+
+        /* seek to next tag unless we know that we'll run into EOF */
+        if ((avio_size(pb)>  0&&  next_tag_ofs>= avio_size(pb)) ||
+            avio_seek(pb, next_tag_ofs, SEEK_SET)<  0) {
              break;
          }
-        avio_seek(pb, next_tag_ofs, SEEK_SET);
      }
  break_loop:
-    if (rf64)
-        size = data_size;
-    if (size<  0)
-        return -1;
-    if (!size) {
-        wav->data_end = INT64_MAX;
-    } else
-        wav->data_end= avio_tell(pb) + size;
+    if (data_ofs<  0) {
+        av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    avio_seek(pb, data_ofs, SEEK_SET);

      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));
+        sample_count = (data_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;

I see this patch is squashed with f86d260 in FFmpeg, which is good. Otherwise I'd complain that this patch introduced a seeking bug.
In other words, looks good.

I was about to post an almost identical rebased patch set myself, but laziness got the best of me.

/Tomas
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to