From d73d2dc1675d2b72a632382db641897f50edbede Mon Sep 17 00:00:00 2001 From: akarin Date: Mon, 17 Apr 2023 16:01:26 +0900 Subject: [PATCH] common/lwlibav_video.c: fix incorrect seeking in some mkvs, again It turns out not only the first frame could have invalid DTS, there are mkv files in the wild that contains first few frames with an invalid DTS. It's beyond me how mkvmerge could have created such a file given that mkv are supposed to be seeking by DTS. Next time, if you face such a mkv, you can: 1. mkvextract the video and then remux with mkvmerge to force it to recreate cue points for all IDR.. 2. add `--cue 0:all` to mkvmerge and remux the broken mkv to fix it. Fixes #14. Signed-off-by: akarin --- common/lwlibav_video.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/lwlibav_video.c b/common/lwlibav_video.c index 2807ef23..342ea82f 100644 --- a/common/lwlibav_video.c +++ b/common/lwlibav_video.c @@ -427,7 +427,10 @@ static uint32_t correct_current_frame_number uint32_t goal ) { -#define MATCH_DTS( j ) (info[j].dts == pkt->dts) +// It's possible that the first few encoded frames all have DTS AV_NOPTS_VALUE, so we really +// shouldn't stop when dts matches: at least we should fallback to checking POS if allowed. +// Also note that `j` might contain side-effects, must always evaluate it exactly once! +#define MATCH_DTS( j ) (info[j].dts == pkt->dts && (pkt->dts != AV_NOPTS_VALUE || ((vdhp->lw_seek_flags & SEEK_POS_CORRECTION) == 0))) #define MATCH_POS( j ) ((vdhp->lw_seek_flags & SEEK_POS_CORRECTION) && info[j].file_offset == pkt->pos) order_converter_t *oc = vdhp->order_converter; video_frame_info_t *info = vdhp->frame_list;