]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mp3dec.c
avformat/dvenc: s->streams[i] -> st
[ffmpeg] / libavformat / mp3dec.c
index dd14174e077129a6459901bf86d96d21a61c55cc..53f803ef55101b1f05ac4bd4c8b0eae2509a1f0e 100644 (file)
@@ -42,8 +42,6 @@
 
 #define XING_TOC_COUNT 100
 
-#define SAME_HEADER_MASK \
-   (0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
 
 typedef struct {
     AVClass *class;
@@ -73,7 +71,7 @@ static int mp3_read_probe(const AVProbeData *p)
     int frames, ret;
     int framesizes, max_framesizes;
     uint32_t header;
-    const uint8_t *buf, *buf0, *buf2, *end;
+    const uint8_t *buf, *buf0, *buf2, *buf3, *end;
 
     buf0 = p->buf;
     end = p->buf + p->buf_size - sizeof(uint32_t);
@@ -88,13 +86,27 @@ static int mp3_read_probe(const AVProbeData *p)
         buf2 = buf;
         for (framesizes = frames = 0; buf2 < end; frames++) {
             MPADecodeHeader h;
+            int header_emu = 0;
+            int available;
 
             header = AV_RB32(buf2);
             ret = avpriv_mpegaudio_decode_header(&h, header);
             if (ret != 0)
                 break;
-            buf2 += h.frame_size;
+
+            available = FFMIN(h.frame_size, end - buf2);
+            for (buf3 = buf2 + 4; buf3 < buf2 + available; buf3++) {
+                uint32_t next_sync = AV_RB32(buf3);
+                header_emu += (next_sync & MP3_MASK) == (header & MP3_MASK);
+            }
+            if (header_emu > 2)
+                break;
             framesizes += h.frame_size;
+            if (available < h.frame_size) {
+                frames++;
+                break;
+            }
+            buf2 += h.frame_size;
         }
         max_frames = FFMAX(max_frames, frames);
         max_framesizes = FFMAX(max_framesizes, framesizes);
@@ -243,13 +255,13 @@ static void mp3_parse_info_tag(AVFormatContext *s, AVStream *st,
 
         mp3->start_pad = v>>12;
         mp3->  end_pad = v&4095;
-        st->start_skip_samples = mp3->start_pad + 528 + 1;
+        st->internal->start_skip_samples = mp3->start_pad + 528 + 1;
         if (mp3->frames) {
-            st->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
-            st->last_discard_sample = mp3->frames * (int64_t)spf;
+            st->internal->first_discard_sample = -mp3->end_pad + 528 + 1 + mp3->frames * (int64_t)spf;
+            st->internal->last_discard_sample = mp3->frames * (int64_t)spf;
         }
         if (!st->start_time)
-            st->start_time = av_rescale_q(st->start_skip_samples,
+            st->start_time = av_rescale_q(st->internal->start_skip_samples,
                                             (AVRational){1, c->sample_rate},
                                             st->time_base);
         av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3->  end_pad);
@@ -398,7 +410,7 @@ static int mp3_read_header(AVFormatContext *s)
             ffio_ensure_seekback(s->pb, i + 1024 + frame_size + 4);
             ret = check(s->pb, off + i + frame_size, &header2);
             if (ret >= 0 &&
-                (header & SAME_HEADER_MASK) == (header2 & SAME_HEADER_MASK))
+                (header & MP3_MASK) == (header2 & MP3_MASK))
             {
                 av_log(s, i > 0 ? AV_LOG_INFO : AV_LOG_VERBOSE, "Skipping %d bytes of junk at %"PRId64".\n", i, off);
                 ret = avio_seek(s->pb, off + i, SEEK_SET);
@@ -419,8 +431,8 @@ static int mp3_read_header(AVFormatContext *s)
     }
 
     // the seek index is relative to the end of the xing vbr headers
-    for (i = 0; i < st->nb_index_entries; i++)
-        st->index_entries[i].pos += avio_tell(s->pb);
+    for (i = 0; i < st->internal->nb_index_entries; i++)
+        st->internal->index_entries[i].pos += avio_tell(s->pb);
 
     /* the parameters will be extracted from the compressed bitstream */
     return 0;
@@ -555,7 +567,7 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp,
         if (ret < 0)
             return ret;
 
-        ie = &st->index_entries[ret];
+        ie = &st->internal->index_entries[ret];
     } else if (fast_seek && st->duration > 0 && filesize > 0) {
         if (!mp3->is_cbr)
             av_log(s, AV_LOG_WARNING, "Using scaling to seek VBR MP3; may be imprecise.\n");