Fix video recording with frame skip enabled.

When we skip frames, we just don't draw them on our frontend. The
function `systemDrawScreen` also send the video frames to be recorded,
but only when called from the core.

Our solution creates a auxiliary `systemSendScreen` that only adds the
frame to the recording. It is called when the core decides to skip a
frame. This way we can get the video frame for recording, just like
audio ones are always sent.
This commit is contained in:
Edênis Freindorfer Azevedo 2020-02-28 16:51:14 -03:00 committed by Rafael Kitover
parent 008aecde67
commit cd029ae696
7 changed files with 26 additions and 10 deletions

View File

@ -50,6 +50,7 @@ extern bool systemPauseOnFrame();
extern void systemGbPrint(uint8_t *, int, int, int, int, int); extern void systemGbPrint(uint8_t *, int, int, int, int, int);
extern void systemScreenCapture(int); extern void systemScreenCapture(int);
extern void systemDrawScreen(); extern void systemDrawScreen();
extern void systemSendScreen();
// updates the joystick data // updates the joystick data
extern bool systemReadJoypads(); extern bool systemReadJoypads();
// return information about the given joystick, -1 for default joystick // return information about the given joystick, -1 for default joystick

View File

@ -5059,8 +5059,10 @@ void gbEmulate(int ticksToStop)
ticksToStop = 0; ticksToStop = 0;
} }
gbFrameSkipCount = 0; gbFrameSkipCount = 0;
} else } else {
gbFrameSkipCount++; gbFrameSkipCount++;
systemSendScreen();
}
frameDone = true; frameDone = true;
@ -5211,6 +5213,8 @@ void gbEmulate(int ticksToStop)
if (systemPauseOnFrame()) if (systemPauseOnFrame())
ticksToStop = 0; ticksToStop = 0;
} }
} else {
systemSendScreen();
} }
gbFrameCount++; gbFrameCount++;

View File

@ -3884,8 +3884,10 @@ void CPULoop(int ticks)
if (frameCount >= framesToSkip) { if (frameCount >= framesToSkip) {
systemDrawScreen(); systemDrawScreen();
frameCount = 0; frameCount = 0;
} else } else {
frameCount++; frameCount++;
systemSendScreen();
}
if (systemPauseOnFrame()) if (systemPauseOnFrame())
ticks = 0; ticks = 0;

View File

@ -1704,6 +1704,10 @@ void systemDrawScreen(void)
video_cb(pix, systemWidth, systemHeight, pitch); video_cb(pix, systemWidth, systemHeight, pitch);
} }
void systemSendScreen(void)
{
}
void systemFrame(void) void systemFrame(void)
{ {
has_frame = 1; has_frame = 1;

View File

@ -1649,7 +1649,7 @@ int main(int argc, char** argv)
sprintf(tmp, "%s.ups", filename); sprintf(tmp, "%s.ups", filename);
patchNames[patchNum] = tmp; patchNames[patchNum] = tmp;
patchNum++; patchNum++;
// no patch given yet - look for ROMBASENAME.bps // no patch given yet - look for ROMBASENAME.bps
tmp = (char*)malloc(strlen(filename) + 4 + 1); tmp = (char*)malloc(strlen(filename) + 4 + 1);
sprintf(tmp, "%s.bps", filename); sprintf(tmp, "%s.bps", filename);
@ -2020,6 +2020,10 @@ void systemDrawScreen()
} }
} }
void systemSendScreen()
{
}
void systemSetTitle(const char* title) void systemSetTitle(const char* title)
{ {
SDL_SetWindowTitle(window, title); SDL_SetWindowTitle(window, title);

View File

@ -2390,15 +2390,10 @@ static const wxString media_err(recording::MediaRet ret)
} }
} }
int save_speedup_frame_skip;
void GameArea::StartVidRecording(const wxString& fname) void GameArea::StartVidRecording(const wxString& fname)
{ {
recording::MediaRet ret; recording::MediaRet ret;
// do not skip frames when recording
save_speedup_frame_skip = speedup_frame_skip;
speedup_frame_skip = 0;
vid_rec.SetSampleRate(soundGetSampleRate()); vid_rec.SetSampleRate(soundGetSampleRate());
if ((ret = vid_rec.Record(fname.mb_str(), basic_width, basic_height, if ((ret = vid_rec.Record(fname.mb_str(), basic_width, basic_height,
systemColorDepth)) systemColorDepth))
@ -2416,8 +2411,6 @@ void GameArea::StartVidRecording(const wxString& fname)
void GameArea::StopVidRecording() void GameArea::StopVidRecording()
{ {
vid_rec.Stop(); vid_rec.Stop();
// allow to skip frames again
speedup_frame_skip = save_speedup_frame_skip;
MainFrame* mf = wxGetApp().frame; MainFrame* mf = wxGetApp().frame;
mf->cmd_enable &= ~CMDEN_VREC; mf->cmd_enable &= ~CMDEN_VREC;
mf->cmd_enable |= CMDEN_NVREC; mf->cmd_enable |= CMDEN_NVREC;

View File

@ -72,6 +72,14 @@ void systemMessage(int id, const char* fmt, ...)
wxLogError(wxT("%s"), wxString(buf, wxConvUTF8).c_str()); wxLogError(wxT("%s"), wxString(buf, wxConvUTF8).c_str());
} }
void systemSendScreen()
{
#ifndef NO_FFMPEG
GameArea* ga = wxGetApp().frame->GetPanel();
if (ga) ga->AddFrame(pix);
#endif
}
static int frames = 0; static int frames = 0;
void systemDrawScreen() void systemDrawScreen()