diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-04-06 12:26:12 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-04-06 12:26:12 +0100 |
| commit | 1bff0990433ab0ce588acaef7c589fa623bd998b (patch) | |
| tree | 65cba435e949deb6359bbf75866b52684116df06 /src | |
| parent | 3429cf48ff2ce056413588be4151be82c8114861 (diff) | |
Add interface to set up still image lengths.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/content.cc | 9 | ||||
| -rw-r--r-- | src/lib/content.h | 7 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 15 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.h | 6 | ||||
| -rw-r--r-- | src/lib/film.cc | 26 | ||||
| -rw-r--r-- | src/lib/film.h | 7 | ||||
| -rw-r--r-- | src/lib/imagemagick_content.cc | 15 | ||||
| -rw-r--r-- | src/lib/imagemagick_content.h | 8 | ||||
| -rw-r--r-- | src/lib/player.cc | 40 | ||||
| -rw-r--r-- | src/lib/player.h | 4 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 16 | ||||
| -rw-r--r-- | src/lib/playlist.h | 7 | ||||
| -rw-r--r-- | src/lib/sndfile_content.h | 4 | ||||
| -rw-r--r-- | src/lib/video_content.cc | 8 | ||||
| -rw-r--r-- | src/wx/film_editor.cc | 132 | ||||
| -rw-r--r-- | src/wx/film_editor.h | 9 | ||||
| -rw-r--r-- | src/wx/film_viewer.cc | 41 | ||||
| -rw-r--r-- | src/wx/film_viewer.h | 2 |
18 files changed, 237 insertions, 119 deletions
diff --git a/src/lib/content.cc b/src/lib/content.cc index 786b5fb09..9c3bcd39d 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -39,7 +39,8 @@ Content::Content (shared_ptr<const cxml::Node> node) } Content::Content (Content const & o) - : _file (o._file) + : boost::enable_shared_from_this<Content> (o) + , _file (o._file) , _digest (o._digest) { @@ -60,3 +61,9 @@ Content::examine (shared_ptr<Film>, shared_ptr<Job>, bool) boost::mutex::scoped_lock lm (_mutex); _digest = d; } + +void +Content::signal_changed (int p) +{ + Changed (shared_from_this (), p); +} diff --git a/src/lib/content.h b/src/lib/content.h index 11c7438a6..fc2672c95 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -23,6 +23,7 @@ #include <boost/filesystem.hpp> #include <boost/signals2.hpp> #include <boost/thread/mutex.hpp> +#include <boost/enable_shared_from_this.hpp> #include <libxml++/libxml++.h> namespace cxml { @@ -32,7 +33,7 @@ namespace cxml { class Job; class Film; -class Content +class Content : public boost::enable_shared_from_this<Content> { public: Content (boost::filesystem::path); @@ -50,9 +51,11 @@ public: return _file; } - boost::signals2::signal<void (int)> Changed; + boost::signals2::signal<void (boost::weak_ptr<Content>, int)> Changed; protected: + void signal_changed (int); + mutable boost::mutex _mutex; private: diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index 7834cb76e..cc95105e5 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -73,7 +73,6 @@ FFmpegContent::FFmpegContent (FFmpegContent const & o) : Content (o) , VideoContent (o) , AudioContent (o) - , boost::enable_shared_from_this<FFmpegContent> (o) , _subtitle_streams (o._subtitle_streams) , _subtitle_stream (o._subtitle_stream) , _audio_streams (o._audio_streams) @@ -148,11 +147,11 @@ FFmpegContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool quick) take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); - Changed (FFmpegContentProperty::SUBTITLE_STREAMS); - Changed (FFmpegContentProperty::SUBTITLE_STREAM); - Changed (FFmpegContentProperty::AUDIO_STREAMS); - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAMS); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAMS); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } string @@ -184,7 +183,7 @@ FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) _subtitle_stream = s; } - Changed (FFmpegContentProperty::SUBTITLE_STREAM); + signal_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void @@ -195,7 +194,7 @@ FFmpegContent::set_audio_stream (FFmpegAudioStream s) _audio_stream = s; } - Changed (FFmpegContentProperty::AUDIO_STREAM); + signal_changed (FFmpegContentProperty::AUDIO_STREAM); } ContentAudioFrame diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 3d69a2f99..cc603e680 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -77,12 +77,16 @@ public: static int const AUDIO_STREAM; }; -class FFmpegContent : public VideoContent, public AudioContent, public boost::enable_shared_from_this<FFmpegContent> +class FFmpegContent : public VideoContent, public AudioContent { public: FFmpegContent (boost::filesystem::path); FFmpegContent (boost::shared_ptr<const cxml::Node>); FFmpegContent (FFmpegContent const &); + + boost::shared_ptr<FFmpegContent> shared_from_this () { + return boost::dynamic_pointer_cast<FFmpegContent> (Content::shared_from_this ()); + } void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>, bool); std::string summary () const; diff --git a/src/lib/film.cc b/src/lib/film.cc index 976f65313..69d2a28e2 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -110,6 +110,8 @@ Film::Film (string d, bool must_exist) , _dirty (false) { set_dci_date_today (); + + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) @@ -179,6 +181,8 @@ Film::Film (Film const & o) _content.push_back ((*i)->clone ()); } + _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2)); + _playlist->setup (_content); } @@ -485,14 +489,17 @@ Film::read_metadata () for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) { string const type = (*i)->string_child ("Type"); + boost::shared_ptr<Content> c; if (type == "FFmpeg") { - _content.push_back (shared_ptr<Content> (new FFmpegContent (*i))); + c.reset (new FFmpegContent (*i)); } else if (type == "ImageMagick") { - _content.push_back (shared_ptr<Content> (new ImageMagickContent (*i))); + c.reset (new ImageMagickContent (*i)); } else if (type == "Sndfile") { - _content.push_back (shared_ptr<Content> (new SndfileContent (*i))); + c.reset (new SndfileContent (*i)); } + + _content.push_back (c); } _dirty = false; @@ -1037,7 +1044,6 @@ Film::add_content (shared_ptr<Content> c) { boost::mutex::scoped_lock lm (_state_mutex); _content.push_back (c); - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); } signal_changed (CONTENT); @@ -1054,14 +1060,6 @@ Film::remove_content (shared_ptr<Content> c) if (i != _content.end ()) { _content.erase (i); } - - for (list<boost::signals2::connection>::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { - i->disconnect (); - } - - for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { - _content_connections.push_back (c->Changed.connect (bind (&Film::content_changed, this, _1))); - } } signal_changed (CONTENT); @@ -1238,13 +1236,13 @@ Film::set_ffmpeg_audio_stream (FFmpegAudioStream s) } void -Film::content_changed (int p) +Film::content_changed (boost::weak_ptr<Content> c, int p) { if (p == VideoContentProperty::VIDEO_FRAME_RATE) { set_dcp_frame_rate (best_dcp_frame_rate (video_frame_rate ())); } if (ui_signaller) { - ui_signaller->emit (boost::bind (boost::ref (ContentChanged), p)); + ui_signaller->emit (boost::bind (boost::ref (ContentChanged), c, p)); } } diff --git a/src/lib/film.h b/src/lib/film.h index 091ac4f97..9c5f561e6 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -119,7 +119,7 @@ public: void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream); void set_ffmpeg_audio_stream (FFmpegAudioStream); - + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -299,7 +299,7 @@ public: mutable boost::signals2::signal<void (Property)> Changed; /** Emitted when some property of our content has changed */ - mutable boost::signals2::signal<void (int)> ContentChanged; + mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged; boost::signals2::signal<void ()> AudioAnalysisSucceeded; @@ -312,7 +312,7 @@ private: void analyse_audio_finished (); std::string video_state_identifier () const; void read_metadata (); - void content_changed (int); + void content_changed (boost::weak_ptr<Content>, int); boost::shared_ptr<FFmpegContent> ffmpeg () const; /** Log to write to */ @@ -334,7 +334,6 @@ private: bool _use_dci_name; bool _trust_content_headers; ContentList _content; - std::list<boost::signals2::connection> _content_connections; /** The type of content that this Film represents (feature, trailer etc.) */ DCPContentType const * _dcp_content_type; /** The format to present this Film in (flat, scope, etc.) */ diff --git a/src/lib/imagemagick_content.cc b/src/lib/imagemagick_content.cc index f7c76a34d..912c180a8 100644 --- a/src/lib/imagemagick_content.cc +++ b/src/lib/imagemagick_content.cc @@ -72,13 +72,13 @@ ImageMagickContent::examine (shared_ptr<Film> film, shared_ptr<Job> job, bool qu { boost::mutex::scoped_lock lm (_mutex); - /* XXX */ + /* Initial length */ _video_length = 10 * 24; } take_from_video_decoder (decoder); - Changed (VideoContentProperty::VIDEO_LENGTH); + signal_changed (VideoContentProperty::VIDEO_LENGTH); } shared_ptr<Content> @@ -86,3 +86,14 @@ ImageMagickContent::clone () const { return shared_ptr<Content> (new ImageMagickContent (*this)); } + +void +ImageMagickContent::set_video_length (ContentVideoFrame len) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _video_length = len; + } + + signal_changed (VideoContentProperty::VIDEO_LENGTH); +} diff --git a/src/lib/imagemagick_content.h b/src/lib/imagemagick_content.h index 2ca58f255..b1e7f9495 100644 --- a/src/lib/imagemagick_content.h +++ b/src/lib/imagemagick_content.h @@ -24,16 +24,22 @@ namespace cxml { class Node; } -class ImageMagickContent : public VideoContent, public boost::enable_shared_from_this<ImageMagickContent> +class ImageMagickContent : public VideoContent { public: ImageMagickContent (boost::filesystem::path); ImageMagickContent (boost::shared_ptr<const cxml::Node>); + boost::shared_ptr<ImageMagickContent> shared_from_this () { + return boost::dynamic_pointer_cast<ImageMagickContent> (Content::shared_from_this ()); + }; + void examine (boost::shared_ptr<Film>, boost::shared_ptr<Job>, bool); std::string summary () const; void as_xml (xmlpp::Node *) const; boost::shared_ptr<Content> clone () const; + void set_video_length (ContentVideoFrame); + static bool valid_file (boost::filesystem::path); }; diff --git a/src/lib/player.cc b/src/lib/player.cc index 6e2e7ed14..60917ba09 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -27,6 +27,8 @@ using std::list; using boost::shared_ptr; +using boost::weak_ptr; +using boost::dynamic_pointer_cast; Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) : _film (f) @@ -34,11 +36,12 @@ Player::Player (shared_ptr<const Film> f, shared_ptr<const Playlist> p) , _video (true) , _audio (true) , _subtitles (true) - , _have_setup_decoders (false) + , _have_valid_decoders (false) , _ffmpeg_decoder_done (false) , _video_sync (true) { - + _playlist->Changed.connect (bind (&Player::playlist_changed, this)); + _playlist->ContentChanged.connect (bind (&Player::content_changed, this, _1, _2)); } void @@ -62,9 +65,9 @@ Player::disable_subtitles () bool Player::pass () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool done = true; @@ -138,9 +141,9 @@ Player::process_audio (shared_ptr<AudioBuffers> b) bool Player::seek (double t) { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -183,9 +186,9 @@ Player::seek (double t) bool Player::seek_to_last () { - if (!_have_setup_decoders) { + if (!_have_valid_decoders) { setup_decoders (); - _have_setup_decoders = true; + _have_valid_decoders = true; } bool r = false; @@ -278,3 +281,24 @@ Player::last_video_time () const return 0; } + +void +Player::content_changed (weak_ptr<Content> w, int p) +{ + shared_ptr<Content> c = w.lock (); + if (!c) { + return; + } + + if (p == VideoContentProperty::VIDEO_LENGTH) { + if (dynamic_pointer_cast<FFmpegContent> (c)) { + _have_valid_decoders = false; + } + } +} + +void +Player::playlist_changed () +{ + _have_valid_decoders = false; +} diff --git a/src/lib/player.h b/src/lib/player.h index bc728d8f2..79203692e 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -56,6 +56,8 @@ private: void process_video (boost::shared_ptr<Image> i, bool same, boost::shared_ptr<Subtitle> s); void process_audio (boost::shared_ptr<AudioBuffers>); void setup_decoders (); + void playlist_changed (); + void content_changed (boost::weak_ptr<Content>, int); boost::shared_ptr<const Film> _film; boost::shared_ptr<const Playlist> _playlist; @@ -64,7 +66,7 @@ private: bool _audio; bool _subtitles; - bool _have_setup_decoders; + bool _have_valid_decoders; boost::shared_ptr<FFmpegDecoder> _ffmpeg_decoder; bool _ffmpeg_decoder_done; std::list<boost::shared_ptr<ImageMagickDecoder> > _imagemagick_decoders; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 0a4803f6e..e0220ef6f 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -31,6 +31,7 @@ using std::list; using std::cout; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; Playlist::Playlist () @@ -50,6 +51,12 @@ Playlist::setup (ContentList content) _imagemagick.clear (); _sndfile.clear (); + for (list<boost::signals2::connection>::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { + i->disconnect (); + } + + _content_connections.clear (); + for (ContentList::const_iterator i = content.begin(); i != content.end(); ++i) { shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i); if (fc) { @@ -74,7 +81,11 @@ Playlist::setup (ContentList content) _sndfile.push_back (sc); _audio_from = AUDIO_SNDFILE; } + + _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); } + + Changed (); } ContentAudioFrame @@ -208,3 +219,8 @@ Playlist::has_audio () const return _audio_from != AUDIO_NONE; } +void +Playlist::content_changed (weak_ptr<Content> c, int p) +{ + ContentChanged (c, p); +} diff --git a/src/lib/playlist.h b/src/lib/playlist.h index 29a52d433..1a24a0227 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -84,12 +84,19 @@ public: std::list<boost::shared_ptr<const SndfileContent> > sndfile () const { return _sndfile; } + + mutable boost::signals2::signal<void ()> Changed; + mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged; private: + void content_changed (boost::weak_ptr<Content>, int); + VideoFrom _video_from; AudioFrom _audio_from; boost::shared_ptr<const FFmpegContent> _ffmpeg; std::list<boost::shared_ptr<const ImageMagickContent> > _imagemagick; std::list<boost::shared_ptr<const SndfileContent> > _sndfile; + + std::list<boost::signals2::connection> _content_connections; }; diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index 90845ba08..b696b57a5 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -28,6 +28,10 @@ class SndfileContent : public AudioContent public: SndfileContent (boost::filesystem::path); SndfileContent (boost::shared_ptr<const cxml::Node>); + + boost::shared_ptr<SndfileContent> shared_from_this () { + return boost::dynamic_pointer_cast<SndfileContent> (Content::shared_from_this ()); + } std::string summary () const; std::string information () const; diff --git a/src/lib/video_content.cc b/src/lib/video_content.cc index 14897c570..8176c5c41 100644 --- a/src/lib/video_content.cc +++ b/src/lib/video_content.cc @@ -81,14 +81,18 @@ VideoContent::take_from_video_decoder (shared_ptr<VideoDecoder> d) _video_frame_rate = vfr; } - Changed (VideoContentProperty::VIDEO_SIZE); - Changed (VideoContentProperty::VIDEO_FRAME_RATE); + signal_changed (VideoContentProperty::VIDEO_SIZE); + signal_changed (VideoContentProperty::VIDEO_FRAME_RATE); } string VideoContent::information () const { + if (video_size().width == 0 || video_size().height == 0) { + return ""; + } + stringstream s; s << String::compose ( diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index efbf212d0..58fc077a3 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -59,13 +59,13 @@ using std::setprecision; using std::list; using std::vector; using boost::shared_ptr; +using boost::weak_ptr; using boost::dynamic_pointer_cast; using boost::lexical_cast; /** @param f Film to edit */ FilmEditor::FilmEditor (shared_ptr<Film> f, wxWindow* parent) : wxPanel (parent) - , _film (f) , _generally_sensitive (true) , _audio_dialog (0) { @@ -84,7 +84,7 @@ FilmEditor::FilmEditor (shared_ptr<Film> f, wxWindow* parent) make_subtitle_panel (); _notebook->AddPage (_subtitle_panel, _("Subtitles"), false); - set_film (_film); + set_film (f); connect_to_widgets (); JobManager::instance()->ActiveJobsChanged.connect ( @@ -200,6 +200,7 @@ FilmEditor::connect_to_widgets () _content_remove->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_remove_clicked), 0, this); _content_earlier->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_earlier_clicked), 0, this); _content_later->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (FilmEditor::content_later_clicked), 0, this); + _imagemagick_video_length->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::imagemagick_video_length_changed), 0, this); _left_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::left_crop_changed), 0, this); _right_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::right_crop_changed), 0, this); _top_crop->Connect (wxID_ANY, wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEventHandler (FilmEditor::top_crop_changed), 0, this); @@ -354,6 +355,21 @@ FilmEditor::make_content_panel () _content_information = new wxTextCtrl (_content_panel, wxID_ANY, wxT ("\n\n\n\n"), wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE); _content_sizer->Add (_content_information, 1, wxEXPAND | wxALL, 6); + + wxFlexGridSizer* grid = new wxFlexGridSizer (2, 4, 4); + _content_sizer->Add (grid, 0, wxEXPAND | wxALL, 6); + + { + add_label_to_sizer (grid, _content_panel, (_("Duration"))); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _imagemagick_video_length = new wxSpinCtrl (_content_panel); + s->Add (_imagemagick_video_length); + /// TRANSLATORS: this is an abbreviation for seconds, the unit of time + add_label_to_sizer (s, _content_panel, _("s")); + grid->Add (s); + } + + _imagemagick_video_length->SetRange (1, 3600); } void @@ -690,7 +706,7 @@ FilmEditor::film_changed (Film::Property p) } void -FilmEditor::film_content_changed (int p) +FilmEditor::film_content_changed (weak_ptr<Content> content, int property) { if (!_film) { /* We call this method ourselves (as well as using it as a signal handler) @@ -699,23 +715,31 @@ FilmEditor::film_content_changed (int p) return; } - if (p == FFmpegContentProperty::SUBTITLE_STREAMS) { + if (property == FFmpegContentProperty::SUBTITLE_STREAMS) { setup_subtitle_control_sensitivity (); setup_streams (); - } else if (p == FFmpegContentProperty::AUDIO_STREAMS) { + } else if (property == FFmpegContentProperty::AUDIO_STREAMS) { setup_streams (); setup_show_audio_sensitivity (); - } else if (p == VideoContentProperty::VIDEO_LENGTH) { + } else if (property == VideoContentProperty::VIDEO_LENGTH) { setup_length (); - setup_content_information (); - } else if (p == FFmpegContentProperty::AUDIO_STREAM) { + + boost::shared_ptr<Content> c = content.lock (); + if (c && c == selected_content()) { + setup_content_information (); + shared_ptr<ImageMagickContent> im = dynamic_pointer_cast<ImageMagickContent> (c); + if (im) { + checked_set (_imagemagick_video_length, im->video_length() / 24); + } + } + } else if (property == FFmpegContentProperty::AUDIO_STREAM) { if (_film->ffmpeg_audio_stream()) { checked_set (_ffmpeg_audio_stream, boost::lexical_cast<string> (_film->ffmpeg_audio_stream()->id)); } setup_dcp_name (); setup_audio_details (); setup_show_audio_sensitivity (); - } else if (p == FFmpegContentProperty::SUBTITLE_STREAM) { + } else if (property == FFmpegContentProperty::SUBTITLE_STREAM) { if (_film->ffmpeg_subtitle_stream()) { checked_set (_ffmpeg_subtitle_stream, boost::lexical_cast<string> (_film->ffmpeg_subtitle_stream()->id)); } @@ -797,13 +821,17 @@ FilmEditor::dcp_content_type_changed (wxCommandEvent &) void FilmEditor::set_film (shared_ptr<Film> f) { + if (_film == f) { + return; + } + _film = f; set_things_sensitive (_film != 0); if (_film) { _film->Changed.connect (bind (&FilmEditor::film_changed, this, _1)); - _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1)); + _film->ContentChanged.connect (bind (&FilmEditor::film_content_changed, this, _1, _2)); } if (_film) { @@ -838,10 +866,10 @@ FilmEditor::set_film (shared_ptr<Film> f) film_changed (Film::DCI_METADATA); film_changed (Film::DCP_FRAME_RATE); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); - film_content_changed (FFmpegContentProperty::AUDIO_STREAMS); - film_content_changed (FFmpegContentProperty::AUDIO_STREAM); + film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAMS); + film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::SUBTITLE_STREAM); + film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::AUDIO_STREAMS); + film_content_changed (boost::shared_ptr<Content> (), FFmpegContentProperty::AUDIO_STREAM); } /** Updates the sensitivity of lots of widgets to a given value. @@ -1224,40 +1252,28 @@ FilmEditor::content_add_clicked (wxCommandEvent &) void FilmEditor::content_remove_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr<Content> c = selected_content (); + if (c) { + _film->remove_content (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->remove_content (c[s]); } void FilmEditor::content_earlier_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr<Content> c = selected_content (); + if (c) { + _film->move_content_earlier (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->move_content_earlier (c[s]); } void FilmEditor::content_later_clicked (wxCommandEvent &) { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { - return; + shared_ptr<Content> c = selected_content (); + if (c) { + _film->move_content_later (c); } - - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _film->move_content_later (c[s]); } void @@ -1265,20 +1281,27 @@ FilmEditor::content_item_selected (wxListEvent &) { setup_content_button_sensitivity (); setup_content_information (); + + shared_ptr<Content> c = selected_content (); + if (c) { + shared_ptr<ImageMagickContent> im = dynamic_pointer_cast<ImageMagickContent> (c); + _imagemagick_video_length->Enable (im); + if (im) { + checked_set (_imagemagick_video_length, im->video_length() / 24); + } + } } void FilmEditor::setup_content_information () { - int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); - if (s == -1) { + shared_ptr<Content> c = selected_content (); + if (!c) { _content_information->SetValue (wxT ("")); return; } - ContentList c = _film->content (); - assert (s >= 0 && size_t (s) < c.size ()); - _content_information->SetValue (std_to_wx (c[s]->information ())); + _content_information->SetValue (std_to_wx (c->information ())); } void @@ -1291,3 +1314,32 @@ FilmEditor::setup_content_button_sensitivity () _content_earlier->Enable (have_selection && _generally_sensitive); _content_later->Enable (have_selection && _generally_sensitive); } + +void +FilmEditor::imagemagick_video_length_changed (wxCommandEvent &) +{ + shared_ptr<Content> c = selected_content (); + if (!c) { + return; + } + + shared_ptr<ImageMagickContent> im = dynamic_pointer_cast<ImageMagickContent> (c); + if (!im) { + return; + } + + im->set_video_length (_imagemagick_video_length->GetValue() * 24); +} + +shared_ptr<Content> +FilmEditor::selected_content () +{ + int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + if (s == -1) { + return shared_ptr<Content> (); + } + + ContentList c = _film->content (); + assert (s >= 0 && size_t (s) < c.size ()); + return c[s]; +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 97d1e0dd3..2870714f9 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -68,6 +68,7 @@ private: void content_remove_clicked (wxCommandEvent &); void content_earlier_clicked (wxCommandEvent &); void content_later_clicked (wxCommandEvent &); + void imagemagick_video_length_changed (wxCommandEvent &); void format_changed (wxCommandEvent &); void trim_start_changed (wxCommandEvent &); void trim_end_changed (wxCommandEvent &); @@ -87,13 +88,11 @@ private: void ffmpeg_subtitle_stream_changed (wxCommandEvent &); void dcp_frame_rate_changed (wxCommandEvent &); void best_dcp_frame_rate_clicked (wxCommandEvent &); + void edit_filters_clicked (wxCommandEvent &); /* Handle changes to the model */ void film_changed (Film::Property); - void film_content_changed (int); - - /* Button clicks */ - void edit_filters_clicked (wxCommandEvent &); + void film_content_changed (boost::weak_ptr<Content>, int); void set_things_sensitive (bool); void setup_formats (); @@ -109,6 +108,7 @@ private: void setup_content_information (); void active_jobs_changed (bool); + boost::shared_ptr<Content> selected_content (); wxNotebook* _notebook; wxPanel* _film_panel; @@ -134,6 +134,7 @@ private: wxButton* _content_earlier; wxButton* _content_later; wxTextCtrl* _content_information; + wxSpinCtrl* _imagemagick_video_length; wxButton* _edit_dci_button; wxChoice* _format; wxStaticText* _format_description; diff --git a/src/wx/film_viewer.cc b/src/wx/film_viewer.cc index 316a42a66..08358c519 100644 --- a/src/wx/film_viewer.cc +++ b/src/wx/film_viewer.cc @@ -37,6 +37,7 @@ #include "lib/player.h" #include "lib/video_content.h" #include "lib/ffmpeg_content.h" +#include "lib/imagemagick_content.h" #include "film_viewer.h" #include "wx_util.h" #include "video_decoder.h" @@ -47,6 +48,7 @@ using std::max; using std::cout; using std::list; using boost::shared_ptr; +using boost::dynamic_pointer_cast; using libdcp::Size; FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p) @@ -84,6 +86,16 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p) set_film (f); + _player = _film->player (); + _player->disable_audio (); + _player->disable_video_sync (); + + /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them + on and off without needing obtain a new Player. + */ + + _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); + JobManager::instance()->ActiveJobsChanged.connect ( bind (&FilmViewer::active_jobs_changed, this, _1) ); @@ -99,7 +111,6 @@ FilmViewer::film_changed (Film::Property p) break; case Film::CONTENT: { - setup_player (); calculate_sizes (); get_frame (); _panel->Refresh (); @@ -124,32 +135,6 @@ FilmViewer::film_changed (Film::Property p) } void -FilmViewer::setup_player () -{ - _player = _film->player (); - _player->disable_audio (); - _player->disable_video_sync (); - - /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them - on and off without needing obtain a new Player. - */ - - _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3)); -} - -void -FilmViewer::film_content_changed (int p) -{ - if (p == VideoContentProperty::VIDEO_LENGTH || p == VideoContentProperty::VIDEO_SIZE) { - setup_player (); - calculate_sizes (); - get_frame (); - _panel->Refresh (); - _v_sizer->Layout (); - } -} - -void FilmViewer::set_film (shared_ptr<Film> f) { if (_film == f) { @@ -163,14 +148,12 @@ FilmViewer::set_film (shared_ptr<Film> f) } _film->Changed.connect (boost::bind (&FilmViewer::film_changed, this, _1)); - _film->ContentChanged.connect (boost::bind (&FilmViewer::film_content_changed, this, _1)); film_changed (Film::CONTENT); film_changed (Film::FORMAT); film_changed (Film::WITH_SUBTITLES); film_changed (Film::SUBTITLE_OFFSET); film_changed (Film::SUBTITLE_SCALE); - film_content_changed (FFmpegContentProperty::SUBTITLE_STREAM); } void diff --git a/src/wx/film_viewer.h b/src/wx/film_viewer.h index bf956ef95..22f443703 100644 --- a/src/wx/film_viewer.h +++ b/src/wx/film_viewer.h @@ -61,7 +61,6 @@ public: private: void film_changed (Film::Property); - void film_content_changed (int); void paint_panel (wxPaintEvent &); void panel_sized (wxSizeEvent &); void slider_moved (wxScrollEvent &); @@ -75,7 +74,6 @@ private: void raw_to_display (); void get_frame (); void active_jobs_changed (bool); - void setup_player (); boost::shared_ptr<Film> _film; boost::shared_ptr<Player> _player; |
