, _eyes (EYES_LEFT)
, _pad_black (false)
#ifdef DCPOMATIC_VARIANT_SWAROOP
- , _in_watermark (false)
, _background_image (false)
#endif
, _state_timer ("viewer")
{
switch (Config::instance()->video_view_type()) {
case Config::VIDEO_VIEW_OPENGL:
- _video_view = new GLVideoView (p);
+ _video_view = new GLVideoView (this, p);
break;
case Config::VIDEO_VIEW_SIMPLE:
_video_view = new SimpleVideoView (this, p);
break;
}
- /* XXX: maybe this should be proxied through the VideoView */
- _video_view->get()->Bind (wxEVT_SIZE, boost::bind (&FilmViewer::video_view_sized, this));
- _timer.Bind (wxEVT_TIMER, boost::bind (&FilmViewer::timer, this));
+ _video_view->Sized.connect (boost::bind(&FilmViewer::video_view_sized, this));
+ _timer.Bind (wxEVT_TIMER, boost::bind(&FilmViewer::timer, this));
set_film (shared_ptr<Film> ());
_player_video.first.reset ();
_player_video.second = DCPTime ();
- _frame.reset ();
+ _video_view->set_image (shared_ptr<Image>());
_closed_captions_dialog->clear ();
if (!_film) {
_player.reset ();
recreate_butler ();
- _frame.reset ();
refresh_view ();
return;
}
Map so that Lt = L(-3dB) + Ls(-3dB) + C(-6dB) + Lfe(-10dB)
Rt = R(-3dB) + Rs(-3dB) + C(-6dB) + Lfe(-10dB)
*/
- map.set (dcp::LEFT, 0, 1 / sqrt(2)); // L -> Lt
- map.set (dcp::RIGHT, 1, 1 / sqrt(2)); // R -> Rt
- map.set (dcp::CENTRE, 0, 1 / 2.0); // C -> Lt
- map.set (dcp::CENTRE, 1, 1 / 2.0); // C -> Rt
- map.set (dcp::LFE, 0, 1 / sqrt(10)); // Lfe -> Lt
- map.set (dcp::LFE, 1, 1 / sqrt(10)); // Lfe -> Rt
- map.set (dcp::LS, 0, 1 / sqrt(2)); // Ls -> Lt
- map.set (dcp::RS, 1, 1 / sqrt(2)); // Rs -> Rt
+ if (_film->audio_channels() > 0) {
+ map.set (dcp::LEFT, 0, 1 / sqrt(2)); // L -> Lt
+ }
+ if (_film->audio_channels() > 1) {
+ map.set (dcp::RIGHT, 1, 1 / sqrt(2)); // R -> Rt
+ }
+ if (_film->audio_channels() > 2) {
+ map.set (dcp::CENTRE, 0, 1 / 2.0); // C -> Lt
+ map.set (dcp::CENTRE, 1, 1 / 2.0); // C -> Rt
+ }
+ if (_film->audio_channels() > 3) {
+ map.set (dcp::LFE, 0, 1 / sqrt(10)); // Lfe -> Lt
+ map.set (dcp::LFE, 1, 1 / sqrt(10)); // Lfe -> Rt
+ }
+ if (_film->audio_channels() > 4) {
+ map.set (dcp::LS, 0, 1 / sqrt(2)); // Ls -> Lt
+ }
+ if (_film->audio_channels() > 5) {
+ map.set (dcp::RS, 1, 1 / sqrt(2)); // Rs -> Rt
+ }
}
_butler.reset (new Butler(_player, map, _audio_channels, bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true));
void
FilmViewer::refresh_view ()
{
- _state_timer.set ("refresh-view");
- _video_view->get()->Refresh ();
- _video_view->get()->Update ();
+ _state_timer.set ("update-view");
+ _video_view->update ();
_state_timer.unset ();
}
+/** @param lazy true if it is *not* important that the display be updated as quickly as possible.
+ * If lazy is true we will try to return from this method quickly and postpone any time-consuming
+ * work until the UI is next idle. Otherwise we will block here and try to get the image on
+ * screen as soon as possible.
+ */
void
-FilmViewer::get ()
+FilmViewer::get (bool lazy)
{
DCPOMATIC_ASSERT (_butler);
++_gets;
do {
Butler::Error e;
- _player_video = _butler->get_video (&e);
+ _player_video = _butler->get_video (!lazy, &e);
if (!_player_video.first && e == Butler::AGAIN) {
- signal_manager->when_idle (boost::bind(&FilmViewer::get, this));
+ signal_manager->when_idle (boost::bind(&FilmViewer::get, this, lazy));
return;
}
} while (
_player_video.first->eyes() != EYES_BOTH
);
- _butler->rethrow ();
+ try {
+ _butler->rethrow ();
+ } catch (DecodeError& e) {
+ error_dialog (_video_view->get(), e.what());
+ }
- display_player_video ();
+ if (lazy) {
+ signal_manager->when_idle (boost::bind(&FilmViewer::display_player_video, this));
+ } else {
+ display_player_video ();
+ }
}
void
FilmViewer::display_player_video ()
{
if (!_player_video.first) {
- _frame.reset ();
+ _video_view->set_image (shared_ptr<Image>());
refresh_view ();
return;
}
_state_timer.set ("get image");
- /* XXX: do we need to store _frame? */
- _frame = _player_video.first->image (bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true);
- _video_view->set_image (_frame);
+ _video_view->set_image (
+ _player_video.first->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), false, true)
+ );
_state_timer.set ("ImageChanged");
ImageChanged (_player_video.first);
return;
}
- get ();
+ get (false);
PositionChanged ();
DCPTime const next = _video_position + one_video_frame();
}
}
-bool
-#ifdef DCPOMATIC_VARIANT_SWAROOP
-XXX
-FilmViewer::maybe_draw_background_image (wxPaintDC& dc)
-{
- optional<boost::filesystem::path> bg = Config::instance()->player_background_image();
- if (bg) {
- wxImage image (std_to_wx(bg->string()));
- wxBitmap bitmap (image);
- dc.DrawBitmap (bitmap, max(0, (_panel_size.width - image.GetSize().GetWidth()) / 2), max(0, (_panel_size.height - image.GetSize().GetHeight()) / 2));
- return true;
- }
-
- return false;
-}
-#else
-FilmViewer::maybe_draw_background_image (wxPaintDC &)
-{
- return false;
-}
-#endif
-
void
FilmViewer::set_outline_content (bool o)
{
_out_size.width = max (64, _out_size.width);
_out_size.height = max (64, _out_size.height);
- /* Make OpenGL happy; XXX: only do this in GLVideoView? Is the round-to-4 constraint a thing? */
- _out_size.width &= ~3;
- _out_size.height &= ~3;
-
_player->set_video_container_size (_out_size);
}
_closed_captions_dialog->clear ();
_butler->seek (t, accurate);
- get ();
+ get (true);
if (was_running) {
start ();