VideoCommon: Add custom stride for framedumping.
This commit is contained in:
parent
1ef5ba0c53
commit
0864ef4352
|
@ -870,7 +870,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
|
||||||
D3D11_MAPPED_SUBRESOURCE map;
|
D3D11_MAPPED_SUBRESOURCE map;
|
||||||
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
|
D3D::context->Map(s_screenshot_texture, 0, D3D11_MAP_READ, 0, &map);
|
||||||
|
|
||||||
DumpFrameData(reinterpret_cast<const u8*>(map.pData), source_width, source_height,
|
DumpFrameData(reinterpret_cast<const u8*>(map.pData), source_width, source_height, map.RowPitch,
|
||||||
AVIDump::DumpFormat::FORMAT_RGBA);
|
AVIDump::DumpFormat::FORMAT_RGBA);
|
||||||
FinishFrameData();
|
FinishFrameData();
|
||||||
|
|
||||||
|
|
|
@ -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));
|
CheckHR(s_screenshot_texture->Map(0, &read_range, &screenshot_texture_map));
|
||||||
|
|
||||||
DumpFrameData(reinterpret_cast<const u8*>(screenshot_texture_map), source_width, source_height,
|
DumpFrameData(reinterpret_cast<const u8*>(screenshot_texture_map), source_width, source_height,
|
||||||
|
dst_location.PlacedFootprint.Footprint.RowPitch,
|
||||||
AVIDump::DumpFormat::FORMAT_RGBA);
|
AVIDump::DumpFormat::FORMAT_RGBA);
|
||||||
FinishFrameData();
|
FinishFrameData();
|
||||||
|
|
||||||
|
|
|
@ -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());
|
flipped_trc.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, image.data());
|
||||||
|
|
||||||
DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(),
|
DumpFrameData(image.data(), flipped_trc.GetWidth(), flipped_trc.GetHeight(),
|
||||||
AVIDump::DumpFormat::FORMAT_RGBA, true);
|
flipped_trc.GetWidth() * 4, AVIDump::DumpFormat::FORMAT_RGBA, true);
|
||||||
FinishFrameData();
|
FinishFrameData();
|
||||||
}
|
}
|
||||||
// Finish up the current frame, print some stats
|
// Finish up the current frame, print some stats
|
||||||
|
|
|
@ -496,6 +496,7 @@ void Renderer::SwapImpl(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height
|
||||||
DumpFrameData(reinterpret_cast<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
|
DumpFrameData(reinterpret_cast<const u8*>(m_screenshot_readback_texture->GetMapPointer()),
|
||||||
static_cast<int>(m_screenshot_render_texture->GetWidth()),
|
static_cast<int>(m_screenshot_render_texture->GetWidth()),
|
||||||
static_cast<int>(m_screenshot_render_texture->GetHeight()),
|
static_cast<int>(m_screenshot_render_texture->GetHeight()),
|
||||||
|
static_cast<int>(m_screenshot_readback_texture->GetRowStride()),
|
||||||
AVIDump::DumpFormat::FORMAT_RGBA);
|
AVIDump::DumpFormat::FORMAT_RGBA);
|
||||||
FinishFrameData();
|
FinishFrameData();
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ static AVStream* s_stream = nullptr;
|
||||||
static AVFrame* s_src_frame = nullptr;
|
static AVFrame* s_src_frame = nullptr;
|
||||||
static AVFrame* s_scaled_frame = nullptr;
|
static AVFrame* s_scaled_frame = nullptr;
|
||||||
static AVPixelFormat s_pix_fmt = AV_PIX_FMT_BGR24;
|
static AVPixelFormat s_pix_fmt = AV_PIX_FMT_BGR24;
|
||||||
static int s_bytes_per_pixel;
|
|
||||||
static SwsContext* s_sws_context = nullptr;
|
static SwsContext* s_sws_context = nullptr;
|
||||||
static int s_width;
|
static int s_width;
|
||||||
static int s_height;
|
static int s_height;
|
||||||
|
@ -52,6 +51,7 @@ static AVIDump::DumpFormat s_current_format;
|
||||||
static const u8* s_stored_frame_data;
|
static const u8* s_stored_frame_data;
|
||||||
static int s_stored_frame_width;
|
static int s_stored_frame_width;
|
||||||
static int s_stored_frame_height;
|
static int s_stored_frame_height;
|
||||||
|
static int s_stored_frame_stride;
|
||||||
|
|
||||||
static void InitAVCodec()
|
static void InitAVCodec()
|
||||||
{
|
{
|
||||||
|
@ -68,12 +68,10 @@ bool AVIDump::Start(int w, int h, DumpFormat format)
|
||||||
if (format == DumpFormat::FORMAT_BGR)
|
if (format == DumpFormat::FORMAT_BGR)
|
||||||
{
|
{
|
||||||
s_pix_fmt = AV_PIX_FMT_BGR24;
|
s_pix_fmt = AV_PIX_FMT_BGR24;
|
||||||
s_bytes_per_pixel = 3;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s_pix_fmt = AV_PIX_FMT_RGBA;
|
s_pix_fmt = AV_PIX_FMT_RGBA;
|
||||||
s_bytes_per_pixel = 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s_current_format = format;
|
s_current_format = format;
|
||||||
|
@ -181,18 +179,18 @@ static void PreparePacket(AVPacket* pkt)
|
||||||
pkt->size = 0;
|
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,
|
// 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
|
// 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.
|
// closing the file or else you store recursion, and dolphins don't like recursion.
|
||||||
if (!s_stop_dumping)
|
if (!s_stop_dumping)
|
||||||
{
|
{
|
||||||
StoreFrameData(data, width, height);
|
StoreFrameData(data, width, height, stride);
|
||||||
CheckResolution(width, height);
|
CheckResolution(width, height);
|
||||||
}
|
}
|
||||||
s_src_frame->data[0] = const_cast<u8*>(data);
|
s_src_frame->data[0] = const_cast<u8*>(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->format = s_pix_fmt;
|
||||||
s_src_frame->width = s_width;
|
s_src_frame->width = s_width;
|
||||||
s_src_frame->height = s_height;
|
s_src_frame->height = s_height;
|
||||||
|
@ -267,7 +265,7 @@ void AVIDump::Stop()
|
||||||
{
|
{
|
||||||
s_stop_dumping = true;
|
s_stop_dumping = true;
|
||||||
// Write the last stored frame just in case frame dumping stops before the next frame update
|
// 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);
|
av_write_trailer(s_format_context);
|
||||||
CloseFile();
|
CloseFile();
|
||||||
s_file_index = 0;
|
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_data = data;
|
||||||
s_stored_frame_width = width;
|
s_stored_frame_width = width;
|
||||||
s_stored_frame_height = height;
|
s_stored_frame_height = height;
|
||||||
|
s_stored_frame_stride = stride;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ private:
|
||||||
static bool CreateFile();
|
static bool CreateFile();
|
||||||
static void CloseFile();
|
static void CloseFile();
|
||||||
static void CheckResolution(int width, int height);
|
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:
|
public:
|
||||||
enum class DumpFormat
|
enum class DumpFormat
|
||||||
|
@ -22,7 +22,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool Start(int w, int h, DumpFormat format);
|
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 Stop();
|
||||||
static void DoState();
|
static void DoState();
|
||||||
};
|
};
|
||||||
|
|
|
@ -555,30 +555,20 @@ bool Renderer::IsFrameDumping()
|
||||||
return false;
|
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)
|
bool swap_upside_down)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_LIBAV) || defined(_WIN32)
|
#if defined(HAVE_LIBAV) || defined(_WIN32)
|
||||||
if (w == 0 || h == 0)
|
if (w == 0 || h == 0)
|
||||||
return;
|
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_width = w;
|
||||||
m_last_framedump_height = h;
|
m_last_framedump_height = h;
|
||||||
m_last_framedump_format = format;
|
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.
|
// 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)
|
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)
|
if (swap_upside_down)
|
||||||
FlipImageData(m_frame_data.data(), w, h, 4);
|
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;
|
m_last_frame_dumped = true;
|
||||||
|
|
|
@ -148,7 +148,7 @@ protected:
|
||||||
static void RecordVideoMemory();
|
static void RecordVideoMemory();
|
||||||
|
|
||||||
bool IsFrameDumping();
|
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);
|
bool swap_upside_down = false);
|
||||||
void FinishFrameData();
|
void FinishFrameData();
|
||||||
|
|
||||||
|
@ -194,6 +194,7 @@ private:
|
||||||
bool m_last_frame_dumped = false;
|
bool m_last_frame_dumped = false;
|
||||||
int m_last_framedump_width = 0;
|
int m_last_framedump_width = 0;
|
||||||
int m_last_framedump_height = 0;
|
int m_last_framedump_height = 0;
|
||||||
|
int m_last_framedump_stride = 0;
|
||||||
AVIDump::DumpFormat m_last_framedump_format;
|
AVIDump::DumpFormat m_last_framedump_format;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue