mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 20:27:23 +00:00
demux_mkv: attempt to fix rounded timestamps
There is some potential for breakage. If it happens, this might have to be disabled by default.
This commit is contained in:
parent
e9ca0b1522
commit
90d7e51643
@ -2112,6 +2112,18 @@ Demuxer
|
|||||||
will be slower (especially when playing over http), or that behavior with
|
will be slower (especially when playing over http), or that behavior with
|
||||||
broken files is much worse. So don't use this option.
|
broken files is much worse. So don't use this option.
|
||||||
|
|
||||||
|
``--demuxer-mkv-fix-timestamps=<yes|no>``
|
||||||
|
Fix rounded Matroska timestamps (enabled by default). Matroska usually
|
||||||
|
stores timestamps rounded to milliseconds. This means timestamps jitter
|
||||||
|
by some amount around the intended timestamp. mpv can correct the timestamps
|
||||||
|
based on the framerate value stored in the file: if the timestamps does
|
||||||
|
not deviate more than 1 frame (as implied by the framerate), the timestamp
|
||||||
|
is rounded to the next frame, which should undo the rounding the muxer
|
||||||
|
did.
|
||||||
|
|
||||||
|
This can break playback if the framerate value stored in the file is too
|
||||||
|
high.
|
||||||
|
|
||||||
``--demuxer-rawaudio-channels=<value>``
|
``--demuxer-rawaudio-channels=<value>``
|
||||||
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
|
Number of channels (or channel layout) if ``--demuxer=rawaudio`` is used
|
||||||
(default: stereo).
|
(default: stereo).
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include <libavutil/common.h>
|
#include <libavutil/common.h>
|
||||||
@ -190,6 +191,7 @@ struct demux_mkv_opts {
|
|||||||
int subtitle_preroll;
|
int subtitle_preroll;
|
||||||
double subtitle_preroll_secs;
|
double subtitle_preroll_secs;
|
||||||
int probe_duration;
|
int probe_duration;
|
||||||
|
int fix_timestamps;
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct m_sub_options demux_mkv_conf = {
|
const struct m_sub_options demux_mkv_conf = {
|
||||||
@ -198,11 +200,13 @@ const struct m_sub_options demux_mkv_conf = {
|
|||||||
OPT_DOUBLE("subtitle-preroll-secs", subtitle_preroll_secs,
|
OPT_DOUBLE("subtitle-preroll-secs", subtitle_preroll_secs,
|
||||||
M_OPT_MIN, .min = 0),
|
M_OPT_MIN, .min = 0),
|
||||||
OPT_FLAG("probe-video-duration", probe_duration, 0),
|
OPT_FLAG("probe-video-duration", probe_duration, 0),
|
||||||
|
OPT_FLAG("fix-timestamps", fix_timestamps, 0),
|
||||||
{0}
|
{0}
|
||||||
},
|
},
|
||||||
.size = sizeof(struct demux_mkv_opts),
|
.size = sizeof(struct demux_mkv_opts),
|
||||||
.defaults = &(const struct demux_mkv_opts){
|
.defaults = &(const struct demux_mkv_opts){
|
||||||
.subtitle_preroll_secs = 1.0,
|
.subtitle_preroll_secs = 1.0,
|
||||||
|
.fix_timestamps = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2327,6 +2331,19 @@ exit:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double fix_timestamp(demuxer_t *demuxer, mkv_track_t *track, double ts)
|
||||||
|
{
|
||||||
|
mkv_demuxer_t *mkv_d = demuxer->priv;
|
||||||
|
if (demuxer->opts->demux_mkv->fix_timestamps && track->default_duration > 0) {
|
||||||
|
// Assume that timestamps have been rounded to the timecode scale.
|
||||||
|
double quant = mkv_d->tc_scale / 1e9;
|
||||||
|
double rts = rint(ts / track->default_duration) * track->default_duration;
|
||||||
|
if (fabs(rts - ts) < quant)
|
||||||
|
ts = rts;
|
||||||
|
}
|
||||||
|
return ts;
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
|
static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
|
||||||
{
|
{
|
||||||
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
mkv_demuxer_t *mkv_d = (mkv_demuxer_t *) demuxer->priv;
|
||||||
@ -2349,7 +2366,7 @@ static int handle_block(demuxer_t *demuxer, struct block_info *block_info)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_pts = tc / 1e9 - track->codec_delay;
|
current_pts = fix_timestamp(demuxer, track, tc / 1e9) - track->codec_delay;
|
||||||
|
|
||||||
if (track->type == MATROSKA_TRACK_AUDIO) {
|
if (track->type == MATROSKA_TRACK_AUDIO) {
|
||||||
if (mkv_d->a_skip_to_keyframe)
|
if (mkv_d->a_skip_to_keyframe)
|
||||||
|
Loading…
Reference in New Issue
Block a user