Index: libavformat/matroskadec.c
===================================================================
--- libavformat/matroskadec.c	(revision 20973)
+++ libavformat/matroskadec.c	(working copy)
@@ -143,6 +143,11 @@
 
     AVStream *stream;
     int64_t end_timecode;
+    AVPacket *pkt2nd;
+    AVPacket *pkt3rd;
+    int64_t prev_dts;
+    int64_t prev_pts0;
+    int64_t prev_pts1;
 } MatroskaTrack;
 
 typedef struct {
@@ -1186,6 +1191,7 @@
                 track->video.display_width = track->video.pixel_width;
             if (!track->video.display_height)
                 track->video.display_height = track->video.pixel_height;
+            track->prev_pts0 = track->prev_pts1 = track->prev_dts = -1;
         } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) {
             if (!track->audio.out_samplerate)
                 track->audio.out_samplerate = track->audio.samplerate;
@@ -1716,6 +1722,42 @@
                     dynarray_add(&matroska->packets,&matroska->num_packets,pkt);
                     matroska->prev_pkt = pkt;
                 }
+
+                if (track->type == MATROSKA_TRACK_TYPE_VIDEO) {
+
+
+                    if (track->prev_dts == -1) // 1st frame
+                        pkt->dts = track->prev_dts = timecode;
+                    else if (track->prev_pts0 == -1) { // 2nd frame
+                        track->prev_dts = pkt->dts = 1;
+                        track->prev_pts0 = timecode;
+                        track->pkt2nd = pkt;
+                    }
+                    else if (track->prev_pts1 == -1) { // 3rd frame
+                        track->prev_dts = pkt->dts = 2;
+                        track->prev_pts1 = timecode;
+                        track->pkt3rd = pkt;
+                    }
+                    else {
+                        if (timecode < track->prev_pts0)
+                            pkt->dts = timecode;
+                        else {
+                            pkt->dts = track->prev_pts0;
+                            track->prev_pts0 = timecode;
+                        }
+                        if (pkt->dts > track->prev_pts1)
+                            FFSWAP(int64_t,pkt->dts,track->prev_pts1);
+                        if (track->pkt2nd && track->pkt3rd) { // recompute dts for 2nd and 3rd frame
+                            int64_t interval = (pkt->dts - track->pkt2nd->dts) / 3;
+                            track->prev_dts = track->pkt3rd->dts = pkt->dts - interval;
+                            track->pkt2nd->dts = track->pkt3rd->dts - interval;
+                            track->pkt2nd = track->pkt3rd = NULL;
+                        }
+                        if (pkt->dts <= track->prev_dts)
+                            pkt->dts = track->prev_dts + 1;
+                        track->prev_dts = pkt->dts;
+                    }
+                }
             }
 
             if (timecode != AV_NOPTS_VALUE)
Index: libavformat/utils.c
===================================================================
--- libavformat/utils.c	(revision 20973)
+++ libavformat/utils.c	(working copy)
@@ -812,7 +812,7 @@
     // some mpeg2 in mpeg-ps lack dts (issue171 / input_file.mpg)
     // we take the conservative approach and discard both
     // Note, if this is misbehaving for a H.264 file then possibly presentation_delayed is not set correctly.
-    if(delay==1 && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
+    if(delay==1 && pkt->dts && pkt->dts == pkt->pts && pkt->dts != AV_NOPTS_VALUE && presentation_delayed){
         av_log(s, AV_LOG_WARNING, "invalid dts/pts combination\n");
         pkt->dts= pkt->pts= AV_NOPTS_VALUE;
     }
@@ -2612,7 +2612,7 @@
         av_log(s, AV_LOG_ERROR,
                "st:%d error, non monotone timestamps %"PRId64" >= %"PRId64"\n",
                st->index, st->cur_dts, pkt->dts);
-        return -1;
+        pkt->dts = st->cur_dts + 1;
     }
     if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
         av_log(s, AV_LOG_ERROR, "st:%d error, pts < dts\n", st->index);
