summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2019-11-19 22:39:38 +0100
committerCarl Hetherington <cth@carlh.net>2019-11-19 22:39:38 +0100
commit4cb18d1e0b8fdedf6bb38e1d4187a2d782957022 (patch)
treefff04fbe4c14161f7ddcd336f28d91f5cf20fc69
parentbcb962515b31ac6a40a3393c6d4e07b28cedc62b (diff)
Fix problems with playing back 3D DCPs and with inserting 3D DCPs
in 2D projects. Also add some tests.
-rw-r--r--src/lib/dcp_encoder.cc11
-rw-r--r--src/lib/video_decoder.cc3
-rw-r--r--test/player_test.cc58
3 files changed, 68 insertions, 4 deletions
diff --git a/src/lib/dcp_encoder.cc b/src/lib/dcp_encoder.cc
index 448fc2a52..d17c6c985 100644
--- a/src/lib/dcp_encoder.cc
+++ b/src/lib/dcp_encoder.cc
@@ -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);
diff --git a/src/lib/video_decoder.cc b/src/lib/video_decoder.cc
index 19a994197..9c80cd5c4 100644
--- a/src/lib/video_decoder.cc
+++ b/src/lib/video_decoder.cc
@@ -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;
diff --git a/test/player_test.cc b/test/player_test.cc
index 30b1a56dd..390ecf444 100644
--- a/test/player_test.cc
+++ b/test/player_test.cc
@@ -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());
+}
+