diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-05-21 17:32:28 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-05-21 17:32:28 +0100 |
| commit | 2255aedd15f985796d2e6f7fcc7fb412a5d98812 (patch) | |
| tree | 744d52adfdd226ce5b0220d62612710873fa77f4 /src | |
| parent | 2de990b0155fcb5c3dac821ef8c2659e903d2f6e (diff) | |
Various more hacks; basically trying to remove Regions as an unnecessary complexity.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_content.h | 2 | ||||
| -rw-r--r-- | src/lib/content.cc | 7 | ||||
| -rw-r--r-- | src/lib/content.h | 6 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 47 | ||||
| -rw-r--r-- | src/lib/ffmpeg_content.h | 23 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.cc | 6 | ||||
| -rw-r--r-- | src/lib/ffmpeg_decoder.h | 10 | ||||
| -rw-r--r-- | src/lib/film.cc | 16 | ||||
| -rw-r--r-- | src/lib/film.h | 2 | ||||
| -rw-r--r-- | src/lib/player.cc | 54 | ||||
| -rw-r--r-- | src/lib/player.h | 12 | ||||
| -rw-r--r-- | src/lib/playlist.cc | 118 | ||||
| -rw-r--r-- | src/lib/playlist.h | 32 | ||||
| -rw-r--r-- | src/lib/sndfile_content.h | 6 | ||||
| -rw-r--r-- | src/wx/audio_mapping_view.cc | 4 | ||||
| -rw-r--r-- | src/wx/ffmpeg_content_dialog.cc | 13 | ||||
| -rw-r--r-- | src/wx/ffmpeg_content_dialog.h | 5 | ||||
| -rw-r--r-- | src/wx/film_editor.cc | 66 | ||||
| -rw-r--r-- | src/wx/film_editor.h | 4 | ||||
| -rw-r--r-- | src/wx/imagemagick_content_dialog.cc | 3 | ||||
| -rw-r--r-- | src/wx/imagemagick_content_dialog.h | 3 | ||||
| -rw-r--r-- | src/wx/timeline.cc | 44 |
22 files changed, 264 insertions, 219 deletions
diff --git a/src/lib/audio_content.h b/src/lib/audio_content.h index 36c36992e..51f05efb0 100644 --- a/src/lib/audio_content.h +++ b/src/lib/audio_content.h @@ -23,6 +23,7 @@ #define DCPOMATIC_AUDIO_CONTENT_H #include "content.h" +#include "audio_mapping.h" namespace cxml { class Node; @@ -49,6 +50,7 @@ public: virtual ContentAudioFrame audio_length () const = 0; virtual int content_audio_frame_rate () const = 0; virtual int output_audio_frame_rate (boost::shared_ptr<const Film>) const = 0; + virtual AudioMapping audio_mapping () const = 0; }; #endif diff --git a/src/lib/content.cc b/src/lib/content.cc index 9c3bcd39d..578dafd67 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -1,3 +1,5 @@ +/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */ + /* Copyright (C) 2013 Carl Hetherington <cth@carlh.net> @@ -25,9 +27,11 @@ using std::string; using boost::shared_ptr; +using boost::lexical_cast; Content::Content (boost::filesystem::path f) : _file (f) + , _time (0) { } @@ -36,12 +40,14 @@ Content::Content (shared_ptr<const cxml::Node> node) { _file = node->string_child ("File"); _digest = node->string_child ("Digest"); + _time = node->number_child<Time> ("Time"); } Content::Content (Content const & o) : boost::enable_shared_from_this<Content> (o) , _file (o._file) , _digest (o._digest) + , _time (o._time) { } @@ -52,6 +58,7 @@ Content::as_xml (xmlpp::Node* node) const boost::mutex::scoped_lock lm (_mutex); node->add_child("File")->add_child_text (_file.string()); node->add_child("Digest")->add_child_text (_digest); + node->add_child("Time")->add_child_text (lexical_cast<string> (_time)); } void diff --git a/src/lib/content.h b/src/lib/content.h index 8db35891a..fd6288acc 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -60,6 +60,11 @@ public: return _digest; } + Time time () const { + boost::mutex::scoped_lock lm (_mutex); + return _time; + } + boost::signals2::signal<void (boost::weak_ptr<Content>, int)> Changed; protected: @@ -70,6 +75,7 @@ protected: private: boost::filesystem::path _file; std::string _digest; + Time _time; }; #endif diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index e898c02d0..fcc775f0a 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -57,7 +57,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const cxml::Node> node) { list<shared_ptr<cxml::Node> > c = node->node_children ("SubtitleStream"); for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) { - _subtitle_streams.push_back (FFmpegSubtitleStream (*i)); + _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (*i))); if ((*i)->optional_number_child<int> ("Selected")) { _subtitle_stream = _subtitle_streams.back (); } @@ -65,7 +65,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const cxml::Node> node) c = node->node_children ("AudioStream"); for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) { - _audio_streams.push_back (FFmpegAudioStream (*i)); + _audio_streams.push_back (shared_ptr<FFmpegAudioStream> (new FFmpegAudioStream (*i))); if ((*i)->optional_number_child<int> ("Selected")) { _audio_stream = _audio_streams.back (); } @@ -94,20 +94,20 @@ FFmpegContent::as_xml (xmlpp::Node* node) const boost::mutex::scoped_lock lm (_mutex); - for (vector<FFmpegSubtitleStream>::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { + for (vector<shared_ptr<FFmpegSubtitleStream> >::const_iterator i = _subtitle_streams.begin(); i != _subtitle_streams.end(); ++i) { xmlpp::Node* t = node->add_child("SubtitleStream"); - if (_subtitle_stream && *i == _subtitle_stream.get()) { + if (_subtitle_stream && *i == _subtitle_stream) { t->add_child("Selected")->add_child_text("1"); } - i->as_xml (t); + (*i)->as_xml (t); } - for (vector<FFmpegAudioStream>::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) { + for (vector<shared_ptr<FFmpegAudioStream> >::const_iterator i = _audio_streams.begin(); i != _audio_streams.end(); ++i) { xmlpp::Node* t = node->add_child("AudioStream"); - if (_audio_stream && *i == _audio_stream.get()) { + if (_audio_stream && *i == _audio_stream) { t->add_child("Selected")->add_child_text("1"); } - i->as_xml (t); + (*i)->as_xml (t); } } @@ -181,7 +181,7 @@ FFmpegContent::information () const } void -FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) +FFmpegContent::set_subtitle_stream (shared_ptr<FFmpegSubtitleStream> s) { { boost::mutex::scoped_lock lm (_mutex); @@ -192,7 +192,7 @@ FFmpegContent::set_subtitle_stream (FFmpegSubtitleStream s) } void -FFmpegContent::set_audio_stream (FFmpegAudioStream s) +FFmpegContent::set_audio_stream (shared_ptr<FFmpegAudioStream> s) { { boost::mutex::scoped_lock lm (_mutex); @@ -205,16 +205,23 @@ FFmpegContent::set_audio_stream (FFmpegAudioStream s) ContentAudioFrame FFmpegContent::audio_length () const { + int const cafr = content_audio_frame_rate (); + int const vfr = video_frame_rate (); + ContentVideoFrame const vl = video_length (); + + boost::mutex::scoped_lock lm (_mutex); if (!_audio_stream) { return 0; } - return video_frames_to_audio_frames (_video_length, content_audio_frame_rate(), video_frame_rate()); + return video_frames_to_audio_frames (vl, cafr, vfr); } int FFmpegContent::audio_channels () const { + boost::mutex::scoped_lock lm (_mutex); + if (!_audio_stream) { return 0; } @@ -225,6 +232,8 @@ FFmpegContent::audio_channels () const int FFmpegContent::content_audio_frame_rate () const { + boost::mutex::scoped_lock lm (_mutex); + if (!_audio_stream) { return 0; } @@ -271,6 +280,7 @@ FFmpegAudioStream::FFmpegAudioStream (shared_ptr<const cxml::Node> node) id = node->number_child<int> ("Id"); frame_rate = node->number_child<int> ("FrameRate"); channels = node->number_child<int64_t> ("Channels"); + mapping = AudioMapping (node->node_child ("Mapping")); } void @@ -280,6 +290,7 @@ FFmpegAudioStream::as_xml (xmlpp::Node* root) const root->add_child("Id")->add_child_text (lexical_cast<string> (id)); root->add_child("FrameRate")->add_child_text (lexical_cast<string> (frame_rate)); root->add_child("Channels")->add_child_text (lexical_cast<string> (channels)); + mapping.as_xml (root->add_child("Mapping")); } /** Construct a SubtitleStream from a value returned from to_string(). @@ -311,3 +322,17 @@ FFmpegContent::length (shared_ptr<const Film> film) const FrameRateConversion frc (video_frame_rate (), film->dcp_video_frame_rate ()); return video_length() * frc.factor() * TIME_HZ / film->dcp_video_frame_rate (); } + +AudioMapping +FFmpegContent::audio_mapping () const +{ + boost::mutex::scoped_lock lm (_mutex); + + if (!_audio_stream) { + return AudioMapping (); + } + + cout << "returning am from stream " << _audio_stream.get() << ".\n"; + return _audio_stream->mapping; +} + diff --git a/src/lib/ffmpeg_content.h b/src/lib/ffmpeg_content.h index 6c141b6c1..d79e4ec35 100644 --- a/src/lib/ffmpeg_content.h +++ b/src/lib/ffmpeg_content.h @@ -34,6 +34,7 @@ public: , id (i) , frame_rate (f) , channels (c) + , mapping (c) {} FFmpegAudioStream (boost::shared_ptr<const cxml::Node>); @@ -44,6 +45,7 @@ public: int id; int frame_rate; int channels; + AudioMapping mapping; }; extern bool operator== (FFmpegAudioStream const & a, FFmpegAudioStream const & b); @@ -98,35 +100,36 @@ public: ContentAudioFrame audio_length () const; int content_audio_frame_rate () const; int output_audio_frame_rate (boost::shared_ptr<const Film>) const; + AudioMapping audio_mapping () const; - std::vector<FFmpegSubtitleStream> subtitle_streams () const { + std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const { boost::mutex::scoped_lock lm (_mutex); return _subtitle_streams; } - boost::optional<FFmpegSubtitleStream> subtitle_stream () const { + boost::shared_ptr<FFmpegSubtitleStream> subtitle_stream () const { boost::mutex::scoped_lock lm (_mutex); return _subtitle_stream; } - std::vector<FFmpegAudioStream> audio_streams () const { + std::vector<boost::shared_ptr<FFmpegAudioStream> > audio_streams () const { boost::mutex::scoped_lock lm (_mutex); return _audio_streams; } - boost::optional<FFmpegAudioStream> audio_stream () const { + boost::shared_ptr<FFmpegAudioStream> audio_stream () const { boost::mutex::scoped_lock lm (_mutex); return _audio_stream; } - void set_subtitle_stream (FFmpegSubtitleStream); - void set_audio_stream (FFmpegAudioStream); + void set_subtitle_stream (boost::shared_ptr<FFmpegSubtitleStream>); + void set_audio_stream (boost::shared_ptr<FFmpegAudioStream>); private: - std::vector<FFmpegSubtitleStream> _subtitle_streams; - boost::optional<FFmpegSubtitleStream> _subtitle_stream; - std::vector<FFmpegAudioStream> _audio_streams; - boost::optional<FFmpegAudioStream> _audio_stream; + std::vector<boost::shared_ptr<FFmpegSubtitleStream> > _subtitle_streams; + boost::shared_ptr<FFmpegSubtitleStream> _subtitle_stream; + std::vector<boost::shared_ptr<FFmpegAudioStream> > _audio_streams; + boost::shared_ptr<FFmpegAudioStream> _audio_stream; }; #endif diff --git a/src/lib/ffmpeg_decoder.cc b/src/lib/ffmpeg_decoder.cc index adf16c940..a637160ae 100644 --- a/src/lib/ffmpeg_decoder.cc +++ b/src/lib/ffmpeg_decoder.cc @@ -141,11 +141,13 @@ FFmpegDecoder::setup_general () } _audio_streams.push_back ( - FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channels) + shared_ptr<FFmpegAudioStream> ( + new FFmpegAudioStream (stream_name (s), i, s->codec->sample_rate, s->codec->channels) + ) ); } else if (s->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - _subtitle_streams.push_back (FFmpegSubtitleStream (stream_name (s), i)); + _subtitle_streams.push_back (shared_ptr<FFmpegSubtitleStream> (new FFmpegSubtitleStream (stream_name (s), i))); } } diff --git a/src/lib/ffmpeg_decoder.h b/src/lib/ffmpeg_decoder.h index 760fc084d..f3f6b126b 100644 --- a/src/lib/ffmpeg_decoder.h +++ b/src/lib/ffmpeg_decoder.h @@ -1,3 +1,5 @@ +/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */ + /* Copyright (C) 2012 Carl Hetherington <cth@carlh.net> @@ -68,11 +70,11 @@ public: int sample_aspect_ratio_numerator () const; int sample_aspect_ratio_denominator () const; - std::vector<FFmpegSubtitleStream> subtitle_streams () const { + std::vector<boost::shared_ptr<FFmpegSubtitleStream> > subtitle_streams () const { return _subtitle_streams; } - std::vector<FFmpegAudioStream> audio_streams () const { + std::vector<boost::shared_ptr<FFmpegAudioStream> > audio_streams () const { return _audio_streams; } @@ -126,8 +128,8 @@ private: std::list<boost::shared_ptr<FilterGraph> > _filter_graphs; boost::mutex _filter_graphs_mutex; - std::vector<FFmpegSubtitleStream> _subtitle_streams; - std::vector<FFmpegAudioStream> _audio_streams; + std::vector<boost::shared_ptr<FFmpegSubtitleStream> > _subtitle_streams; + std::vector<boost::shared_ptr<FFmpegAudioStream> > _audio_streams; bool _decode_video; bool _decode_audio; diff --git a/src/lib/film.cc b/src/lib/film.cc index 1b5779f2d..37af4cb20 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -317,7 +317,7 @@ Film::make_dcp () throw MissingSettingError (_("format")); } - if (_playlist->regions().empty ()) { + if (_playlist->content().empty ()) { throw StringError (_("You must add some content to the DCP before creating it")); } @@ -697,11 +697,11 @@ Film::set_trust_content_headers (bool t) signal_changed (TRUST_CONTENT_HEADERS); - Playlist::RegionList regions = _playlist->regions (); - if (!_trust_content_headers && !regions.empty()) { + Playlist::ContentList content = _playlist->content (); + if (!_trust_content_headers && !content.empty()) { /* We just said that we don't trust the content's header */ - for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - examine_content ((*i)->content); + for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) { + examine_content (*i); } } } @@ -1040,10 +1040,10 @@ Film::playlist () const return _playlist; } -Playlist::RegionList -Film::regions () const +Playlist::ContentList +Film::content () const { - return _playlist->regions (); + return _playlist->content (); } void diff --git a/src/lib/film.h b/src/lib/film.h index 03d472cee..c0417382f 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -111,7 +111,7 @@ public: /* Proxies for some Playlist methods */ - Playlist::RegionList regions () const; + Playlist::ContentList content () const; Time length () const; bool has_subtitles () const; diff --git a/src/lib/player.cc b/src/lib/player.cc index 675fcae5c..5d4635e5a 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -89,12 +89,12 @@ Player::pass () */ Time earliest_pos = TIME_MAX; - shared_ptr<RegionDecoder> earliest; + shared_ptr<DecoderRecord> earliest; Time next_wait = TIME_MAX; - for (list<shared_ptr<RegionDecoder> >::iterator i = _decoders.begin(); i != _decoders.end(); ++i) { - Time const ts = (*i)->region->time; - Time const te = (*i)->region->time + (*i)->region->content->length (_film); + for (list<shared_ptr<DecoderRecord> >::iterator i = _decoders.begin(); i != _decoders.end(); ++i) { + Time const ts = (*i)->content->time(); + Time const te = (*i)->content->time() + (*i)->content->length (_film); if (ts <= _position && te > _position) { Time const pos = ts + (*i)->last; if (pos < earliest_pos) { @@ -121,24 +121,24 @@ Player::pass () } void -Player::process_video (shared_ptr<RegionDecoder> rd, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time) +Player::process_video (shared_ptr<DecoderRecord> dr, shared_ptr<const Image> image, bool same, shared_ptr<Subtitle> sub, Time time) { - shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (rd->decoder); + shared_ptr<VideoDecoder> vd = dynamic_pointer_cast<VideoDecoder> (dr->decoder); - Time const global_time = rd->region->time + time; + Time const global_time = dr->content->time() + time; while ((global_time - _last_video) > 1) { /* Fill in with black */ emit_black_frame (); } Video (image, same, sub, global_time); - rd->last = time; + dr->last = time; _last_video = global_time; _last_was_black = false; } void -Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffers> audio, Time time) +Player::process_audio (shared_ptr<DecoderRecord> dr, shared_ptr<const AudioBuffers> audio, Time time) { /* XXX: mapping */ @@ -172,7 +172,7 @@ Player::process_audio (shared_ptr<RegionDecoder> rd, shared_ptr<const AudioBuffe _audio_buffers.ensure_size (time - _last_audio + audio->frames()); _audio_buffers.accumulate (audio.get(), 0, _film->time_to_audio_frames (time - _last_audio)); - rd->last = time + _film->audio_frames_to_time (audio->frames ()); + dr->last = time + _film->audio_frames_to_time (audio->frames ()); } /** @return true on error */ @@ -212,34 +212,34 @@ Player::seek_forward () void Player::setup_decoders () { - list<shared_ptr<RegionDecoder> > old_decoders = _decoders; + list<shared_ptr<DecoderRecord> > old_decoders = _decoders; _decoders.clear (); - Playlist::RegionList regions = _playlist->regions (); - for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + Playlist::ContentList content = _playlist->content (); + for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) { - shared_ptr<RegionDecoder> rd (new RegionDecoder); - rd->region = *i; + shared_ptr<DecoderRecord> dr (new DecoderRecord); + dr->content = *i; /* XXX: into content? */ - shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> ((*i)->content); + shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i); if (fc) { shared_ptr<FFmpegDecoder> fd (new FFmpegDecoder (_film, fc, _video, _audio, _subtitles)); - fd->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4)); - fd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2)); + fd->Video.connect (bind (&Player::process_video, this, dr, _1, _2, _3, _4)); + fd->Audio.connect (bind (&Player::process_audio, this, dr, _1, _2)); - rd->decoder = fd; + dr->decoder = fd; } - shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> ((*i)->content); + shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i); if (ic) { shared_ptr<ImageMagickDecoder> id; /* See if we can re-use an old ImageMagickDecoder */ - for (list<shared_ptr<RegionDecoder> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) { + for (list<shared_ptr<DecoderRecord> >::const_iterator i = old_decoders.begin(); i != old_decoders.end(); ++i) { shared_ptr<ImageMagickDecoder> imd = dynamic_pointer_cast<ImageMagickDecoder> ((*i)->decoder); if (imd && imd->content() == ic) { id = imd; @@ -248,21 +248,21 @@ Player::setup_decoders () if (!id) { id.reset (new ImageMagickDecoder (_film, ic)); - id->Video.connect (bind (&Player::process_video, this, rd, _1, _2, _3, _4)); + id->Video.connect (bind (&Player::process_video, this, dr, _1, _2, _3, _4)); } - rd->decoder = id; + dr->decoder = id; } - shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> ((*i)->content); + shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i); if (sc) { shared_ptr<AudioDecoder> sd (new SndfileDecoder (_film, sc)); - sd->Audio.connect (bind (&Player::process_audio, this, rd, _1, _2)); + sd->Audio.connect (bind (&Player::process_audio, this, dr, _1, _2)); - rd->decoder = sd; + dr->decoder = sd; } - _decoders.push_back (rd); + _decoders.push_back (dr); } _position = 0; diff --git a/src/lib/player.h b/src/lib/player.h index 4979778ed..44b95e076 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -62,19 +62,19 @@ public: private: - struct RegionDecoder + struct DecoderRecord { - RegionDecoder () + DecoderRecord () : last (0) {} - boost::shared_ptr<Playlist::Region> region; + boost::shared_ptr<Content> content; boost::shared_ptr<Decoder> decoder; Time last; }; - void process_video (boost::shared_ptr<RegionDecoder>, boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, Time); - void process_audio (boost::shared_ptr<RegionDecoder>, boost::shared_ptr<const AudioBuffers>, Time); + void process_video (boost::shared_ptr<DecoderRecord>, boost::shared_ptr<const Image>, bool, boost::shared_ptr<Subtitle>, Time); + void process_audio (boost::shared_ptr<DecoderRecord>, boost::shared_ptr<const AudioBuffers>, Time); void setup_decoders (); void playlist_changed (); void content_changed (boost::weak_ptr<Content>, int); @@ -90,7 +90,7 @@ private: /** Our decoders are ready to go; if this is false the decoders must be (re-)created before they are used */ bool _have_valid_decoders; - std::list<boost::shared_ptr<RegionDecoder> > _decoders; + std::list<boost::shared_ptr<DecoderRecord> > _decoders; Time _position; AudioBuffers _audio_buffers; diff --git a/src/lib/playlist.cc b/src/lib/playlist.cc index 8db5c5fc2..ad71f87d7 100644 --- a/src/lib/playlist.cc +++ b/src/lib/playlist.cc @@ -58,11 +58,17 @@ Playlist::Playlist () Playlist::Playlist (shared_ptr<const Playlist> other) : _loop (other->_loop) { - for (RegionList::const_iterator i = other->_regions.begin(); i != other->_regions.end(); ++i) { - _regions.push_back (shared_ptr<Region> (new Region ((*i)->content->clone(), (*i)->time, this))); + for (ContentList::const_iterator i = other->_content.begin(); i != other->_content.end(); ++i) { + _content.push_back ((*i)->clone ()); } } +Playlist::~Playlist () +{ + _content.clear (); + reconnect (); +} + void Playlist::content_changed (weak_ptr<Content> c, int p) { @@ -74,14 +80,14 @@ Playlist::audio_digest () const { string t; - for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { - if (!dynamic_pointer_cast<const AudioContent> ((*i)->content)) { + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + if (!dynamic_pointer_cast<const AudioContent> (*i)) { continue; } - t += (*i)->content->digest (); + t += (*i)->digest (); - shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> ((*i)->content); + shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i); if (fc) { t += lexical_cast<string> (fc->audio_stream()->id); } @@ -97,13 +103,13 @@ Playlist::video_digest () const { string t; - for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { - if (!dynamic_pointer_cast<const VideoContent> ((*i)->content)) { + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + if (!dynamic_pointer_cast<const VideoContent> (*i)) { continue; } - t += (*i)->content->digest (); - shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> ((*i)->content); + t += (*i)->digest (); + shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i); if (fc && fc->subtitle_stream()) { t += fc->subtitle_stream()->id; } @@ -114,22 +120,34 @@ Playlist::video_digest () const return md5_digest (t.c_str(), t.length()); } +/** @param node <Playlist> node */ void Playlist::set_from_xml (shared_ptr<const cxml::Node> node) { - list<shared_ptr<cxml::Node> > c = node->node_children ("Region"); + list<shared_ptr<cxml::Node> > c = node->node_children ("Content"); for (list<shared_ptr<cxml::Node> >::iterator i = c.begin(); i != c.end(); ++i) { - _regions.push_back (shared_ptr<Region> (new Region (*i, this))); + string const type = (*i)->string_child ("Type"); + + boost::shared_ptr<Content> content; + + if (type == "FFmpeg") { + content.reset (new FFmpegContent (*i)); + } else if (type == "ImageMagick") { + content.reset (new ImageMagickContent (*i)); + } else if (type == "Sndfile") { + content.reset (new SndfileContent (*i)); + } } _loop = node->number_child<int> ("Loop"); } +/** @param node <Playlist> node */ void Playlist::as_xml (xmlpp::Node* node) { - for (RegionList::iterator i = _regions.begin(); i != _regions.end(); ++i) { - (*i)->as_xml (node->add_child ("Region")); + for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { + (*i)->as_xml (node->add_child ("Content")); } node->add_child("Loop")->add_child_text(lexical_cast<string> (_loop)); @@ -138,20 +156,21 @@ Playlist::as_xml (xmlpp::Node* node) void Playlist::add (shared_ptr<Content> c) { - _regions.push_back (shared_ptr<Region> (new Region (c, 0, this))); + _content.push_back (c); + reconnect (); Changed (); } void Playlist::remove (shared_ptr<Content> c) { - RegionList::iterator i = _regions.begin (); - while (i != _regions.end() && (*i)->content != c) { + ContentList::iterator i = _content.begin (); + while (i != _content.end() && *i != c) { ++i; } - if (i != _regions.end ()) { - _regions.erase (i); + if (i != _content.end ()) { + _content.erase (i); Changed (); } } @@ -166,8 +185,8 @@ Playlist::set_loop (int l) bool Playlist::has_subtitles () const { - for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { - shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> ((*i)->content); + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (*i); if (fc && !fc->subtitle_streams().empty()) { return true; } @@ -176,40 +195,6 @@ Playlist::has_subtitles () const return false; } -Playlist::Region::Region (shared_ptr<Content> c, Time t, Playlist* p) - : content (c) - , time (t) -{ - connection = c->Changed.connect (bind (&Playlist::content_changed, p, _1, _2)); -} - -Playlist::Region::Region (shared_ptr<const cxml::Node> node, Playlist* p) -{ - shared_ptr<const cxml::Node> content_node = node->node_child ("Content"); - string const type = content_node->string_child ("Type"); - - if (type == "FFmpeg") { - content.reset (new FFmpegContent (content_node)); - } else if (type == "ImageMagick") { - content.reset (new ImageMagickContent (content_node)); - } else if (type == "Sndfile") { - content.reset (new SndfileContent (content_node)); - } - - time = node->number_child<Time> ("Time"); - audio_mapping = AudioMapping (node->node_child ("AudioMapping")); - connection = content->Changed.connect (bind (&Playlist::content_changed, p, _1, _2)); -} - -void -Playlist::Region::as_xml (xmlpp::Node* node) const -{ - xmlpp::Node* sub = node->add_child ("Content"); - content->as_xml (sub); - node->add_child ("Time")->add_child_text (lexical_cast<string> (time)); - audio_mapping.as_xml (node->add_child ("AudioMapping")); -} - class FrameRateCandidate { public: @@ -248,8 +233,8 @@ Playlist::best_dcp_frame_rate () const while (i != candidates.end()) { float this_error = std::numeric_limits<float>::max (); - for (RegionList::const_iterator j = _regions.begin(); j != _regions.end(); ++j) { - shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> ((*j)->content); + for (ContentList::const_iterator j = _content.begin(); j != _content.end(); ++j) { + shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (*j); if (!vc) { continue; } @@ -276,10 +261,25 @@ Time Playlist::length (shared_ptr<const Film> film) const { Time len = 0; - for (RegionList::const_iterator i = _regions.begin(); i != _regions.end(); ++i) { - Time const t = (*i)->time + (*i)->content->length (film); + for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) { + Time const t = (*i)->time() + (*i)->length (film); len = max (len, t); } return len; } + +void +Playlist::reconnect () +{ + for (list<boost::signals2::connection>::iterator i = _content_connections.begin(); i != _content_connections.end(); ++i) { + i->disconnect (); + } + + _content_connections.clear (); + + for (ContentList::iterator i = _content.begin(); i != _content.end(); ++i) { + _content_connections.push_back ((*i)->Changed.connect (bind (&Playlist::content_changed, this, _1, _2))); + } +} + diff --git a/src/lib/playlist.h b/src/lib/playlist.h index f677f0ad7..e8cac0247 100644 --- a/src/lib/playlist.h +++ b/src/lib/playlist.h @@ -41,6 +41,7 @@ class SndfileContent; class SndfileDecoder; class Job; class Film; +class Region; /** @class Playlist * @brief A set of content files (video and audio), with knowledge of how they should be arranged into @@ -57,6 +58,7 @@ class Playlist public: Playlist (); Playlist (boost::shared_ptr<const Playlist>); + ~Playlist (); void as_xml (xmlpp::Node *); void set_from_xml (boost::shared_ptr<const cxml::Node>); @@ -66,30 +68,10 @@ public: bool has_subtitles () const; - struct Region - { - Region () - : time (0) - {} - - Region (boost::shared_ptr<Content> c, Time t, Playlist* p); - Region (boost::shared_ptr<const cxml::Node>, Playlist* p); - - void as_xml (xmlpp::Node *) const; - - boost::shared_ptr<Content> content; - Time time; - /* XXX: obviously not used for video-only; there should - really by AudioRegion / VideoRegion etc. - */ - AudioMapping audio_mapping; - boost::signals2::connection connection; - }; - - typedef std::vector<boost::shared_ptr<Region> > RegionList; + typedef std::vector<boost::shared_ptr<Content> > ContentList; - RegionList regions () const { - return _regions; + ContentList content () const { + return _content; } std::string audio_digest () const; @@ -109,9 +91,11 @@ public: private: void content_changed (boost::weak_ptr<Content>, int); + void reconnect (); - RegionList _regions; + ContentList _content; int _loop; + std::list<boost::signals2::connection> _content_connections; }; #endif diff --git a/src/lib/sndfile_content.h b/src/lib/sndfile_content.h index d930d7061..1ef4b3f02 100644 --- a/src/lib/sndfile_content.h +++ b/src/lib/sndfile_content.h @@ -62,6 +62,11 @@ public: } int output_audio_frame_rate (boost::shared_ptr<const Film>) const; + + AudioMapping audio_mapping () const { + boost::mutex::scoped_lock lm (_mutex); + return _audio_mapping; + } static bool valid_file (boost::filesystem::path); @@ -69,4 +74,5 @@ private: int _audio_channels; ContentAudioFrame _audio_length; int _audio_frame_rate; + AudioMapping _audio_mapping; }; diff --git a/src/wx/audio_mapping_view.cc b/src/wx/audio_mapping_view.cc index d0deca69e..43119ef4e 100644 --- a/src/wx/audio_mapping_view.cc +++ b/src/wx/audio_mapping_view.cc @@ -136,9 +136,9 @@ AudioMappingView::left_click (wxGridEvent& ev) AudioMapping mapping; for (int i = 0; i < _grid->GetNumberRows(); ++i) { - for (int j = 0; j < _grid->GetNumberCols(); ++j) { + for (int j = 1; j < _grid->GetNumberCols(); ++j) { if (_grid->GetCellValue (i, j) == wxT ("1")) { - mapping.add (i, static_cast<libdcp::Channel> (j)); + mapping.add (i, static_cast<libdcp::Channel> (j - 1)); } } } diff --git a/src/wx/ffmpeg_content_dialog.cc b/src/wx/ffmpeg_content_dialog.cc index 8bf8a8e35..06b58c58c 100644 --- a/src/wx/ffmpeg_content_dialog.cc +++ b/src/wx/ffmpeg_content_dialog.cc @@ -33,10 +33,9 @@ using boost::shared_ptr; using boost::lexical_cast; using boost::dynamic_pointer_cast; -FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<Playlist::Region> region) +FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<FFmpegContent> content) : wxDialog (parent, wxID_ANY, _("Video")) - , _region (region) - , _content (dynamic_pointer_cast<FFmpegContent> (region->content)) + , _content (content) { wxFlexGridSizer* grid = new wxFlexGridSizer (3, 6, 6); grid->AddGrowableCol (1, 1); @@ -52,9 +51,6 @@ FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<Playlist: grid->Add (_subtitle_stream, 1, wxEXPAND | wxALL, 6); grid->AddSpacer (0); - shared_ptr<FFmpegContent> content = _content.lock (); - assert (content); - _audio_stream->Clear (); vector<FFmpegAudioStream> a = content->audio_streams (); for (vector<FFmpegAudioStream>::iterator i = a.begin(); i != a.end(); ++i) { @@ -85,7 +81,7 @@ FFmpegContentDialog::FFmpegContentDialog (wxWindow* parent, shared_ptr<Playlist: overall_sizer->Add (grid, 1, wxEXPAND | wxALL, 6); _audio_mapping = new AudioMappingView (this); - _audio_mapping->set_mapping (region->audio_mapping); + _audio_mapping->set_mapping (content->audio_mapping ()); overall_sizer->Add (_audio_mapping, 1, wxEXPAND | wxALL, 6); wxSizer* buttons = CreateSeparatedButtonSizer (wxOK); @@ -166,6 +162,7 @@ FFmpegContentDialog::audio_mapping_changed (AudioMapping m) return; } - /* XXX: set mapping in playlist */ + cout << "setting map in stream " << content->audio_stream().get() << "\n"; + content->audio_stream()->mapping = m; } diff --git a/src/wx/ffmpeg_content_dialog.h b/src/wx/ffmpeg_content_dialog.h index 380b31f21..302c8166f 100644 --- a/src/wx/ffmpeg_content_dialog.h +++ b/src/wx/ffmpeg_content_dialog.h @@ -23,23 +23,22 @@ #include <boost/shared_ptr.hpp> #include <boost/weak_ptr.hpp> #include "lib/audio_mapping.h" -#include "lib/playlist.h" class wxSpinCtrl; class FFmpegContent; class AudioMappingView; +class Region; class FFmpegContentDialog : public wxDialog { public: - FFmpegContentDialog (wxWindow *, boost::shared_ptr<Playlist::Region>); + FFmpegContentDialog (wxWindow *, boost::shared_ptr<FFmpegContent>); private: void audio_stream_changed (wxCommandEvent &); void subtitle_stream_changed (wxCommandEvent &); void audio_mapping_changed (AudioMapping); - boost::weak_ptr<Playlist::Region> _region; boost::weak_ptr<FFmpegContent> _content; wxChoice* _audio_stream; wxStaticText* _audio_description; diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 226feaca2..177202d25 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -712,7 +712,7 @@ FilmEditor::film_content_changed (weak_ptr<Content> content, int property) } else if (property == VideoContentProperty::VIDEO_LENGTH || property == AudioContentProperty::AUDIO_LENGTH) { setup_length (); boost::shared_ptr<Content> c = content.lock (); - if (selected_region() && c == selected_region()->content) { + if (selected_content() && c == selected_content()) { setup_content_information (); } } else if (property == FFmpegContentProperty::AUDIO_STREAM) { @@ -1119,16 +1119,16 @@ FilmEditor::setup_content () _content->DeleteAllItems (); - Playlist::RegionList regions = _film->regions (); - for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { + Playlist::ContentList content = _film->content (); + for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) { int const t = _content->GetItemCount (); - _content->InsertItem (t, std_to_wx ((*i)->content->summary ())); - if ((*i)->content->summary() == selected_summary) { + _content->InsertItem (t, std_to_wx ((*i)->summary ())); + if ((*i)->summary() == selected_summary) { _content->SetItemState (t, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } } - if (selected_summary.empty () && !regions.empty ()) { + if (selected_summary.empty () && !content.empty ()) { /* Select the item of content if non was selected before */ _content->SetItemState (0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED); } @@ -1166,43 +1166,45 @@ FilmEditor::content_add_clicked (wxCommandEvent &) void FilmEditor::content_remove_clicked (wxCommandEvent &) { - shared_ptr<Playlist::Region> r = selected_region (); - if (r) { - _film->remove_content (r->content); + shared_ptr<Content> c = selected_content (); + if (c) { + _film->remove_content (c); } } void FilmEditor::content_activated (wxListEvent& ev) { - Playlist::RegionList r = _film->regions (); - assert (ev.GetIndex() >= 0 && size_t (ev.GetIndex()) < r.size ()); + Playlist::ContentList c = _film->content (); + assert (ev.GetIndex() >= 0 && size_t (ev.GetIndex()) < c.size ()); - region_properties (r[ev.GetIndex()]); + content_properties (c[ev.GetIndex()]); } void FilmEditor::content_properties_clicked (wxCommandEvent &) { - shared_ptr<Playlist::Region> r = selected_region (); - if (!r) { + shared_ptr<Content> c = selected_content (); + if (!c) { return; } - content_properties (r); + content_properties (c); } void -FilmEditor::region_properties (shared_ptr<Playlist::Region> region) +FilmEditor::content_properties (shared_ptr<Content> content) { - if (dynamic_pointer_cast<ImageMagickContent> (region->content)) { - ImageMagickContentDialog* d = new ImageMagickContentDialog (this, region); + shared_ptr<ImageMagickContent> ic = dynamic_pointer_cast<ImageMagickContent> (content); + if (ic) { + ImageMagickContentDialog* d = new ImageMagickContentDialog (this, ic); d->ShowModal (); d->Destroy (); } - if (dynamic_pointer_cast<FFmpegContent> (region->content)) { - FFmpegContentDialog* d = new FFmpegContentDialog (this, region); + shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (content); + if (fc) { + FFmpegContentDialog* d = new FFmpegContentDialog (this, fc); d->ShowModal (); d->Destroy (); } @@ -1218,13 +1220,13 @@ FilmEditor::content_selection_changed (wxListEvent &) void FilmEditor::setup_content_information () { - shared_ptr<Playlist::Region> r = selected_region (); - if (!r) { + shared_ptr<Content> c = selected_content (); + if (!c) { _content_information->SetValue (wxT ("")); return; } - _content_information->SetValue (std_to_wx (r->content->information ())); + _content_information->SetValue (std_to_wx (c->information ())); } void @@ -1232,31 +1234,31 @@ FilmEditor::setup_content_button_sensitivity () { _content_add->Enable (_generally_sensitive); - shared_ptr<Playlist::Region> selection = selected_region (); + shared_ptr<Content> selection = selected_content (); _content_properties->Enable ( selection && _generally_sensitive && - (dynamic_pointer_cast<ImageMagickContent> (selection->content) || dynamic_pointer_cast<FFmpegContent> (selection->content)) + (dynamic_pointer_cast<ImageMagickContent> (selection) || dynamic_pointer_cast<FFmpegContent> (selection)) ); _content_remove->Enable (selection && _generally_sensitive); _content_timeline->Enable (_generally_sensitive); } -shared_ptr<Playlist::Region> -FilmEditor::selected_region () +shared_ptr<Content> +FilmEditor::selected_content () { int const s = _content->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (s == -1) { - return shared_ptr<Playlist::Region> (); + return shared_ptr<Content> (); } - Playlist::RegionList r = _film->regions (); - if (s < 0 || size_t (s) >= r.size ()) { - return shared_ptr<Playlist::Region> (); + Playlist::ContentList c = _film->content (); + if (s < 0 || size_t (s) >= c.size ()) { + return shared_ptr<Content> (); } - return r[s]; + return c[s]; } void diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index c74d631ad..4bdba9979 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -111,8 +111,8 @@ private: void setup_loop_sensitivity (); void active_jobs_changed (bool); - boost::shared_ptr<Playlist::Region> selected_region (); - void region_properties (boost::shared_ptr<Playlist::Region>); + boost::shared_ptr<Content> selected_content (); + void content_properties (boost::shared_ptr<Content>); wxNotebook* _notebook; wxPanel* _film_panel; diff --git a/src/wx/imagemagick_content_dialog.cc b/src/wx/imagemagick_content_dialog.cc index 24b92fdaf..52f3cf1a7 100644 --- a/src/wx/imagemagick_content_dialog.cc +++ b/src/wx/imagemagick_content_dialog.cc @@ -1,3 +1,5 @@ +/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */ + /* Copyright (C) 2013 Carl Hetherington <cth@carlh.net> @@ -23,6 +25,7 @@ #include "wx_util.h" using boost::shared_ptr; +using boost::dynamic_pointer_cast; ImageMagickContentDialog::ImageMagickContentDialog (wxWindow* parent, shared_ptr<ImageMagickContent> content) : wxDialog (parent, wxID_ANY, _("Image")) diff --git a/src/wx/imagemagick_content_dialog.h b/src/wx/imagemagick_content_dialog.h index b22ff6817..9a4ea2694 100644 --- a/src/wx/imagemagick_content_dialog.h +++ b/src/wx/imagemagick_content_dialog.h @@ -1,3 +1,5 @@ +/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */ + /* Copyright (C) 2013 Carl Hetherington <cth@carlh.net> @@ -21,6 +23,7 @@ class wxSpinCtrl; class ImageMagickContent; +class Region; class ImageMagickContentDialog : public wxDialog { diff --git a/src/wx/timeline.cc b/src/wx/timeline.cc index 7e2243ccd..3a833e701 100644 --- a/src/wx/timeline.cc +++ b/src/wx/timeline.cc @@ -57,10 +57,9 @@ protected: class ContentView : public View { public: - ContentView (Timeline& tl, shared_ptr<const Content> c, Time s, int t) + ContentView (Timeline& tl, shared_ptr<const Content> c, int t) : View (tl) , _content (c) - , _start (s) , _track (t) , _selected (false) { @@ -75,6 +74,7 @@ public: return; } + Time const start = content->time (); Time const len = content->length (film); gc->SetPen (*wxBLACK_PEN); @@ -96,11 +96,11 @@ public: #endif wxGraphicsPath path = gc->CreatePath (); - path.MoveToPoint (time_x (_start), y_pos (_track)); - path.AddLineToPoint (time_x (_start + len), y_pos (_track)); - path.AddLineToPoint (time_x (_start + len), y_pos (_track + 1)); - path.AddLineToPoint (time_x (_start), y_pos (_track + 1)); - path.AddLineToPoint (time_x (_start), y_pos (_track)); + path.MoveToPoint (time_x (start), y_pos (_track)); + path.AddLineToPoint (time_x (start + len), y_pos (_track)); + path.AddLineToPoint (time_x (start + len), y_pos (_track + 1)); + path.AddLineToPoint (time_x (start), y_pos (_track + 1)); + path.AddLineToPoint (time_x (start), y_pos (_track)); gc->StrokePath (path); gc->FillPath (path); @@ -111,8 +111,8 @@ public: wxDouble name_leading; gc->GetTextExtent (name, &name_width, &name_height, &name_descent, &name_leading); - gc->Clip (wxRegion (time_x (_start), y_pos (_track), len * _timeline.pixels_per_time_unit(), _timeline.track_height())); - gc->DrawText (name, time_x (_start) + 12, y_pos (_track + 1) - name_height - 4); + gc->Clip (wxRegion (time_x (start), y_pos (_track), len * _timeline.pixels_per_time_unit(), _timeline.track_height())); + gc->DrawText (name, time_x (start) + 12, y_pos (_track + 1) - name_height - 4); gc->ResetClip (); } @@ -124,7 +124,12 @@ public: return Rect (); } - return Rect (time_x (_start), y_pos (_track), content->length (film) * _timeline.pixels_per_time_unit(), _timeline.track_height()); + return Rect ( + time_x (content->time ()), + y_pos (_track), + content->length (film) * _timeline.pixels_per_time_unit(), + _timeline.track_height() + ); } void set_selected (bool s) { @@ -147,7 +152,6 @@ private: } boost::weak_ptr<const Content> _content; - Time _start; int _track; bool _selected; }; @@ -155,8 +159,8 @@ private: class AudioContentView : public ContentView { public: - AudioContentView (Timeline& tl, shared_ptr<const Content> c, Time s, int t) - : ContentView (tl, c, s, t) + AudioContentView (Timeline& tl, shared_ptr<const Content> c, int t) + : ContentView (tl, c, t) {} private: @@ -174,8 +178,8 @@ private: class VideoContentView : public ContentView { public: - VideoContentView (Timeline& tl, shared_ptr<const Content> c, Time s, int t) - : ContentView (tl, c, s, t) + VideoContentView (Timeline& tl, shared_ptr<const Content> c, int t) + : ContentView (tl, c, t) {} private: @@ -319,13 +323,13 @@ Timeline::playlist_changed () _views.clear (); - Playlist::RegionList regions = fl->playlist()->regions (); + Playlist::ContentList content = fl->playlist()->content (); - for (Playlist::RegionList::iterator i = regions.begin(); i != regions.end(); ++i) { - if (dynamic_pointer_cast<VideoContent> ((*i)->content)) { - _views.push_back (shared_ptr<View> (new VideoContentView (*this, (*i)->content, (*i)->time, 0))); + for (Playlist::ContentList::iterator i = content.begin(); i != content.end(); ++i) { + if (dynamic_pointer_cast<VideoContent> (*i)) { + _views.push_back (shared_ptr<View> (new VideoContentView (*this, *i, 0))); } else { - _views.push_back (shared_ptr<View> (new AudioContentView (*this, (*i)->content, (*i)->time, 1))); + _views.push_back (shared_ptr<View> (new AudioContentView (*this, *i, 1))); } } |
