Add some tests; fix failure to make DCP when there is a bit of audio right at the...
authorCarl Hetherington <cth@carlh.net>
Wed, 12 Jul 2017 14:21:31 +0000 (15:21 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 12 Jul 2017 14:21:31 +0000 (15:21 +0100)
src/lib/player.cc
src/lib/player.h
src/lib/video_content.cc
src/lib/video_content.h
test/data
test/empty_test.cc
test/player_test.cc
test/reels_test.cc

index adaee931e1dcb19347672a59a575df96c8fac614..3ed0e4f4506661a2c286dfa49ef0c3e5fb302964 100644 (file)
@@ -156,8 +156,8 @@ Player::setup_pieces ()
                }
        }
 
                }
        }
 
-       _black = Empty (_playlist, bind(&Content::video, _1));
-       _silent = Empty (_playlist, bind(&Content::audio, _1));
+       _black = Empty (_film, bind(&Content::video, _1));
+       _silent = Empty (_film, bind(&Content::audio, _1));
 
        _last_video_time = DCPTime ();
        _last_audio_time = DCPTime ();
 
        _last_video_time = DCPTime ();
        _last_audio_time = DCPTime ();
@@ -552,7 +552,7 @@ Player::pass ()
 
        /* Emit any audio that is ready */
 
 
        /* Emit any audio that is ready */
 
-       DCPTime pull_to = _playlist->length ();
+       DCPTime pull_to = _film->length ();
        for (map<AudioStreamPtr, StreamState>::const_iterator i = _stream_states.begin(); i != _stream_states.end(); ++i) {
                if (!i->second.piece->done && i->second.last_push_end < pull_to) {
                        pull_to = i->second.last_push_end;
        for (map<AudioStreamPtr, StreamState>::const_iterator i = _stream_states.begin(); i != _stream_states.end(); ++i) {
                if (!i->second.piece->done && i->second.last_push_end < pull_to) {
                        pull_to = i->second.last_push_end;
index 230f7f4f8a7a041d7678ff61190a6247db097bdd..ee7f89aaac8773f23e3df0d5204ef3cbc8adcfdc 100644 (file)
@@ -89,6 +89,7 @@ private:
        friend struct player_time_calculation_test1;
        friend struct player_time_calculation_test2;
        friend struct player_time_calculation_test3;
        friend struct player_time_calculation_test1;
        friend struct player_time_calculation_test2;
        friend struct player_time_calculation_test3;
+       friend struct player_subframe_test;
 
        void setup_pieces ();
        void flush ();
 
        void setup_pieces ();
        void flush ();
index 30a4630893ac4d2b97cd9bc9999577936e1a4711..92219b4c7cf9be404289d09f1be614f10f75144c 100644 (file)
@@ -538,3 +538,9 @@ VideoContent::use_template (shared_ptr<const VideoContent> c)
        _fade_in = c->_fade_in;
        _fade_out = c->_fade_out;
 }
        _fade_in = c->_fade_in;
        _fade_out = c->_fade_out;
 }
+
+void
+VideoContent::modify_position (DCPTime& pos) const
+{
+       pos = pos.ceil (_parent->film()->video_frame_rate());
+}
index 623a1858bc48c6031b602c05bdb27f5814de8eb0..19ea113f76fed45232cf3e8e06ffc2a66beb8d2c 100644 (file)
@@ -168,6 +168,8 @@ public:
        void take_from_examiner (boost::shared_ptr<VideoExaminer>);
        void add_properties (std::list<UserProperty> &) const;
 
        void take_from_examiner (boost::shared_ptr<VideoExaminer>);
        void add_properties (std::list<UserProperty> &) const;
 
+       void modify_position (DCPTime& pos) const;
+
        static boost::shared_ptr<VideoContent> from_xml (Content* parent, cxml::ConstNodePtr, int);
 
 private:
        static boost::shared_ptr<VideoContent> from_xml (Content* parent, cxml::ConstNodePtr, int);
 
 private:
index e4f09e5b45400f04a868f29409b291b27c426c08..afcff70aee5dd8d2fd83164cd56e9d842b132858 160000 (submodule)
--- a/test/data
+++ b/test/data
@@ -1 +1 @@
-Subproject commit e4f09e5b45400f04a868f29409b291b27c426c08
+Subproject commit afcff70aee5dd8d2fd83164cd56e9d842b132858
index b7dce1ab89ca12c0bfde11701ca094c225079c2e..326ae9530cb15d248d85f6866dace92a3c58902b 100644 (file)
@@ -43,17 +43,59 @@ BOOST_AUTO_TEST_CASE (empty_test1)
        film->examine_and_add_content (contentB);
        wait_for_jobs ();
 
        film->examine_and_add_content (contentB);
        wait_for_jobs ();
 
+       int const vfr = film->video_frame_rate ();
+
        contentA->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
        contentA->video->set_length (3);
        contentA->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
        contentA->video->set_length (3);
-       contentA->set_position (DCPTime::from_frames (2, film->video_frame_rate ()));
+       contentA->set_position (DCPTime::from_frames (2, vfr));
        contentB->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
        contentB->video->set_length (1);
        contentB->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
        contentB->video->set_length (1);
-       contentB->set_position (DCPTime::from_frames (7, film->video_frame_rate ()));
+       contentB->set_position (DCPTime::from_frames (7, vfr));
 
 
-       Empty black (film->playlist(), bind(&Content::video, _1));
+       Empty black (film, bind(&Content::video, _1));
        BOOST_REQUIRE_EQUAL (black._periods.size(), 2);
        BOOST_CHECK (black._periods.front().from == DCPTime());
        BOOST_REQUIRE_EQUAL (black._periods.size(), 2);
        BOOST_CHECK (black._periods.front().from == DCPTime());
-       BOOST_CHECK (black._periods.front().to == DCPTime::from_frames(2, film->video_frame_rate()));
-       BOOST_CHECK (black._periods.back().from == DCPTime::from_frames(5, film->video_frame_rate()));
-       BOOST_CHECK (black._periods.back().to == DCPTime::from_frames(7, film->video_frame_rate()));
+       BOOST_CHECK (black._periods.front().to == DCPTime::from_frames(2, vfr));
+       BOOST_CHECK (black._periods.back().from == DCPTime::from_frames(5, vfr));
+       BOOST_CHECK (black._periods.back().to == DCPTime::from_frames(7, vfr));
+}
+
+/** Some tests where the first empty period is not at time 0 */
+BOOST_AUTO_TEST_CASE (empty_test2)
+{
+       shared_ptr<Film> film = new_test_film ("empty_test1");
+       film->set_dcp_content_type (DCPContentType::from_isdcf_name ("FTR"));
+       film->set_name ("empty_test1");
+       film->set_container (Ratio::from_id ("185"));
+       film->set_sequence (false);
+       shared_ptr<ImageContent> contentA (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
+       shared_ptr<ImageContent> contentB (new ImageContent (film, "test/data/simple_testcard_640x480.png"));
+
+       film->examine_and_add_content (contentA);
+       film->examine_and_add_content (contentB);
+       wait_for_jobs ();
+
+       int const vfr = film->video_frame_rate ();
+
+       contentA->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       contentA->video->set_length (3);
+       contentA->set_position (DCPTime(0));
+       contentB->video->set_scale (VideoContentScale (Ratio::from_id ("185")));
+       contentB->video->set_length (1);
+       contentB->set_position (DCPTime::from_frames (7, vfr));
+
+       Empty black (film, bind(&Content::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));
+
+       /* position should initially be the start of the first empty period */
+       BOOST_CHECK (black.position() == DCPTime::from_frames(3, vfr));
+
+       /* check that done() works */
+       BOOST_CHECK (!black.done ());
+       black.set_position (DCPTime::from_frames (4, vfr));
+       BOOST_CHECK (!black.done ());
+       black.set_position (DCPTime::from_frames (7, vfr));
+       BOOST_CHECK (black.done ());
 }
 }
index a1b0f1148f32423bebb08bbc478b619603808007..14a1fa0c62966cef73c04c05a1b595074a8ea2f8 100644 (file)
@@ -23,8 +23,6 @@
  *  @ingroup selfcontained
  */
 
  *  @ingroup selfcontained
  */
 
-#include <iostream>
-#include <boost/test/unit_test.hpp>
 #include "lib/film.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/film.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/player.h"
 #include "lib/video_content.h"
 #include "lib/image_content.h"
 #include "lib/player.h"
 #include "lib/video_content.h"
 #include "lib/image_content.h"
+#include "lib/content_factory.h"
 #include "test.h"
 #include "test.h"
+#include <boost/test/unit_test.hpp>
+#include <iostream>
 
 using std::cout;
 using std::list;
 
 using std::cout;
 using std::list;
@@ -115,3 +116,32 @@ BOOST_AUTO_TEST_CASE (player_black_fill_test)
 
        check_dcp (ref.string(), check.string());
 }
 
        check_dcp (ref.string(), check.string());
 }
+
+/** Check behaviour with an awkward playlist whose data does not end on a video frame start */
+BOOST_AUTO_TEST_CASE (player_subframe_test)
+{
+       shared_ptr<Film> film = new_test_film ("reels_test7");
+       film->set_name ("reels_test7");
+       film->set_container (Ratio::from_id ("185"));
+       film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
+       shared_ptr<Content> A = content_factory(film, "test/data/flat_red.png").front();
+       film->examine_and_add_content (A);
+       BOOST_REQUIRE (!wait_for_jobs ());
+       shared_ptr<Content> B = content_factory(film, "test/data/awkward_length.wav").front();
+       film->examine_and_add_content (B);
+       BOOST_REQUIRE (!wait_for_jobs ());
+       film->set_video_frame_rate (24);
+       A->video->set_length (3 * 24);
+
+       BOOST_CHECK (A->full_length() == DCPTime::from_frames(3 * 24, 24));
+       BOOST_CHECK (B->full_length() == DCPTime(289920));
+       /* Length should be rounded up from B's length to the next video frame */
+       BOOST_CHECK (film->length() == DCPTime::from_frames(3 * 24 + 1, 24));
+
+       shared_ptr<Player> player (new Player (film, film->playlist ()));
+       player->setup_pieces ();
+       BOOST_REQUIRE_EQUAL (player->_black._periods.size(), 1);
+       BOOST_CHECK (player->_black._periods.front() == DCPTimePeriod(DCPTime::from_frames(3 * 24, 24), DCPTime::from_frames(3 * 24 + 1, 24)));
+       BOOST_REQUIRE_EQUAL (player->_silent._periods.size(), 1);
+       BOOST_CHECK (player->_silent._periods.front() == DCPTimePeriod(DCPTime(289920), DCPTime::from_frames(3 * 24 + 1, 24)));
+}
index 6c617d6b206d6d918fa0b958eb49fbd58db84000..72a3fe7d3545773e68ba9355a044418d81f8c5d7 100644 (file)
 #include "lib/dcp_content.h"
 #include "lib/video_content.h"
 #include "lib/text_subtitle_content.h"
 #include "lib/dcp_content.h"
 #include "lib/video_content.h"
 #include "lib/text_subtitle_content.h"
+#include "lib/content_factory.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/foreach.hpp>
 
 using std::list;
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/foreach.hpp>
 
 using std::list;
+using std::cout;
 using boost::shared_ptr;
 
 /** Test Film::reels() */
 using boost::shared_ptr;
 
 /** Test Film::reels() */
@@ -307,14 +309,20 @@ BOOST_AUTO_TEST_CASE (reels_test7)
        film->set_name ("reels_test7");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
        film->set_name ("reels_test7");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TST"));
-       shared_ptr<FFmpegContent> A (new FFmpegContent (film, "test/data/flat_red.png"));
+       shared_ptr<Content> A = content_factory(film, "test/data/flat_red.png").front();
        film->examine_and_add_content (A);
        BOOST_REQUIRE (!wait_for_jobs ());
        film->examine_and_add_content (A);
        BOOST_REQUIRE (!wait_for_jobs ());
-       shared_ptr<FFmpegContent> B (new FFmpegContent (film, "test/data/awkward_length.wav"));
+       shared_ptr<Content> B = content_factory(film, "test/data/awkward_length.wav").front();
        film->examine_and_add_content (B);
        BOOST_REQUIRE (!wait_for_jobs ());
        film->examine_and_add_content (B);
        BOOST_REQUIRE (!wait_for_jobs ());
+       film->set_video_frame_rate (24);
+       A->video->set_length (3 * 24);
 
        film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
 
        film->set_reel_type (REELTYPE_BY_VIDEO_CONTENT);
+       BOOST_REQUIRE_EQUAL (film->reels().size(), 2);
+       BOOST_CHECK (film->reels().front() == DCPTimePeriod(DCPTime(0), DCPTime::from_frames(3 * 24, 24)));
+       BOOST_CHECK (film->reels().back() == DCPTimePeriod(DCPTime::from_frames(3 * 24, 24), DCPTime::from_frames(3 * 24 + 1, 24)));
+
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 }
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 }