From f45ddddf1cf5ec7904a83924614161e00bc10d21 Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 7 Oct 2016 20:31:51 +0200 Subject: [PATCH] VideoCommon: Add shared framedumping code. --- Source/Core/VideoCommon/RenderBase.cpp | 96 ++++++++++++++++++++++++-- Source/Core/VideoCommon/RenderBase.h | 14 +++- 2 files changed, 100 insertions(+), 10 deletions(-) diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 60375a43db..1ba81ecf2b 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -20,6 +20,7 @@ #include "Common/CommonTypes.h" #include "Common/Event.h" +#include "Common/FileUtil.h" #include "Common/Flag.h" #include "Common/Profiler.h" #include "Common/StringUtil.h" @@ -97,14 +98,10 @@ static float AspectToWidescreen(float aspect) return aspect * ((16.0f / 9.0f) / (4.0f / 3.0f)); } -Renderer::Renderer() : frame_data(), bLastFrameDumped(false) +Renderer::Renderer() { UpdateActiveConfig(); TextureCacheBase::OnConfigChanged(g_ActiveConfig); - -#if defined _WIN32 || defined HAVE_LIBAV - bAVIDumping = false; -#endif } Renderer::~Renderer() @@ -113,9 +110,14 @@ Renderer::~Renderer() prev_efb_format = PEControl::INVALID_FMT; efb_scale_numeratorX = efb_scale_numeratorY = efb_scale_denominatorX = efb_scale_denominatorY = 1; -#if defined _WIN32 || defined HAVE_LIBAV - if (SConfig::GetInstance().m_DumpFrames && bLastFrameDumped && bAVIDumping) + +#if defined(HAVE_LIBAV) || defined(_WIN32) + // Stop frame dumping if it was left enabled at shutdown time. + if (bAVIDumping) + { AVIDump::Stop(); + bAVIDumping = false; + } #endif } @@ -534,6 +536,86 @@ void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const XFBWrited = false; } +bool Renderer::IsFrameDumping() +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames) + return true; + + if (bLastFrameDumped && bAVIDumping) + { + AVIDump::Stop(); + std::vector().swap(frame_data); + m_last_framedump_width = m_last_framedump_height = 0; + bAVIDumping = false; + OSD::AddMessage("Stop dumping frames", 2000); + } + bLastFrameDumped = false; +#endif + return false; +} + +void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, + bool swap_upside_down) +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (w == 0 || h == 0) + return; + + size_t image_size; + switch (format) + { + case AVIDump::DumpFormat::FORMAT_BGR: + image_size = 3 * w * h; + break; + case AVIDump::DumpFormat::FORMAT_RGBA: + image_size = 4 * w * h; + break; + } + + m_last_framedump_width = w; + m_last_framedump_height = h; + m_last_framedump_format = format; + + // TODO: Refactor this. Right now it's needed for the implace flipping of the image. + // It's also used to repeat the last frame. + frame_data.assign(data, data + image_size); + + if (!bLastFrameDumped) + { + bAVIDumping = AVIDump::Start(w, h, format); + if (!bAVIDumping) + { + OSD::AddMessage("AVIDump Start failed", 2000); + } + else + { + OSD::AddMessage(StringFromFormat("Dumping Frames to \"%sframedump0.avi\" (%dx%d RGB24)", + File::GetUserPath(D_DUMPFRAMES_IDX).c_str(), w, h), + 2000); + } + } + if (bAVIDumping) + { + if (swap_upside_down) + FlipImageData(&frame_data[0], w, h, 4); + AVIDump::AddFrame(&frame_data[0], w, h); + } + + bLastFrameDumped = true; +#endif +} + +void Renderer::RepeatFrameDumpFrame() +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (SConfig::GetInstance().m_DumpFrames && bAVIDumping && !frame_data.empty()) + { + AVIDump::AddFrame(&frame_data[0], m_last_framedump_width, m_last_framedump_height); + } +#endif +} + void Renderer::FlipImageData(u8* data, int w, int h, int pixel_width) { for (int y = 0; y < h / 2; ++y) diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 584c8dbec6..27a8dfa089 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -23,6 +23,7 @@ #include "Common/Event.h" #include "Common/Flag.h" #include "Common/MathUtil.h" +#include "VideoCommon/AVIDump.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/FPSCounter.h" #include "VideoCommon/VideoBackendBase.h" @@ -146,14 +147,21 @@ protected: static void CheckFifoRecording(); static void RecordVideoMemory(); + bool IsFrameDumping(); + void DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, + bool swap_upside_down = false); + void RepeatFrameDumpFrame(); + static volatile bool s_bScreenshot; static std::mutex s_criticalScreenshot; static std::string s_sScreenshotName; - bool bAVIDumping; - std::vector frame_data; - bool bLastFrameDumped; + bool bAVIDumping = false; + bool bLastFrameDumped = false; + int m_last_framedump_width = 0; + int m_last_framedump_height = 0; + AVIDump::DumpFormat m_last_framedump_format; // The framebuffer size static int s_target_width;