diff --git a/aegisub/src/dialog_detached_video.cpp b/aegisub/src/dialog_detached_video.cpp index 44071d594..0fa4393d8 100644 --- a/aegisub/src/dialog_detached_video.cpp +++ b/aegisub/src/dialog_detached_video.cpp @@ -100,11 +100,18 @@ DialogDetachedVideo::DialogDetachedVideo(agi::Context *context) DialogDetachedVideo::~DialogDetachedVideo() { } void DialogDetachedVideo::OnClose(wxCloseEvent &evt) { - evt.Skip(); + // Deleting a GL context seems to invalidate ALL contexts, so we need to + // delete both the detached and undetached contexts here, then recreate + // the undetached one later + context->videoDisplay->Destroy(); + old_display->Reload(); + context->videoDisplay = old_display; context->videoSlider = old_slider; + OPT_SET("Video/Detached/Enabled")->SetBool(false); - context->videoController->Reload(); + + evt.Skip(); } void DialogDetachedVideo::OnMinimize(wxIconizeEvent &event) { diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index e5788665c..573c588bf 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -439,6 +439,7 @@ void FrameMain::OnVideoOpen() { try { context->audioController->OpenAudio(context->videoController->GetVideoName()); } + catch (agi::UserCancelException const&) { } // Opening a video with no audio data isn't an error, so just log // and move on catch (agi::FileNotAccessibleError const&) { diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 60551a78f..35ddb5a09 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -202,12 +202,9 @@ void VideoContext::SetVideo(const wxString &filename) { config::mru->Add("Video", STD_STR(filename)); StandardPaths::SetPathValue("?video", wxFileName(filename).GetPath()); - // Get frame - frame_n = 0; - // Show warning wxString warning = videoProvider->GetWarning(); - if (!warning.empty()) wxMessageBox(warning,"Warning",wxICON_WARNING | wxOK); + if (!warning.empty()) wxMessageBox(warning, "Warning", wxICON_WARNING | wxOK); hasSubtitles = false; if (filename.Right(4).Lower() == ".mkv") { @@ -230,6 +227,8 @@ void VideoContext::SetVideo(const wxString &filename) { if (commit_subs) context->ass->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO); + else + JumpToFrame(0); } void VideoContext::Reload() { diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp index cfb990cea..0f819974c 100644 --- a/aegisub/src/video_display.cpp +++ b/aegisub/src/video_display.cpp @@ -114,7 +114,7 @@ VideoDisplay::VideoDisplay( zoomBox->Bind(wxEVT_COMMAND_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, this); con->videoController->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); - slots.push_back(con->videoController->AddVideoOpenListener(&VideoDisplay::OnVideoOpen, this)); + slots.push_back(con->videoController->AddVideoOpenListener(&VideoDisplay::UpdateSize, this, false)); slots.push_back(con->videoController->AddARChangeListener(&VideoDisplay::UpdateSize, this, true)); Bind(wxEVT_PAINT, std::tr1::bind(&VideoDisplay::Render, this)); @@ -133,8 +133,9 @@ VideoDisplay::VideoDisplay( c->videoDisplay = this; + UpdateSize(); if (con->videoController->IsLoaded()) - OnVideoOpen(); + con->videoController->JumpToFrame(con->videoController->GetFrameN()); } VideoDisplay::~VideoDisplay () { @@ -158,11 +159,17 @@ bool VideoDisplay::InitContext() { } void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { - if (!InitContext()) return; + if (!InitContext()) { + evt.Skip(); + return; + } if (!videoOut) videoOut.reset(new VideoOutGL); + if (!tool) + cmd::call("video/tool/cross", con); + try { videoOut->UploadFrameData(*evt.frame); } @@ -183,14 +190,6 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { Render(); } -void VideoDisplay::OnVideoOpen() { - if (!con->videoController->IsLoaded()) return; - if (!tool) - cmd::call("video/tool/cross", con); - UpdateSize(); - con->videoController->JumpToFrame(0); -} - void VideoDisplay::Render() try { if (!con->videoController->IsLoaded() || !videoOut || !InitContext() ) return; @@ -221,7 +220,7 @@ void VideoDisplay::Render() try { } } - if (mouse_pos || alwaysShowTools->GetBool()) + if ((mouse_pos || alwaysShowTools->GetBool()) && tool) tool->Draw(); SwapBuffers(); @@ -273,8 +272,7 @@ void VideoDisplay::DrawOverscanMask(float horizontal_percent, float vertical_per } void VideoDisplay::UpdateSize(bool force) { - if (!con->videoController->IsLoaded()) return; - if (!IsShownOnScreen()) return; + if (!con->videoController->IsLoaded() || !IsShownOnScreen()) return; int vidW = con->videoController->GetWidth(); int vidH = con->videoController->GetHeight(); @@ -359,7 +357,7 @@ void VideoDisplay::UpdateSize(bool force) { } } - if (tool.get()) + if (tool) tool->SetDisplayArea(viewport_left, viewport_top, viewport_width, viewport_height); Refresh(false); @@ -378,12 +376,14 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { mouse_pos = event.GetPosition(); - tool->OnMouseEvent(event); + if (tool) + tool->OnMouseEvent(event); } void VideoDisplay::OnMouseLeave(wxMouseEvent& event) { mouse_pos = Vector2D(); - tool->OnMouseEvent(event); + if (tool) + tool->OnMouseEvent(event); } void VideoDisplay::OnMouseWheel(wxMouseEvent& event) { @@ -449,3 +449,12 @@ bool VideoDisplay::ToolIsType(std::type_info const& type) const { Vector2D VideoDisplay::GetMousePosition() const { return mouse_pos ? tool->ToScriptCoords(mouse_pos) : mouse_pos; } + +void VideoDisplay::Reload() { + glContext.reset(); + videoOut.reset(); + tool.reset(); + + if (con->videoController->IsLoaded()) + con->videoController->JumpToFrame(con->videoController->GetFrameN()); +} diff --git a/aegisub/src/video_display.h b/aegisub/src/video_display.h index 7d23096a9..819fcd5a0 100644 --- a/aegisub/src/video_display.h +++ b/aegisub/src/video_display.h @@ -127,8 +127,6 @@ class VideoDisplay : public wxGLCanvas { /// @return Could the context be set? bool InitContext(); - void OnVideoOpen(); - /// @brief Set the size of the display based on the current zoom and video resolution /// @param force Force the size to be set based on zoom even in detached mode void UpdateSize(bool force = false); @@ -172,4 +170,7 @@ public: void SetTool(VisualToolBase *new_tool); bool ToolIsType(std::type_info const& type) const; + + /// Discard all OpenGL state + void Reload(); };