Assorted fixes to queue management.
authorCarl Hetherington <cth@carlh.net>
Thu, 7 Jun 2018 16:17:11 +0000 (17:17 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 7 Jun 2018 16:17:11 +0000 (17:17 +0100)
src/lib/writer.cc
test/player_test.cc

index b135f43..8ee6293 100644 (file)
@@ -74,8 +74,9 @@ Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
        , _thread (0)
        , _finish (false)
        , _queued_full_in_memory (0)
-       , _maximum_frames_in_memory (0)
-       , _maximum_queue_size (0)
+       /* These will be reset to sensible values when J2KEncoder is created */
+       , _maximum_frames_in_memory (8)
+       , _maximum_queue_size (8)
        , _full_written (0)
        , _fake_written (0)
        , _repeat_written (0)
@@ -201,7 +202,12 @@ Writer::fake_write (Frame frame, Eyes eyes)
        boost::mutex::scoped_lock lock (_state_mutex);
 
        while (_queue.size() > _maximum_queue_size) {
-               /* The queue is too big; wait until that is sorted out */
+               /* The queue is too big; wait until that is sorted out.  We're assuming here
+                  that it will be sorted out either by time or by a necessary full-written
+                  frame being given to us.  fake_write() must be called more-or-less in
+                  order or this will deadlock due to the main write thread waiting for
+                  a frame that never arrives because we're waiting here.
+               */
                _full_condition.wait (lock);
        }
 
@@ -342,8 +348,6 @@ try
                                break;
                        }
 
-                       DCPOMATIC_ASSERT (_queue.size() < _maximum_queue_size);
-
                        /* Nothing to do: wait until something happens which may indicate that we do */
                        LOG_TIMING (N_("writer-sleep queue=%1"), _queue.size());
                        _empty_condition.wait (lock);
@@ -714,8 +718,9 @@ operator== (QueueItem const & a, QueueItem const & b)
 void
 Writer::set_encoder_threads (int threads)
 {
+       boost::mutex::scoped_lock lm (_state_mutex);
        _maximum_frames_in_memory = lrint (threads * Config::instance()->frames_in_memory_multiplier());
-       _maximum_queue_size = lrint (threads * 16);
+       _maximum_queue_size = threads * 16;
 }
 
 void
index 6a6864d..52f3097 100644 (file)
@@ -263,3 +263,22 @@ BOOST_AUTO_TEST_CASE (player_seek_test2)
                check_image(String::compose("test/data/player_seek_test2_%1.png", i), String::compose("build/test/player_seek_test2_%1.png", i), 0.011);
        }
 }
+
+/** Test a bug when trimmed content follows other content */
+BOOST_AUTO_TEST_CASE (player_trim_test)
+{
+       shared_ptr<Film> film = new_test_film2 ("player_trim_test");
+       shared_ptr<Content> A = content_factory(film, "test/data/flat_red.png").front();
+       film->examine_and_add_content (A);
+       BOOST_REQUIRE (!wait_for_jobs ());
+       A->video->set_length (10 * 24);
+       shared_ptr<Content> B = content_factory(film, "test/data/flat_red.png").front();
+       film->examine_and_add_content (B);
+       BOOST_REQUIRE (!wait_for_jobs ());
+       B->video->set_length (10 * 24);
+       B->set_position (DCPTime::from_seconds (10));
+       B->set_trim_start (ContentTime::from_seconds (2));
+
+       film->make_dcp ();
+       BOOST_REQUIRE (!wait_for_jobs ());
+}