+
+
+void
+Player::set_dcp_decode_reduction (optional<int> reduction)
+{
+ Change (ChangeType::PENDING, PlayerProperty::DCP_DECODE_REDUCTION, false);
+
+ {
+ boost::mutex::scoped_lock lm (_mutex);
+
+ if (reduction == _dcp_decode_reduction) {
+ lm.unlock ();
+ Change (ChangeType::CANCELLED, PlayerProperty::DCP_DECODE_REDUCTION, false);
+ return;
+ }
+
+ _dcp_decode_reduction = reduction;
+ setup_pieces_unlocked ();
+ }
+
+ Change (ChangeType::DONE, PlayerProperty::DCP_DECODE_REDUCTION, false);
+}
+
+
+optional<DCPTime>
+Player::content_time_to_dcp (shared_ptr<const Content> content, ContentTime t)
+{
+ boost::mutex::scoped_lock lm (_mutex);
+
+ for (auto i: _pieces) {
+ if (i->content == content) {
+ return content_time_to_dcp (i, t);
+ }
+ }
+
+ /* We couldn't find this content; perhaps things are being changed over */
+ return {};
+}
+
+
+shared_ptr<const Playlist>
+Player::playlist () const
+{
+ return _playlist ? _playlist : _film->playlist();
+}
+
+
+void
+Player::atmos (weak_ptr<Piece> weak_piece, ContentAtmos data)
+{
+ if (_suspended) {
+ return;
+ }
+
+ auto piece = weak_piece.lock ();
+ DCPOMATIC_ASSERT (piece);
+
+ auto const vfr = _film->video_frame_rate();
+
+ DCPTime const dcp_time = DCPTime::from_frames(data.frame, vfr) - DCPTime(piece->content->trim_start(), FrameRateChange(vfr, vfr));
+ if (dcp_time < piece->content->position() || dcp_time >= (piece->content->end(_film))) {
+ return;
+ }
+
+ Atmos (data.data, dcp_time, data.metadata);
+}
+