summaryrefslogtreecommitdiffstats
path: root/demux
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 /demux
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).
Diffstat (limited to 'demux')
-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;