summaryrefslogtreecommitdiffstats
path: root/video/decode
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-27 21:56:46 +0200
committerwm4 <wm4@nowhere>2014-05-27 21:58:07 +0200
commit22b16a40e58d17f1de5328bb3533631b22d0f4ad (patch)
tree2b0e55a276412b61e4ce415fabe474575e503bd9 /video/decode
parent96bc188172b87aa41310fe42a1415b53e173d6a4 (diff)
downloadmpv-22b16a40e58d17f1de5328bb3533631b22d0f4ad.tar.bz2
mpv-22b16a40e58d17f1de5328bb3533631b22d0f4ad.tar.xz
video: better handling for (very) broken timestamps
Sometimes, Matroska files store monotonic PTS for h264 tracks with b-frames, which means the decoder actually returns non-monotonic PTS. Handle this with an evil trick: if DTS is missing, set it to the PTS. Then the existing logic, which deals with falling back to DTS if PTS is broken. Actually, this trick is not so evil at all, because usually, PTS has no errors, and DTS is either always set, or always unset. So this _should_ provoke no regressions (famous last words). libavformat actually does something similar: it derives DTS from PTS in ways unknown to me. The result is very broken, but it causes the DTS fallback to become active, and thus happens to work. Also, prevent the heuristic from being active if PTS is merely monotonic instead of strictly-monotonic. Non-unique PTS is broken, but we can't fallback to DTS anyway in these cases. The specific mkv file that is fixed with this commit had the following fields set: Muxing application: libebml v1.3.0 + libmatroska v1.4.1 Writing application: mkvmerge v6.7.0 ('Back to the Ground') [...] But I know that this should also fix playback of mencoder produced mkv files.
Diffstat (limited to 'video/decode')
-rw-r--r--video/decode/dec_video.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/video/decode/dec_video.c b/video/decode/dec_video.c
index ed2cf7f5eb..dcadb5e491 100644
--- a/video/decode/dec_video.c
+++ b/video/decode/dec_video.c
@@ -290,6 +290,14 @@ struct mp_image *video_decode(struct dec_video *d_video,
bool sort_pts =
(opts->user_pts_assoc_mode != 1 || d_video->header->video->avi_dts)
&& opts->correct_pts;
+
+ struct demux_packet packet_copy;
+ if (packet && packet->dts == MP_NOPTS_VALUE) {
+ packet_copy = *packet;
+ packet = &packet_copy;
+ packet->dts = packet->pts;
+ }
+
double pkt_pts = packet ? packet->pts : MP_NOPTS_VALUE;
double pkt_dts = packet ? packet->dts : MP_NOPTS_VALUE;
@@ -325,7 +333,7 @@ struct mp_image *video_decode(struct dec_video *d_video,
if (pts == MP_NOPTS_VALUE) {
d_video->codec_pts = prev_codec_pts;
- } else if (pts <= prev_codec_pts) {
+ } else if (pts < prev_codec_pts) {
d_video->num_codec_pts_problems++;
}