diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-10-15 22:04:53 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-10-15 22:04:53 +0000 |
| commit | 392d675f5799671abbcf1a9a47820321bcbdcca2 (patch) | |
| tree | c16b8f92a193b9c70b017041c4aad3479ef50046 | |
| parent | 7b83ed2e6aa876636158411b7d12a17a4123a8fa (diff) | |
Fix assertion failure on making a VF, in certain circumstances.v2.14.11
These circumstances were a VF which refers to at least one complete
reel of audio from a OV before adding more audio of its own.
| -rw-r--r-- | src/lib/writer.cc | 5 | ||||
| -rw-r--r-- | test/reels_test.cc | 41 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/lib/writer.cc b/src/lib/writer.cc index ca412dd3f..f9009be37 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -268,8 +268,11 @@ Writer::write (shared_ptr<const AudioBuffers> audio, DCPTime const time) /* Easy case: we can write all the audio to this reel */ _audio_reel->write (audio); t = end; + } else if (_audio_reel->period().to <= t) { + /* This reel is entirely before the start of our audio; just skip the reel */ + ++_audio_reel; } else { - /* Split the audio into two and write the first part */ + /* This audio is over a reel boundary; split the audio into two and write the first part */ DCPTime part_lengths[2] = { _audio_reel->period().to - t, end - _audio_reel->period().to diff --git a/test/reels_test.cc b/test/reels_test.cc index eea9ebfbe..442579fe4 100644 --- a/test/reels_test.cc +++ b/test/reels_test.cc @@ -371,3 +371,44 @@ BOOST_AUTO_TEST_CASE (reels_test9) film2->make_dcp(); BOOST_REQUIRE(!wait_for_jobs()); } + +/** Another reels-related error; make_dcp() would raise a ProgrammingError + * in AudioBuffers::allocate due to an attempt to allocate a negatively-sized buffer. + * This was triggered by a VF where there are referenced audio reels followed by + * VF audio. When the VF audio arrives the Writer did not correctly skip over the + * referenced reels. + */ +BOOST_AUTO_TEST_CASE (reels_test10) +{ + /* Make the OV */ + shared_ptr<Film> ov = new_test_film2("reels_test10_ov"); + shared_ptr<FFmpegContent> A(new FFmpegContent("test/data/flat_red.png")); + ov->examine_and_add_content (A); + BOOST_REQUIRE (!wait_for_jobs()); + A->video->set_length (5 * 24); + + shared_ptr<FFmpegContent> B(new FFmpegContent("test/data/flat_red.png")); + ov->examine_and_add_content (B); + BOOST_REQUIRE (!wait_for_jobs()); + B->video->set_length (5 * 24); + + ov->set_reel_type (REELTYPE_BY_VIDEO_CONTENT); + ov->make_dcp (); + BOOST_REQUIRE (!wait_for_jobs()); + ov->write_metadata (); + + /* Now try to make the VF; this used to fail */ + shared_ptr<Film> vf = new_test_film2("reels_test10_vf"); + shared_ptr<DCPContent> ov_dcp(new DCPContent(ov->dir(ov->dcp_name()))); + vf->examine_and_add_content (ov_dcp); + BOOST_REQUIRE (!wait_for_jobs()); + vf->set_reel_type (REELTYPE_BY_VIDEO_CONTENT); + ov_dcp->set_reference_video (true); + ov_dcp->set_reference_audio (true); + vf->examine_and_add_content (content_factory("test/data/15s.srt").front()); + BOOST_REQUIRE (!wait_for_jobs()); + + vf->make_dcp (); + BOOST_REQUIRE (!wait_for_jobs()); + vf->write_metadata (); +} |
