Prevent crashes when closing the window during video playback

This commit is contained in:
Struma 2022-01-23 04:03:50 -05:00
parent 67abad7036
commit 683b5af87e
3 changed files with 39 additions and 7 deletions

View file

@ -260,6 +260,24 @@ RB_METHOD(graphicsCenter)
return Qnil;
}
typedef struct {
const char *filename;
int volume;
bool skippable;
} PlayMovieArgs;
void *playMovieInternal(void *args) {
PlayMovieArgs *a = (PlayMovieArgs*)args;
GFX_GUARD_EXC(
shState->graphics().playMovie(a->filename, a->volume, a->skippable);
// Signals for shutdown or reset only make playMovie quit early,
// so check again
shState->graphics().update();
);
return 0;
}
RB_METHOD(graphicsPlayMovie)
{
RB_UNUSED_PARAM;
@ -270,11 +288,18 @@ RB_METHOD(graphicsPlayMovie)
bool skip;
rb_bool_arg(skippable, &skip);
int volume = (volumeArg == Qnil) ? 100 : NUM2INT(volumeArg);
// TODO: Video control inputs (e.g. skip, pause)
GFX_GUARD_EXC(shState->graphics().playMovie(RSTRING_PTR(filename), volume, skip););
PlayMovieArgs args{};
args.filename = RSTRING_PTR(filename);
args.volume = (volumeArg == Qnil) ? 100 : NUM2INT(volumeArg);;
args.skippable = skip;
#if RAPI_MAJOR >= 2
rb_thread_call_without_gvl(playMovieInternal, &args, 0, 0);
#else
playMovieInternal(&args);
#endif
return Qnil;
}

View file

@ -320,10 +320,12 @@ struct Movie
}
// Got a video frame, now draw it
videoBitmap->replaceRaw(video->pixels, video->width * video->height * 4);
if (video) {
videoBitmap->replaceRaw(video->pixels, video->width * video->height * 4);
THEORAPLAY_freeVideo(video);
video = NULL;
}
shState->graphics().update(false);
THEORAPLAY_freeVideo(video);
video = NULL;
if (openedAudio) {
queueMoreMovieAudio(decoder, now);
@ -1362,10 +1364,10 @@ void Graphics::repaintWait(const AtomicFlag &exitCond, bool checkReset) {
GLMeta::blitSource(lastFrame);
while (!exitCond) {
shState->checkShutdown();
0;//shState->checkShutdown();
if (checkReset)
shState->checkReset();
0;//shState->checkReset();
FBO::clear();
p->metaBlitBufferFlippedScaled();

View file

@ -742,6 +742,11 @@ void EventThread::showMessageBox(const char *body, int flags)
{
msgBoxDone.clear();
// mkxp has already been asked to quit.
// Don't break things if the window wants to close
if (shState->rtData().rqTerm)
return;
SDL_Event event;
event.user.code = flags;
event.user.data1 = strdup(body);