diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index cec40e0250a9cfcb19a53ef009c00f2f3b5ea27c..1221dab2d91359071c7db533b49eaffebda14938 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -39,6 +39,8 @@
 
 #define VALIDATE_INDEX_TS_THRESH 2500
 
+#define RESYNC_BUFFER_SIZE (1<<20)
+
 typedef struct FLVContext {
     const AVClass *class; ///< Class for private options.
     int trust_metadata;   ///< configure streams according onMetaData
@@ -54,6 +56,8 @@ typedef struct FLVContext {
     int validate_next;
     int validate_count;
     int searched_for_end;
+
+    uint8_t resync_buffer[2*RESYNC_BUFFER_SIZE];
 } FLVContext;
 
 static int probe(AVProbeData *p, int live)
@@ -790,6 +794,36 @@ skip:
     return ret;
 }
 
+static int resync(AVFormatContext *s)
+{
+    FLVContext *flv = s->priv_data;
+    int64_t i;
+    int64_t pos = avio_tell(s->pb);
+
+    for (i=0; !avio_feof(s->pb); i++) {
+        int j  = i & (RESYNC_BUFFER_SIZE-1);
+        int j1 = j + RESYNC_BUFFER_SIZE;
+        flv->resync_buffer[j ] =
+        flv->resync_buffer[j1] = avio_r8(s->pb);
+
+        if (i > 22) {
+            unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4);
+            if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) {
+                unsigned  size2 = AV_RB24(flv->resync_buffer + j1 - lsize2 + 1 - 4);
+                unsigned lsize1 = AV_RB32(flv->resync_buffer + j1 - lsize2 - 8);
+                if (lsize1 >= 11 && lsize1 + 8LL + lsize2 < FFMIN(i, RESYNC_BUFFER_SIZE)) {
+                    unsigned  size1 = AV_RB24(flv->resync_buffer + j1 - lsize1 + 1 - lsize2 - 8);
+                    if (size1 == lsize1 - 11 && size2  == lsize2 - 11) {
+                        avio_seek(s->pb, pos + i - lsize1 - lsize2 - 8, SEEK_SET);
+                        return 1;
+                    }
+                }
+            }
+        }
+    }
+    return AVERROR_EOF;
+}
+
 static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
 {
     FLVContext *flv = s->priv_data;
@@ -802,11 +836,14 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
     int av_uninit(sample_rate);
     AVStream *st    = NULL;
     int last = -1;
+    int orig_size;
 
+retry:
     /* pkt size is repeated at end. skip it */
     for (;; last = avio_rb32(s->pb)) {
         pos  = avio_tell(s->pb);
         type = (avio_r8(s->pb) & 0x1F);
+        orig_size =
         size = avio_rb24(s->pb);
         dts  = avio_rb24(s->pb);
         dts |= avio_r8(s->pb) << 24;
@@ -1089,7 +1126,16 @@ retry_duration:
         pkt->flags |= AV_PKT_FLAG_KEY;
 
 leave:
-    avio_skip(s->pb, 4);
+    last = avio_rb32(s->pb);
+    if (last != orig_size + 11) {
+        av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d\n", last, orig_size + 11);
+        avio_seek(s->pb, pos + 1, SEEK_SET);
+        ret = resync(s);
+        if (ret >= 0) {
+            av_free_packet(pkt);
+            goto retry;
+        }
+    }
     return ret;
 }