Catch exceptions from RtAudio::startStream() in all cases.
[dcpomatic.git] / src / wx / film_viewer.cc
index 22de7b5934c28751b8d73b2c14a3b56a24273249..ac12bea3f6f9870a001e976b20d6f5d0eb1d8e0a 100644 (file)
@@ -283,17 +283,21 @@ FilmViewer::calculate_sizes ()
 
        auto const container = _film->container ();
 
-       auto const view_ratio = float(_video_view->get()->GetSize().x) / _video_view->get()->GetSize().y;
+       auto const scale = dpi_scale_factor (_video_view->get());
+       int const video_view_width = std::round(_video_view->get()->GetSize().x * scale);
+       int const video_view_height = std::round(_video_view->get()->GetSize().y * scale);
+
+       auto const view_ratio = float(video_view_width) / video_view_height;
        auto const film_ratio = container ? container->ratio () : 1.78;
 
        dcp::Size out_size;
        if (view_ratio < film_ratio) {
                /* panel is less widscreen than the film; clamp width */
-               out_size.width = _video_view->get()->GetSize().x;
+               out_size.width = video_view_width;
                out_size.height = lrintf (out_size.width / film_ratio);
        } else {
                /* panel is more widescreen than the film; clamp height */
-               out_size.height = _video_view->get()->GetSize().y;
+               out_size.height = video_view_height;
                out_size.width = lrintf (out_size.height * film_ratio);
        }
 
@@ -315,16 +319,31 @@ FilmViewer::suspend ()
 }
 
 
+void
+FilmViewer::start_audio_stream_if_open ()
+{
+       if (_audio.isStreamOpen()) {
+               _audio.setStreamTime (_video_view->position().seconds());
+               try {
+                       _audio.startStream ();
+               } catch (RtAudioError& e) {
+                       _audio_channels = 0;
+                       error_dialog (
+                               _video_view->get(),
+                               _("There was a problem starting audio playback.  Please try another audio output device in Preferences."), std_to_wx(e.what())
+                               );
+               }
+       }
+}
+
+
 void
 FilmViewer::resume ()
 {
        DCPOMATIC_ASSERT (_suspended > 0);
        --_suspended;
        if (_playing && !_suspended) {
-               if (_audio.isStreamOpen()) {
-                       _audio.setStreamTime (_video_view->position().seconds());
-                       _audio.startStream ();
-               }
+               start_audio_stream_if_open ();
                _video_view->start ();
        }
 }
@@ -354,24 +373,13 @@ FilmViewer::start ()
        /* Take the video view's idea of position as our `playhead' and start the
           audio stream (which is the timing reference) there.
          */
-       if (_audio.isStreamOpen()) {
-               _audio.setStreamTime (_video_view->position().seconds());
-               try {
-                       _audio.startStream ();
-               } catch (RtAudioError& e) {
-                       _audio_channels = 0;
-                       error_dialog (
-                               _video_view->get(),
-                               _("There was a problem starting audio playback.  Please try another audio output device in Preferences."), std_to_wx(e.what())
-                               );
-               }
-       }
+       start_audio_stream_if_open ();
 
        _playing = true;
        /* 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());
+       Started ();
        _video_view->start ();
 }
 
@@ -390,7 +398,7 @@ FilmViewer::stop ()
 
        _playing = false;
        _video_view->stop ();
-       Stopped (position());
+       Stopped ();
 
        _video_view->rethrow ();
        return true;
@@ -649,7 +657,7 @@ int
 FilmViewer::audio_callback (void* out_p, unsigned int frames)
 {
        while (true) {
-               auto t = _butler->get_audio (reinterpret_cast<float*> (out_p), frames);
+               auto t = _butler->get_audio (Butler::Behaviour::NON_BLOCKING, reinterpret_cast<float*> (out_p), frames);
                if (!t || DCPTime(uncorrected_time() - *t) < one_video_frame()) {
                        /* There was an underrun or this audio is on time; carry on */
                        break;