summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2018-02-24 01:05:14 +0000
committerCarl Hetherington <cth@carlh.net>2018-02-24 23:35:11 +0000
commit14cccb179fff7bbbf422e13f9d2e3264239c93c7 (patch)
tree15b8c2f07965f22aabd3fcfa0494ffa51d8e09e6 /src
parent63eb29920980dfecf4c5f06a1746dad830b7ea32 (diff)
Speed some operations by re-using the last PlayerVideo but with
updated metadata (where possible). Helps with #1194.
Diffstat (limited to 'src')
-rw-r--r--src/lib/player.cc28
-rw-r--r--src/lib/player.h18
-rw-r--r--src/lib/player_video.cc30
-rw-r--r--src/lib/player_video.h11
-rw-r--r--src/wx/film_viewer.cc81
-rw-r--r--src/wx/film_viewer.h9
-rw-r--r--src/wx/video_waveform_dialog.cc2
7 files changed, 133 insertions, 46 deletions
diff --git a/src/lib/player.cc b/src/lib/player.cc
index 0d4d9f0a2..bd194c373 100644
--- a/src/lib/player.cc
+++ b/src/lib/player.cc
@@ -78,6 +78,12 @@ using boost::dynamic_pointer_cast;
using boost::optional;
using boost::scoped_ptr;
+int const PlayerProperty::VIDEO_CONTAINER_SIZE = 700;
+int const PlayerProperty::PLAYLIST = 701;
+int const PlayerProperty::FILM_CONTAINER = 702;
+int const PlayerProperty::FILM_VIDEO_FRAME_RATE = 703;
+int const PlayerProperty::DCP_DECODE_REDUCTION = 704;
+
Player::Player (shared_ptr<const Film> film, shared_ptr<const Playlist> playlist)
: _film (film)
, _playlist (playlist)
@@ -211,7 +217,7 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
) {
_have_valid_pieces = false;
- Changed (frequent);
+ Changed (property, frequent);
} else if (
property == SubtitleContentProperty::LINE_SPACING ||
@@ -231,7 +237,7 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
property == VideoContentProperty::FADE_OUT
) {
- Changed (frequent);
+ Changed (property, frequent);
}
}
@@ -247,14 +253,14 @@ Player::set_video_container_size (dcp::Size s)
_black_image.reset (new Image (AV_PIX_FMT_RGB24, _video_container_size, true));
_black_image->make_black ();
- Changed (false);
+ Changed (PlayerProperty::VIDEO_CONTAINER_SIZE, false);
}
void
Player::playlist_changed ()
{
_have_valid_pieces = false;
- Changed (false);
+ Changed (PlayerProperty::PLAYLIST, false);
}
void
@@ -266,13 +272,13 @@ Player::film_changed (Film::Property p)
*/
if (p == Film::CONTAINER) {
- Changed (false);
+ Changed (PlayerProperty::FILM_CONTAINER, false);
} else if (p == Film::VIDEO_FRAME_RATE) {
/* Pieces contain a FrameRateChange which contains the DCP frame rate,
so we need new pieces here.
*/
_have_valid_pieces = false;
- Changed (false);
+ Changed (PlayerProperty::FILM_VIDEO_FRAME_RATE, false);
} else if (p == Film::AUDIO_PROCESSOR) {
if (_film->audio_processor ()) {
_audio_processor = _film->audio_processor()->clone (_film->audio_frame_rate ());
@@ -337,7 +343,9 @@ Player::black_player_video_frame (Eyes eyes) const
_video_container_size,
eyes,
PART_WHOLE,
- PresetColourConversion::all().front().conversion
+ PresetColourConversion::all().front().conversion,
+ boost::weak_ptr<Content>(),
+ boost::optional<Frame>()
)
);
}
@@ -758,7 +766,9 @@ Player::video (weak_ptr<Piece> wp, ContentVideo video)
_video_container_size,
video.eyes,
video.part,
- piece->content->video->colour_conversion ()
+ piece->content->video->colour_conversion(),
+ piece->content,
+ video.frame
)
);
@@ -1078,5 +1088,5 @@ Player::set_dcp_decode_reduction (optional<int> reduction)
_dcp_decode_reduction = reduction;
_have_valid_pieces = false;
- Changed (false);
+ Changed (PlayerProperty::DCP_DECODE_REDUCTION, false);
}
diff --git a/src/lib/player.h b/src/lib/player.h
index 8142f8e7f..fc7117ba2 100644
--- a/src/lib/player.h
+++ b/src/lib/player.h
@@ -48,6 +48,16 @@ class AudioBuffers;
class ReferencedReelAsset;
class Shuffler;
+class PlayerProperty
+{
+public:
+ static int const VIDEO_CONTAINER_SIZE;
+ static int const PLAYLIST;
+ static int const FILM_CONTAINER;
+ static int const FILM_VIDEO_FRAME_RATE;
+ static int const DCP_DECODE_REDUCTION;
+};
+
/** @class Player
* @brief A class which can `play' a Playlist.
*/
@@ -62,6 +72,9 @@ public:
std::list<boost::shared_ptr<Font> > get_subtitle_fonts ();
std::list<ReferencedReelAsset> get_reel_assets ();
+ dcp::Size video_container_size () const {
+ return _video_container_size;
+ }
void set_video_container_size (dcp::Size);
void set_ignore_video ();
@@ -75,9 +88,10 @@ public:
* the last frame again it would look different. This is not emitted after
* a seek.
*
- * The parameter is true if these signals are currently likely to be frequent.
+ * The first parameter is what changed.
+ * The second parameter is true if these signals are currently likely to be frequent.
*/
- boost::signals2::signal<void (bool)> Changed;
+ boost::signals2::signal<void (int, bool)> Changed;
/** Emitted when a video frame is ready. These emissions happen in the correct order. */
boost::signals2::signal<void (boost::shared_ptr<PlayerVideo>, DCPTime)> Video;
diff --git a/src/lib/player_video.cc b/src/lib/player_video.cc
index 4784b1637..c24f9ccaa 100644
--- a/src/lib/player_video.cc
+++ b/src/lib/player_video.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
@@ -19,6 +19,8 @@
*/
#include "player_video.h"
+#include "content.h"
+#include "video_content.h"
#include "image.h"
#include "image_proxy.h"
#include "j2k_image_proxy.h"
@@ -33,6 +35,7 @@ extern "C" {
using std::string;
using std::cout;
using boost::shared_ptr;
+using boost::weak_ptr;
using boost::dynamic_pointer_cast;
using boost::optional;
using boost::function;
@@ -47,7 +50,9 @@ PlayerVideo::PlayerVideo (
dcp::Size out_size,
Eyes eyes,
Part part,
- optional<ColourConversion> colour_conversion
+ optional<ColourConversion> colour_conversion,
+ weak_ptr<Content> content,
+ optional<Frame> video_frame
)
: _in (in)
, _crop (crop)
@@ -57,6 +62,8 @@ PlayerVideo::PlayerVideo (
, _eyes (eyes)
, _part (part)
, _colour_conversion (colour_conversion)
+ , _content (content)
+ , _video_frame (video_frame)
{
}
@@ -272,7 +279,24 @@ PlayerVideo::shallow_copy () const
_out_size,
_eyes,
_part,
- _colour_conversion
+ _colour_conversion,
+ _content,
+ _video_frame
)
);
}
+
+/** Re-read crop, fade, inter/out size and colour conversion from our content */
+void
+PlayerVideo::reset_metadata (dcp::Size video_container_size, dcp::Size film_frame_size)
+{
+ shared_ptr<Content> content = _content.lock();
+ DCPOMATIC_ASSERT (content);
+ DCPOMATIC_ASSERT (_video_frame);
+
+ _crop = content->video->crop();
+ _fade = content->video->fade(_video_frame.get());
+ _inter_size = content->video->scale().size(content->video, video_container_size, film_frame_size);
+ _out_size = video_container_size;
+ _colour_conversion = content->video->colour_conversion();
+}
diff --git a/src/lib/player_video.h b/src/lib/player_video.h
index a6e39d66e..7cc00f46b 100644
--- a/src/lib/player_video.h
+++ b/src/lib/player_video.h
@@ -30,6 +30,7 @@ extern "C" {
#include <libavutil/pixfmt.h>
}
#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
class Image;
class ImageProxy;
@@ -50,7 +51,9 @@ public:
dcp::Size,
Eyes,
Part,
- boost::optional<ColourConversion>
+ boost::optional<ColourConversion>,
+ boost::weak_ptr<Content>,
+ boost::optional<Frame>
);
PlayerVideo (boost::shared_ptr<cxml::Node>, boost::shared_ptr<Socket>);
@@ -68,6 +71,8 @@ public:
void add_metadata (xmlpp::Node* node) const;
void send_binary (boost::shared_ptr<Socket> socket) const;
+ void reset_metadata (dcp::Size video_container_size, dcp::Size film_frame_size);
+
bool has_j2k () const;
dcp::Data j2k () const;
@@ -105,6 +110,10 @@ private:
Part _part;
boost::optional<ColourConversion> _colour_conversion;
boost::optional<PositionImage> _subtitle;
+ /** Content that we came from. This is so that reset_metadata() can work */
+ boost::weak_ptr<Content> _content;
+ /** Video frame that we came from. Again, this is for reset_metadata() */
+ boost::optional<Frame> _video_frame;
};
#endif
diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc
index d521e5385..11505e510 100644
--- a/src/wx/film_viewer.cc
+++ b/src/wx/film_viewer.cc
@@ -87,7 +87,6 @@ FilmViewer::FilmViewer (wxWindow* p, bool outline_content, bool jump_to_selected
, _timecode (new wxStaticText (this, wxID_ANY, wxT("")))
, _play_button (new wxToggleButton (this, wxID_ANY, _("Play")))
, _coalesce_player_changes (false)
- , _pending_player_change (false)
, _slider_being_moved (false)
, _was_running_before_slider (false)
, _audio (DCPOMATIC_RTAUDIO_API)
@@ -146,8 +145,8 @@ FilmViewer::FilmViewer (wxWindow* p, bool outline_content, bool jump_to_selected
if (_outline_content) {
_outline_content->Bind (wxEVT_CHECKBOX, boost::bind (&FilmViewer::refresh_panel, this));
}
- _left_eye->Bind (wxEVT_RADIOBUTTON, boost::bind (&FilmViewer::refresh, this));
- _right_eye->Bind (wxEVT_RADIOBUTTON, boost::bind (&FilmViewer::refresh, this));
+ _left_eye->Bind (wxEVT_RADIOBUTTON, boost::bind (&FilmViewer::slow_refresh, this));
+ _right_eye->Bind (wxEVT_RADIOBUTTON, boost::bind (&FilmViewer::slow_refresh, this));
_slider->Bind (wxEVT_SCROLL_THUMBTRACK, boost::bind (&FilmViewer::slider_moved, this, false));
_slider->Bind (wxEVT_SCROLL_PAGEUP, boost::bind (&FilmViewer::slider_moved, this, true));
_slider->Bind (wxEVT_SCROLL_PAGEDOWN, boost::bind (&FilmViewer::slider_moved, this, true));
@@ -222,7 +221,7 @@ FilmViewer::set_film (shared_ptr<Film> film)
_player->set_play_referenced ();
_film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1));
- _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1));
+ _player->Changed.connect (boost::bind (&FilmViewer::player_changed, this, _1, _2));
/* Keep about 1 second's worth of history samples */
_latency_history_count = _film->audio_frame_rate() / _audio_block_size;
@@ -230,7 +229,7 @@ FilmViewer::set_film (shared_ptr<Film> film)
recreate_butler ();
calculate_sizes ();
- refresh ();
+ slow_refresh ();
setup_sensitivity ();
}
@@ -283,27 +282,32 @@ FilmViewer::get ()
{
DCPOMATIC_ASSERT (_butler);
- pair<shared_ptr<PlayerVideo>, DCPTime> video;
do {
- video = _butler->get_video ();
+ _player_video = _butler->get_video ();
} while (
_film->three_d() &&
- ((_left_eye->GetValue() && video.first->eyes() == EYES_RIGHT) || (_right_eye->GetValue() && video.first->eyes() == EYES_LEFT))
+ ((_left_eye->GetValue() && _player_video.first->eyes() == EYES_RIGHT) || (_right_eye->GetValue() && _player_video.first->eyes() == EYES_LEFT))
);
_butler->rethrow ();
- if (!video.first) {
+ display_player_video ();
+}
+
+void
+FilmViewer::display_player_video ()
+{
+ if (!_player_video.first) {
_frame.reset ();
refresh_panel ();
return;
}
- if (_playing && (time() - video.second) > one_video_frame()) {
+ if (_playing && (time() - _player_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;
+ _video_position = _player_video.second;
++_dropped;
return;
}
@@ -326,17 +330,17 @@ FilmViewer::get ()
* image and convert it (from whatever the user has said it is) to RGB.
*/
- _frame = video.first->image (
+ _frame = _player_video.first->image (
bind (&Log::dcp_log, _film->log().get(), _1, _2),
bind (&PlayerVideo::always_rgb, _1),
false, true
);
- ImageChanged (video.first);
+ ImageChanged (_player_video.first);
- _video_position = video.second;
- _inter_position = video.first->inter_position ();
- _inter_size = video.first->inter_size ();
+ _video_position = _player_video.second;
+ _inter_position = _player_video.first->inter_position ();
+ _inter_size = _player_video.first->inter_size ();
refresh_panel ();
}
@@ -442,7 +446,7 @@ FilmViewer::panel_sized (wxSizeEvent& ev)
_panel_size.height = ev.GetSize().GetHeight();
calculate_sizes ();
- refresh ();
+ quick_refresh ();
update_position_label ();
update_position_slider ();
}
@@ -623,19 +627,31 @@ FilmViewer::forward_clicked (wxMouseEvent& ev)
}
void
-FilmViewer::player_changed (bool frequent)
+FilmViewer::player_changed (int property, bool frequent)
{
if (frequent) {
return;
}
if (_coalesce_player_changes) {
- _pending_player_change = true;
+ _pending_player_changes.push_back (property);
return;
}
calculate_sizes ();
- refresh ();
+ 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
+ ) {
+ quick_refresh ();
+ } else {
+ slow_refresh ();
+ }
update_position_label ();
update_position_slider ();
}
@@ -673,13 +689,25 @@ FilmViewer::film_changed (Film::Property p)
}
}
-/** Re-get the current frame */
+/** Re-get the current frame slowly by seeking */
void
-FilmViewer::refresh ()
+FilmViewer::slow_refresh ()
{
seek (_video_position, true);
}
+/** Re-get the current frame quickly by resetting the metadata in the PlayerVideo that we used last time */
+void
+FilmViewer::quick_refresh ()
+{
+ if (!_player_video.first) {
+ return;
+ }
+
+ _player_video.first->reset_metadata (_player->video_container_size(), _film->frame_size());
+ display_player_video ();
+}
+
void
FilmViewer::set_position (DCPTime p)
{
@@ -694,12 +722,11 @@ FilmViewer::set_coalesce_player_changes (bool c)
{
_coalesce_player_changes = c;
- if (c) {
- _pending_player_change = false;
- } else {
- if (_pending_player_change) {
- player_changed (false);
+ if (!c) {
+ BOOST_FOREACH (int i, _pending_player_changes) {
+ player_changed (i, false);
}
+ _pending_player_changes.clear ();
}
}
diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h
index 1c4f3c693..f769fd6b9 100644
--- a/src/wx/film_viewer.h
+++ b/src/wx/film_viewer.h
@@ -59,7 +59,8 @@ public:
void set_dcp_decode_reduction (boost::optional<int> reduction);
boost::optional<int> dcp_decode_reduction () const;
- void refresh ();
+ void slow_refresh ();
+ void quick_refresh ();
int dropped () const {
return _dropped;
@@ -82,10 +83,11 @@ private:
void rewind_clicked (wxMouseEvent &);
void back_clicked (wxMouseEvent &);
void forward_clicked (wxMouseEvent &);
- void player_changed (bool);
+ void player_changed (int, bool);
void update_position_label ();
void update_position_slider ();
void get ();
+ void display_player_video ();
void seek (DCPTime t, bool accurate);
void refresh_panel ();
void setup_sensitivity ();
@@ -122,10 +124,11 @@ private:
wxToggleButton* _play_button;
wxTimer _timer;
bool _coalesce_player_changes;
- bool _pending_player_change;
+ std::list<int> _pending_player_changes;
bool _slider_being_moved;
bool _was_running_before_slider;
+ std::pair<boost::shared_ptr<PlayerVideo>, DCPTime> _player_video;
boost::shared_ptr<const Image> _frame;
DCPTime _video_position;
Position<int> _inter_position;
diff --git a/src/wx/video_waveform_dialog.cc b/src/wx/video_waveform_dialog.cc
index 83253d335..c38dbf65d 100644
--- a/src/wx/video_waveform_dialog.cc
+++ b/src/wx/video_waveform_dialog.cc
@@ -106,7 +106,7 @@ VideoWaveformDialog::shown (wxShowEvent& ev)
{
_plot->set_enabled (ev.IsShown ());
if (ev.IsShown ()) {
- _viewer->refresh ();
+ _viewer->slow_refresh ();
}
}