mirror of https://github.com/PCSX2/pcsx2.git
Capture: Optimizations with filenames, audio, and capture mainFrame gui
*Resulting .wavs should get saved in the same location as the video file on linux *Keep gui capture state consistent regardless of the method used to start recording *Reworked mainFrame capture menu video options to route to a single toggleCapture_click function *Split GS & SPU2 recording into start & end functions
This commit is contained in:
parent
1e5e742601
commit
c60cdbba07
|
@ -133,10 +133,12 @@ void CALLBACK GSsetGameCRC(int crc, int gameoptions);
|
|||
// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done
|
||||
void CALLBACK GSsetFrameSkip(int frameskip);
|
||||
|
||||
// if start is 1, starts recording spu2 data, else stops
|
||||
// Starts recording GS frame data
|
||||
// returns a non zero value if successful
|
||||
// for now, pData is not used
|
||||
int CALLBACK GSsetupRecording(int start, void *pData);
|
||||
int CALLBACK GSsetupRecording(std::string& filename);
|
||||
|
||||
// Stops recording GS frame data
|
||||
void CALLBACK GSendRecording();
|
||||
|
||||
void CALLBACK GSreset();
|
||||
//deprecated: GSgetTitleInfo was used in PCSX2 but no plugin supported it prior to r4070:
|
||||
|
@ -183,7 +185,8 @@ typedef void(CALLBACK *_GSsetGameCRC)(int, int);
|
|||
typedef void(CALLBACK *_GSsetFrameSkip)(int frameskip);
|
||||
typedef void(CALLBACK *_GSsetVsync)(int enabled);
|
||||
typedef void(CALLBACK *_GSsetExclusive)(int isExclusive);
|
||||
typedef std::wstring*(CALLBACK *_GSsetupRecording)(int);
|
||||
typedef int(CALLBACK* _GSsetupRecording)(std::string&);
|
||||
typedef void(CALLBACK* _GSendRecording)();
|
||||
typedef void(CALLBACK *_GSreset)();
|
||||
typedef void(CALLBACK *_GSwriteCSR)(u32 value);
|
||||
typedef bool(CALLBACK *_GSmakeSnapshot)(const char *path);
|
||||
|
@ -220,6 +223,7 @@ extern _GSsetGameCRC GSsetGameCRC;
|
|||
extern _GSsetFrameSkip GSsetFrameSkip;
|
||||
extern _GSsetVsync GSsetVsync;
|
||||
extern _GSsetupRecording GSsetupRecording;
|
||||
extern _GSendRecording GSendRecording;
|
||||
extern _GSreset GSreset;
|
||||
extern _GSwriteCSR GSwriteCSR;
|
||||
#endif
|
||||
|
|
|
@ -177,6 +177,7 @@ _GSsetFrameSkip GSsetFrameSkip;
|
|||
_GSsetVsync GSsetVsync;
|
||||
_GSsetExclusive GSsetExclusive;
|
||||
_GSsetupRecording GSsetupRecording;
|
||||
_GSendRecording GSendRecording;
|
||||
_GSreset GSreset;
|
||||
_GSwriteCSR GSwriteCSR;
|
||||
#endif
|
||||
|
@ -316,6 +317,7 @@ static const LegacyApi_OptMethod s_MethMessOpt_GS[] =
|
|||
{ "GSopen2", (vMeth**)&GSopen2 },
|
||||
{ "GSreset", (vMeth**)&GSreset },
|
||||
{ "GSsetupRecording", (vMeth**)&GSsetupRecording },
|
||||
{ "GSendRecording", (vMeth**)&GSendRecording },
|
||||
{ "GSmakeSnapshot2", (vMeth**)&GSmakeSnapshot2 },
|
||||
{ "GSgifSoftReset", (vMeth**)&GSgifSoftReset },
|
||||
{ "GSreadFIFO", (vMeth**)&GSreadFIFO },
|
||||
|
|
|
@ -682,7 +682,7 @@ extern SndOutModule* mods[];
|
|||
|
||||
extern bool WavRecordEnabled;
|
||||
|
||||
extern void RecordStart(std::wstring* filename);
|
||||
extern int RecordStart(const std::string* filename);
|
||||
extern void RecordStop();
|
||||
extern void RecordWrite(const StereoOut16& sample);
|
||||
|
||||
|
|
|
@ -110,28 +110,27 @@ bool WavRecordEnabled = false;
|
|||
static WavOutFile* m_wavrecord = nullptr;
|
||||
static Mutex WavRecordMutex;
|
||||
|
||||
void RecordStart(std::wstring* filename)
|
||||
int RecordStart(const std::string* filename)
|
||||
{
|
||||
WavRecordEnabled = false;
|
||||
|
||||
try
|
||||
{
|
||||
ScopedLock lock(WavRecordMutex);
|
||||
safe_delete(m_wavrecord);
|
||||
#ifdef _WIN32
|
||||
if (filename)
|
||||
m_wavrecord = new WavOutFile((*filename) + "wav", 48000, 16, 2);
|
||||
m_wavrecord = new WavOutFile(filename->c_str(), 48000, 16, 2);
|
||||
else
|
||||
m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2);
|
||||
#elif defined(__unix__)
|
||||
m_wavrecord = new WavOutFile("audio_recording.wav", 48000, 16, 2);
|
||||
#endif
|
||||
WavRecordEnabled = true;
|
||||
return 1;
|
||||
}
|
||||
catch (std::runtime_error&)
|
||||
{
|
||||
m_wavrecord = nullptr; // not needed, but what the heck. :)
|
||||
SysMessage("SPU2 couldn't open file for recording: %s.\nRecording to wavfile disabled.", "audio_recording.wav");
|
||||
if (filename)
|
||||
SysMessage("SPU2-X couldn't open file for recording: %s.\nWavfile capture disabled.", filename->c_str());
|
||||
else
|
||||
SysMessage("SPU2-X couldn't open file for recording: audio_recording.wav.\nWavfile capture disabled.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -578,17 +578,16 @@ void SPU2write(u32 rmem, u16 value)
|
|||
}
|
||||
}
|
||||
|
||||
// if start is 1, starts recording spu2 data, else stops
|
||||
// returns a non zero value if successful
|
||||
// for now, pData is not used
|
||||
int SPU2setupRecording(int start, std::wstring* filename)
|
||||
int SPU2setupRecording(const std::string* filename)
|
||||
{
|
||||
if (start == 0)
|
||||
RecordStop();
|
||||
else if (start == 1)
|
||||
RecordStart(filename);
|
||||
return RecordStart(filename);
|
||||
}
|
||||
|
||||
return 0;
|
||||
void SPU2endRecording()
|
||||
{
|
||||
if (WavRecordEnabled)
|
||||
RecordStop();
|
||||
}
|
||||
|
||||
s32 SPU2freeze(int mode, freezeData* data)
|
||||
|
|
|
@ -31,10 +31,9 @@ void SPU2write(u32 mem, u16 value);
|
|||
u16 SPU2read(u32 mem);
|
||||
|
||||
// extended funcs
|
||||
// if start is 1, starts recording spu2 data, else stops
|
||||
// returns a non zero value if successful
|
||||
// for now, pData is not used
|
||||
int SPU2setupRecording(int start, std::wstring* filename);
|
||||
int SPU2setupRecording(const std::string* filename);
|
||||
void SPU2endRecording();
|
||||
|
||||
void SPU2setClockPtr(u32* ptr);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ uint renderswitch_delay = 0;
|
|||
|
||||
extern bool switchAR;
|
||||
|
||||
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
|
||||
static bool g_Pcsx2Recording = false; // true if recording video and sound
|
||||
|
||||
|
||||
KeyAcceleratorCode::KeyAcceleratorCode(const wxKeyEvent& evt)
|
||||
|
@ -450,9 +450,14 @@ namespace Implementations
|
|||
ScopedCoreThreadPause paused_core;
|
||||
paused_core.AllowResume();
|
||||
|
||||
g_Pcsx2Recording ^= 1;
|
||||
if (wxGetApp().HasGUI())
|
||||
{
|
||||
sMainFrame.VideoCaptureToggle();
|
||||
return;
|
||||
}
|
||||
|
||||
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
|
||||
g_Pcsx2Recording = !g_Pcsx2Recording;
|
||||
if (g_Pcsx2Recording)
|
||||
{
|
||||
// start recording
|
||||
|
@ -469,23 +474,17 @@ namespace Implementations
|
|||
if (GSsetupRecording)
|
||||
{
|
||||
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens.
|
||||
std::wstring* filename = nullptr;
|
||||
if (filename = GSsetupRecording(g_Pcsx2Recording))
|
||||
{
|
||||
SPU2setupRecording(g_Pcsx2Recording, filename);
|
||||
delete filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
// recording dialog canceled by the user. align our state
|
||||
g_Pcsx2Recording ^= 1;
|
||||
}
|
||||
std::string filename;
|
||||
if (GSsetupRecording(filename))
|
||||
// Note: Add a dialog box here (or in the function) that prompts the user to answer whether a failed
|
||||
// SPU2 recording setup should still lead to the visuals being recorded.
|
||||
SPU2setupRecording(&filename);
|
||||
else // recording dialog canceled by the user. align our state
|
||||
g_Pcsx2Recording = false;
|
||||
}
|
||||
// the GS doesn't support recording
|
||||
else
|
||||
{
|
||||
// the GS doesn't support recording
|
||||
SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
}
|
||||
g_Pcsx2Recording = SPU2setupRecording(nullptr);
|
||||
|
||||
if (GetMainFramePtr() && needsMainFrameEnable)
|
||||
GetMainFramePtr()->Enable();
|
||||
|
@ -493,9 +492,9 @@ namespace Implementations
|
|||
else
|
||||
{
|
||||
// stop recording
|
||||
if (GSsetupRecording)
|
||||
GSsetupRecording(g_Pcsx2Recording);
|
||||
SPU2setupRecording(g_Pcsx2Recording, NULL);
|
||||
if (GSendRecording)
|
||||
GSendRecording();
|
||||
SPU2endRecording();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,8 +289,8 @@ void MainEmuFrame::ConnectMenus()
|
|||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Debug_Open_Click, this, MenuId_Debug_Open);
|
||||
|
||||
// Capture
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_Record_Click, this, MenuId_Capture_Video_Record);
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_Stop_Click, this, MenuId_Capture_Video_Stop);
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click, this, MenuId_Capture_Video_Record);
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click, this, MenuId_Capture_Video_Stop);
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Screenshot_Screenshot_Click, this, MenuId_Capture_Screenshot_Screenshot);
|
||||
Bind(wxEVT_MENU, &MainEmuFrame::Menu_Capture_Screenshot_Screenshot_As_Click, this, MenuId_Capture_Screenshot_Screenshot_As);
|
||||
|
||||
|
@ -573,6 +573,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
|
|||
|
||||
{
|
||||
m_RestartEmuOnDelete = false;
|
||||
m_capturingVideo = false;
|
||||
|
||||
for (int i = 0; i < PluginId_Count; ++i)
|
||||
m_PluginMenuPacks[i].Populate((PluginsEnum_t)i);
|
||||
|
|
|
@ -172,6 +172,7 @@ public:
|
|||
void CommitPreset_noTrigger();
|
||||
void AppendShortcutToMenuOption(wxMenuItem& item, wxString keyCodeStr);
|
||||
void UpdateStatusBar();
|
||||
void VideoCaptureToggle();
|
||||
#ifndef DISABLE_RECORDING
|
||||
void initializeRecordingMenuItem(MenuIdentifiers menuId, wxString keyCodeStr, bool enable = true);
|
||||
void enableRecordingMenuItem(MenuIdentifiers menuId, bool enable);
|
||||
|
@ -252,9 +253,7 @@ protected:
|
|||
void Menu_Wiki(wxCommandEvent& event);
|
||||
void Menu_ShowAboutBox(wxCommandEvent& event);
|
||||
|
||||
void Menu_Capture_Video_Record_Click(wxCommandEvent& event);
|
||||
void Menu_Capture_Video_Stop_Click(wxCommandEvent& event);
|
||||
void VideoCaptureUpdate();
|
||||
void Menu_Capture_Video_ToggleCapture_Click(wxCommandEvent& event);
|
||||
void Menu_Capture_Screenshot_Screenshot_Click(wxCommandEvent& event);
|
||||
void Menu_Capture_Screenshot_Screenshot_As_Click(wxCommandEvent& event);
|
||||
|
||||
|
|
|
@ -848,27 +848,17 @@ void MainEmuFrame::Menu_ShowAboutBox(wxCommandEvent& event)
|
|||
AppOpenDialog<AboutBoxDialog>(this);
|
||||
}
|
||||
|
||||
void MainEmuFrame::Menu_Capture_Video_Record_Click(wxCommandEvent& event)
|
||||
void MainEmuFrame::Menu_Capture_Video_ToggleCapture_Click(wxCommandEvent& event)
|
||||
{
|
||||
ScopedCoreThreadPause paused_core;
|
||||
paused_core.AllowResume();
|
||||
|
||||
m_capturingVideo = true;
|
||||
VideoCaptureUpdate();
|
||||
VideoCaptureToggle();
|
||||
}
|
||||
|
||||
void MainEmuFrame::Menu_Capture_Video_Stop_Click(wxCommandEvent& event)
|
||||
{
|
||||
ScopedCoreThreadPause paused_core;
|
||||
paused_core.AllowResume();
|
||||
|
||||
m_capturingVideo = false;
|
||||
VideoCaptureUpdate();
|
||||
}
|
||||
|
||||
void MainEmuFrame::VideoCaptureUpdate()
|
||||
void MainEmuFrame::VideoCaptureToggle()
|
||||
{
|
||||
GetMTGS().WaitGS(); // make sure GS is in sync with the audio stream when we start.
|
||||
m_capturingVideo = !m_capturingVideo;
|
||||
if (m_capturingVideo)
|
||||
{
|
||||
// start recording
|
||||
|
@ -876,20 +866,23 @@ void MainEmuFrame::VideoCaptureUpdate()
|
|||
// make the recording setup dialog[s] pseudo-modal also for the main PCSX2 window
|
||||
// (the GSdx dialog is already properly modal for the GS window)
|
||||
bool needsMainFrameEnable = false;
|
||||
if (GetMainFramePtr() && GetMainFramePtr()->IsEnabled())
|
||||
if (IsEnabled())
|
||||
{
|
||||
needsMainFrameEnable = true;
|
||||
GetMainFramePtr()->Disable();
|
||||
Disable();
|
||||
}
|
||||
|
||||
if (GSsetupRecording)
|
||||
{
|
||||
// GSsetupRecording can be aborted/canceled by the user. Don't go on to record the audio if that happens
|
||||
std::wstring* filename = nullptr;
|
||||
if (filename = GSsetupRecording(m_capturingVideo))
|
||||
std::string filename;
|
||||
if (GSsetupRecording(filename))
|
||||
{
|
||||
SPU2setupRecording(m_capturingVideo, filename);
|
||||
delete filename;
|
||||
// Note: Add a dialog box here (or in the function) that prompts the user to answer whether a failed
|
||||
// SPU2 recording setup should still lead to the visuals being recorded.
|
||||
SPU2setupRecording(&filename);
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, false);
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -900,29 +893,26 @@ void MainEmuFrame::VideoCaptureUpdate()
|
|||
else
|
||||
{
|
||||
// the GS doesn't support recording.
|
||||
SPU2setupRecording(m_capturingVideo, nullptr);
|
||||
if (SPU2setupRecording(nullptr))
|
||||
{
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, false);
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, true);
|
||||
}
|
||||
else
|
||||
m_capturingVideo = false;
|
||||
}
|
||||
|
||||
if (GetMainFramePtr() && needsMainFrameEnable)
|
||||
GetMainFramePtr()->Enable();
|
||||
if (needsMainFrameEnable)
|
||||
Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
// stop recording
|
||||
if (GSsetupRecording)
|
||||
GSsetupRecording(m_capturingVideo);
|
||||
SPU2setupRecording(m_capturingVideo, nullptr);
|
||||
}
|
||||
|
||||
if (m_capturingVideo)
|
||||
{
|
||||
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(false);
|
||||
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Record)->Enable(true);
|
||||
m_submenuVideoCapture.FindItem(MenuId_Capture_Video_Stop)->Enable(false);
|
||||
if (GSendRecording)
|
||||
GSendRecording();
|
||||
SPU2endRecording();
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Record, true);
|
||||
m_submenuVideoCapture.Enable(MenuId_Capture_Video_Stop, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -677,7 +677,11 @@ EXPORT_C_(uint32) GSmakeSnapshot(char* path)
|
|||
{
|
||||
// Allows for providing a complete path
|
||||
std::string extension = s.substr(s.size() - 4, 4);
|
||||
#ifdef _WIN32
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), (char(_cdecl*)(int))tolower);
|
||||
#else
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), tolower);
|
||||
#endif
|
||||
if (extension == ".png")
|
||||
return s_gs->MakeSnapshot(s);
|
||||
else if (s[s.length() - 1] != DIRECTORY_SEPARATOR)
|
||||
|
@ -807,41 +811,36 @@ void pt(const char* str){
|
|||
printf("%02i:%02i:%02i%s", current->tm_hour, current->tm_min, current->tm_sec, str);
|
||||
}
|
||||
|
||||
EXPORT_C_(std::wstring*) GSsetupRecording(int start)
|
||||
EXPORT_C_(int) GSsetupRecording(std::string& filename)
|
||||
{
|
||||
if (s_gs == NULL) {
|
||||
printf("GSdx: no s_gs for recording\n");
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
#if defined(__unix__) || defined(__APPLE__)
|
||||
if (!theApp.GetConfigB("capture_enabled")) {
|
||||
printf("GSdx: Recording is disabled\n");
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
std::wstring* filename = nullptr;
|
||||
if(start & 1)
|
||||
printf("GSdx: Recording start command\n");
|
||||
if (s_gs->BeginCapture(filename))
|
||||
{
|
||||
printf("GSdx: Recording start command\n");
|
||||
filename = s_gs->BeginCapture();
|
||||
if (filename)
|
||||
{
|
||||
pt(" - Capture started\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
pt(" - Capture cancelled\n");
|
||||
return nullptr;
|
||||
}
|
||||
pt(" - Capture started\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GSdx: Recording end command\n");
|
||||
s_gs->EndCapture();
|
||||
pt(" - Capture ended\n");
|
||||
pt(" - Capture cancelled\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
EXPORT_C_(void) GSendRecording()
|
||||
{
|
||||
printf("GSdx: Recording end command\n");
|
||||
s_gs->EndCapture();
|
||||
pt(" - Capture ended\n");
|
||||
}
|
||||
|
||||
EXPORT_C GSsetGameCRC(uint32 crc, int options)
|
||||
|
|
|
@ -404,7 +404,7 @@ GSCapture::~GSCapture()
|
|||
EndCapture();
|
||||
}
|
||||
|
||||
std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect)
|
||||
int GSCapture::BeginCapture(float fps, GSVector2i recommendedResolution, float aspect, std::string& filename)
|
||||
{
|
||||
printf("Recommended resolution: %d x %d, DAR for muxing: %.4f\n", recommendedResolution.x, recommendedResolution.y, aspect);
|
||||
std::lock_guard<std::recursive_mutex> lock(m_lock);
|
||||
|
@ -418,10 +418,10 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
GSCaptureDlg dlg;
|
||||
|
||||
if (IDOK != dlg.DoModal())
|
||||
return nullptr;
|
||||
return 0;
|
||||
|
||||
{
|
||||
int start = dlg.m_filename.length() - 4;
|
||||
const int start = dlg.m_filename.length() - 4;
|
||||
if (start > 0)
|
||||
{
|
||||
std::string test = dlg.m_filename.substr(start);
|
||||
|
@ -438,11 +438,11 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
else
|
||||
{
|
||||
dlg.InvalidFile();
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring fn{dlg.m_filename.begin(), dlg.m_filename.end()};
|
||||
;
|
||||
|
||||
m_size.x = (dlg.m_width + 7) & ~7;
|
||||
m_size.y = (dlg.m_height + 7) & ~7;
|
||||
|
@ -456,9 +456,9 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
if(FAILED(hr = m_graph.CoCreateInstance(CLSID_FilterGraph))
|
||||
|| FAILED(hr = cgb.CoCreateInstance(CLSID_CaptureGraphBuilder2))
|
||||
|| FAILED(hr = cgb->SetFiltergraph(m_graph))
|
||||
|| FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, fn.c_str(), &mux, NULL)))
|
||||
|| FAILED(hr = cgb->SetOutputFileName(&MEDIASUBTYPE_Avi, std::wstring(dlg.m_filename.begin(), dlg.m_filename.end()).c_str(), &mux, NULL)))
|
||||
{
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_src = new GSSource(m_size.x, m_size.y, fps, NULL, hr, dlg.m_colorspace);
|
||||
|
@ -466,22 +466,22 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
if (dlg.m_enc==0)
|
||||
{
|
||||
if (FAILED(hr = m_graph->AddFilter(m_src, L"Source")))
|
||||
return nullptr;
|
||||
return 0;
|
||||
if (FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL)))
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(FAILED(hr = m_graph->AddFilter(m_src, L"Source"))
|
||||
|| FAILED(hr = m_graph->AddFilter(dlg.m_enc, L"Encoder")))
|
||||
{
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(FAILED(hr = m_graph->ConnectDirect(GetFirstPin(m_src, PINDIR_OUTPUT), GetFirstPin(dlg.m_enc, PINDIR_INPUT), NULL))
|
||||
|| FAILED(hr = m_graph->ConnectDirect(GetFirstPin(dlg.m_enc, PINDIR_OUTPUT), GetFirstPin(mux, PINDIR_INPUT), NULL)))
|
||||
{
|
||||
return nullptr;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -509,7 +509,8 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
CComQIPtr<IGSSource>(m_src)->DeliverNewSegment();
|
||||
|
||||
m_capturing = true;
|
||||
return new std::wstring(dlg.m_filename.begin(), dlg.m_filename.end() - 3);
|
||||
filename = dlg.m_filename.erase(dlg.m_filename.length() - 3, 3) + "wav";
|
||||
return 1;
|
||||
#elif defined(__unix__)
|
||||
// Note I think it doesn't support multiple depth creation
|
||||
GSmkdir(m_out_dir.c_str());
|
||||
|
@ -525,7 +526,8 @@ std::wstring* GSCapture::BeginCapture(float fps, GSVector2i recommendedResolutio
|
|||
}
|
||||
|
||||
m_capturing = true;
|
||||
return new std::wstring();
|
||||
filename = m_out_dir + "/audio_recording.wav";
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -564,6 +566,9 @@ bool GSCapture::DeliverFrame(const void* bits, int pitch, bool rgba)
|
|||
|
||||
bool GSCapture::EndCapture()
|
||||
{
|
||||
if (!m_capturing)
|
||||
return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(m_lock);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
GSCapture();
|
||||
virtual ~GSCapture();
|
||||
|
||||
std::wstring* BeginCapture(float fps, GSVector2i recommendedResolution, float aspect);
|
||||
int BeginCapture(float fps, GSVector2i recommendedResolution, float aspect, std::string& filename);
|
||||
bool DeliverFrame(const void* bits, int pitch, bool rgba);
|
||||
bool EndCapture();
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ void GSmkdir(const wchar_t* dir)
|
|||
if (!CreateDirectory(dir, nullptr)) {
|
||||
DWORD errorID = ::GetLastError();
|
||||
if (errorID != ERROR_ALREADY_EXISTS) {
|
||||
fprintf(stderr, "Failed to create directory: %s error %u\n", dir, errorID);
|
||||
fprintf(stderr, "Failed to create directory: %ls error %u\n", dir, errorID);
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -34,6 +34,7 @@ EXPORTS
|
|||
GSreadFIFO2
|
||||
GSirqCallback
|
||||
GSsetupRecording
|
||||
GSendRecording
|
||||
GSsetGameCRC
|
||||
GSsetFrameSkip
|
||||
GSsetVsync
|
||||
|
|
|
@ -533,12 +533,12 @@ bool GSRenderer::MakeSnapshot(const std::string& path)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::wstring* GSRenderer::BeginCapture()
|
||||
int GSRenderer::BeginCapture(std::string& filename)
|
||||
{
|
||||
GSVector4i disp = m_wnd->GetClientRect().fit(m_aspectratio);
|
||||
float aspect = (float)disp.width() / std::max(1, disp.height());
|
||||
|
||||
return m_capture.BeginCapture(GetTvRefreshRate(), GetInternalResolution(), aspect);
|
||||
return m_capture.BeginCapture(GetTvRefreshRate(), GetInternalResolution(), aspect, filename);
|
||||
}
|
||||
|
||||
void GSRenderer::EndCapture()
|
||||
|
|
|
@ -72,7 +72,7 @@ public:
|
|||
void SetAspectRatio(int aspect) {m_aspectratio = aspect;}
|
||||
void SetVSync(int vsync);
|
||||
|
||||
virtual std::wstring* BeginCapture();
|
||||
virtual int BeginCapture(std::string& filename);
|
||||
virtual void EndCapture();
|
||||
|
||||
void PurgePool();
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
void GSCaptureDlg::InvalidFile()
|
||||
{
|
||||
wchar_t tmp[512];
|
||||
swprintf_s(tmp, L"GSdx couldn't open file for capturing: %s.\nCapture aborted.", m_filename.c_str());
|
||||
std::wstring tmpstr(m_filename.begin(), m_filename.end());
|
||||
swprintf_s(tmp, L"GSdx couldn't open file for capturing: %ls.\nCapture aborted.", tmpstr.c_str());
|
||||
MessageBox(GetActiveWindow(), tmp, L"GSdx System Message", MB_OK | MB_SETFOREGROUND);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue