diff options
author | wm4 <wm4@nowhere> | 2017-03-01 16:13:15 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2017-03-01 16:13:27 +0100 |
commit | 9080e4d468d0c50c8f863a873097a7632b48a7d6 (patch) | |
tree | 9792ea61535db4171553ea13c37c4f64253fcf0e | |
parent | ee9c850a00acdae06d8fe904c382182fc049a0a0 (diff) | |
download | mpv-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.c | 21 |
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; |