summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-04-04 01:43:14 +0200
committerwm4 <wm4@nowhere>2013-04-04 14:45:29 +0200
commit75afa370b9aba90be73b8acc97eb9669bc0f2133 (patch)
treeddbf1ef6a0c9008e19bd48a20511327db6f0acb2 /demux/demux_mkv.c
parentf36a5a88d0ac17e8fdc1885d2f3bf95e903d54e3 (diff)
downloadmpv-75afa370b9aba90be73b8acc97eb9669bc0f2133.tar.bz2
mpv-75afa370b9aba90be73b8acc97eb9669bc0f2133.tar.xz
demux_mkv: try to show current subtitle when seeking
Makes sure that seeking to a given time position shows the subtitle at that position. This can fail if the subtitle packet is not close enough to the seek target. Always enabled for hr-seeks, and can be manually enabled for normal seeks with --mkv-subtitle-preroll. This helps displaying subtitles correctly with ordered chapters. When switching ordered chapter segments, a seek is performed. If the subtitle is timed slightly before the start of the segment, it normally won't be demuxed. This is a problem with all seeks, but in this case normal playback is affected. Since switching segments always uses hr-seeks, the code added by this commit is always active in this situation. If no subtitles are selected or the subtitles come from an external file, the demuxer should behave exactly as before this commit.
Diffstat (limited to 'demux/demux_mkv.c')
-rw-r--r--demux/demux_mkv.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 5b178d66b9..0171b1e9a2 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -178,6 +178,7 @@ typedef struct mkv_demuxer {
uint64_t skip_to_timecode;
int v_skip_to_keyframe, a_skip_to_keyframe;
+ bool subtitle_preroll;
int num_audio_tracks;
int num_video_tracks;
@@ -2114,6 +2115,18 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
track->fix_i_bps = 0;
}
}
+ } else if (track->type == MATROSKA_TRACK_SUBTITLE
+ && track->id == demuxer->sub->id) {
+ if (tc < mkv_d->skip_to_timecode && !mkv_d->subtitle_preroll)
+ use_this_block = 0;
+ if (use_this_block) {
+ ds = demuxer->sub;
+ if (laces > 1) {
+ mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Subtitles use Matroska "
+ "lacing. This is abnormal and not supported.\n");
+ use_this_block = 0;
+ }
+ }
} else if (tc < mkv_d->skip_to_timecode)
use_this_block = 0;
else if (track->type == MATROSKA_TRACK_VIDEO
@@ -2121,14 +2134,6 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
ds = demuxer->video;
if (mkv_d->v_skip_to_keyframe)
use_this_block = keyframe;
- } else if (track->type == MATROSKA_TRACK_SUBTITLE
- && track->id == demuxer->sub->id) {
- ds = demuxer->sub;
- if (laces > 1) {
- mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Subtitles use Matroska "
- "lacing. This is abnormal and not supported.\n");
- use_this_block = 0;
- }
} else
use_this_block = 0;
@@ -2170,6 +2175,7 @@ static int handle_block(demuxer_t *demuxer, uint8_t *block, uint64_t length,
if (ds == demuxer->video) {
mkv_d->v_skip_to_keyframe = 0;
mkv_d->skip_to_timecode = 0;
+ mkv_d->subtitle_preroll = false;
} else if (ds == demuxer->audio)
mkv_d->a_skip_to_keyframe = 0;
@@ -2410,6 +2416,7 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
if (flags & SEEK_BACKWARD)
min_diff = -min_diff;
min_diff = FFMAX(min_diff, 1);
+
for (int i = 0; i < mkv_d->num_indexes; i++)
if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) {
int64_t diff =
@@ -2427,8 +2434,22 @@ static struct mkv_index *seek_with_cues(struct demuxer *demuxer, int seek_id,
}
if (index) { /* We've found an entry. */
+ uint64_t seek_pos = index->filepos;
+ if (mkv_d->subtitle_preroll && demuxer->sub->id >= 0) {
+ uint64_t prev_target = 0;
+ for (int i = 0; i < mkv_d->num_indexes; i++) {
+ if (seek_id < 0 || mkv_d->indexes[i].tnum == seek_id) {
+ uint64_t index_pos = mkv_d->indexes[i].filepos;
+ if (index_pos > prev_target && index_pos < seek_pos)
+ prev_target = index_pos;
+ }
+ }
+ if (prev_target)
+ seek_pos = prev_target;
+ }
+
mkv_d->cluster_size = mkv_d->blockgroup_size = 0;
- stream_seek(demuxer->stream, index->filepos);
+ stream_seek(demuxer->stream, seek_pos);
}
return index;
}
@@ -2445,6 +2466,7 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
if (demuxer->audio->id >= 0)
a_tnum = find_track_by_num(mkv_d, demuxer->audio->id,
MATROSKA_TRACK_AUDIO)->tnum;
+ mkv_d->subtitle_preroll = !!(flags & SEEK_SUBPREROLL);
if (!(flags & (SEEK_BACKWARD | SEEK_FORWARD))) {
if (flags & SEEK_ABSOLUTE || rel_seek_secs < 0)
flags |= SEEK_BACKWARD;