Fix player being destroyed while the butler is still using it.
authorCarl Hetherington <cth@carlh.net>
Wed, 26 Oct 2022 17:45:11 +0000 (19:45 +0200)
committerCarl Hetherington <cth@carlh.net>
Wed, 26 Oct 2022 17:45:11 +0000 (19:45 +0200)
src/wx/film_viewer.cc
src/wx/film_viewer.h

index c5fb502177af5c52b5cc3e1280464b711cf04748..fb02f0a0ff41074015ebc9c6b9b939aa5698f6b1 100644 (file)
@@ -160,9 +160,11 @@ FilmViewer::set_film (shared_ptr<Film> film)
        _video_view->clear ();
        _closed_captions_dialog->clear ();
 
+       destroy_butler();
+
        if (!_film) {
                _player = boost::none;
-               recreate_butler ();
+               resume();
                _video_view->update ();
                return;
        }
@@ -176,6 +178,7 @@ FilmViewer::set_film (shared_ptr<Film> film)
        } catch (bad_alloc &) {
                error_dialog (_video_view->get(), _("There is not enough free memory to do that."));
                _film.reset ();
+               resume();
                return;
        }
 
@@ -195,7 +198,7 @@ FilmViewer::set_film (shared_ptr<Film> film)
 
        _closed_captions_dialog->update_tracks (_film);
 
-       recreate_butler ();
+       create_butler();
 
        calculate_sizes ();
        slow_refresh ();
@@ -203,16 +206,30 @@ FilmViewer::set_film (shared_ptr<Film> film)
 
 
 void
-FilmViewer::recreate_butler ()
+FilmViewer::destroy_butler()
 {
        suspend ();
        _butler.reset ();
+}
+
+
+void
+FilmViewer::destroy_and_maybe_create_butler()
+{
+       destroy_butler();
 
        if (!_film) {
                resume ();
                return;
        }
 
+       create_butler();
+}
+
+
+void
+FilmViewer::create_butler()
+{
 #if wxCHECK_VERSION(3, 1, 0)
        auto const j2k_gl_optimised = dynamic_pointer_cast<GLVideoView>(_video_view) && _optimise_for_j2k;
 #else
@@ -476,7 +493,7 @@ FilmViewer::film_change (ChangeType type, Film::Property p)
        }
 
        if (p == Film::Property::AUDIO_CHANNELS) {
-               recreate_butler ();
+               destroy_and_maybe_create_butler();
        } else if (p == Film::Property::VIDEO_FRAME_RATE) {
                _video_view->set_video_frame_rate (_film->video_frame_rate());
        } else if (p == Film::Property::THREE_D) {
@@ -579,7 +596,7 @@ void
 FilmViewer::config_changed (Config::Property p)
 {
        if (p == Config::AUDIO_MAPPING) {
-               recreate_butler ();
+               destroy_and_maybe_create_butler();
                return;
        }
 
@@ -625,11 +642,11 @@ FilmViewer::config_changed (Config::Property p)
                                _("Could not set up audio output.  There will be no audio during the preview."), std_to_wx(e.what())
                                );
                }
-               recreate_butler ();
+               destroy_and_maybe_create_butler();
 
        } else {
                _audio_channels = 0;
-               recreate_butler ();
+               destroy_and_maybe_create_butler();
        }
 }
 
index 062522ffd54bb2fa24d48b582212e57c8670b22d..aea3f8c8633465933af11c5e5ccad26610d87d4d 100644 (file)
@@ -163,7 +163,9 @@ private:
        void idle_handler ();
        void request_idle_display_next_frame ();
        void film_change (ChangeType, Film::Property);
-       void recreate_butler ();
+       void destroy_butler();
+       void create_butler();
+       void destroy_and_maybe_create_butler();
        void config_changed (Config::Property);
        void film_length_change ();
        void ui_finished ();