Index: libs/libavformat/mpeg.c
===================================================================
--- libs/libavformat/mpeg.c	(revision 12657)
+++ libs/libavformat/mpeg.c	(working copy)
@@ -1440,18 +1440,15 @@
 {
     MpegDemuxContext *m = s->priv_data;
     int len, size, startcode, c, flags, header_len;
-    int64_t pts, dts;
-    int64_t last_sync= url_ftell(&s->pb);
+    int64_t pts, dts, last_pos;
 
- error_redo:
-        url_fseek(&s->pb, last_sync, SEEK_SET);
+    last_pos = -1;
  redo:
         /* next start code (should be immediately after) */
         m->header_state = 0xff;
         size = MAX_SYNC_SIZE;
         startcode = find_next_start_code(&s->pb, &size, &m->header_state);
-        last_sync = url_ftell(&s->pb);
-    //printf("startcode=%x pos=0x%"PRIx64"\n", startcode, url_ftell(&s->pb));
+    //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb));
     if (startcode < 0)
         return AVERROR_IO;
     if (startcode == PACK_START_CODE)
@@ -1484,7 +1481,7 @@
     /* stuffing */
     for(;;) {
         if (len < 1)
-            goto error_redo;
+            goto redo;
         c = get_byte(&s->pb);
         len--;
         /* XXX: for mpeg1, should test only bit 7 */
@@ -1493,17 +1490,23 @@
     }
     if ((c & 0xc0) == 0x40) {
         /* buffer scale & size */
+        if (len < 2)
+            goto redo;
         get_byte(&s->pb);
         c = get_byte(&s->pb);
         len -= 2;
     }
-    if ((c & 0xe0) == 0x20) {
+    if ((c & 0xf0) == 0x20) {
+        if (len < 4)
+            goto redo;
         dts = pts = get_pts(&s->pb, c);
         len -= 4;
-        if (c & 0x10){
-            dts = get_pts(&s->pb, -1);
-            len -= 5;
-        }
+    } else if ((c & 0xf0) == 0x30) {
+        if (len < 9)
+            goto redo;
+        pts = get_pts(&s->pb, c);
+        dts = get_pts(&s->pb, -1);
+        len -= 9;
     } else if ((c & 0xc0) == 0x80) {
         /* mpeg 2 PES */
 #if 0 /* some streams have this field set for no apparent reason */
@@ -1516,36 +1519,45 @@
         header_len = get_byte(&s->pb);
         len -= 2;
         if (header_len > len)
-            goto error_redo;
-        len -= header_len;
-        if (flags & 0x80) {
+            goto redo;
+        if ((flags & 0xc0) == 0x80) {
             dts = pts = get_pts(&s->pb, -1);
+            if (header_len < 5)
+                goto redo;
             header_len -= 5;
-            if (flags & 0x40) {
-                dts = get_pts(&s->pb, -1);
-                header_len -= 5;
-            }
+            len -= 5;
+        } if ((flags & 0xc0) == 0xc0) {
+            pts = get_pts(&s->pb, -1);
+            dts = get_pts(&s->pb, -1);
+            if (header_len < 10)
+                goto redo;
+            header_len -= 10;
+            len -= 10;
         }
-        if(header_len < 0)
-            goto error_redo;
-        url_fskip(&s->pb, header_len);
+        len -= header_len;
+        while (header_len > 0) {
+            get_byte(&s->pb);
+            header_len--;
+        }
     }
     else if( c!= 0xf )
         goto redo;
 
     if (startcode == PRIVATE_STREAM_1 && !m->psm_es_type[startcode & 0xff]) {
+        if (len < 1)
+            goto redo;
         startcode = get_byte(&s->pb);
         len--;
         if (startcode >= 0x80 && startcode <= 0xbf) {
             /* audio: skip header */
+            if (len < 3)
+                goto redo;
             get_byte(&s->pb);
             get_byte(&s->pb);
             get_byte(&s->pb);
             len -= 3;
         }
     }
-    if(len<0)
-        goto error_redo;
     if(dts != AV_NOPTS_VALUE && ppos && s->build_index){
         int i;
         for(i=0; i<s->nb_streams; i++){

