From f1c990069c8d0e54f7aa079e6e2c7b785a0d56db Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Tue, 26 Feb 2013 20:47:48 -0500 Subject: [PATCH] Yell at the user if they change window size while dumping frames, and some other avi dumping stuff. --- Source/Core/VideoCommon/Src/AVIDump.cpp | 18 ++++- Source/Core/VideoCommon/Src/AVIDump.h | 6 +- Source/Core/VideoCommon/Src/RenderBase.cpp | 5 +- Source/Core/VideoCommon/Src/RenderBase.h | 2 +- .../Plugins/Plugin_VideoDX11/Src/Render.cpp | 25 ++++--- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 29 ++++---- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 66 ++++++++----------- 7 files changed, 73 insertions(+), 78 deletions(-) diff --git a/Source/Core/VideoCommon/Src/AVIDump.cpp b/Source/Core/VideoCommon/Src/AVIDump.cpp index c172903b5dec..8514e8bd0389 100644 --- a/Source/Core/VideoCommon/Src/AVIDump.cpp +++ b/Source/Core/VideoCommon/Src/AVIDump.cpp @@ -157,9 +157,21 @@ void AVIDump::Stop() NOTICE_LOG(VIDEO, "Stop"); } -void AVIDump::AddFrame(char *data) +void AVIDump::AddFrame(const u8* data, int w, int h) { - AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, (LPVOID) data, m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer); + static bool bShownError = false; + if ((w != m_bitmap.biWidth || h != m_bitmap.biHeight) && !bShownError) + { + PanicAlert("You have resized the window while dumping frames.\n" + "Nothing sane can be done to handle this.\n" + "Your video will likely be broken."); + bShownError=true; + + m_bitmap.biWidth = w; + m_bitmap.biHeight = h; + } + + AVIStreamWrite(m_streamCompressed, ++m_frameCount, 1, const_cast(data), m_bitmap.biSizeImage, AVIIF_KEYFRAME, NULL, &m_byteBuffer); m_totalBytes += m_byteBuffer; // Close the recording if the file is more than 2gb // VfW can't properly save files over 2gb in size, but can keep writing to them up to 4gb. @@ -298,7 +310,7 @@ bool AVIDump::CreateFile() return true; } -void AVIDump::AddFrame(uint8_t *data, int width, int height) +void AVIDump::AddFrame(const u8* data, int width, int height) { avpicture_fill((AVPicture *)s_BGRFrame, data, PIX_FMT_BGR24, width, height); diff --git a/Source/Core/VideoCommon/Src/AVIDump.h b/Source/Core/VideoCommon/Src/AVIDump.h index e74df05db468..08ab6be2542c 100644 --- a/Source/Core/VideoCommon/Src/AVIDump.h +++ b/Source/Core/VideoCommon/Src/AVIDump.h @@ -24,6 +24,8 @@ #include #endif +#include "CommonTypes.h" + class AVIDump { private: @@ -36,11 +38,11 @@ class AVIDump public: #ifdef _WIN32 static bool Start(HWND hWnd, int w, int h); - static void AddFrame(char *data); #else static bool Start(int w, int h); - static void AddFrame(uint8_t *data, int width, int height); #endif + static void AddFrame(const u8* data, int width, int height); + static void Stop(); }; diff --git a/Source/Core/VideoCommon/Src/RenderBase.cpp b/Source/Core/VideoCommon/Src/RenderBase.cpp index 8e1d012fa2d2..90a09aec4378 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.cpp +++ b/Source/Core/VideoCommon/Src/RenderBase.cpp @@ -83,7 +83,9 @@ unsigned int Renderer::efb_scale_denominatorY = 1; unsigned int Renderer::ssaa_multiplier = 1; -Renderer::Renderer() : frame_data(NULL), bLastFrameDumped(false) +Renderer::Renderer() + : frame_data() + , bLastFrameDumped(false) { UpdateActiveConfig(); TextureCache::OnConfigChanged(g_ActiveConfig); @@ -110,7 +112,6 @@ Renderer::~Renderer() if (pFrameDump.IsOpen()) pFrameDump.Close(); #endif - delete[] frame_data; } void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index 5376577cbd6e..8b5505e082ff 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -147,7 +147,7 @@ class Renderer #else File::IOFile pFrameDump; #endif - char* frame_data; + std::vector frame_data; bool bLastFrameDumped; // The framebuffer size diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index a6cb52c40fde..44f4f1b15b1a 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -761,11 +761,11 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle return SUCCEEDED(hr); } -void formatBufferDump(const char *in, char *out, int w, int h, int p) +void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { for (int y = 0; y < h; ++y) { - const u8 *line = (u8*)(in + (h - y - 1) * p); + auto line = (in + (h - y - 1) * p); for (int x = 0; x < w; ++x) { out[0] = line[2]; @@ -782,8 +782,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -794,8 +794,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -934,16 +934,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3D11_MAPPED_SUBRESOURCE map; D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map); - if (!frame_data || w != s_recordWidth || h != s_recordHeight) + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) { - delete[] frame_data; - frame_data = new char[3 * s_recordWidth * s_recordHeight]; + frame_data.resize(3 * s_recordWidth * s_recordHeight); w = s_recordWidth; h = s_recordHeight; } - char* source_ptr = (char*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch; - formatBufferDump(source_ptr, frame_data, s_recordWidth, s_recordHeight, map.RowPitch); - AVIDump::AddFrame(frame_data); + auto source_ptr = (const u8*)map.pData + GetTargetRectangle().left*4 + GetTargetRectangle().top*map.RowPitch; + formatBufferDump(source_ptr, &frame_data[0], s_recordWidth, s_recordHeight, map.RowPitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); D3D::context->Unmap(s_screenshot_texture, 0); } bLastFrameDumped = true; @@ -952,7 +951,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - SAFE_DELETE_ARRAY(frame_data); + std::vector().swap(frame_data); w = h = 0; AVIDump::Stop(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 065730980144..151d80b16f1d 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -216,11 +216,11 @@ TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc) } -void formatBufferDump(const char *in, char *out, int w, int h, int p) +void formatBufferDump(const u8* in, u8* out, int w, int h, int p) { for (int y = 0; y < h; y++) { - const char *line = in + (h - y - 1) * p; + auto line = in + (h - y - 1) * p; for (int x = 0; x < w; x++) { memcpy(out, line, 3); @@ -725,8 +725,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -737,8 +737,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if ((!xfbSourceList || xfbCount == 0) && g_ActiveConfig.bUseXFB && !g_ActiveConfig.bUseRealXFB) { - if (g_ActiveConfig.bDumpFrames && frame_data) - AVIDump::AddFrame(frame_data); + if (g_ActiveConfig.bDumpFrames && !frame_data.empty()) + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); Core::Callback_VideoCopiedToXFB(false); return; @@ -935,15 +935,14 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons D3DLOCKED_RECT rect; if (SUCCEEDED(ScreenShootMEMSurface->LockRect(&rect, GetTargetRectangle().AsRECT(), D3DLOCK_NO_DIRTY_UPDATE | D3DLOCK_NOSYSLOCK | D3DLOCK_READONLY))) { - if (!frame_data || w != s_recordWidth || h != s_recordHeight) + if (frame_data.empty() || w != s_recordWidth || h != s_recordHeight) { - delete[] frame_data; - frame_data = new char[3 * s_recordWidth * s_recordHeight]; + frame_data.resize(3 * s_recordWidth * s_recordHeight); w = s_recordWidth; h = s_recordHeight; } - formatBufferDump((const char*)rect.pBits, frame_data, s_recordWidth, s_recordHeight, rect.Pitch); - AVIDump::AddFrame(frame_data); + formatBufferDump((const u8*)rect.pBits, &frame_data[0], s_recordWidth, s_recordHeight, rect.Pitch); + AVIDump::AddFrame(&frame_data[0], fbWidth, fbHeight); ScreenShootMEMSurface->UnlockRect(); } } @@ -953,12 +952,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - if (frame_data) - { - delete[] frame_data; - frame_data = 0; - w = h = 0; - } + std::vector().swap(frame_data); + w = h = 0; AVIDump::Stop(); bAVIDumping = false; OSD::AddMessage("Stop dumping frames to AVI", 2000); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 3ff8b834ce7c..3cb44265131b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -956,20 +956,23 @@ void Renderer::SetBlendMode(bool forceUpdate) s_blendMode = newval; } +void DumpFrame(const std::vector& data, int w, int h) +{ +#if defined(HAVE_LIBAV) || defined(_WIN32) + if (g_ActiveConfig.bDumpFrames && !data.empty()) + { + AVIDump::AddFrame(&data[0], w, h); + } +#endif +} + // This function has the final picture. We adjust the aspect ratio here. void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,const EFBRectangle& rc,float Gamma) { static int w = 0, h = 0; if (g_bSkipCurrentFrame || (!XFBWrited && !g_ActiveConfig.RealXFBEnabled()) || !fbWidth || !fbHeight) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } @@ -979,14 +982,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons const XFBSourceBase* const* xfbSourceList = FramebufferManager::GetXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); if (g_ActiveConfig.VirtualXFBEnabled() && (!xfbSourceList || xfbCount == 0)) { - if (g_ActiveConfig.bDumpFrames && frame_data) - { -#ifdef _WIN32 - AVIDump::AddFrame(frame_data); -#elif defined HAVE_LIBAV - AVIDump::AddFrame((u8*)frame_data, w, h); -#endif - } + DumpFrame(frame_data, w, h); Core::Callback_VideoCopiedToXFB(false); return; } @@ -1149,16 +1145,15 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons if (g_ActiveConfig.bDumpFrames) { std::lock_guard lk(s_criticalScreenshot); - if (!frame_data || w != flipped_trc.GetWidth() || + if (frame_data.empty() || w != flipped_trc.GetWidth() || h != flipped_trc.GetHeight()) { - if (frame_data) delete[] frame_data; w = flipped_trc.GetWidth(); h = flipped_trc.GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); } glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(flipped_trc.left, flipped_trc.bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR && w > 0 && h > 0) { if (!bLastFrameDumped) @@ -1179,12 +1174,11 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons } if (bAVIDumping) { - #ifdef _WIN32 - AVIDump::AddFrame(frame_data); - #else - FlipImageData((u8*)frame_data, w, h); - AVIDump::AddFrame((u8*)frame_data, w, h); + #ifndef _WIN32 + FlipImageData(&frame_data[0], w, h); #endif + + AVIDump::AddFrame(&frame_data[0], w, h); } bLastFrameDumped = true; @@ -1196,12 +1190,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons { if (bLastFrameDumped && bAVIDumping) { - if (frame_data) - { - delete[] frame_data; - frame_data = NULL; - w = h = 0; - } + std::vector().swap(frame_data); + w = h = 0; AVIDump::Stop(); bAVIDumping = false; OSD::AddMessage("Stop dumping frames", 2000); @@ -1215,9 +1205,9 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons std::string movie_file_name; w = GetTargetRectangle().GetWidth(); h = GetTargetRectangle().GetHeight(); - frame_data = new char[3 * w * h]; + frame_data.resize(3 * w * h); glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, frame_data); + glReadPixels(GetTargetRectangle().left, GetTargetRectangle().bottom, w, h, GL_BGR, GL_UNSIGNED_BYTE, &frame_data[0]); if (GL_REPORT_ERROR() == GL_NO_ERROR) { if (!bLastFrameDumped) @@ -1228,21 +1218,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons OSD::AddMessage("Error opening framedump.raw for writing.", 2000); else { - char msg [255]; - sprintf(msg, "Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h); - OSD::AddMessage(msg, 2000); + OSD::AddMessage(StromFromFormat("Dumping Frames to \"%s\" (%dx%d RGB24)", movie_file_name.c_str(), w, h), 2000); } } if (pFrameDump) { - FlipImageData((u8*)frame_data, w, h); - pFrameDump.WriteBytes(frame_data, w * 3 * h); + FlipImageData(&frame_data[0], w, h); + pFrameDump.WriteBytes(&frame_data[0], w * 3 * h); pFrameDump.Flush(); } bLastFrameDumped = true; } - - delete[] frame_data; } else {