path: root/demux/demux_mkv.c
diff options
authorwm4 <wm4@nowhere>2019-05-31 14:54:29 +0200
committerwm4 <wm4@nowhere>2019-09-19 20:37:05 +0200
commitab19888ba49b52e80c1b9ba4aa305b6ee8548059 (patch)
tree2e4c39f2f3b9e86d25b70f8fb6e7b8de13ec4831 /demux/demux_mkv.c
parentaf60a45fdfbf4384d34a9ade4347eed0ca98de71 (diff)
demux_mkv: don't set keyframe flag for timestamp-less audio frames
Matroska has this weird concept of "lacing", which are really sub-blocks packed into a larger actual block. They are demuxed as individual packets, because that's what the decoder needs. Basically they're a Matroska hack to reduce per-packet muxing overhead. One problem is that these sub-blocks don't have timestamps. The timestamps need to be created from the "default duration". If this default duration isn't in the file header (or if we drop it when it has a known broken value), the resulting packets won't have a timestamp. This is an usual and weird situation, that may confuse the demuxer layer (and backward playback in particular). Fix this by not setting the keyframe flag for these. This affects only audio packets. Subtitle lacing is explicitly not supported (in theory would at least lack a way to specify durations), and video won't usually use it for real video codecs (not every frame is a "keyframe", timestamp reordering).
Diffstat (limited to 'demux/demux_mkv.c')
1 files changed, 3 insertions, 2 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 24279f7267..a98d2864e6 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -2693,14 +2693,15 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
if (!dp)
- dp->keyframe = keyframe;
dp->pos = filepos;
/* If default_duration is 0, assume no pts value is known
* for packets after the first one (rather than all pts
* values being the same). Also, don't use it for extra
* packets resulting from parsing. */
- if (i == 0 || track->default_duration)
+ if (i == 0 || track->default_duration) {
dp->pts = current_pts + i * track->default_duration;
+ dp->keyframe = keyframe;
+ }
if (stream->codec->avi_dts)
MPSWAP(double, dp->pts, dp->dts);
if (i == 0 && block_info->duration_known)