Build Empty objects from the presence or absence of decoders in
authorCarl Hetherington <cth@carlh.net>
Mon, 3 Sep 2018 23:39:39 +0000 (00:39 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 3 Sep 2018 23:39:39 +0000 (00:39 +0100)
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
src/lib/empty.h
src/lib/player.cc
src/lib/player.h
test/empty_test.cc

index 68a153b0755d39a4869781847f12451fe042a4f8..1e6e1c3fb51d21e76b1d7f2c8b058bb97040a2e1 100644 (file)
@@ -25,6 +25,7 @@
 #include "content_part.h"
 #include "dcp_content.h"
 #include "dcpomatic_time_coalesce.h"
 #include "content_part.h"
 #include "dcp_content.h"
 #include "dcpomatic_time_coalesce.h"
+#include "piece.h"
 #include <boost/foreach.hpp>
 #include <iostream>
 
 #include <boost/foreach.hpp>
 #include <iostream>
 
@@ -34,12 +35,12 @@ using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 using boost::function;
 
 using boost::dynamic_pointer_cast;
 using boost::function;
 
-Empty::Empty (ContentList content, DCPTime length, function<shared_ptr<ContentPart> (Content *)> part)
+Empty::Empty (list<shared_ptr<Piece> > pieces, DCPTime length, function<bool (shared_ptr<Piece>)> part)
 {
        list<DCPTimePeriod> full;
 {
        list<DCPTimePeriod> full;
-       BOOST_FOREACH (shared_ptr<Content> i, content) {
-               if (part (i.get())) {
-                       full.push_back (DCPTimePeriod (i->position(), i->end()));
+       BOOST_FOREACH (shared_ptr<Piece> i, pieces) {
+               if (part(i)) {
+                       full.push_back (DCPTimePeriod (i->content->position(), i->content->end()));
                }
        }
 
                }
        }
 
index d8b00047fbe2e3520ed2a91349e4cb130bc173db..73548f72981c271721f4ef6d661b7e1f4be1bfb5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
-    Copyright (C) 2017 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 
     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"
 #include "playlist.h"
 #include "dcpomatic_time.h"
 #include "content_part.h"
 struct empty_test1;
 struct empty_test2;
 struct player_subframe_test;
 struct empty_test1;
 struct empty_test2;
 struct player_subframe_test;
+class Piece;
 
 class Empty
 {
 public:
        Empty () {}
 
 class Empty
 {
 public:
        Empty () {}
-       Empty (ContentList content, DCPTime length, boost::function<boost::shared_ptr<ContentPart> (Content *)> part);
+       Empty (std::list<boost::shared_ptr<Piece> > pieces, DCPTime length, boost::function<bool (boost::shared_ptr<Piece>)> part);
 
        DCPTime position () const {
                return _position;
 
        DCPTime position () const {
                return _position;
@@ -51,3 +55,5 @@ private:
        std::list<DCPTimePeriod> _periods;
        DCPTime _position;
 };
        std::list<DCPTimePeriod> _periods;
        DCPTime _position;
 };
+
+#endif
index 15f274e988625d6a67eab1f5eb5cf9d78f3b8884..a7440cb4ffaef40de59a1ca5d5a68259e340c49c 100644 (file)
@@ -123,6 +123,18 @@ Player::setup_pieces ()
        setup_pieces_unlocked ();
 }
 
        setup_pieces_unlocked ();
 }
 
+bool
+have_video (shared_ptr<Piece> piece)
+{
+       return piece->decoder && piece->decoder->video;
+}
+
+bool
+have_audio (shared_ptr<Piece> piece)
+{
+       return piece->decoder && piece->decoder->audio;
+}
+
 void
 Player::setup_pieces_unlocked ()
 {
 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;
 
        _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) {
                /* 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;
        }
 
                _suspended = false;
        }
 
index 95547f61c35d5fb2075901b1734e1e20cffca911..b3c4e82b42394453677f886a47b7f7f3899d03f2 100644 (file)
@@ -90,9 +90,6 @@ public:
 
        boost::signals2::signal<void (ChangeType, int, bool)> Change;
 
 
        boost::signals2::signal<void (ChangeType, int, bool)> Change;
 
-       /** The change suggested by a MayChange did not happen */
-       boost::signals2::signal<void ()> NotChanged;
-
        /** Emitted when a video frame is ready.  These emissions happen in the correct order. */
        boost::signals2::signal<void (boost::shared_ptr<PlayerVideo>, DCPTime)> Video;
        boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, DCPTime)> Audio;
        /** Emitted when a video frame is ready.  These emissions happen in the correct order. */
        boost::signals2::signal<void (boost::shared_ptr<PlayerVideo>, DCPTime)> Video;
        boost::signals2::signal<void (boost::shared_ptr<AudioBuffers>, 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 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 ();
 
        void setup_pieces ();
        void setup_pieces_unlocked ();
@@ -146,7 +145,7 @@ private:
        boost::shared_ptr<const Film> _film;
        boost::shared_ptr<const Playlist> _playlist;
 
        boost::shared_ptr<const Film> _film;
        boost::shared_ptr<const Playlist> _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<boost::shared_ptr<Piece> > _pieces;
 
        bool _suspended;
        std::list<boost::shared_ptr<Piece> > _pieces;
 
index 71397273942bbbe8312ec90bc1b4a42ffd0a8ff8..576577b97e1cba5701575a9267f926e42ac8e526 100644 (file)
 #include "lib/video_content.h"
 #include "lib/image_content.h"
 #include "lib/empty.h"
 #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 <boost/test/unit_test.hpp>
 
 using boost::shared_ptr;
 
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 
 using boost::shared_ptr;
 
+bool
+has_video (shared_ptr<Piece> piece)
+{
+        return piece->decoder && piece->decoder->video;
+}
+
 BOOST_AUTO_TEST_CASE (empty_test1)
 {
        shared_ptr<Film> film = new_test_film ("empty_test1");
 BOOST_AUTO_TEST_CASE (empty_test1)
 {
        shared_ptr<Film> 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));
 
        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> 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));
        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));
 
        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> 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));
        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));