From c720211542c2741b1b768a25a4a00ad3511be856 Mon Sep 17 00:00:00 2001 From: Martino Fontana Date: Sun, 27 Apr 2025 13:08:33 +0200 Subject: [PATCH] VideoCommon: Limit maximum denominator for MPEG4 It happened to be under the limit normally, but now that the VBI rate can be changed, that's no longer the case. --- Source/Core/VideoCommon/FrameDumpFFMpeg.cpp | 13 +++++++++---- Source/Core/VideoCommon/FrameDumpFFMpeg.h | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp index ea8bda7893..44ec0a6a27 100644 --- a/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp +++ b/Source/Core/VideoCommon/FrameDumpFFMpeg.cpp @@ -62,13 +62,13 @@ struct FrameDumpContext namespace { -AVRational GetTimeBaseForCurrentRefreshRate() +AVRational GetTimeBaseForCurrentRefreshRate(s64 max_denominator) { auto& vi = Core::System::GetInstance().GetVideoInterface(); int num; int den; av_reduce(&num, &den, int(vi.GetTargetRefreshRateDenominator()), - int(vi.GetTargetRefreshRateNumerator()), std::numeric_limits::max()); + int(vi.GetTargetRefreshRateNumerator()), max_denominator); return AVRational{num, den}; } @@ -248,11 +248,16 @@ bool FFMpegFrameDump::CreateVideoFile() return false; } + m_max_denominator = std::numeric_limits::max(); + // Force XVID FourCC for better compatibility when using H.263 if (codec->id == AV_CODEC_ID_MPEG4) + { m_context->codec->codec_tag = MKTAG('X', 'V', 'I', 'D'); + m_max_denominator = std::numeric_limits::max(); + } - const auto time_base = GetTimeBaseForCurrentRefreshRate(); + const auto time_base = GetTimeBaseForCurrentRefreshRate(m_max_denominator); INFO_LOG_FMT(FRAMEDUMP, "Creating video file: {} x {} @ {}/{} fps", m_context->width, m_context->height, time_base.den, time_base.num); @@ -535,7 +540,7 @@ FrameState FFMpegFrameDump::FetchState(u64 ticks, int frame_number) const state.frame_number = frame_number; state.savestate_index = m_savestate_index; - const auto time_base = GetTimeBaseForCurrentRefreshRate(); + const auto time_base = GetTimeBaseForCurrentRefreshRate(m_max_denominator); state.refresh_rate_num = time_base.den; state.refresh_rate_den = time_base.num; return state; diff --git a/Source/Core/VideoCommon/FrameDumpFFMpeg.h b/Source/Core/VideoCommon/FrameDumpFFMpeg.h index 8431e24274..87387b3e41 100644 --- a/Source/Core/VideoCommon/FrameDumpFFMpeg.h +++ b/Source/Core/VideoCommon/FrameDumpFFMpeg.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "Common/CommonTypes.h" @@ -62,6 +63,9 @@ private: // Used for filename generation. std::time_t m_start_time = {}; u32 m_file_index = 0; + + // Some codecs (like MPEG4) have a limit to this + int64_t m_max_denominator = std::numeric_limits::max(); }; #if !defined(HAVE_FFMPEG)