Skip to content
Permalink
Browse files

Yell at the user if they change window size while dumping frames, and…

… some other avi dumping stuff.
  • Loading branch information
jordan-woyak authored and RachelBryk committed Feb 27, 2013
1 parent 46adbfa commit f1c990069c8d0e54f7aa079e6e2c7b785a0d56db
@@ -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<u8*>(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);

@@ -24,6 +24,8 @@
#include <stdint.h>
#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();
};

@@ -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)
@@ -147,7 +147,7 @@ class Renderer
#else
File::IOFile pFrameDump;
#endif
char* frame_data;
std::vector<u8> frame_data;
bool bLastFrameDumped;

// The framebuffer size
@@ -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<u8>().swap(frame_data);
w = h = 0;

AVIDump::Stop();
@@ -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<u8>().swap(frame_data);
w = h = 0;
AVIDump::Stop();
bAVIDumping = false;
OSD::AddMessage("Stop dumping frames to AVI", 2000);
@@ -956,20 +956,23 @@ void Renderer::SetBlendMode(bool forceUpdate)
s_blendMode = newval;
}

void DumpFrame(const std::vector<u8>& 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<std::mutex> 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<u8>().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
{

0 comments on commit f1c9900

Please sign in to comment.
You can’t perform that action at this time.