From d0112298644ad72e0e597e223eb1b12d51f0e44d Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Tue, 25 Oct 2022 17:24:40 +0100 Subject: [PATCH] ffmpegdecoder: Catch bad stream duration estimates For some formats, particularly mxf, FFmpeg calculates the duration of the stream incorrectly. Here we try to catch that and force Olive to use it's much slower, but correct fallback method. --- app/codec/ffmpeg/ffmpegdecoder.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index d2292f002..6bff06232 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -350,6 +350,13 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can int64_t footage_duration = fmt_ctx->duration; + bool bad_duration = false; + + if (fmt_ctx->duration_estimation_method == AVFMT_DURATION_FROM_BITRATE) { + bad_duration = true; + qWarning() << "Potentially bad duration estimation, using fallback. This could be slow."; + } + // Dump it into the Footage object for (unsigned int i=0;inb_streams;i++) { @@ -409,8 +416,8 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can if (ret >= 0) { // Check if we need a manual duration - if (avstream->duration == AV_NOPTS_VALUE) { - if (footage_duration == AV_NOPTS_VALUE) { + if (avstream->duration == AV_NOPTS_VALUE || bad_duration) { + if (footage_duration == AV_NOPTS_VALUE || bad_duration) { // Manually read through file for duration int64_t new_dur; @@ -468,9 +475,9 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can channel_layout = static_cast(av_get_default_channel_layout(avstream->codecpar->channels)); } - if (avstream->duration == AV_NOPTS_VALUE) { + if (avstream->duration == AV_NOPTS_VALUE || bad_duration) { // Loop through stream until we get the whole duration - if (footage_duration == AV_NOPTS_VALUE) { + if (footage_duration == AV_NOPTS_VALUE || bad_duration) { Instance instance; instance.Open(filename_c, avstream->index);