X-Git-Url: https://git.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fplayer.cc;h=53b1733330764aa5b76b988f58b096da6a331f62;hp=58ea4f2dea660ac6db81c51fbe55767573661c20;hb=d2e40a18eee940f1333c7e63d423b1d56e50c5e6;hpb=d1b4dbb793e2850d032ce3c91f0c91d045ae19dc diff --git a/src/lib/player.cc b/src/lib/player.cc index 58ea4f2de..53b173333 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -166,8 +166,19 @@ Player::setup_pieces_unlocked () 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 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()) { @@ -219,7 +230,7 @@ Player::setup_pieces_unlocked () _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), _1)); } else { @@ -810,7 +821,9 @@ Player::pass () } if (done) { - _shuffler->flush (); + if (_shuffler) { + _shuffler->flush (); + } for (auto const& i: _delay) { do_emit_video(i.first, i.second); } @@ -881,13 +894,13 @@ Player::open_subtitles_for_frame (DCPTime time) const void -Player::video (weak_ptr wp, ContentVideo video) +Player::video (weak_ptr weak_piece, ContentVideo video) { if (_suspended) { return; } - auto piece = wp.lock (); + auto piece = weak_piece.lock (); if (!piece) { return; } @@ -927,7 +940,7 @@ Player::video (weak_ptr wp, ContentVideo video) /* Fill if we have more than half a frame to do */ if ((fill_to - fill_from) > one_video_frame() / 2) { - auto last = _last_video.find (wp); + auto last = _last_video.find (weak_piece); if (_film->three_d()) { auto fill_to_eyes = video.eyes; if (fill_to_eyes == Eyes::BOTH) { @@ -971,7 +984,7 @@ Player::video (weak_ptr wp, ContentVideo video) auto const content_video = piece->content->video; - _last_video[wp] = std::make_shared( + _last_video[weak_piece] = std::make_shared( video.image, content_video->actual_crop(), content_video->fade (_film, video.frame), @@ -994,7 +1007,7 @@ Player::video (weak_ptr wp, ContentVideo video) DCPTime t = time; for (int i = 0; i < frc.repeat; ++i) { if (t < piece->content->end(_film)) { - emit_video (_last_video[wp], t); + emit_video (_last_video[weak_piece], t); } t += one_video_frame (); } @@ -1002,7 +1015,7 @@ Player::video (weak_ptr wp, ContentVideo video) void -Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_audio) +Player::audio (weak_ptr weak_piece, AudioStreamPtr stream, ContentAudio content_audio) { if (_suspended) { return; @@ -1010,7 +1023,7 @@ Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_a DCPOMATIC_ASSERT (content_audio.audio->frames() > 0); - auto piece = wp.lock (); + auto piece = weak_piece.lock (); if (!piece) { return; } @@ -1092,58 +1105,61 @@ Player::audio (weak_ptr wp, AudioStreamPtr stream, ContentAudio content_a void -Player::bitmap_text_start (weak_ptr wp, weak_ptr wc, ContentBitmapText subtitle) +Player::bitmap_text_start (weak_ptr weak_piece, weak_ptr weak_content, ContentBitmapText subtitle) { if (_suspended) { return; } - auto piece = wp.lock (); - auto text = wc.lock (); - if (!piece || !text) { + auto piece = weak_piece.lock (); + auto content = weak_content.lock (); + if (!piece || !content) { return; } - /* Apply content's subtitle offsets */ - subtitle.sub.rectangle.x += text->x_offset (); - subtitle.sub.rectangle.y += text->y_offset (); + PlayerText ps; + for (auto& sub: subtitle.subs) + { + /* Apply content's subtitle offsets */ + sub.rectangle.x += content->x_offset (); + sub.rectangle.y += content->y_offset (); - /* Apply a corrective translation to keep the subtitle centred after the scale that is coming up */ - subtitle.sub.rectangle.x -= subtitle.sub.rectangle.width * ((text->x_scale() - 1) / 2); - subtitle.sub.rectangle.y -= subtitle.sub.rectangle.height * ((text->y_scale() - 1) / 2); + /* Apply a corrective translation to keep the subtitle centred after the scale that is coming up */ + sub.rectangle.x -= sub.rectangle.width * ((content->x_scale() - 1) / 2); + sub.rectangle.y -= sub.rectangle.height * ((content->y_scale() - 1) / 2); - /* Apply content's subtitle scale */ - subtitle.sub.rectangle.width *= text->x_scale (); - subtitle.sub.rectangle.height *= text->y_scale (); + /* Apply content's subtitle scale */ + sub.rectangle.width *= content->x_scale (); + sub.rectangle.height *= content->y_scale (); - PlayerText ps; - auto image = subtitle.sub.image; + auto image = sub.image; - /* We will scale the subtitle up to fit _video_container_size */ - int const width = subtitle.sub.rectangle.width * _video_container_size.width; - int const height = subtitle.sub.rectangle.height * _video_container_size.height; - if (width == 0 || height == 0) { - return; - } + /* We will scale the subtitle up to fit _video_container_size */ + int const width = sub.rectangle.width * _video_container_size.width; + int const height = sub.rectangle.height * _video_container_size.height; + if (width == 0 || height == 0) { + return; + } - dcp::Size scaled_size (width, height); - ps.bitmap.push_back (BitmapText(image->scale(scaled_size, dcp::YUVToRGB::REC601, image->pixel_format(), Image::Alignment::PADDED, _fast), subtitle.sub.rectangle)); - DCPTime from (content_time_to_dcp (piece, subtitle.from())); + dcp::Size scaled_size (width, height); + ps.bitmap.push_back (BitmapText(image->scale(scaled_size, dcp::YUVToRGB::REC601, image->pixel_format(), Image::Alignment::PADDED, _fast), sub.rectangle)); + } - _active_texts[static_cast(text->type())].add_from (wc, ps, from); + DCPTime from(content_time_to_dcp(piece, subtitle.from())); + _active_texts[static_cast(content->type())].add_from(weak_content, ps, from); } void -Player::plain_text_start (weak_ptr wp, weak_ptr wc, ContentStringText subtitle) +Player::plain_text_start (weak_ptr weak_piece, weak_ptr weak_content, ContentStringText subtitle) { if (_suspended) { return; } - auto piece = wp.lock (); - auto text = wc.lock (); - if (!piece || !text) { + auto piece = weak_piece.lock (); + auto content = weak_content.lock (); + if (!piece || !content) { return; } @@ -1155,10 +1171,10 @@ Player::plain_text_start (weak_ptr wp, weak_ptr wc, Co } for (auto s: subtitle.subs) { - s.set_h_position (s.h_position() + text->x_offset ()); - s.set_v_position (s.v_position() + text->y_offset ()); - float const xs = text->x_scale(); - float const ys = text->y_scale(); + s.set_h_position (s.h_position() + content->x_offset()); + s.set_v_position (s.v_position() + content->y_offset()); + float const xs = content->x_scale(); + float const ys = content->y_scale(); float size = s.size(); /* Adjust size to express the common part of the scaling; @@ -1175,31 +1191,31 @@ Player::plain_text_start (weak_ptr wp, weak_ptr wc, Co } s.set_in (dcp::Time(from.seconds(), 1000)); - ps.string.push_back (StringText (s, text->outline_width())); - ps.add_fonts (text->fonts ()); + ps.string.push_back (StringText (s, content->outline_width())); + ps.add_fonts (content->fonts ()); } - _active_texts[static_cast(text->type())].add_from (wc, ps, from); + _active_texts[static_cast(content->type())].add_from(weak_content, ps, from); } void -Player::subtitle_stop (weak_ptr wp, weak_ptr wc, ContentTime to) +Player::subtitle_stop (weak_ptr weak_piece, weak_ptr weak_content, ContentTime to) { if (_suspended) { return; } - auto text = wc.lock (); - if (!text) { + auto content = weak_content.lock (); + if (!content) { return; } - if (!_active_texts[static_cast(text->type())].have(wc)) { + if (!_active_texts[static_cast(content->type())].have(weak_content)) { return; } - shared_ptr piece = wp.lock (); + auto piece = weak_piece.lock (); if (!piece) { return; } @@ -1210,11 +1226,11 @@ Player::subtitle_stop (weak_ptr wp, weak_ptr wc, Conte return; } - auto from = _active_texts[static_cast(text->type())].add_to (wc, dcp_to); + auto from = _active_texts[static_cast(content->type())].add_to(weak_content, dcp_to); - bool const always = (text->type() == TextType::OPEN_SUBTITLE && _always_burn_open_subtitles); - if (text->use() && !always && !text->burn()) { - Text (from.first, text->type(), text->dcp_track().get_value_or(DCPTextTrack()), DCPTimePeriod (from.second, dcp_to)); + bool const always = (content->type() == TextType::OPEN_SUBTITLE && _always_burn_open_subtitles); + if (content->use() && !always && !content->burn()) { + Text (from.first, content->type(), content->dcp_track().get_value_or(DCPTextTrack()), DCPTimePeriod(from.second, dcp_to)); } } @@ -1429,6 +1445,22 @@ Player::content_time_to_dcp (shared_ptr content, ContentTime t) } +optional +Player::dcp_to_content_time (shared_ptr content, DCPTime t) +{ + boost::mutex::scoped_lock lm (_mutex); + + for (auto i: _pieces) { + if (i->content == content) { + return dcp_to_content_time (i, t); + } + } + + /* We couldn't find this content; perhaps things are being changed over */ + return {}; +} + + shared_ptr Player::playlist () const {