AVIDump: Move CoreTiming into caller.

This commit is contained in:
degasus
2016-10-08 12:56:28 +02:00
parent a583d36c7f
commit 9f264c0872
22 changed files with 63 additions and 48 deletions

View File

@ -20,7 +20,6 @@ extern "C" {
#include "Common/MsgHandler.h"
#include "Core/ConfigManager.h"
#include "Core/CoreTiming.h"
#include "Core/HW/SystemTimers.h"
#include "Core/HW/VideoInterface.h" //for TargetRefreshRate
#include "Core/Movie.h"
@ -41,6 +40,7 @@ static SwsContext* s_sws_context = nullptr;
static int s_width;
static int s_height;
static u64 s_last_frame;
static bool s_last_frame_is_valid = false;
static bool s_start_dumping = false;
static bool s_stop_dumping = false;
static u64 s_last_pts;
@ -51,6 +51,7 @@ 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 u64 s_stored_frame_ticks;
static void InitAVCodec()
{
@ -71,7 +72,7 @@ bool AVIDump::Start(int w, int h)
s_current_width = w;
s_current_height = h;
s_last_frame = CoreTiming::GetTicks();
s_last_frame_is_valid = false;
s_last_pts = 0;
s_stop_dumping = false;
@ -169,14 +170,14 @@ static void PreparePacket(AVPacket* pkt)
pkt->size = 0;
}
void AVIDump::AddFrame(const u8* data, int width, int height, int stride)
void AVIDump::AddFrame(const u8* data, int width, int height, int stride, u64 ticks)
{
// 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, stride);
StoreFrameData(data, width, height, stride, ticks);
CheckResolution(width, height);
}
s_src_frame->data[0] = const_cast<u8*>(data);
@ -205,15 +206,20 @@ void AVIDump::AddFrame(const u8* data, int width, int height, int stride)
// Check to see if the first frame being dumped is the first frame of output from the emulator.
// This prevents an issue with starting dumping later in emulation from placing the frames
// incorrectly.
if (!s_last_frame_is_valid)
{
s_last_frame = ticks;
s_last_frame_is_valid = true;
}
if (!s_start_dumping && Movie::GetCurrentFrame() < 1)
{
delta = CoreTiming::GetTicks();
delta = ticks;
last_pts = AV_NOPTS_VALUE;
s_start_dumping = true;
}
else
{
delta = CoreTiming::GetTicks() - s_last_frame;
delta = ticks - s_last_frame;
last_pts = (s_last_pts * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond();
}
u64 pts_in_ticks = s_last_pts + delta;
@ -221,7 +227,7 @@ void AVIDump::AddFrame(const u8* data, int width, int height, int stride)
(pts_in_ticks * s_stream->codec->time_base.den) / SystemTimers::GetTicksPerSecond();
if (s_scaled_frame->pts != last_pts)
{
s_last_frame = CoreTiming::GetTicks();
s_last_frame = ticks;
s_last_pts = pts_in_ticks;
error = avcodec_encode_video2(s_stream->codec, &pkt, s_scaled_frame, &got_packet);
}
@ -255,7 +261,8 @@ 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, s_stored_frame_stride);
AddFrame(s_stored_frame_data, s_stored_frame_width, s_stored_frame_height, s_stored_frame_stride,
s_stored_frame_ticks);
av_write_trailer(s_format_context);
CloseFile();
s_file_index = 0;
@ -295,7 +302,7 @@ void AVIDump::CloseFile()
void AVIDump::DoState()
{
s_last_frame = CoreTiming::GetTicks();
s_last_frame_is_valid = false;
}
void AVIDump::CheckResolution(int width, int height)
@ -316,10 +323,11 @@ void AVIDump::CheckResolution(int width, int height)
}
}
void AVIDump::StoreFrameData(const u8* data, int width, int height, int stride)
void AVIDump::StoreFrameData(const u8* data, int width, int height, int stride, u64 ticks)
{
s_stored_frame_data = data;
s_stored_frame_width = width;
s_stored_frame_height = height;
s_stored_frame_stride = stride;
s_stored_frame_ticks = ticks;
}

View File

@ -12,11 +12,11 @@ private:
static bool CreateFile();
static void CloseFile();
static void CheckResolution(int width, int height);
static void StoreFrameData(const u8* data, int width, int height, int stride);
static void StoreFrameData(const u8* data, int width, int height, int stride, u64 ticks);
public:
static bool Start(int w, int h);
static void AddFrame(const u8* data, int width, int height, int stride);
static void AddFrame(const u8* data, int width, int height, int stride, u64 ticks);
static void Stop();
static void DoState();
};

View File

@ -135,7 +135,7 @@ void AsyncRequests::HandleEvent(const AsyncRequests::Event& e)
case Event::SWAP_EVENT:
Renderer::Swap(e.swap_event.xfbAddr, e.swap_event.fbWidth, e.swap_event.fbStride,
e.swap_event.fbHeight, rc);
e.swap_event.fbHeight, rc, e.time);
break;
case Event::BBOX_READ:

View File

@ -47,14 +47,15 @@ void VideoBackendBase::Video_ExitLoop()
}
// Run from the CPU thread (from VideoInterface.cpp)
void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight)
void VideoBackendBase::Video_BeginField(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
u64 ticks)
{
if (m_initialized && g_ActiveConfig.bUseXFB && g_renderer)
{
Fifo::SyncGPU(Fifo::SyncGPUReason::Swap);
AsyncRequests::Event e;
e.time = 0;
e.time = ticks;
e.type = AsyncRequests::Event::SWAP_EVENT;
e.swap_event.xfbAddr = xfbAddr;

View File

@ -28,6 +28,7 @@
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
#include "Core/FifoPlayer/FifoRecorder.h"
#include "Core/HW/VideoInterface.h"
#include "Core/Host.h"
@ -138,8 +139,11 @@ void Renderer::RenderToXFB(u32 xfbAddr, const EFBRectangle& sourceRc, u32 fbStri
}
else
{
// The timing is not predictable here. So try to use the XFB path to dump frames.
u64 ticks = CoreTiming::GetTicks();
// below div two to convert from bytes to pixels - it expects width, not stride
Swap(xfbAddr, fbStride / 2, fbStride / 2, fbHeight, sourceRc, Gamma);
Swap(xfbAddr, fbStride / 2, fbStride / 2, fbHeight, sourceRc, ticks, Gamma);
}
}
@ -516,10 +520,10 @@ void Renderer::RecordVideoMemory()
}
void Renderer::Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,
float Gamma)
u64 ticks, float Gamma)
{
// TODO: merge more generic parts into VideoCommon
g_renderer->SwapImpl(xfbAddr, fbWidth, fbStride, fbHeight, rc, Gamma);
g_renderer->SwapImpl(xfbAddr, fbWidth, fbStride, fbHeight, rc, ticks, Gamma);
if (XFBWrited)
g_renderer->m_fps_counter.Update();
@ -558,7 +562,8 @@ bool Renderer::IsFrameDumping()
return false;
}
void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, bool swap_upside_down)
void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, u64 ticks,
bool swap_upside_down)
{
if (w == 0 || h == 0)
return;
@ -601,7 +606,7 @@ void Renderer::DumpFrameData(const u8* data, int w, int h, int stride, bool swap
}
if (m_AVI_dumping)
{
AVIDump::AddFrame(m_frame_data.data(), w, h, stride);
AVIDump::AddFrame(m_frame_data.data(), w, h, stride, ticks);
}
m_last_frame_dumped = true;

View File

@ -123,9 +123,9 @@ public:
// Finish up the current frame, print some stats
static void Swap(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, const EFBRectangle& rc,
float Gamma = 1.0f);
u64 ticks, float Gamma = 1.0f);
virtual void SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight,
const EFBRectangle& rc, float Gamma = 1.0f) = 0;
const EFBRectangle& rc, u64 ticks, float Gamma = 1.0f) = 0;
static PEControl::PixelFormat GetPrevPixelFormat() { return prev_efb_format; }
static void StorePixelFormat(PEControl::PixelFormat new_format) { prev_efb_format = new_format; }
@ -146,7 +146,8 @@ protected:
static void RecordVideoMemory();
bool IsFrameDumping();
void DumpFrameData(const u8* data, int w, int h, int stride, bool swap_upside_down = false);
void DumpFrameData(const u8* data, int w, int h, int stride, u64 ticks,
bool swap_upside_down = false);
void FinishFrameData();
static volatile bool s_bScreenshot;

View File

@ -75,7 +75,7 @@ public:
void Video_ExitLoop();
virtual void Video_Cleanup() = 0; // called from gl/d3d thread
void Video_BeginField(u32, u32, u32, u32);
void Video_BeginField(u32, u32, u32, u32, u64);
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32);
u32 Video_GetQueryResult(PerfQueryType type);