Player::Player (shared_ptr<const Film> film, Image::Alignment subtitle_alignment)
: _film (film)
, _suspended (0)
+ , _ignore_video(false)
+ , _ignore_audio(false)
+ , _ignore_text(false)
+ , _always_burn_open_subtitles(false)
+ , _fast(false)
, _tolerant (film->tolerant())
, _audio_merger (_film->audio_frame_rate())
, _subtitle_alignment (subtitle_alignment)
: _film (film)
, _playlist (playlist_)
, _suspended (0)
+ , _ignore_video(false)
+ , _ignore_audio(false)
+ , _ignore_text(false)
+ , _always_burn_open_subtitles(false)
+ , _fast(false)
, _tolerant (film->tolerant())
, _audio_merger (_film->audio_frame_rate())
{
bool
have_audio (shared_ptr<const Content> content)
{
- return static_cast<bool>(content->audio);
+ return static_cast<bool>(content->audio) && content->can_be_played();
}
auto old_pieces = _pieces;
_pieces.clear ();
- _shuffler.reset (new Shuffler());
- _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
+ auto playlist_content = playlist()->content();
+ bool const have_threed = std::any_of(
+ playlist_content.begin(),
+ playlist_content.end(),
+ [](shared_ptr<const Content> c) {
+ return c->video && (c->video->frame_type() == VideoFrameType::THREE_D_LEFT || c->video->frame_type() == VideoFrameType::THREE_D_RIGHT);
+ });
+
+
+ if (have_threed) {
+ _shuffler.reset(new Shuffler());
+ _shuffler->Video.connect(bind(&Player::video, this, _1, _2));
+ }
for (auto i: playlist()->content()) {
_pieces.push_back (piece);
if (decoder->video) {
- if (i->video->frame_type() == VideoFrameType::THREE_D_LEFT || i->video->frame_type() == VideoFrameType::THREE_D_RIGHT) {
+ if (have_threed) {
/* We need a Shuffler to cope with 3D L/R video data arriving out of sequence */
decoder->video->Data.connect (bind(&Shuffler::video, _shuffler.get(), weak_ptr<Piece>(piece), _1));
} else {
}
}
+ auto ignore_overlap = [](shared_ptr<VideoContent> v) {
+ return v && v->use() && v->frame_type() != VideoFrameType::THREE_D_LEFT && v->frame_type() != VideoFrameType::THREE_D_RIGHT;
+ };
+
for (auto i = _pieces.begin(); i != _pieces.end(); ++i) {
- if (auto video = (*i)->content->video) {
- if (video->use() && video->frame_type() != VideoFrameType::THREE_D_LEFT && video->frame_type() != VideoFrameType::THREE_D_RIGHT) {
- /* Look for content later in the content list with in-use video that overlaps this */
- auto period = DCPTimePeriod((*i)->content->position(), (*i)->content->end(_film));
- auto j = i;
- ++j;
- for (; j != _pieces.end(); ++j) {
- if ((*j)->content->video && (*j)->content->video->use()) {
- (*i)->ignore_video = DCPTimePeriod((*j)->content->position(), (*j)->content->end(_film)).overlap(period);
- }
+ if (ignore_overlap((*i)->content->video)) {
+ /* Look for content later in the content list with in-use video that overlaps this */
+ auto const period = DCPTimePeriod((*i)->content->position(), (*i)->content->end(_film));
+ for (auto j = std::next(i); j != _pieces.end(); ++j) {
+ if ((*j)->content->video && ignore_overlap((*j)->content->video)) {
+ (*i)->ignore_video = DCPTimePeriod((*j)->content->position(), (*j)->content->end(_film)).overlap(period);
}
}
}
}
-vector<FontData>
+vector<shared_ptr<Font>>
Player::get_subtitle_fonts ()
{
boost::mutex::scoped_lock lm (_mutex);
- vector<FontData> fonts;
- for (auto i: _pieces) {
- /* XXX: things may go wrong if there are duplicate font IDs
- with different font files.
- */
- auto f = i->decoder->fonts ();
- copy (f.begin(), f.end(), back_inserter(fonts));
+ vector<shared_ptr<Font>> fonts;
+ for (auto piece: _pieces) {
+ for (auto text: piece->content->text) {
+ auto text_fonts = text->fonts();
+ copy (text_fonts.begin(), text_fonts.end(), back_inserter(fonts));
+ }
}
return fonts;
void
Player::set_ignore_video ()
{
- boost::mutex::scoped_lock lm (_mutex);
_ignore_video = true;
- setup_pieces_unlocked ();
+ setup_pieces();
}
void
Player::set_ignore_audio ()
{
- boost::mutex::scoped_lock lm (_mutex);
_ignore_audio = true;
- setup_pieces_unlocked ();
+ setup_pieces();
}
void
Player::set_ignore_text ()
{
- boost::mutex::scoped_lock lm (_mutex);
_ignore_text = true;
- setup_pieces_unlocked ();
+ setup_pieces();
}
void
Player::set_always_burn_open_subtitles ()
{
- boost::mutex::scoped_lock lm (_mutex);
_always_burn_open_subtitles = true;
}
void
Player::set_fast ()
{
- boost::mutex::scoped_lock lm (_mutex);
_fast = true;
- setup_pieces_unlocked ();
+ setup_pieces();
}
Frame const reel_trim_start = min(reel_duration, max(int64_t(0), trim_start - offset_from_start));
Frame const reel_trim_end = min(reel_duration, max(int64_t(0), reel_duration - (offset_from_end - trim_end)));
- auto const from = max(DCPTime(), content->position() + DCPTime::from_frames(offset_from_start, frame_rate) - DCPTime::from_frames(trim_start, frame_rate));
+ auto const from = content->position() + std::max(DCPTime(), DCPTime::from_frames(offset_from_start - trim_start, frame_rate));
if (dcp->reference_video()) {
maybe_add_asset (reel_assets, reel->main_picture(), reel_trim_start, reel_trim_end, from, frame_rate);
}
);
if (latest_last_push_end != _stream_states.end()) {
- LOG_DEBUG_PLAYER("Leading stream is in %1 at %2", latest_last_push_end->second.piece->content->path(0), to_string(latest_last_push_end->second.last_push_end));
+ LOG_DEBUG_PLAYER("Leading audio stream is in %1 at %2", latest_last_push_end->second.piece->content->path(0), to_string(latest_last_push_end->second.last_push_end));
}
/* Now make a list of those streams that are less than ignore_streams_behind behind the leader */
}
if (done) {
- _shuffler->flush ();
+ if (_shuffler) {
+ _shuffler->flush ();
+ }
for (auto const& i: _delay) {
do_emit_video(i.first, i.second);
}
/* String subtitles (rendered to an image) */
if (!j.string.empty()) {
- auto s = render_text (j.string, j.fonts, _video_container_size, time, vfr);
+ auto s = render_text(j.string, _video_container_size, time, vfr);
copy (s.begin(), s.end(), back_inserter (captions));
}
}
}
s.set_in (dcp::Time(from.seconds(), 1000));
- ps.string.push_back (StringText (s, content->outline_width()));
- ps.add_fonts (content->fonts ());
+ ps.string.push_back (s);
}
_active_texts[static_cast<int>(content->type())].add_from(weak_content, ps, from);