From 5e95b35900bb8c840169c4446634ff67982aa842 Mon Sep 17 00:00:00 2001 From: xperia64 Date: Sun, 26 Apr 2020 03:22:11 -0400 Subject: [PATCH 1/6] Update FPS to roughly match the actual 3DS rate --- src/core/dumping/ffmpeg_backend.cpp | 7 +++++-- src/core/hw/gpu.h | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/dumping/ffmpeg_backend.cpp b/src/core/dumping/ffmpeg_backend.cpp index 05cc25acf..2816190c0 100644 --- a/src/core/dumping/ffmpeg_backend.cpp +++ b/src/core/dumping/ffmpeg_backend.cpp @@ -124,8 +124,11 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout codec_context->bit_rate = Settings::values.video_bitrate; codec_context->width = layout.width; codec_context->height = layout.height; - codec_context->time_base.num = 1; - codec_context->time_base.den = 60; + // TODO(xperia64): Replace with the core timing derived refresh rate + // Verify that an FPS of 59.83... can actually be requested + // (this doesn't seem to be working currently) + codec_context->time_base.num = 1000000; + codec_context->time_base.den = 59833997; codec_context->gop_size = 12; codec_context->pix_fmt = codec->pix_fmts ? codec->pix_fmts[0] : AV_PIX_FMT_YUV420P; if (format_context->oformat->flags & AVFMT_GLOBALHEADER) diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 3252364e2..4e1c92289 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -19,7 +19,10 @@ class MemorySystem; namespace GPU { -constexpr float SCREEN_REFRESH_RATE = 60; +// TODO(xperia64): This should be defined by the number of +// ARM11 cycles per vblank interval once that value is measured +// and not the other way around +constexpr double SCREEN_REFRESH_RATE = 59.833997376556916; // Returns index corresponding to the Regs member labeled by field_name #define GPU_REG_INDEX(field_name) (offsetof(GPU::Regs, field_name) / sizeof(u32)) From 03145e307b05b238f4c7563c6a6c6807aee77002 Mon Sep 17 00:00:00 2001 From: xperia64 Date: Sun, 26 Apr 2020 18:02:25 -0400 Subject: [PATCH 2/6] Add measured frame cycles --- src/core/hw/gpu.cpp | 2 -- src/core/hw/gpu.h | 11 +++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 4f6a31441..e31ea4e5c 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -30,8 +30,6 @@ namespace GPU { Regs g_regs; Memory::MemorySystem* g_memory; -/// 268MHz CPU clocks / 60Hz frames per second -const u64 frame_ticks = static_cast(BASE_CLOCK_RATE_ARM11 / SCREEN_REFRESH_RATE); /// Event id for CoreTiming static Core::TimingEventType* vblank_event; diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h index 4e1c92289..1e49967e9 100644 --- a/src/core/hw/gpu.h +++ b/src/core/hw/gpu.h @@ -12,6 +12,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "core/core_timing.h" namespace Memory { class MemorySystem; @@ -19,10 +20,12 @@ class MemorySystem; namespace GPU { -// TODO(xperia64): This should be defined by the number of -// ARM11 cycles per vblank interval once that value is measured -// and not the other way around -constexpr double SCREEN_REFRESH_RATE = 59.833997376556916; +// Measured on hardware to be 2240568 timer cycles or 4481136 ARM11 cycles +constexpr u64 frame_ticks = 4481136ull; + +// Refresh rate defined by ratio of ARM11 frequency to ARM11 ticks per frame +// (268,111,856) / (4,481,136) = 59.83122493939037Hz +constexpr double SCREEN_REFRESH_RATE = BASE_CLOCK_RATE_ARM11 / static_cast(frame_ticks); // Returns index corresponding to the Regs member labeled by field_name #define GPU_REG_INDEX(field_name) (offsetof(GPU::Regs, field_name) / sizeof(u32)) From 016d2b08e382e14c7382d869ee51ce82006e1b95 Mon Sep 17 00:00:00 2001 From: xperia64 Date: Wed, 10 Jun 2020 19:42:23 -0400 Subject: [PATCH 3/6] Fix ffmpeg time base --- src/core/dumping/ffmpeg_backend.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/core/dumping/ffmpeg_backend.cpp b/src/core/dumping/ffmpeg_backend.cpp index 2816190c0..e097ecbc6 100644 --- a/src/core/dumping/ffmpeg_backend.cpp +++ b/src/core/dumping/ffmpeg_backend.cpp @@ -9,6 +9,7 @@ #include "common/param_package.h" #include "common/string_util.h" #include "core/dumping/ffmpeg_backend.h" +#include "core/hw/gpu.h" #include "core/settings.h" #include "video_core/renderer_base.h" #include "video_core/video_core.h" @@ -127,8 +128,8 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout // TODO(xperia64): Replace with the core timing derived refresh rate // Verify that an FPS of 59.83... can actually be requested // (this doesn't seem to be working currently) - codec_context->time_base.num = 1000000; - codec_context->time_base.den = 59833997; + codec_context->time_base.num = static_cast(GPU::frame_ticks); + codec_context->time_base.den = static_cast(BASE_CLOCK_RATE_ARM11); codec_context->gop_size = 12; codec_context->pix_fmt = codec->pix_fmts ? codec->pix_fmts[0] : AV_PIX_FMT_YUV420P; if (format_context->oformat->flags & AVFMT_GLOBALHEADER) From c63797a096a2dc159a21fb8d5f0e09b7a32670ed Mon Sep 17 00:00:00 2001 From: xperia64 Date: Wed, 10 Jun 2020 19:47:28 -0400 Subject: [PATCH 4/6] Recomment the ffmpeg backend --- src/core/dumping/ffmpeg_backend.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/dumping/ffmpeg_backend.cpp b/src/core/dumping/ffmpeg_backend.cpp index e097ecbc6..41dbd5954 100644 --- a/src/core/dumping/ffmpeg_backend.cpp +++ b/src/core/dumping/ffmpeg_backend.cpp @@ -125,9 +125,11 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout codec_context->bit_rate = Settings::values.video_bitrate; codec_context->width = layout.width; codec_context->height = layout.height; - // TODO(xperia64): Replace with the core timing derived refresh rate - // Verify that an FPS of 59.83... can actually be requested - // (this doesn't seem to be working currently) + // TODO(xperia64): While these numbers from core timing work fine, certain video codecs do not + // support the strange resulting timebase (280071/16756991); Addressing this issue would require + // resampling the video + // Known working: mjpeg, libx264 + // Known not working: mpeg2, mpeg4 codec_context->time_base.num = static_cast(GPU::frame_ticks); codec_context->time_base.den = static_cast(BASE_CLOCK_RATE_ARM11); codec_context->gop_size = 12; From c873b3838717a4a144a4d0357a7115acf59097d3 Mon Sep 17 00:00:00 2001 From: xperia64 Date: Thu, 11 Jun 2020 22:05:29 -0400 Subject: [PATCH 5/6] Update codec information --- src/core/dumping/ffmpeg_backend.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/dumping/ffmpeg_backend.cpp b/src/core/dumping/ffmpeg_backend.cpp index 41dbd5954..dc7928fe0 100644 --- a/src/core/dumping/ffmpeg_backend.cpp +++ b/src/core/dumping/ffmpeg_backend.cpp @@ -128,8 +128,8 @@ bool FFmpegVideoStream::Init(FFmpegMuxer& muxer, const Layout::FramebufferLayout // TODO(xperia64): While these numbers from core timing work fine, certain video codecs do not // support the strange resulting timebase (280071/16756991); Addressing this issue would require // resampling the video - // Known working: mjpeg, libx264 - // Known not working: mpeg2, mpeg4 + // List of codecs known broken by this change: mpeg1, mpeg2, mpeg4, libxvid + // See https://github.com/citra-emu/citra/pull/5273#issuecomment-643023325 for more information codec_context->time_base.num = static_cast(GPU::frame_ticks); codec_context->time_base.den = static_cast(BASE_CLOCK_RATE_ARM11); codec_context->gop_size = 12; From b0aa58ba56946a930f9c572fd4d3151a06882a7a Mon Sep 17 00:00:00 2001 From: xperia64 Date: Thu, 11 Jun 2020 23:29:12 -0400 Subject: [PATCH 6/6] Fix cheat frame interval --- src/core/cheats/cheats.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/cheats/cheats.cpp b/src/core/cheats/cheats.cpp index 9053b5ca6..75192f584 100644 --- a/src/core/cheats/cheats.cpp +++ b/src/core/cheats/cheats.cpp @@ -11,10 +11,11 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hle/kernel/process.h" +#include "core/hw/gpu.h" namespace Cheats { -constexpr u64 run_interval_ticks = BASE_CLOCK_RATE_ARM11 / 60; +constexpr u64 run_interval_ticks = GPU::frame_ticks; CheatEngine::CheatEngine(Core::System& system_) : system(system_) { LoadCheatFile();