From b5c5fc7a08a4f02d80a664ee18812e84d08dc6fd Mon Sep 17 00:00:00 2001 From: Sakari Bergen Date: Tue, 30 Oct 2012 20:15:11 +0000 Subject: [PATCH] Fix chunker to handle end of input properly git-svn-id: svn://localhost/ardour2/branches/3.0@13370 d708f5d6-7413-0410-9779-e7cbd77b26cf --- .../audiographer/general/chunker.h | 9 +++--- .../tests/general/chunker_test.cc | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/libs/audiographer/audiographer/general/chunker.h b/libs/audiographer/audiographer/general/chunker.h index 397d67ffc5..cc46aa4575 100644 --- a/libs/audiographer/audiographer/general/chunker.h +++ b/libs/audiographer/audiographer/general/chunker.h @@ -49,14 +49,15 @@ class Chunker framecnt_t const frames_to_copy = chunk_size - position; TypeUtils::copy (&context.data()[input_position], &buffer[position], frames_to_copy); - // Output whole buffer - ProcessContext c_out (context, buffer, chunk_size); - ListedSource::output (c_out); - // Update counters position = 0; input_position += frames_to_copy; frames_left -= frames_to_copy; + + // Output whole buffer + ProcessContext c_out (context, buffer, chunk_size); + if (frames_left) { c_out.remove_flag(ProcessContext::EndOfInput); } + ListedSource::output (c_out); } if (frames_left) { diff --git a/libs/audiographer/tests/general/chunker_test.cc b/libs/audiographer/tests/general/chunker_test.cc index ea5c29a410..d3adab3691 100644 --- a/libs/audiographer/tests/general/chunker_test.cc +++ b/libs/audiographer/tests/general/chunker_test.cc @@ -14,6 +14,7 @@ class ChunkerTest : public CppUnit::TestFixture CPPUNIT_TEST (testSynchronousProcess); CPPUNIT_TEST (testAsynchronousProcess); CPPUNIT_TEST (testChoppingProcess); + CPPUNIT_TEST (testEndOfInputFlagHandling); CPPUNIT_TEST_SUITE_END (); public: @@ -136,6 +137,36 @@ class ChunkerTest : public CppUnit::TestFixture CPPUNIT_ASSERT (TestUtils::array_equals (random_data, &sink->get_array()[ 3 * frames / 2], frames / 2)); } + void testEndOfInputFlagHandling() + { + boost::shared_ptr > grabber(new ProcessContextGrabber()); + + assert (frames % 2 == 0); + chunker.reset (new Chunker(frames)); + chunker->add_output (grabber); + + ProcessContext const half_context (random_data, frames / 2, 1); + ProcessContext const context (random_data, frames, 1); + context.set_flag(ProcessContext<>::EndOfInput); + + // Process 0.5 then 1.0 + chunker->process (half_context); + chunker->process (context); + + // Should output two contexts + CPPUNIT_ASSERT_EQUAL((int)grabber->contexts.size(), 2); + ProcessContextGrabber::ContextList::iterator it = grabber->contexts.begin(); + + // first 1.0 not end of input + CPPUNIT_ASSERT_EQUAL(it->frames(), frames); + CPPUNIT_ASSERT(!it->has_flag(ProcessContext<>::EndOfInput)); + + // Then 0.5 with end of input + ++it; + CPPUNIT_ASSERT_EQUAL(it->frames(), frames / 2); + CPPUNIT_ASSERT(it->has_flag(ProcessContext<>::EndOfInput)); + } + private: boost::shared_ptr > chunker; boost::shared_ptr > sink;