Give an error if 2D content is set to 3D (#1565). Also run
authorCarl Hetherington <cth@carlh.net>
Tue, 21 May 2019 00:47:22 +0000 (01:47 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 21 May 2019 00:50:07 +0000 (01:50 +0100)
3D tests with more parallel jobs to speed them up.

Backported from 11c07c6fd98620c859c7d3dcf6a4bbf6a05e567e in v2.15.x.

src/lib/job_manager.h
src/lib/video_decoder.cc
src/lib/video_decoder.h
src/wx/film_viewer.cc
test/threed_test.cc

index e0b72994df9dd2ab87495df0c6be3eb710afca2e..2788fc657d2a00278e81ac55fb6c785059134dce 100644 (file)
@@ -32,6 +32,7 @@
 class Job;
 class Film;
 class Playlist;
+struct threed_test7;
 
 extern bool wait_for_jobs ();
 
@@ -73,6 +74,7 @@ public:
 private:
        /* This function is part of the test suite */
        friend bool ::wait_for_jobs ();
+       friend struct threed_test7;
 
        JobManager ();
        ~JobManager ();
index 813320eb86f89ecd5518a315df121a9011500411..de1df727f13838563484bb9d348835c1ba248c2f 100644 (file)
@@ -65,12 +65,28 @@ VideoDecoder::emit (shared_ptr<const Film> film, shared_ptr<const ImageProxy> im
                break;
        case VIDEO_FRAME_TYPE_3D:
        {
-               /* We receive the same frame index twice for 3D; hence we know which
+               /* We should receive the same frame index twice for 3D; hence we know which
                   frame this one is.
                */
-               bool const same = (_last_emitted && _last_emitted.get() == frame);
-               Data (ContentVideo (image, frame, same ? EYES_RIGHT : EYES_LEFT, PART_WHOLE));
-               _last_emitted = frame;
+               bool const same = (_last_emitted_frame && _last_emitted_frame.get() == frame);
+               if (!same && _last_emitted_eyes && *_last_emitted_eyes == EYES_LEFT) {
+                       /* We just got a new frame index but the last frame was left-eye; it looks like
+                          this content is not really 3D.
+                       */
+                       boost::throw_exception (
+                               DecodeError(
+                                       String::compose(
+                                               _("The content file %1 is set as 3D but does not appear to contain 3D images.  Please set it to 2D.  "
+                                                 "You can still make a 3D DCP from this content by ticking the 3D option in the DCP video tab."),
+                                               _content->path(0)
+                                               )
+                                       )
+                               );
+               }
+               Eyes const eyes = same ? EYES_RIGHT : EYES_LEFT;
+               Data (ContentVideo (image, frame, eyes, PART_WHOLE));
+               _last_emitted_frame = frame;
+               _last_emitted_eyes = eyes;
                break;
        }
        case VIDEO_FRAME_TYPE_3D_ALTERNATE:
@@ -102,5 +118,6 @@ void
 VideoDecoder::seek ()
 {
        _position = ContentTime();
-       _last_emitted.reset ();
+       _last_emitted_frame.reset ();
+       _last_emitted_eyes.reset ();
 }
index 0fc7ca5a404832a34ba5daadcd567611a5eaa277..ed56feea05284ccc785e74ba1167b2049cf6322f 100644 (file)
@@ -62,9 +62,10 @@ public:
        boost::signals2::signal<void (ContentVideo)> Data;
 
 private:
-       /** Time of last thing to be emitted */
        boost::shared_ptr<const Content> _content;
-       boost::optional<Frame> _last_emitted;
+       /** Frame of last thing to be emitted */
+       boost::optional<Frame> _last_emitted_frame;
+       boost::optional<Eyes> _last_emitted_eyes;
        ContentTime _position;
 };
 
index 6d050157c40f0deef027b8ca2fcb902ef4aebef3..25665325dd34933d3d56f46ba6a94b9a156164fa 100644 (file)
@@ -234,7 +234,11 @@ FilmViewer::get ()
                _player_video.first->eyes() != EYES_BOTH
                );
 
-       _butler->rethrow ();
+       try {
+               _butler->rethrow ();
+       } catch (DecodeError& e) {
+               error_dialog (_video_view->get(), e.what());
+       }
 
        display_player_video ();
 }
index c749694c60d827c5cad409bf0251a63b41ce7022..6d0524d7250d5f04f76fd501c349521f1f9271f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
  *  @ingroup completedcp
  */
 
-#include <boost/test/unit_test.hpp>
 #include "test.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
+#include "lib/config.h"
 #include "lib/dcp_content_type.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/video_content.h"
+#include "lib/job_manager.h"
+#include "lib/cross.h"
+#include "lib/job.h"
+#include <boost/test/unit_test.hpp>
 #include <iostream>
 
 using std::cout;
@@ -103,6 +107,8 @@ BOOST_AUTO_TEST_CASE (threed_test3)
 
 BOOST_AUTO_TEST_CASE (threed_test4)
 {
+       Config::instance()->set_master_encoding_threads (8);
+
        shared_ptr<Film> film = new_test_film2 ("threed_test4");
        shared_ptr<FFmpegContent> L (new FFmpegContent(private_data / "LEFT_TEST_DCP3D4K.mov"));
        film->examine_and_add_content (L);
@@ -118,10 +124,14 @@ BOOST_AUTO_TEST_CASE (threed_test4)
        film->write_metadata ();
 
        BOOST_REQUIRE (!wait_for_jobs ());
+
+       Config::instance()->set_master_encoding_threads (8);
 }
 
 BOOST_AUTO_TEST_CASE (threed_test5)
 {
+       Config::instance()->set_master_encoding_threads (8);
+
        shared_ptr<Film> film = new_test_film2 ("threed_test5");
        shared_ptr<FFmpegContent> L (new FFmpegContent(private_data / "boon_telly.mkv"));
        film->examine_and_add_content (L);
@@ -137,6 +147,8 @@ BOOST_AUTO_TEST_CASE (threed_test5)
        film->write_metadata ();
 
        BOOST_REQUIRE (!wait_for_jobs ());
+
+       Config::instance()->set_master_encoding_threads (1);
 }
 
 BOOST_AUTO_TEST_CASE (threed_test6)
@@ -159,7 +171,7 @@ BOOST_AUTO_TEST_CASE (threed_test6)
        check_dcp ("test/data/threed_test6", film->dir(film->dcp_name()));
 }
 
-/** Check 2D content set as being 3D; this fails with a -114 in some versions */
+/** Check 2D content set as being 3D; this should give an informative error */
 BOOST_AUTO_TEST_CASE (threed_test7)
 {
        shared_ptr<Film> film = new_test_film2 ("threed_test7");
@@ -173,5 +185,20 @@ BOOST_AUTO_TEST_CASE (threed_test7)
        film->make_dcp ();
        film->write_metadata ();
 
-       BOOST_REQUIRE (!wait_for_jobs());
+       JobManager* jm = JobManager::instance ();
+       while (jm->work_to_do ()) {
+               while (signal_manager->ui_idle()) {}
+               dcpomatic_sleep (1);
+       }
+
+       BOOST_REQUIRE (jm->errors());
+       shared_ptr<Job> failed;
+       BOOST_FOREACH (shared_ptr<Job> i, jm->_jobs) {
+               if (i->finished_in_error()) {
+                       BOOST_REQUIRE (!failed);
+                       failed = i;
+               }
+       }
+       BOOST_REQUIRE (failed);
+       BOOST_CHECK_EQUAL (failed->error_summary(), "The content file test/data/red_24.mp4 is set as 3D but does not appear to contain 3D images.  Please set it to 2D.  You can still make a 3D DCP from this content by ticking the 3D option in the DCP video tab.");
 }