mirror of https://github.com/mpv-player/mpv
demux_mkv: cleanup: separate index creation part of seeking
Move the code to build an index and seek without using cue information from the file to a separate function.
This commit is contained in:
parent
a7b91626cf
commit
4de3f19426
|
@ -2426,6 +2426,74 @@ static int demux_mkv_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int seek_creating_index(struct demuxer *demuxer, float rel_seek_secs,
|
||||||
|
int flags)
|
||||||
|
{
|
||||||
|
struct mkv_demuxer *mkv_d = demuxer->priv;
|
||||||
|
struct stream *s = demuxer->stream;
|
||||||
|
int64_t target_tc_ns = (int64_t) (rel_seek_secs * 1e9);
|
||||||
|
if (target_tc_ns < 0)
|
||||||
|
target_tc_ns = 0;
|
||||||
|
uint64_t max_filepos = 0;
|
||||||
|
int64_t max_tc = -1;
|
||||||
|
int n = mkv_d->num_cluster_pos;
|
||||||
|
if (n > 0) {
|
||||||
|
max_filepos = mkv_d->cluster_positions[n - 1].filepos;
|
||||||
|
max_tc = mkv_d->cluster_positions[n - 1].timecode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_tc_ns > max_tc) {
|
||||||
|
if ((off_t) max_filepos > stream_tell(s))
|
||||||
|
stream_seek(s, max_filepos);
|
||||||
|
else
|
||||||
|
stream_seek(s, stream_tell(s) + mkv_d->cluster_size);
|
||||||
|
/* parse all the clusters upto target_filepos */
|
||||||
|
while (!s->eof) {
|
||||||
|
uint64_t start = stream_tell(s);
|
||||||
|
uint32_t type = ebml_read_id(s, NULL);
|
||||||
|
uint64_t len = ebml_read_length(s, NULL);
|
||||||
|
uint64_t end = stream_tell(s) + len;
|
||||||
|
if (type == MATROSKA_ID_CLUSTER) {
|
||||||
|
while (!s->eof && stream_tell(s) < end) {
|
||||||
|
if (ebml_read_id(s, NULL) == MATROSKA_ID_TIMECODE) {
|
||||||
|
uint64_t tc = ebml_read_uint(s, NULL);
|
||||||
|
tc *= mkv_d->tc_scale;
|
||||||
|
add_cluster_position(mkv_d, start, tc);
|
||||||
|
if (tc >= target_tc_ns)
|
||||||
|
goto enough_index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stream_seek(s, end);
|
||||||
|
}
|
||||||
|
enough_index:
|
||||||
|
if (s->eof)
|
||||||
|
stream_reset(s);
|
||||||
|
}
|
||||||
|
if (!mkv_d->num_cluster_pos) {
|
||||||
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] no target for seek found\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
uint64_t cluster_pos = mkv_d->cluster_positions[0].filepos;
|
||||||
|
/* Let's find the nearest cluster */
|
||||||
|
int64_t min_diff = 0xFFFFFFFFFFFFFFF;
|
||||||
|
for (int i = 0; i < mkv_d->num_cluster_pos; i++) {
|
||||||
|
int64_t diff = mkv_d->cluster_positions[i].timecode - target_tc_ns;
|
||||||
|
if (flags & SEEK_BACKWARD && diff < 0 && -diff < min_diff) {
|
||||||
|
cluster_pos = mkv_d->cluster_positions[i].filepos;
|
||||||
|
min_diff = -diff;
|
||||||
|
} else if (flags & SEEK_FORWARD
|
||||||
|
&& (diff < 0 ? -1 * diff : diff) < min_diff) {
|
||||||
|
cluster_pos = mkv_d->cluster_positions[i].filepos;
|
||||||
|
min_diff = diff < 0 ? -1 * diff : diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mkv_d->cluster_size = mkv_d->blockgroup_size = 0;
|
||||||
|
stream_seek(s, cluster_pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||||
float audio_delay, int flags)
|
float audio_delay, int flags)
|
||||||
{
|
{
|
||||||
|
@ -2462,66 +2530,8 @@ static void demux_mkv_seek(demuxer_t *demuxer, float rel_seek_secs,
|
||||||
target_timecode = 0;
|
target_timecode = 0;
|
||||||
|
|
||||||
if (mkv_d->indexes == NULL) { /* no index was found */
|
if (mkv_d->indexes == NULL) { /* no index was found */
|
||||||
int64_t target_tc_ns = (int64_t) (rel_seek_secs * 1e9);
|
if (seek_creating_index(demuxer, rel_seek_secs, flags) < 0)
|
||||||
if (target_tc_ns < 0)
|
|
||||||
target_tc_ns = 0;
|
|
||||||
uint64_t max_filepos = 0;
|
|
||||||
int64_t max_tc = -1;
|
|
||||||
int n = mkv_d->num_cluster_pos;
|
|
||||||
if (n > 0) {
|
|
||||||
max_filepos = mkv_d->cluster_positions[n - 1].filepos;
|
|
||||||
max_tc = mkv_d->cluster_positions[n - 1].timecode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target_tc_ns > max_tc) {
|
|
||||||
if ((off_t) max_filepos > stream_tell(s))
|
|
||||||
stream_seek(s, max_filepos);
|
|
||||||
else
|
|
||||||
stream_seek(s, stream_tell(s) + mkv_d->cluster_size);
|
|
||||||
/* parse all the clusters upto target_filepos */
|
|
||||||
while (!s->eof) {
|
|
||||||
uint64_t start = stream_tell(s);
|
|
||||||
uint32_t type = ebml_read_id(s, NULL);
|
|
||||||
uint64_t len = ebml_read_length(s, NULL);
|
|
||||||
uint64_t end = stream_tell(s) + len;
|
|
||||||
if (type == MATROSKA_ID_CLUSTER) {
|
|
||||||
while (!s->eof && stream_tell(s) < end) {
|
|
||||||
if (ebml_read_id(s, NULL)
|
|
||||||
== MATROSKA_ID_TIMECODE) {
|
|
||||||
uint64_t tc = ebml_read_uint(s, NULL);
|
|
||||||
tc *= mkv_d->tc_scale;
|
|
||||||
add_cluster_position(mkv_d, start, tc);
|
|
||||||
if (tc >= target_tc_ns)
|
|
||||||
goto enough_index;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stream_seek(s, end);
|
|
||||||
}
|
|
||||||
enough_index:
|
|
||||||
if (s->eof)
|
|
||||||
stream_reset(s);
|
|
||||||
}
|
|
||||||
if (!mkv_d->num_cluster_pos) {
|
|
||||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] no target for seek found\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
uint64_t cluster_pos = mkv_d->cluster_positions[0].filepos;
|
|
||||||
/* Let's find the nearest cluster */
|
|
||||||
for (i = 0; i < mkv_d->num_cluster_pos; i++) {
|
|
||||||
diff = mkv_d->cluster_positions[i].timecode - target_tc_ns;
|
|
||||||
if (flags & SEEK_BACKWARD && diff < 0 && -diff < min_diff) {
|
|
||||||
cluster_pos = mkv_d->cluster_positions[i].filepos;
|
|
||||||
min_diff = -diff;
|
|
||||||
} else if (flags & SEEK_FORWARD
|
|
||||||
&& (diff < 0 ? -1 * diff : diff) < min_diff) {
|
|
||||||
cluster_pos = mkv_d->cluster_positions[i].filepos;
|
|
||||||
min_diff = diff < 0 ? -1 * diff : diff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mkv_d->cluster_size = mkv_d->blockgroup_size = 0;
|
|
||||||
stream_seek(s, cluster_pos);
|
|
||||||
} else {
|
} else {
|
||||||
int seek_id = (demuxer->video->id < 0) ?
|
int seek_id = (demuxer->video->id < 0) ?
|
||||||
a_tnum : v_tnum;
|
a_tnum : v_tnum;
|
||||||
|
|
Loading…
Reference in New Issue