]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/wavdec.c
qsv: Default PicStruct to progressive
[ffmpeg] / libavformat / wavdec.c
index 1b427117baee198f7c108f6a642c40a8ff5d6ad7..8c78666f845220fcb2b390558ff3e51f94a075c0 100644 (file)
@@ -23,6 +23,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include <stdint.h>
+
 #include "libavutil/avassert.h"
 #include "libavutil/dict.h"
 #include "libavutil/log.h"
@@ -49,6 +51,12 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag)
     return avio_rl32(pb);
 }
 
+/* RIFF chunks are always on a even offset. */
+static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence)
+{
+    return avio_seek(s, offset + (offset & 1), whence);
+}
+
 /* return the size of the found tag */
 static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
 {
@@ -61,7 +69,7 @@ static int64_t find_tag(AVIOContext *pb, uint32_t tag1)
         size = next_tag(pb, &tag);
         if (tag == tag1)
             break;
-        avio_skip(pb, size);
+        wav_seek_tag(pb, size, SEEK_CUR);
     }
     return size;
 }
@@ -73,9 +81,9 @@ 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. */
+            /* Since the ACT demuxer has a standard WAV header at the top of
+             * its own, the returned score is decreased to avoid a probe
+             * conflict between ACT and WAV. */
             return AVPROBE_SCORE_MAX - 1;
         else if (!memcmp(p->buf,      "RF64", 4) &&
                  !memcmp(p->buf + 12, "ds64", 4))
@@ -94,12 +102,12 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
     if (!*st)
         return AVERROR(ENOMEM);
 
-    ret = ff_get_wav_header(pb, (*st)->codec, size);
+    ret = ff_get_wav_header(s, pb, (*st)->codecpar, size);
     if (ret < 0)
         return ret;
     (*st)->need_parsing = AVSTREAM_PARSE_FULL;
 
-    avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
+    avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate);
 
     return 0;
 }
@@ -219,18 +227,18 @@ static int wav_read_header(AVFormatContext *s)
 
     rf64 = tag == MKTAG('R', 'F', '6', '4');
     if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
-        return -1;
+        return AVERROR_INVALIDDATA;
     avio_rl32(pb); /* file size */
     tag = avio_rl32(pb);
     if (tag != MKTAG('W', 'A', 'V', 'E'))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     if (rf64) {
         if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
-            return -1;
+            return AVERROR_INVALIDDATA;
         size = avio_rl32(pb);
         if (size < 16)
-            return -1;
+            return AVERROR_INVALIDDATA;
         avio_rl64(pb); /* RIFF size */
 
         data_size    = avio_rl64(pb);
@@ -281,7 +289,7 @@ static int wav_read_header(AVFormatContext *s)
             /* 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))
+            if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!rf64 && !size))
                 goto break_loop;
             break;
         case MKTAG('f', 'a', 'c', 't'):
@@ -307,7 +315,7 @@ static int wav_read_header(AVFormatContext *s)
 
         /* 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) {
+            wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) {
             break;
         }
     }
@@ -320,11 +328,11 @@ break_loop:
 
     avio_seek(pb, data_ofs, SEEK_SET);
 
-    if (!sample_count && st->codec->channels &&
-        av_get_bits_per_sample(st->codec->codec_id))
+    if (!sample_count && st->codecpar->channels &&
+        av_get_bits_per_sample(st->codecpar->codec_id))
         sample_count = (data_size << 3) /
-                       (st->codec->channels *
-                        (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+                       (st->codecpar->channels *
+                        (uint64_t)av_get_bits_per_sample(st->codecpar->codec_id));
     if (sample_count)
         st->duration = sample_count;
 
@@ -383,10 +391,10 @@ static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     size = MAX_SIZE;
-    if (st->codec->block_align > 1) {
-        if (size < st->codec->block_align)
-            size = st->codec->block_align;
-        size = (size / st->codec->block_align) * st->codec->block_align;
+    if (st->codecpar->block_align > 1) {
+        if (size < st->codecpar->block_align)
+            size = st->codecpar->block_align;
+        size = (size / st->codecpar->block_align) * st->codecpar->block_align;
     }
     size = FFMIN(size, left);
     ret  = av_get_packet(s->pb, pkt, size);
@@ -403,7 +411,7 @@ static int wav_read_seek(AVFormatContext *s,
     AVStream *st;
 
     st = s->streams[0];
-    switch (st->codec->codec_id) {
+    switch (st->codecpar->codec_id) {
     case AV_CODEC_ID_MP2:
     case AV_CODEC_ID_MP3:
     case AV_CODEC_ID_AC3:
@@ -467,22 +475,22 @@ static int w64_read_header(AVFormatContext *s)
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, guid_riff, 16))
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     /* riff + wave + fmt + sizes */
     if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
-        return -1;
+        return AVERROR_INVALIDDATA;
 
     avio_read(pb, guid, 16);
     if (memcmp(guid, guid_wave, 16)) {
         av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     size = find_guid(pb, guid_fmt);
     if (size < 0) {
         av_log(s, AV_LOG_ERROR, "could not find fmt guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
 
     st = avformat_new_stream(s, NULL);
@@ -490,19 +498,19 @@ static int w64_read_header(AVFormatContext *s)
         return AVERROR(ENOMEM);
 
     /* subtract chunk header size - normal wav file doesn't count it */
-    ret = ff_get_wav_header(pb, st->codec, size - 24);
+    ret = ff_get_wav_header(s, pb, st->codecpar, size - 24);
     if (ret < 0)
         return ret;
     avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
 
     st->need_parsing = AVSTREAM_PARSE_FULL;
 
-    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
 
     size = find_guid(pb, guid_data);
     if (size < 0) {
         av_log(s, AV_LOG_ERROR, "could not find data guid\n");
-        return -1;
+        return AVERROR_INVALIDDATA;
     }
     wav->data_end = avio_tell(pb) + size - 24;
     wav->w64      = 1;