}
Content::Content (Content const & o)
- : _file (o._file)
+ : boost::enable_shared_from_this<Content> (o)
+ , _file (o._file)
, _digest (o._digest)
{
boost::mutex::scoped_lock lm (_mutex);
_digest = d;
}
+
+void
+Content::signal_changed (int p)
+{
+ Changed (shared_from_this (), p);
+}
#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 {
class Job;
class Film;
-class Content
+class Content : public boost::enable_shared_from_this<Content>
{
public:
Content (boost::filesystem::path);
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:
: 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)
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
_subtitle_stream = s;
}
- Changed (FFmpegContentProperty::SUBTITLE_STREAM);
+ signal_changed (FFmpegContentProperty::SUBTITLE_STREAM);
}
void
_audio_stream = s;
}
- Changed (FFmpegContentProperty::AUDIO_STREAM);
+ signal_changed (FFmpegContentProperty::AUDIO_STREAM);
}
ContentAudioFrame
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;
, _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)
_content.push_back ((*i)->clone ());
}
+ _playlist->ContentChanged.connect (bind (&Film::content_changed, this, _1, _2));
+
_playlist->setup (_content);
}
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;
{
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);
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);
}
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));
}
}
void set_ffmpeg_subtitle_stream (FFmpegSubtitleStream);
void set_ffmpeg_audio_stream (FFmpegAudioStream);
-
+
/** Identifiers for the parts of our state;
used for signalling changes.
*/
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;
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 */
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.) */
{
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>
{
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);
+}
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);
};
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)
, _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
bool
Player::pass ()
{
- if (!_have_setup_decoders) {
+ if (!_have_valid_decoders) {
setup_decoders ();
- _have_setup_decoders = true;
+ _have_valid_decoders = true;
}
bool done = true;
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;
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;
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;
+}
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;
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;
using std::cout;
using std::vector;
using boost::shared_ptr;
+using boost::weak_ptr;
using boost::dynamic_pointer_cast;
Playlist::Playlist ()
_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) {
_sndfile.push_back (sc);
_audio_from = AUDIO_SNDFILE;
}
+
+ _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2)));
}
+
+ Changed ();
}
ContentAudioFrame
return _audio_from != AUDIO_NONE;
}
+void
+Playlist::content_changed (weak_ptr<Content> c, int p)
+{
+ ContentChanged (c, p);
+}
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;
};
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;
_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 (
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)
{
make_subtitle_panel ();
_notebook->AddPage (_subtitle_panel, _("Subtitles"), false);
- set_film (_film);
+ set_film (f);
connect_to_widgets ();
JobManager::instance()->ActiveJobsChanged.connect (
_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);
_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
}
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)
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));
}
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) {
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.
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
{
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
_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];
+}
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 &);
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 ();
void setup_content_information ();
void active_jobs_changed (bool);
+ boost::shared_ptr<Content> selected_content ();
wxNotebook* _notebook;
wxPanel* _film_panel;
wxButton* _content_earlier;
wxButton* _content_later;
wxTextCtrl* _content_information;
+ wxSpinCtrl* _imagemagick_video_length;
wxButton* _edit_dci_button;
wxChoice* _format;
wxStaticText* _format_description;
#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"
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)
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)
);
break;
case Film::CONTENT:
{
- setup_player ();
calculate_sizes ();
get_frame ();
_panel->Refresh ();
}
}
-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)
{
}
_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
private:
void film_changed (Film::Property);
- void film_content_changed (int);
void paint_panel (wxPaintEvent &);
void panel_sized (wxSizeEvent &);
void slider_moved (wxScrollEvent &);
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;