From 2377472fac2a3fd4bda66e6498628ca22b950ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Mon, 10 Sep 2018 16:50:05 -0400 Subject: [PATCH] OpenSL: prevent buffer copy, cleanup Make AudioQueue and sample_buf non-copyable to avoid implicit copies and memory corruption. Fixes crashes on Android 4.4 Change-Id: I274dc5d3ecf63ea328e577e69e217f572408db57 --- src/media/audio/opensl/buf_manager.h | 9 +++++++++ src/media/audio/opensl/opensllayer.cpp | 15 ++++++--------- src/media/audio/opensl/opensllayer.h | 3 --- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/media/audio/opensl/buf_manager.h b/src/media/audio/opensl/buf_manager.h index 8af485c9c5..497402e648 100644 --- a/src/media/audio/opensl/buf_manager.h +++ b/src/media/audio/opensl/buf_manager.h @@ -19,6 +19,7 @@ #include "audio/audiobuffer.h" #include "logger.h" +#include "noncopyable.h" #include <SLES/OpenSLES.h> #include <sys/types.h> @@ -146,6 +147,7 @@ public: } private: + NON_COPYABLE(ProducerConsumerQueue); std::vector<T> buffer_; // forcing cache line alignment to eliminate false sharing of the @@ -162,9 +164,16 @@ struct sample_buf { size_t size_ {0}; // audio sample size (n buf) in byte sample_buf() {} sample_buf(size_t alloc, size_t size) : buf_(new uint8_t[alloc]), cap_(size) {} + sample_buf(sample_buf&& o) : buf_(o.buf_), cap_(o.cap_), size_(o.size_) { + o.buf_ = nullptr; + o.cap_ = 0; + o.size_ = 0; + } + ~sample_buf() { if (buf_) delete[] buf_; } + NON_COPYABLE(sample_buf); }; using AudioQueue = ProducerConsumerQueue<sample_buf*>; diff --git a/src/media/audio/opensl/opensllayer.cpp b/src/media/audio/opensl/opensllayer.cpp index 51ba7c33f0..d02e010e19 100644 --- a/src/media/audio/opensl/opensllayer.cpp +++ b/src/media/audio/opensl/opensllayer.cpp @@ -48,7 +48,6 @@ namespace ring { // Constructor OpenSLLayer::OpenSLLayer(const AudioPreference &pref) : AudioLayer(pref), - audioInputDescriptor_(), mainRingBuffer_(Manager::instance().getRingBufferPool().getRingBuffer(RingBufferPool::DEFAULT_ID)) {} @@ -408,25 +407,23 @@ OpenSLLayer::getCaptureDeviceList() const SLresult res; // Get the Audio IO DEVICE CAPABILITIES interface, implicit - RING_DBG("Get the Audio IO DEVICE CAPABILITIES interface, implicit"); - - res = (*engineObject_)->GetInterface(engineObject_, SL_IID_AUDIOIODEVICECAPABILITIES, (void*)&AudioIODeviceCapabilitiesItf); + SLAudioIODeviceCapabilitiesItf deviceCapabilities {nullptr}; + res = (*engineObject_)->GetInterface(engineObject_, SL_IID_AUDIOIODEVICECAPABILITIES, (void*)&deviceCapabilities); if (res != SL_RESULT_SUCCESS) return captureDeviceList; - RING_DBG("Get the Audio IO DEVICE CAPABILITIES interface, implicit"); numInputs = MAX_NUMBER_INPUT_DEVICES; - - res = (*AudioIODeviceCapabilitiesItf)->GetAvailableAudioInputs(AudioIODeviceCapabilitiesItf, &numInputs, InputDeviceIDs); + res = (*deviceCapabilities)->GetAvailableAudioInputs(deviceCapabilities, &numInputs, InputDeviceIDs); if (res != SL_RESULT_SUCCESS) return captureDeviceList; // Search for either earpiece microphone or headset microphone input // device - with a preference for the latter for (int i = 0; i < numInputs; i++) { - res = (*AudioIODeviceCapabilitiesItf)->QueryAudioInputCapabilities(AudioIODeviceCapabilitiesItf, + SLAudioInputDescriptor audioInputDescriptor_; + res = (*deviceCapabilities)->QueryAudioInputCapabilities(deviceCapabilities, InputDeviceIDs[i], - (SLAudioInputDescriptor_ *)&audioInputDescriptor_); + &audioInputDescriptor_); if (res != SL_RESULT_SUCCESS) return captureDeviceList; diff --git a/src/media/audio/opensl/opensllayer.h b/src/media/audio/opensl/opensllayer.h index e44d96fb4e..f3785b8fc3 100644 --- a/src/media/audio/opensl/opensllayer.h +++ b/src/media/audio/opensl/opensllayer.h @@ -188,9 +188,6 @@ class OpenSLLayer : public AudioLayer { std::vector<sample_buf> bufs_; - SLAudioIODeviceCapabilitiesItf AudioIODeviceCapabilitiesItf {nullptr}; - SLAudioInputDescriptor audioInputDescriptor_; - AudioFormat hardwareFormat_ {AudioFormat::MONO()}; size_t hardwareBuffSize_ {BUFFER_SIZE}; -- GitLab