mirror of
https://github.com/mpv-player/mpv
synced 2025-02-17 13:17:13 +00:00
demux_mkv: add an option for compatibility with Haali
This was requested on IRC.
This commit is contained in:
parent
cc84f73a95
commit
d51a032fd7
@ -792,6 +792,7 @@ Property list
|
||||
|
||||
``ab-loop-a``, ``ab-loop-b`` (TW)
|
||||
Set/get A-B loop points. See corresponding options and ``ab_loop`` command.
|
||||
The special value ``no`` on either of these properties disables looping.
|
||||
|
||||
``angle`` (RW)
|
||||
Current DVD angle.
|
||||
|
@ -2070,6 +2070,13 @@ Demuxer
|
||||
``--demuxer-mkv-subtitle-preroll-secs=<value>``
|
||||
See ``--demuxer-mkv-subtitle-preroll``.
|
||||
|
||||
``--demuxer-mkv-probe-video-duration``
|
||||
When opening the file, seek to the end of it, and check what timestamp the
|
||||
last video packet has, and report that as file duration. This is strictly
|
||||
for compatibility with Haali only. In this mode, it's possible that opening
|
||||
will slower (especially when playing over http), or that behavior with
|
||||
broken files is much worse. So don't use this option.
|
||||
|
||||
``--demuxer-rawaudio-channels=<value>``
|
||||
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
|
||||
(default: stereo).
|
||||
|
@ -199,6 +199,8 @@ typedef struct mkv_demuxer {
|
||||
// (Subtitle packets added before first A/V keyframe packet is found with seek.)
|
||||
#define NUM_SUB_PREROLL_PACKETS 500
|
||||
|
||||
static void probe_last_timestamp(struct demuxer *demuxer);
|
||||
|
||||
#define AAC_SYNC_EXTENSION_TYPE 0x02b7
|
||||
static int aac_get_sample_rate_index(uint32_t sample_rate)
|
||||
{
|
||||
@ -1845,6 +1847,9 @@ static int demux_mkv_open(demuxer_t *demuxer, enum demux_check check)
|
||||
process_tags(demuxer);
|
||||
display_create_tracks(demuxer);
|
||||
|
||||
if (demuxer->opts->mkv_probe_duration)
|
||||
probe_last_timestamp(demuxer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2859,6 +2864,66 @@ static void demux_mkv_seek(demuxer_t *demuxer, double rel_seek_secs, int flags)
|
||||
demux_mkv_fill_buffer(demuxer);
|
||||
}
|
||||
|
||||
static void probe_last_timestamp(struct demuxer *demuxer)
|
||||
{
|
||||
mkv_demuxer_t *mkv_d = demuxer->priv;
|
||||
int64_t old_pos = stream_tell(demuxer->stream);
|
||||
|
||||
if (!demuxer->seekable)
|
||||
return;
|
||||
|
||||
// Pick some arbitrary video track
|
||||
int v_tnum = -1;
|
||||
for (int n = 0; n < mkv_d->num_tracks; n++) {
|
||||
if (mkv_d->tracks[n]->type == MATROSKA_TRACK_VIDEO) {
|
||||
v_tnum = mkv_d->tracks[n]->tnum;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (v_tnum < 0)
|
||||
return;
|
||||
|
||||
read_deferred_cues(demuxer);
|
||||
|
||||
if (!mkv_d->index_complete)
|
||||
return;
|
||||
|
||||
// Find last cluster that still has video packets
|
||||
int64_t target = 0;
|
||||
for (size_t i = 0; i < mkv_d->num_indexes; i++) {
|
||||
struct mkv_index *cur = &mkv_d->indexes[i];
|
||||
if (cur->tnum == v_tnum)
|
||||
target = MPMAX(target, cur->filepos);
|
||||
}
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (!stream_seek(demuxer->stream, target))
|
||||
return;
|
||||
|
||||
int64_t last_ts[STREAM_TYPE_COUNT] = {0};
|
||||
while (1) {
|
||||
struct block_info block;
|
||||
int res = read_next_block(demuxer, &block);
|
||||
if (res < 0)
|
||||
break;
|
||||
if (res > 0) {
|
||||
if (block.track && block.track->stream) {
|
||||
enum stream_type type = block.track->stream->type;
|
||||
if (last_ts[type] < block.timecode)
|
||||
last_ts[type] = block.timecode;
|
||||
}
|
||||
free_block(&block);
|
||||
}
|
||||
}
|
||||
|
||||
if (last_ts[STREAM_VIDEO])
|
||||
mkv_d->duration = last_ts[STREAM_VIDEO] / 1e9;
|
||||
|
||||
stream_seek(demuxer->stream, old_pos);
|
||||
mkv_d->cluster_start = mkv_d->cluster_end = 0;
|
||||
}
|
||||
|
||||
static int demux_mkv_control(demuxer_t *demuxer, int cmd, void *arg)
|
||||
{
|
||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||
|
@ -306,6 +306,7 @@ const m_option_t mp_opts[] = {
|
||||
OPT_FLAG("mkv-subtitle-preroll", mkv_subtitle_preroll, 0), // old alias
|
||||
OPT_DOUBLE("demuxer-mkv-subtitle-preroll-secs", mkv_subtitle_preroll_secs,
|
||||
M_OPT_MIN, .min = 0),
|
||||
OPT_FLAG("demuxer-mkv-probe-video-duration", mkv_probe_duration, 0),
|
||||
|
||||
// ------------------------- subtitles options --------------------
|
||||
|
||||
|
@ -196,6 +196,7 @@ typedef struct MPOpts {
|
||||
char *sub_demuxer_name;
|
||||
int mkv_subtitle_preroll;
|
||||
double mkv_subtitle_preroll_secs;
|
||||
int mkv_probe_duration;
|
||||
|
||||
double demuxer_min_secs_cache;
|
||||
int cache_pausing;
|
||||
|
Loading…
Reference in New Issue
Block a user