summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-03-01 16:13:15 +0100
committerwm4 <wm4@nowhere>2017-03-01 16:13:27 +0100
commit9080e4d468d0c50c8f863a873097a7632b48a7d6 (patch)
tree9792ea61535db4171553ea13c37c4f64253fcf0e
parentee9c850a00acdae06d8fe904c382182fc049a0a0 (diff)
downloadmpv-9080e4d468d0c50c8f863a873097a7632b48a7d6.tar.bz2
mpv-9080e4d468d0c50c8f863a873097a7632b48a7d6.tar.xz
demux_lavf: get total duration from per-track durations as fallback
Apparently fixes youtube mp4 streams if avformat_find_stream_info() is not called. Keeping audio/video track and other track durations separate is for the sake of embedded subtitle streams, where we want to include the duration of overlong subtitle streams (I think).
-rw-r--r--demux/demux_lavf.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 26833053c7..8371985419 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -1039,8 +1039,25 @@ static int demux_lavf_control(demuxer_t *demuxer, int cmd, void *arg)
switch (cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (priv->avfc->duration == 0 || priv->avfc->duration == AV_NOPTS_VALUE)
- return DEMUXER_CTRL_DONTKNOW;
+ if (priv->avfc->duration <= 0) {
+ double total_duration = 0;
+ double av_duration = 0;
+ for (int n = 0; n < priv->avfc->nb_streams; n++) {
+ AVStream *st = priv->avfc->streams[n];
+ if (st->duration <= 0)
+ continue;
+ double f_duration = st->duration * av_q2d(st->time_base);
+ total_duration = MPMAX(total_duration, f_duration);
+ if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO ||
+ st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
+ av_duration = MPMAX(av_duration, f_duration);
+ }
+ double duration = av_duration > 0 ? av_duration : total_duration;
+ if (duration <= 0)
+ return DEMUXER_CTRL_DONTKNOW;
+ *(double *)arg = duration;
+ return DEMUXER_CTRL_OK;
+ }
*((double *)arg) = (double)priv->avfc->duration / AV_TIME_BASE;
return DEMUXER_CTRL_OK;