From d0112298644ad72e0e597e223eb1b12d51f0e44d Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Tue, 25 Oct 2022 17:24:40 +0100 Subject: [PATCH 1/3] 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); From 9bc10e830169859a028c01b0b4d9126a7b0d52e7 Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Tue, 25 Oct 2022 17:39:45 +0100 Subject: [PATCH 2/3] ffmpegdecoder: add comment --- app/codec/ffmpeg/ffmpegdecoder.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 6bff06232..87f96bb8c 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -352,6 +352,8 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can bool bad_duration = false; + // Catch when ffmpeg uses its inaccurate method of duration estimation so we can + // use manual calculation if (fmt_ctx->duration_estimation_method == AVFMT_DURATION_FROM_BITRATE) { bad_duration = true; qWarning() << "Potentially bad duration estimation, using fallback. This could be slow."; From ddeab29da37b4cdd2cef1033a6f8fb1cb83b8103 Mon Sep 17 00:00:00 2001 From: Thomas Wilshaw Date: Wed, 26 Oct 2022 21:02:59 +0100 Subject: [PATCH 3/3] ffmepgdecoder: simplify code and improve vairable name --- app/codec/ffmpeg/ffmpegdecoder.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 87f96bb8c..edb37d273 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -350,14 +350,7 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can int64_t footage_duration = fmt_ctx->duration; - bool bad_duration = false; - - // Catch when ffmpeg uses its inaccurate method of duration estimation so we can - // use manual calculation - if (fmt_ctx->duration_estimation_method == AVFMT_DURATION_FROM_BITRATE) { - bad_duration = true; - qWarning() << "Potentially bad duration estimation, using fallback. This could be slow."; - } + bool duration_guessed_from_bitrate = (fmt_ctx->duration_estimation_method == AVFMT_DURATION_FROM_BITRATE); // Dump it into the Footage object for (unsigned int i=0;inb_streams;i++) { @@ -418,8 +411,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 || bad_duration) { - if (footage_duration == AV_NOPTS_VALUE || bad_duration) { + if (avstream->duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) { + if (footage_duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) { // Manually read through file for duration int64_t new_dur; @@ -477,9 +470,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 || bad_duration) { + if (avstream->duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) { // Loop through stream until we get the whole duration - if (footage_duration == AV_NOPTS_VALUE || bad_duration) { + if (footage_duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) { Instance instance; instance.Open(filename_c, avstream->index);