Fix warning in previous.
[dcpomatic.git] / src / wx / film_viewer.cc
index bca3631ab07a5ab811997948d3b7bc1c9503d22d..cc18d634d3963b2a583880a973163bc2aa72b176 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2019 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
 */
 
+
 /** @file  src/film_viewer.cc
  *  @brief A wx widget to view a preview of a Film.
  */
 
-#include "film_viewer.h"
-#include "playhead_to_timecode_dialog.h"
-#include "playhead_to_frame_dialog.h"
-#include "wx_util.h"
+
 #include "closed_captions_dialog.h"
+#include "film_viewer.h"
 #include "gl_video_view.h"
+#include "nag_dialog.h"
+#include "playhead_to_frame_dialog.h"
+#include "playhead_to_timecode_dialog.h"
 #include "simple_video_view.h"
+#include "wx_util.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
 #include "lib/util.h"
@@ -65,9 +68,10 @@ using std::list;
 using std::bad_alloc;
 using std::make_pair;
 using std::exception;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::weak_ptr;
+using std::shared_ptr;
+using std::dynamic_pointer_cast;
+using std::vector;
+using std::weak_ptr;
 using boost::optional;
 #if BOOST_VERSION >= 106100
 using namespace boost::placeholders;
@@ -105,6 +109,7 @@ FilmViewer::FilmViewer (wxWindow* p)
        }
 
        _video_view->Sized.connect (boost::bind(&FilmViewer::video_view_sized, this));
+       _video_view->TooManyDropped.connect (boost::bind(&FilmViewer::too_many_frames_dropped, this));
 
        set_film (shared_ptr<Film> ());
 
@@ -137,11 +142,11 @@ FilmViewer::idle_handler ()
                return;
        }
 
-       if (_video_view->display_next_frame(true)) {
-               _idle_get = false;
-       } else {
+       if (_video_view->display_next_frame(true) == VideoView::AGAIN) {
                /* get() could not complete quickly so we'll try again later */
                signal_manager->when_idle (boost::bind(&FilmViewer::idle_handler, this));
+       } else {
+               _idle_get = false;
        }
 }
 
@@ -180,12 +185,11 @@ FilmViewer::set_film (shared_ptr<Film> film)
        _player->set_play_referenced ();
 
        _film->Change.connect (boost::bind (&FilmViewer::film_change, this, _1, _2));
-       _film->ContentChange.connect (boost::bind(&FilmViewer::content_change, this, _1, _3));
        _film->LengthChange.connect (boost::bind(&FilmViewer::film_length_change, this));
        _player->Change.connect (boost::bind (&FilmViewer::player_change, this, _1, _2, _3));
 
-       film_change (CHANGE_TYPE_DONE, Film::VIDEO_FRAME_RATE);
-       film_change (CHANGE_TYPE_DONE, Film::THREE_D);
+       film_change (ChangeType::DONE, Film::Property::VIDEO_FRAME_RATE);
+       film_change (ChangeType::DONE, Film::Property::THREE_D);
        film_length_change ();
 
        /* Keep about 1 second's worth of history samples */
@@ -217,7 +221,7 @@ FilmViewer::recreate_butler ()
                        Config::instance()->audio_mapping(_audio_channels),
                        _audio_channels,
                        bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24),
-                       VIDEO_RANGE_FULL,
+                       VideoRange::FULL,
                        false,
                        true
                        )
@@ -346,8 +350,11 @@ FilmViewer::start ()
        }
 
        _playing = true;
-       _video_view->start ();
+       /* Calling start() below may directly result in Stopped being emitted, and if that
+        * happens we want it to come after the Started signal, so do that first.
+        */
        Started (position());
+       _video_view->start ();
 }
 
 bool
@@ -373,7 +380,7 @@ FilmViewer::stop ()
 void
 FilmViewer::player_change (ChangeType type, int property, bool frequent)
 {
-       if (type != CHANGE_TYPE_DONE || frequent) {
+       if (type != ChangeType::DONE || frequent) {
                return;
        }
 
@@ -382,39 +389,58 @@ FilmViewer::player_change (ChangeType type, int property, bool frequent)
                return;
        }
 
+       player_change ({property});
+}
+
+void
+FilmViewer::player_change (vector<int> properties)
+{
        calculate_sizes ();
-       bool refreshed = false;
-       if (
-               property == VideoContentProperty::CROP ||
-               property == VideoContentProperty::SCALE ||
-               property == VideoContentProperty::FADE_IN ||
-               property == VideoContentProperty::FADE_OUT ||
-               property == VideoContentProperty::COLOUR_CONVERSION ||
-               property == PlayerProperty::VIDEO_CONTAINER_SIZE ||
-               property == PlayerProperty::FILM_CONTAINER
-               ) {
-               refreshed = quick_refresh ();
-       }
-
-       if (!refreshed) {
+
+       bool try_quick_refresh = false;
+       bool update_ccap_tracks = false;
+
+       for (auto i: properties) {
+               if (
+                       i == VideoContentProperty::CROP ||
+                       i == VideoContentProperty::SCALE ||
+                       i == VideoContentProperty::FADE_IN ||
+                       i == VideoContentProperty::FADE_OUT ||
+                       i == VideoContentProperty::COLOUR_CONVERSION ||
+                       i == PlayerProperty::VIDEO_CONTAINER_SIZE ||
+                       i == PlayerProperty::FILM_CONTAINER
+                  ) {
+                       try_quick_refresh = true;
+               }
+
+               if (i == TextContentProperty::USE || i == TextContentProperty::TYPE || i == TextContentProperty::DCP_TRACK) {
+                       update_ccap_tracks = true;
+               }
+       }
+
+       if (!try_quick_refresh || !quick_refresh()) {
                slow_refresh ();
        }
+
+       if (update_ccap_tracks) {
+               _closed_captions_dialog->update_tracks (_film);
+       }
 }
 
 void
 FilmViewer::film_change (ChangeType type, Film::Property p)
 {
-       if (type != CHANGE_TYPE_DONE) {
+       if (type != ChangeType::DONE) {
                return;
        }
 
-       if (p == Film::AUDIO_CHANNELS) {
+       if (p == Film::Property::AUDIO_CHANNELS) {
                recreate_butler ();
-       } else if (p == Film::VIDEO_FRAME_RATE) {
+       } else if (p == Film::Property::VIDEO_FRAME_RATE) {
                _video_view->set_video_frame_rate (_film->video_frame_rate());
-       } else if (p == Film::THREE_D) {
+       } else if (p == Film::Property::THREE_D) {
                _video_view->set_three_d (_film->three_d());
-       } else if (p == Film::CONTENT) {
+       } else if (p == Film::Property::CONTENT) {
                _closed_captions_dialog->update_tracks (_film);
        }
 }
@@ -442,7 +468,7 @@ FilmViewer::quick_refresh ()
        if (!_video_view || !_film || !_player) {
                return true;
        }
-       return _video_view->refresh_metadata (_film, _player->video_container_size());
+       return _video_view->reset_metadata (_film, _player->video_container_size());
 }
 
 void
@@ -460,9 +486,7 @@ FilmViewer::set_coalesce_player_changes (bool c)
        _coalesce_player_changes = c;
 
        if (!c) {
-               BOOST_FOREACH (int i, _pending_player_changes) {
-                       player_change (CHANGE_TYPE_DONE, i, false);
-               }
+               player_change (_pending_player_changes);
                _pending_player_changes.clear ();
        }
 }
@@ -496,7 +520,7 @@ FilmViewer::seek (DCPTime t, bool accurate)
                /* We're going to start playing again straight away
                   so wait for the seek to finish.
                */
-               while (!_video_view->display_next_frame(false)) {}
+               while (_video_view->display_next_frame(false) == VideoView::AGAIN) {}
        }
 
        resume ();
@@ -619,7 +643,7 @@ FilmViewer::average_latency () const
         }
 
         Frame total = 0;
-        BOOST_FOREACH (Frame i, _latency_history) {
+        for (auto i: _latency_history) {
                 total += i;
         }
 
@@ -705,21 +729,27 @@ FilmViewer::gets () const
 
 
 void
-FilmViewer::content_change (ChangeType type, int property)
+FilmViewer::image_changed (shared_ptr<PlayerVideo> pv)
 {
-       if (type != CHANGE_TYPE_DONE) {
-               return;
-       }
-
-       if (property == TextContentProperty::USE || property == TextContentProperty::TYPE || property == TextContentProperty::DCP_TRACK) {
-               _closed_captions_dialog->update_tracks (_film);
-       }
+       emit (boost::bind(boost::ref(ImageChanged), pv));
 }
 
 
 void
-FilmViewer::image_changed (shared_ptr<PlayerVideo> pv)
+FilmViewer::too_many_frames_dropped ()
 {
-       emit (boost::bind(boost::ref(ImageChanged), pv));
-}
+       if (!Config::instance()->nagged(Config::NAG_TOO_MANY_DROPPED_FRAMES)) {
+               stop ();
+       }
 
+       NagDialog::maybe_nag (
+               panel(),
+               Config::NAG_TOO_MANY_DROPPED_FRAMES,
+               _("The player is dropping a lot of frames, so playback may not be accurate.\n\n"
+                 "<b>This does not necessarily mean that the DCP you are playing is defective!</b>\n\n"
+                 "You may be able to improve player performance by:\n"
+                 "• choosing 'decode at half resolution' or 'decode at quarter resolution' from the View menu\n"
+                 "• using a more powerful computer.\n"
+                )
+               );
+}