Fix problems with playing back 3D DCPs and with inserting 3D DCPs
authorCarl Hetherington <cth@carlh.net>
Tue, 19 Nov 2019 21:39:38 +0000 (22:39 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 19 Nov 2019 21:39:38 +0000 (22:39 +0100)
in 2D projects.  Also add some tests.

src/lib/dcp_encoder.cc
src/lib/video_decoder.cc
test/player_test.cc

index 448fc2a5298e4e506f99c52cef110ec5bbaf21e5..d17c6c985b07bd1f5529e75adddae38c78b0fe45 100644 (file)
@@ -126,9 +126,14 @@ DCPEncoder::go ()
 void
 DCPEncoder::video (shared_ptr<PlayerVideo> data, DCPTime time)
 {
-       if (!_film->three_d() && data->eyes() == EYES_LEFT) {
-               /* Use left-eye images for both eyes */
-               data->set_eyes (EYES_BOTH);
+       if (!_film->three_d()) {
+               if (data->eyes() == EYES_LEFT) {
+                       /* Use left-eye images for both eyes... */
+                       data->set_eyes (EYES_BOTH);
+               } else if (data->eyes() == EYES_RIGHT) {
+                       /* ...and discard the right */
+                       return;
+               }
        }
 
        _j2k_encoder->encode (data, time);
index 19a99419753f402413652248a82e0df80a6905ee..9c80cd5c4b1ecc379b97d416f32e43ed0b6f1171 100644 (file)
@@ -80,7 +80,8 @@ VideoDecoder::emit (shared_ptr<const Film> film, shared_ptr<const ImageProxy> im
                        frame = decoder_frame;
                }
        } else {
-               if (_content->video->frame_type() == VIDEO_FRAME_TYPE_3D_ALTERNATE) {
+               VideoFrameType const ft = _content->video->frame_type ();
+               if (ft == VIDEO_FRAME_TYPE_3D_ALTERNATE || ft == VIDEO_FRAME_TYPE_3D) {
                        DCPOMATIC_ASSERT (_last_emitted_eyes);
                        if (_last_emitted_eyes.get() == EYES_RIGHT) {
                                frame = _position->frames_round(afr) + 1;
index 30b1a56dde93083ce6488f79e838142af2e953dc..390ecf444e66c7c56511929bbff3b515e12be55b 100644 (file)
@@ -358,3 +358,61 @@ BOOST_AUTO_TEST_CASE (player_silence_crash)
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs());
 }
+
+/** Test a crash when processing a 3D DCP */
+BOOST_AUTO_TEST_CASE (player_3d_test_1)
+{
+       shared_ptr<Film> film = new_test_film2 ("player_3d_test_1a");
+       shared_ptr<Content> left = content_factory("test/data/flat_red.png").front();
+       film->examine_and_add_content (left);
+       shared_ptr<Content> right = content_factory("test/data/flat_blue.png").front();
+       film->examine_and_add_content (right);
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       left->video->set_frame_type (VIDEO_FRAME_TYPE_3D_LEFT);
+       left->set_position (film, DCPTime());
+       right->video->set_frame_type (VIDEO_FRAME_TYPE_3D_RIGHT);
+       right->set_position (film, DCPTime());
+       film->set_three_d (true);
+
+       film->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       shared_ptr<Film> film2 = new_test_film2 ("player_3d_test_1b");
+       shared_ptr<Content> dcp(new DCPContent(film->dir(film->dcp_name())));
+       film2->examine_and_add_content (dcp);
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       film2->set_three_d (true);
+       film2->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs());
+}
+
+/** Test a crash when processing a 3D DCP as content in a 2D project */
+BOOST_AUTO_TEST_CASE (player_3d_test_2)
+{
+       shared_ptr<Film> film = new_test_film2 ("player_3d_test_2a");
+       shared_ptr<Content> left = content_factory("test/data/flat_red.png").front();
+       film->examine_and_add_content (left);
+       shared_ptr<Content> right = content_factory("test/data/flat_blue.png").front();
+       film->examine_and_add_content (right);
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       left->video->set_frame_type (VIDEO_FRAME_TYPE_3D_LEFT);
+       left->set_position (film, DCPTime());
+       right->video->set_frame_type (VIDEO_FRAME_TYPE_3D_RIGHT);
+       right->set_position (film, DCPTime());
+       film->set_three_d (true);
+
+       film->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       shared_ptr<Film> film2 = new_test_film2 ("player_3d_test_2b");
+       shared_ptr<Content> dcp(new DCPContent(film->dir(film->dcp_name())));
+       film2->examine_and_add_content (dcp);
+       BOOST_REQUIRE (!wait_for_jobs());
+
+       film2->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs());
+}
+