Merge branch 'master' into 12bit
[dcpomatic.git] / src / wx / film_viewer.cc
index b4935dcf4a4a696acfba35066a355bcc993304ca..54cd3e77dc30014816f35b90457d0014ea045f16 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@
 #include "lib/examine_content_job.h"
 #include "lib/filter.h"
 #include "lib/player.h"
+#include "lib/player_video_frame.h"
 #include "lib/video_content.h"
 #include "lib/video_decoder.h"
 #include "film_viewer.h"
@@ -45,13 +46,14 @@ using std::min;
 using std::max;
 using std::cout;
 using std::list;
+using std::bad_alloc;
 using std::make_pair;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::weak_ptr;
 using libdcp::Size;
 
-FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
+FilmViewer::FilmViewer (wxWindow* p)
        : wxPanel (p)
        , _panel (new wxPanel (this))
        , _slider (new wxSlider (this, wxID_ANY, 0, 0, 4096))
@@ -101,8 +103,8 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
        _back_button->Bind    (wxEVT_COMMAND_BUTTON_CLICKED,       boost::bind (&FilmViewer::back_clicked,    this));
        _forward_button->Bind (wxEVT_COMMAND_BUTTON_CLICKED,       boost::bind (&FilmViewer::forward_clicked, this));
 
-       set_film (f);
-
+       set_film (shared_ptr<Film> ());
+       
        JobManager::instance()->ActiveJobsChanged.connect (
                bind (&FilmViewer::active_jobs_changed, this, _1)
                );
@@ -126,9 +128,16 @@ FilmViewer::set_film (shared_ptr<Film> f)
                return;
        }
 
-       _player = f->make_player ();
+       try {
+               _player = f->make_player ();
+       } catch (bad_alloc) {
+               error_dialog (this, _("There is not enough free memory to do that."));
+               _film.reset ();
+               return;
+       }
+       
        _player->disable_audio ();
-       _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _2, _5));
+       _player->Video.connect (boost::bind (&FilmViewer::process_video, this, _1, _3));
        _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1));
 
        calculate_sizes ();
@@ -211,7 +220,12 @@ void
 FilmViewer::slider_moved ()
 {
        if (_film && _player) {
-               _player->seek (_slider->GetValue() * _film->length() / 4096, false);
+               Time t = _slider->GetValue() * _film->length() / 4096;
+               /* Ensure that we hit the end of the film at the end of the slider */
+               if (t >= _film->length ()) {
+                       t = _film->length() - _film->video_frames_to_time (1);
+               }
+               _player->seek (t, false);
                fetch_next_frame ();
        }
 }
@@ -275,13 +289,13 @@ FilmViewer::check_play_state ()
 }
 
 void
-FilmViewer::process_video (shared_ptr<const Image> image, Eyes eyes, Time t)
+FilmViewer::process_video (shared_ptr<PlayerVideoFrame> pvf, Time t)
 {
-       if (eyes == EYES_RIGHT) {
+       if (pvf->eyes() == EYES_RIGHT) {
                return;
        }
        
-       _frame = image;
+       _frame = pvf->image (PIX_FMT_RGB24);
        _got_frame = true;
 
        set_position_text (t);
@@ -396,7 +410,7 @@ FilmViewer::player_changed (bool frequent)
        if (frequent) {
                return;
        }
-       
+
        calculate_sizes ();
        fetch_current_frame_again ();
 }