From 1d807644c99508cc54c9b93a6e5543af4a612703 Mon Sep 17 00:00:00 2001 From: Lefucjusz Date: Mon, 23 Jan 2023 20:25:05 +0100 Subject: [PATCH] [MOS-882] Fix heap fragmentation issue during playback Fix of the heap fragmentation issue that caused phone crash when trying to play music files while connecting USB cable in a certain order. Audio stream buffering length was slightly reduced, so that smaller contiguous block of heap is required to store audio buffer. --- module-audio/Audio/Stream.hpp | 4 ++-- module-audio/Audio/StreamFactory.cpp | 17 +++++++++-------- module-audio/Audio/StreamFactory.hpp | 4 ++-- module-audio/Audio/test/unittest_stream.cpp | 6 ++---- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/module-audio/Audio/Stream.hpp b/module-audio/Audio/Stream.hpp index 74b6fa339afb8e18038faeabde96e6f8db4da39f..865270fb1d2ea3e5b9c99ccef45fc384e604c687 100644 --- a/module-audio/Audio/Stream.hpp +++ b/module-audio/Audio/Stream.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -50,7 +50,7 @@ namespace audio virtual UniqueStreamBuffer allocate(std::size_t size) = 0; }; - static constexpr auto defaultBufferingSize = 32U; + static constexpr auto defaultBufferingSize = 24U; Stream(AudioFormat format, Allocator &allocator, diff --git a/module-audio/Audio/StreamFactory.cpp b/module-audio/Audio/StreamFactory.cpp index 9c1862d40bd62dec68d65bcd63d6ba2f23ee0cf1..aec7a97cd6fa5847a388c9bde915e257499b6d17 100644 --- a/module-audio/Audio/StreamFactory.cpp +++ b/module-audio/Audio/StreamFactory.cpp @@ -48,12 +48,11 @@ auto StreamFactory::makeStream(Source &source, Sink &sink) -> std::unique_ptr std::unique_ptr { - auto streamBuffering = defaultBuffering; - auto endpointsTraits = {sourceTraits, sinkTraits}; + const auto endpointsTraits = {sourceTraits, sinkTraits}; + const auto timingConstraint = getTimingConstraints(std::initializer_list>{ + sinkTraits.timeConstraint, sourceTraits.timeConstraint, periodRequirement}); auto blockSizeConstraint = getBlockSizeConstraint(endpointsTraits); auto &streamAllocator = negotiateAllocator(endpointsTraits); - auto timingConstraint = getTimingConstraints(std::initializer_list>{ - sinkTraits.timeConstraint, sourceTraits.timeConstraint, periodRequirement}); if (streamFormat == audio::nullFormat) { throw std::invalid_argument("No source format provided"); @@ -63,13 +62,15 @@ auto StreamFactory::makeStream(Traits sourceTraits, Traits sinkTraits, AudioForm blockSizeConstraint = binary::ceilPowerOfTwo(streamFormat.microsecondsToBytes(timingConstraint)); } - auto blockTransferDuration = + const auto blockTransferDuration = std::chrono::duration(streamFormat.bytesToMicroseconds(blockSizeConstraint.value())); - streamBuffering = static_cast(std::ceil(timingConstraint / blockTransferDuration)) * defaultBuffering; + const auto streamBuffering = + static_cast(std::ceil(timingConstraint / blockTransferDuration)) * defaultBuffering; - LOG_DEBUG("Creating audio stream: block size = %lu; buffering = %u", + LOG_DEBUG("Creating audio stream: block size = %lu bytes; buffering = %u -> stream buffer size = %lu bytes", static_cast(blockSizeConstraint.value()), - streamBuffering); + streamBuffering, + static_cast(blockSizeConstraint.value() * streamBuffering)); return std::make_unique(streamFormat, streamAllocator, blockSizeConstraint.value(), streamBuffering); } diff --git a/module-audio/Audio/StreamFactory.hpp b/module-audio/Audio/StreamFactory.hpp index 70250dcd177114657546abd4461bad78bda4af2d..c1b31c1333bfa1fa556e1e90a85828ad3235f09d 100644 --- a/module-audio/Audio/StreamFactory.hpp +++ b/module-audio/Audio/StreamFactory.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -32,7 +32,7 @@ namespace audio private: using Traits = audio::Endpoint::Traits; - static constexpr auto defaultBuffering = 32U; + static constexpr auto defaultBuffering = 24U; auto makeStream(Traits sourceTraits, Traits sinkTraits, AudioFormat streamFormat) -> std::unique_ptr; diff --git a/module-audio/Audio/test/unittest_stream.cpp b/module-audio/Audio/test/unittest_stream.cpp index c17d5ce5b610031ccd1a8aed041725f9c0cfb89b..c252f546fceb9df0d110c6155068688c871df0b3 100644 --- a/module-audio/Audio/test/unittest_stream.cpp +++ b/module-audio/Audio/test/unittest_stream.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include @@ -21,15 +21,13 @@ using audio::NonCacheableStreamAllocator; using audio::StandardStreamAllocator; using audio::Stream; -using audio::StreamFactory; using testing::Return; using testing::audio::MockStream; -using testing::audio::MockStreamEventListener; using namespace std::chrono_literals; constexpr std::size_t defaultBlockSize = 64U; -constexpr std::size_t defaultBuffering = 32U; +constexpr std::size_t defaultBuffering = 24U; constexpr audio::AudioFormat format = audio::AudioFormat(44100, 16, 2); static std::uint8_t testData[defaultBuffering][defaultBlockSize];