From 1938b1b08d38fc199717d1875a61ef05e5b965de Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 4 Sep 2018 00:39:39 +0100 Subject: [PATCH] Build Empty objects from the presence or absence of decoders in Pieces, rather than the presence or absence of content. This seems better because of cases like encrypted DCPs without a a KDM: here we may have content but no decoder. --- src/lib/empty.cc | 9 +++++---- src/lib/empty.h | 10 ++++++++-- src/lib/player.cc | 17 +++++++++++++++-- src/lib/player.h | 7 +++---- test/empty_test.cc | 14 ++++++++++++-- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/lib/empty.cc b/src/lib/empty.cc index 68a153b07..1e6e1c3fb 100644 --- a/src/lib/empty.cc +++ b/src/lib/empty.cc @@ -25,6 +25,7 @@ #include "content_part.h" #include "dcp_content.h" #include "dcpomatic_time_coalesce.h" +#include "piece.h" #include #include @@ -34,12 +35,12 @@ using boost::shared_ptr; using boost::dynamic_pointer_cast; using boost::function; -Empty::Empty (ContentList content, DCPTime length, function (Content *)> part) +Empty::Empty (list > pieces, DCPTime length, function)> part) { list full; - BOOST_FOREACH (shared_ptr i, content) { - if (part (i.get())) { - full.push_back (DCPTimePeriod (i->position(), i->end())); + BOOST_FOREACH (shared_ptr i, pieces) { + if (part(i)) { + full.push_back (DCPTimePeriod (i->content->position(), i->content->end())); } } diff --git a/src/lib/empty.h b/src/lib/empty.h index d8b00047f..73548f729 100644 --- a/src/lib/empty.h +++ b/src/lib/empty.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2017 Carl Hetherington + Copyright (C) 2018 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,9 @@ */ +#ifndef DCPOMATIC_EMPTY_H +#define DCPOMATIC_EMPTY_H + #include "playlist.h" #include "dcpomatic_time.h" #include "content_part.h" @@ -26,12 +29,13 @@ struct empty_test1; struct empty_test2; struct player_subframe_test; +class Piece; class Empty { public: Empty () {} - Empty (ContentList content, DCPTime length, boost::function (Content *)> part); + Empty (std::list > pieces, DCPTime length, boost::function)> part); DCPTime position () const { return _position; @@ -51,3 +55,5 @@ private: std::list _periods; DCPTime _position; }; + +#endif diff --git a/src/lib/player.cc b/src/lib/player.cc index 15f274e98..a7440cb4f 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -123,6 +123,18 @@ Player::setup_pieces () setup_pieces_unlocked (); } +bool +have_video (shared_ptr piece) +{ + return piece->decoder && piece->decoder->video; +} + +bool +have_audio (shared_ptr piece) +{ + return piece->decoder && piece->decoder->audio; +} + void Player::setup_pieces_unlocked () { @@ -215,8 +227,8 @@ Player::setup_pieces_unlocked () } } - _black = Empty (_film->content(), _film->length(), bind(&Content::video, _1)); - _silent = Empty (_film->content(), _film->length(), bind(&Content::audio, _1)); + _black = Empty (_pieces, _film->length(), bind(&have_video, _1)); + _silent = Empty (_pieces, _film->length(), bind(&have_audio, _1)); _last_video_time = DCPTime (); _last_video_eyes = EYES_BOTH; @@ -238,6 +250,7 @@ Player::playlist_content_change (ChangeType type, int property, bool frequent) /* A change in our content has gone through. Re-build our pieces. */ setup_pieces (); } else if (type == CHANGE_TYPE_CANCELLED) { + boost::mutex::scoped_lock lm (_mutex); _suspended = false; } diff --git a/src/lib/player.h b/src/lib/player.h index 95547f61c..b3c4e82b4 100644 --- a/src/lib/player.h +++ b/src/lib/player.h @@ -90,9 +90,6 @@ public: boost::signals2::signal Change; - /** The change suggested by a MayChange did not happen */ - boost::signals2::signal NotChanged; - /** Emitted when a video frame is ready. These emissions happen in the correct order. */ boost::signals2::signal, DCPTime)> Video; boost::signals2::signal, DCPTime)> Audio; @@ -108,6 +105,8 @@ private: friend struct player_time_calculation_test2; friend struct player_time_calculation_test3; friend struct player_subframe_test; + friend struct empty_test1; + friend struct empty_test2; void setup_pieces (); void setup_pieces_unlocked (); @@ -146,7 +145,7 @@ private: boost::shared_ptr _film; boost::shared_ptr _playlist; - /** true if we are suspended (i.e. pass() and seek() do nothing */ + /** true if we are suspended (i.e. pass() and seek() do nothing) */ bool _suspended; std::list > _pieces; diff --git a/test/empty_test.cc b/test/empty_test.cc index 713972739..576577b97 100644 --- a/test/empty_test.cc +++ b/test/empty_test.cc @@ -24,11 +24,19 @@ #include "lib/video_content.h" #include "lib/image_content.h" #include "lib/empty.h" +#include "lib/player.h" +#include "lib/decoder.h" #include "test.h" #include using boost::shared_ptr; +bool +has_video (shared_ptr piece) +{ + return piece->decoder && piece->decoder->video; +} + BOOST_AUTO_TEST_CASE (empty_test1) { shared_ptr film = new_test_film ("empty_test1"); @@ -52,7 +60,8 @@ BOOST_AUTO_TEST_CASE (empty_test1) contentB->video->set_length (1); contentB->set_position (DCPTime::from_frames (7, vfr)); - Empty black (film->content(), film->length(), bind(&Content::video, _1)); + shared_ptr player (new Player(film, film->playlist())); + Empty black (player->_pieces, film->length(), bind(&has_video, _1)); BOOST_REQUIRE_EQUAL (black._periods.size(), 2); BOOST_CHECK (black._periods.front().from == DCPTime()); BOOST_CHECK (black._periods.front().to == DCPTime::from_frames(2, vfr)); @@ -84,7 +93,8 @@ BOOST_AUTO_TEST_CASE (empty_test2) contentB->video->set_length (1); contentB->set_position (DCPTime::from_frames (7, vfr)); - Empty black (film->content(), film->length(), bind(&Content::video, _1)); + shared_ptr player (new Player(film, film->playlist())); + Empty black (player->_pieces, film->length(), bind(&has_video, _1)); BOOST_REQUIRE_EQUAL (black._periods.size(), 1); BOOST_CHECK (black._periods.front().from == DCPTime::from_frames(3, vfr)); BOOST_CHECK (black._periods.front().to == DCPTime::from_frames(7, vfr)); -- 2.30.2