Fix assertion failure in AudioBuffers::copy_from() (#1909)
authorCarl Hetherington <cth@carlh.net>
Tue, 23 Feb 2021 19:01:49 +0000 (20:01 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 23 Feb 2021 19:11:23 +0000 (20:11 +0100)
A number of frames N was being split up into two parts which together
were bigger than N, meaning a copy of one of the parts failed.

src/lib/writer.cc
test/writer_test.cc [new file with mode: 0644]
test/wscript

index 9ebdd92a3e3b2e25f6c06c1e840b81e19652a2a9..ad588f0a62aa0ff0709168c89c304666ec0867fe 100644 (file)
@@ -306,11 +306,14 @@ Writer::write (shared_ptr<const AudioBuffers> audio, DCPTime const time)
                                end - _audio_reel->period().to
                        };
 
+                       /* Be careful that part_lengths[0] + part_lengths[1] can't be bigger than audio->frames() */
                        Frame part_frames[2] = {
                                part_lengths[0].frames_ceil(afr),
-                               part_lengths[1].frames_ceil(afr)
+                               part_lengths[1].frames_floor(afr)
                        };
 
+                       DCPOMATIC_ASSERT ((part_frames[0] + part_frames[1]) <= audio->frames());
+
                        if (part_frames[0]) {
                                shared_ptr<AudioBuffers> part (new AudioBuffers(audio, part_frames[0], 0));
                                _audio_reel->write (part);
diff --git a/test/writer_test.cc b/test/writer_test.cc
new file mode 100644 (file)
index 0000000..dade4d6
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+    Copyright (C) 2021 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "lib/audio_buffers.h"
+#include "lib/content.h"
+#include "lib/content_factory.h"
+#include "lib/film.h"
+#include "lib/job.h"
+#include "lib/video_content.h"
+#include "lib/writer.h"
+#include "test.h"
+#include <boost/test/unit_test.hpp>
+#include <memory>
+
+
+using std::make_shared;
+using std::shared_ptr;
+
+
+BOOST_AUTO_TEST_CASE (test_write_odd_amount_of_silence)
+{
+       auto content = content_factory("test/data/flat_red.png").front();
+       auto film = new_test_film2 ("test_write_odd_amount_of_silence", {content});
+       content->video->set_length(24);
+       auto writer = make_shared<Writer>(film, shared_ptr<Job>());
+
+       auto audio = make_shared<AudioBuffers>(6, 48000);
+       audio->make_silent ();
+       writer->write (audio, dcpomatic::DCPTime(1));
+}
+
index cbe2c176c09d9e1413e6bbb8149361ad8f931f09..4303db835e0698c39a14d19da8718efd6ee8650e 100644 (file)
@@ -138,6 +138,7 @@ def build(bld):
                  video_level_test.cc
                  video_mxf_content_test.cc
                  vf_kdm_test.cc
+                 writer_test.cc
                  zipper_test.cc
                  """