0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

demux_mkv: add an option for compatibility with Haali

This was requested on IRC.
This commit is contained in:
wm4 2014-11-18 23:07:20 +01:00
parent cc84f73a95
commit d51a032fd7
5 changed files with 75 additions and 0 deletions

View File

@ -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.

View File

@ -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).

View File

@ -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;

View File

@ -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 --------------------

View File

@ -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;