From ebc617882b3375883d6c214381d44b9114f23d9e Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 7 Oct 2016 22:59:39 +0200 Subject: [PATCH 1/4] VideoCommon: Drop RepeatFrameDumpFrame helper. This was needed with fixed framerate dumping. As we now synchronize the frames, the last one will just get padded. --- Source/Core/VideoBackends/D3D/Render.cpp | 2 -- Source/Core/VideoBackends/D3D12/Render.cpp | 2 -- Source/Core/VideoBackends/OGL/Render.cpp | 2 -- Source/Core/VideoCommon/RenderBase.cpp | 11 ----------- Source/Core/VideoCommon/RenderBase.h | 1 - 5 files changed, 18 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index fa0fe3581e..c298287e05 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -768,7 +768,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } @@ -778,7 +777,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index fb1740d9ac..90709bd4eb 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -711,7 +711,6 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fb_width || !fb_height) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } @@ -721,7 +720,6 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height FramebufferManager::GetXFBSource(xfb_addr, fb_stride, fb_height, &xfb_count); if ((!xfb_source_list || xfb_count == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 2f53d0e9a6..39744b5211 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1353,7 +1353,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, if (Fifo::WillSkipCurrentFrame() || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } @@ -1363,7 +1362,6 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, FramebufferManager::GetXFBSource(xfbAddr, fbStride, fbHeight, &xfbCount); if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0)) { - RepeatFrameDumpFrame(); Core::Callback_VideoCopiedToXFB(false); return; } diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 1dd07c905b..0d7d44622b 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -578,7 +578,6 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat f 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. m_frame_data.assign(data, data + image_size); if (!m_last_frame_dumped) @@ -606,16 +605,6 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat f #endif } -void Renderer::RepeatFrameDumpFrame() -{ -#if defined(HAVE_LIBAV) || defined(_WIN32) - if (SConfig::GetInstance().m_DumpFrames && m_AVI_dumping && !m_frame_data.empty()) - { - AVIDump::AddFrame(m_frame_data.data(), 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 1f648bb17b..074c508a26 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -150,7 +150,6 @@ protected: 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; From b5a91e1dfaf62924e05421de48987c105546f8ca Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 00:04:25 +0200 Subject: [PATCH 2/4] Framedumps: Add finish() function to limit memory lifetime. --- Source/Core/VideoBackends/D3D/Render.cpp | 1 + Source/Core/VideoBackends/D3D12/Render.cpp | 1 + Source/Core/VideoBackends/OGL/Render.cpp | 1 + Source/Core/VideoBackends/Vulkan/Renderer.cpp | 1 + Source/Core/VideoCommon/RenderBase.cpp | 4 ++++ Source/Core/VideoCommon/RenderBase.h | 1 + 6 files changed, 9 insertions(+) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index c298287e05..730bd731a8 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -891,6 +891,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, formatBufferDump((u8*)map.pData, image.data(), source_width, source_height, map.RowPitch); DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true); + FinishFrameData(); D3D::context->Unmap(s_screenshot_texture, 0); } diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 90709bd4eb..0646490044 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -869,6 +869,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height source_height, dst_location.PlacedFootprint.Footprint.RowPitch); DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true); + FinishFrameData(); D3D12_RANGE write_range = {}; s_screenshot_texture->Unmap(0, &write_range); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 39744b5211..27aff46e61 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1470,6 +1470,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(), AVIDump::DumpFormat::FORMAT_RGBA, true); + FinishFrameData(); } // Finish up the current frame, print some stats diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index e149e17118..c9721927de 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -497,6 +497,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height static_cast(m_screenshot_render_texture->GetWidth()), static_cast(m_screenshot_render_texture->GetHeight()), AVIDump::DumpFormat::FORMAT_RGBA); + FinishFrameData(); } } diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 0d7d44622b..6f1a581b6e 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -605,6 +605,10 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat f #endif } +void Renderer::FinishFrameData() +{ +} + 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 074c508a26..9cb957c986 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -150,6 +150,7 @@ protected: bool IsFrameDumping(); void DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, bool swap_upside_down = false); + void FinishFrameData(); static volatile bool s_bScreenshot; static std::mutex s_criticalScreenshot; From 1ef5ba0c53fc82017dbe9ec745e7eb2765a928ed Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 14:46:44 +0200 Subject: [PATCH 3/4] D3D: Skip redundant format convertions. --- Source/Core/VideoBackends/D3D/Render.cpp | 23 ++------------------- Source/Core/VideoBackends/D3D12/Render.cpp | 24 ++-------------------- 2 files changed, 4 insertions(+), 43 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 730bd731a8..9aecea08ec 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -745,22 +745,6 @@ bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle return saved_png; } -void formatBufferDump(const u8* in, u8* out, int w, int h, int p) -{ - for (int y = 0; y < h; ++y) - { - auto line = (in + (h - y - 1) * p); - for (int x = 0; x < w; ++x) - { - out[0] = line[2]; - out[1] = line[1]; - out[2] = line[0]; - out += 3; - line += 4; - } - } -} - // This function has the final picture. We adjust the aspect ratio here. void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc, float Gamma) @@ -886,11 +870,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, D3D11_MAPPED_SUBRESOURCE map; D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map); - // TODO: This convertion is not needed. Get rid of it. - std::vector image(source_width * source_height * 3); - formatBufferDump((u8*)map.pData, image.data(), source_width, source_height, map.RowPitch); - - DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true); + DumpFrameData(reinterpret_cast(map.pData), source_width, source_height, + AVIDump::DumpFormat::FORMAT_RGBA); FinishFrameData(); D3D::context->Unmap(s_screenshot_texture, 0); diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 0646490044..cd402d0ecc 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -688,22 +688,6 @@ bool Renderer::SaveScreenshot(const std::string& filename, const TargetRectangle return saved_png; } -void formatBufferDump(const u8* in, u8* out, int w, int h, int p) -{ - for (int y = 0; y < h; ++y) - { - auto line = (in + (h - y - 1) * p); - for (int x = 0; x < w; ++x) - { - out[0] = line[2]; - out[1] = line[1]; - out[2] = line[0]; - out += 3; - line += 4; - } - } -} - // This function has the final picture. We adjust the aspect ratio here. void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, const EFBRectangle& rc, float gamma) @@ -863,12 +847,8 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height D3D12_RANGE read_range = {0, dst_location.PlacedFootprint.Footprint.RowPitch * source_height}; CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map)); - // TODO: This convertion is not needed. Get rid of it. - std::vector image(source_width * source_height * 3); - formatBufferDump(static_cast(screenshot_texture_map), image.data(), source_width, - source_height, dst_location.PlacedFootprint.Footprint.RowPitch); - - DumpFrameData(image.data(), source_width, source_height, AVIDump::DumpFormat::FORMAT_BGR, true); + DumpFrameData(reinterpret_cast(screenshot_texture_map), source_width, source_height, + AVIDump::DumpFormat::FORMAT_RGBA); FinishFrameData(); D3D12_RANGE write_range = {}; From 0864ef435219dbbded3b07a8159a85731e605087 Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 8 Oct 2016 15:28:12 +0200 Subject: [PATCH 4/4] VideoCommon: Add custom stride for framedumping. --- Source/Core/VideoBackends/D3D/Render.cpp | 2 +- Source/Core/VideoBackends/D3D12/Render.cpp | 1 + Source/Core/VideoBackends/OGL/Render.cpp | 2 +- Source/Core/VideoBackends/Vulkan/Renderer.cpp | 1 + Source/Core/VideoCommon/AVIDump.cpp | 15 +++++++-------- Source/Core/VideoCommon/AVIDump.h | 4 ++-- Source/Core/VideoCommon/RenderBase.cpp | 18 ++++-------------- Source/Core/VideoCommon/RenderBase.h | 3 ++- 8 files changed, 19 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 9aecea08ec..7ee261d912 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -870,7 +870,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, D3D11_MAPPED_SUBRESOURCE map; D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map); - DumpFrameData(reinterpret_cast(map.pData), source_width, source_height, + DumpFrameData(reinterpret_cast(map.pData), source_width, source_height, map.RowPitch, AVIDump::DumpFormat::FORMAT_RGBA); FinishFrameData(); diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index cd402d0ecc..53d6eb3d7f 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -848,6 +848,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map)); DumpFrameData(reinterpret_cast(screenshot_texture_map), source_width, source_height, + dst_location.PlacedFootprint.Footprint.RowPitch, AVIDump::DumpFormat::FORMAT_RGBA); FinishFrameData(); diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 27aff46e61..4b8b638212 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -1469,7 +1469,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data()); DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(), - AVIDump::DumpFormat::FORMAT_RGBA, true); + flipped_trc.GetWidth() * 4, AVIDump::DumpFormat::FORMAT_RGBA, true); FinishFrameData(); } // Finish up the current frame, print some stats diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index c9721927de..f164f132a7 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -496,6 +496,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height DumpFrameData(reinterpret_cast(m_screenshot_readback_texture->GetMapPointer()), static_cast(m_screenshot_render_texture->GetWidth()), static_cast(m_screenshot_render_texture->GetHeight()), + static_cast(m_screenshot_readback_texture->GetRowStride()), AVIDump::DumpFormat::FORMAT_RGBA); FinishFrameData(); } diff --git a/Source/Core/VideoCommon/AVIDump.cpp b/Source/Core/VideoCommon/AVIDump.cpp index d31601d545..ab5b99c993 100644 --- a/Source/Core/VideoCommon/AVIDump.cpp +++ b/Source/Core/VideoCommon/AVIDump.cpp @@ -37,7 +37,6 @@ static AVStream* s_stream = nullptr; static AVFrame* s_src_frame = nullptr; static AVFrame* s_scaled_frame = nullptr; static AVPixelFormat s_pix_fmt = AV_PIX_FMT_BGR24; -static int s_bytes_per_pixel; static SwsContext* s_sws_context = nullptr; static int s_width; static int s_height; @@ -52,6 +51,7 @@ static AVIDump::DumpFormat s_current_format; static const u8* s_stored_frame_data; static int s_stored_frame_width; static int s_stored_frame_height; +static int s_stored_frame_stride; static void InitAVCodec() { @@ -68,12 +68,10 @@ bool AVIDump::Start(int w, int h, DumpFormat format) if (format == DumpFormat::FORMAT_BGR) { s_pix_fmt = AV_PIX_FMT_BGR24; - s_bytes_per_pixel = 3; } else { s_pix_fmt = AV_PIX_FMT_RGBA; - s_bytes_per_pixel = 4; } s_current_format = format; @@ -181,18 +179,18 @@ static void PreparePacket(AVPacket* pkt) pkt->size = 0; } -void AVIDump::AddFrame(const u8* data, int width, int height) +void AVIDump::AddFrame(const u8* data, int width, int height, int stride) { // Store current frame data in case frame dumping stops before next frame update, // but make sure that you don't store the last stored frame and check the resolution upon // closing the file or else you store recursion, and dolphins don't like recursion. if (!s_stop_dumping) { - StoreFrameData(data, width, height); + StoreFrameData(data, width, height, stride); CheckResolution(width, height); } s_src_frame->data[0] = const_cast(data); - s_src_frame->linesize[0] = width * s_bytes_per_pixel; + s_src_frame->linesize[0] = stride; s_src_frame->format = s_pix_fmt; s_src_frame->width = s_width; s_src_frame->height = s_height; @@ -267,7 +265,7 @@ void AVIDump::Stop() { s_stop_dumping = true; // Write the last stored frame just in case frame dumping stops before the next frame update - AddFrame(s_stored_frame_data, s_stored_frame_width, s_stored_frame_height); + AddFrame(s_stored_frame_data, s_stored_frame_width, s_stored_frame_height, s_stored_frame_stride); av_write_trailer(s_format_context); CloseFile(); s_file_index = 0; @@ -328,9 +326,10 @@ void AVIDump::CheckResolution(int width, int height) } } -void AVIDump::StoreFrameData(const u8* data, int width, int height) +void AVIDump::StoreFrameData(const u8* data, int width, int height, int stride) { s_stored_frame_data = data; s_stored_frame_width = width; s_stored_frame_height = height; + s_stored_frame_stride = stride; } diff --git a/Source/Core/VideoCommon/AVIDump.h b/Source/Core/VideoCommon/AVIDump.h index 6b0837f789..a3b2ef4bd5 100644 --- a/Source/Core/VideoCommon/AVIDump.h +++ b/Source/Core/VideoCommon/AVIDump.h @@ -12,7 +12,7 @@ private: static bool CreateFile(); static void CloseFile(); static void CheckResolution(int width, int height); - static void StoreFrameData(const u8* data, int width, int height); + static void StoreFrameData(const u8* data, int width, int height, int stride); public: enum class DumpFormat @@ -22,7 +22,7 @@ public: }; static bool Start(int w, int h, DumpFormat format); - static void AddFrame(const u8* data, int width, int height); + static void AddFrame(const u8* data, int width, int height, int stride); static void Stop(); static void DoState(); }; diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 6f1a581b6e..e523fd8a67 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -555,30 +555,20 @@ bool Renderer::IsFrameDumping() return false; } -void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, +void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, 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; + m_last_framedump_stride = stride; // TODO: Refactor this. Right now it's needed for the implace flipping of the image. - m_frame_data.assign(data, data + image_size); + m_frame_data.assign(data, data + stride * h); if (!m_last_frame_dumped) { @@ -598,7 +588,7 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat f { if (swap_upside_down) FlipImageData(m_frame_data.data(), w, h, 4); - AVIDump::AddFrame(m_frame_data.data(), w, h); + AVIDump::AddFrame(m_frame_data.data(), w, h, stride); } m_last_frame_dumped = true; diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 9cb957c986..9a78ce4a4b 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -148,7 +148,7 @@ protected: static void RecordVideoMemory(); bool IsFrameDumping(); - void DumpFrameData(const u8* data, int w, int h, AVIDump::DumpFormat format, + void DumpFrameData(const u8* data, int w, int h, int stride, AVIDump::DumpFormat format, bool swap_upside_down = false); void FinishFrameData(); @@ -194,6 +194,7 @@ private: bool m_last_frame_dumped = false; int m_last_framedump_width = 0; int m_last_framedump_height = 0; + int m_last_framedump_stride = 0; AVIDump::DumpFormat m_last_framedump_format; };