Primitive dropped frame count in display.
[dcpomatic.git] / src / wx / film_viewer.cc
index 0299b24626fd803c505b567b2d8e0338c2bb4d79..036646ba5179f78aa62a21c9a39100341c821dc9 100644 (file)
@@ -72,7 +72,7 @@ rtaudio_callback (void* out, void *, unsigned int frames, double, RtAudioStreamS
        return reinterpret_cast<FilmViewer*>(data)->audio_callback (out, frames);
 }
 
-FilmViewer::FilmViewer (wxWindow* p)
+FilmViewer::FilmViewer (wxWindow* p, bool outline_content, bool jump_to_selected)
        : wxPanel (p)
        , _panel (new wxPanel (this))
        , _outline_content (new wxCheckBox (this, wxID_ANY, _("Outline content")))
@@ -93,6 +93,7 @@ FilmViewer::FilmViewer (wxWindow* p)
        , _audio_block_size (1024)
        , _playing (false)
        , _latency_history_count (0)
+       , _dropped (0)
 {
 #ifndef __WXOSX__
        _panel->SetDoubleBuffered (true);
@@ -106,10 +107,14 @@ FilmViewer::FilmViewer (wxWindow* p)
        _v_sizer->Add (_panel, 1, wxEXPAND);
 
        wxBoxSizer* view_options = new wxBoxSizer (wxHORIZONTAL);
-       view_options->Add (_outline_content, 0, wxRIGHT, DCPOMATIC_SIZER_GAP);
+       if (outline_content) {
+               view_options->Add (_outline_content, 0, wxRIGHT, DCPOMATIC_SIZER_GAP);
+       }
        view_options->Add (_left_eye, 0, wxLEFT | wxRIGHT, DCPOMATIC_SIZER_GAP);
        view_options->Add (_right_eye, 0, wxLEFT | wxRIGHT, DCPOMATIC_SIZER_GAP);
-       view_options->Add (_jump_to_selected, 0, wxLEFT | wxRIGHT, DCPOMATIC_SIZER_GAP);
+       if (jump_to_selected) {
+               view_options->Add (_jump_to_selected, 0, wxLEFT | wxRIGHT, DCPOMATIC_SIZER_GAP);
+       }
        _v_sizer->Add (view_options, 0, wxALL, DCPOMATIC_SIZER_GAP);
 
        wxBoxSizer* h_sizer = new wxBoxSizer (wxHORIZONTAL);
@@ -277,6 +282,15 @@ FilmViewer::get ()
                return;
        }
 
+       if ((time() - video.second) > one_video_frame()) {
+               /* Too late; just drop this frame before we try to get its image (which will be the time-consuming
+                  part if this frame is J2K).
+               */
+               _video_position = video.second;
+               ++_dropped;
+               return;
+       }
+
        /* In an ideal world, what we would do here is:
         *
         * 1. convert to XYZ exactly as we do in the DCP creation path.
@@ -320,7 +334,7 @@ FilmViewer::timer ()
        get ();
        update_position_label ();
        update_position_slider ();
-       DCPTime const next = _video_position + DCPTime::from_frames (1, _film->video_frame_rate ());
+       DCPTime const next = _video_position + one_video_frame();
 
        if (next >= _film->length()) {
                stop ();
@@ -378,10 +392,11 @@ FilmViewer::slider_moved (bool update_slider)
                return;
        }
 
+
        DCPTime t (_slider->GetValue() * _film->length().get() / 4096);
        /* Ensure that we hit the end of the film at the end of the slider */
        if (t >= _film->length ()) {
-               t = _film->length() - DCPTime::from_frames (1, _film->video_frame_rate ());
+               t = _film->length() - one_video_frame();
        }
        seek (t, false);
        update_position_label ();
@@ -460,6 +475,7 @@ FilmViewer::start ()
        }
 
        _playing = true;
+       _dropped = 0;
        timer ();
 }
 
@@ -525,7 +541,7 @@ FilmViewer::active_jobs_changed (optional<string> j)
 DCPTime
 FilmViewer::nudge_amount (wxMouseEvent& ev)
 {
-       DCPTime amount = DCPTime::from_frames (1, _film->video_frame_rate ());
+       DCPTime amount = one_video_frame ();
 
        if (ev.ShiftDown() && !ev.ControlDown()) {
                amount = DCPTime::from_seconds (1);
@@ -782,3 +798,15 @@ FilmViewer::average_latency () const
 
         return total / _latency_history.size();
 }
+
+void
+FilmViewer::set_dcp_decode_reduction (optional<int> reduction)
+{
+       _player->set_dcp_decode_reduction (reduction);
+}
+
+DCPTime
+FilmViewer::one_video_frame () const
+{
+       return DCPTime::from_frames (1, _film->video_frame_rate());
+}