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)