Index: libavformat/matroskadec.c
===================================================================
--- libavformat/matroskadec.c	(revision 19624)
+++ 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;
@@ -1715,6 +1723,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
+                        pkt->dts = 1;
+                        track->prev_dts = pkt->dts;
+                        track->prev_pts0 = timecode;
+                        track->pkt2nd = pkt;
+                    }
+                    else if (track->prev_pts1 == -1) { // 3rd frame
+                        pkt->dts = 2;
+                        track->prev_dts = pkt->dts;
+                        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->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)
