mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Oboe: Updated to release 1.5.1
This commit is contained in:
parent
433750941b
commit
8aa84abd7c
9 changed files with 249 additions and 20 deletions
|
|
@ -429,7 +429,8 @@ public:
|
||||||
/**
|
/**
|
||||||
* Create and open a stream object based on the current settings.
|
* Create and open a stream object based on the current settings.
|
||||||
*
|
*
|
||||||
* The caller owns the pointer to the AudioStream object.
|
* The caller owns the pointer to the AudioStream object
|
||||||
|
* and must delete it when finished.
|
||||||
*
|
*
|
||||||
* @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead.
|
* @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead.
|
||||||
* @param stream pointer to a variable to receive the stream address
|
* @param stream pointer to a variable to receive the stream address
|
||||||
|
|
@ -455,6 +456,8 @@ public:
|
||||||
* The caller must create a unique ptr, and pass by reference so it can be
|
* The caller must create a unique ptr, and pass by reference so it can be
|
||||||
* modified to point to an opened stream. The caller owns the unique ptr,
|
* modified to point to an opened stream. The caller owns the unique ptr,
|
||||||
* and it will be automatically closed and deleted when going out of scope.
|
* and it will be automatically closed and deleted when going out of scope.
|
||||||
|
*
|
||||||
|
* @deprecated Use openStream(std::shared_ptr<oboe::AudioStream> &stream) instead.
|
||||||
* @param stream Reference to the ManagedStream (uniqueptr) used to keep track of stream
|
* @param stream Reference to the ManagedStream (uniqueptr) used to keep track of stream
|
||||||
* @return OBOE_OK if successful or a negative error code.
|
* @return OBOE_OK if successful or a negative error code.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@
|
||||||
#define OBOE_VERSION_MINOR 5
|
#define OBOE_VERSION_MINOR 5
|
||||||
|
|
||||||
// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.
|
// Type: 16-bit unsigned int. Min value: 0 Max value: 65535. See below for description.
|
||||||
#define OBOE_VERSION_PATCH 0
|
#define OBOE_VERSION_PATCH 1
|
||||||
|
|
||||||
#define OBOE_STRINGIFY(x) #x
|
#define OBOE_STRINGIFY(x) #x
|
||||||
#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)
|
#define OBOE_TOSTRING(x) OBOE_STRINGIFY(x)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef OBOE_AAUDIO_EXTENSIONS_H
|
||||||
|
#define OBOE_AAUDIO_EXTENSIONS_H
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <sys/system_properties.h>
|
||||||
|
|
||||||
|
#include "common/OboeDebug.h"
|
||||||
|
#include "oboe/Oboe.h"
|
||||||
|
#include "AAudioLoader.h"
|
||||||
|
|
||||||
|
namespace oboe {
|
||||||
|
|
||||||
|
#define LIB_AAUDIO_NAME "libaaudio.so"
|
||||||
|
#define FUNCTION_IS_MMAP "AAudioStream_isMMapUsed"
|
||||||
|
#define FUNCTION_SET_MMAP_POLICY "AAudio_setMMapPolicy"
|
||||||
|
#define FUNCTION_GET_MMAP_POLICY "AAudio_getMMapPolicy"
|
||||||
|
|
||||||
|
#define AAUDIO_ERROR_UNAVAILABLE static_cast<aaudio_result_t>(Result::ErrorUnavailable)
|
||||||
|
|
||||||
|
typedef struct AAudioStreamStruct AAudioStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call some AAudio test routines that are not part of the normal API.
|
||||||
|
*/
|
||||||
|
class AAudioExtensions {
|
||||||
|
public:
|
||||||
|
AAudioExtensions() {
|
||||||
|
int32_t policy = getIntegerProperty("aaudio.mmap_policy", 0);
|
||||||
|
mMMapSupported = isPolicyEnabled(policy);
|
||||||
|
|
||||||
|
policy = getIntegerProperty("aaudio.mmap_exclusive_policy", 0);
|
||||||
|
mMMapExclusiveSupported = isPolicyEnabled(policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isPolicyEnabled(int32_t policy) {
|
||||||
|
return (policy == AAUDIO_POLICY_AUTO || policy == AAUDIO_POLICY_ALWAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AAudioExtensions &getInstance() {
|
||||||
|
static AAudioExtensions instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMMapUsed(oboe::AudioStream *oboeStream) {
|
||||||
|
AAudioStream *aaudioStream = (AAudioStream *) oboeStream->getUnderlyingStream();
|
||||||
|
return isMMapUsed(aaudioStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMMapUsed(AAudioStream *aaudioStream) {
|
||||||
|
if (loadSymbols()) return false;
|
||||||
|
if (mAAudioStream_isMMap == nullptr) return false;
|
||||||
|
return mAAudioStream_isMMap(aaudioStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls whether the MMAP data path can be selected when opening a stream.
|
||||||
|
* It has no effect after the stream has been opened.
|
||||||
|
* It only affects the application that calls it. Other apps are not affected.
|
||||||
|
*
|
||||||
|
* @param enabled
|
||||||
|
* @return 0 or a negative error code
|
||||||
|
*/
|
||||||
|
int32_t setMMapEnabled(bool enabled) {
|
||||||
|
if (loadSymbols()) return AAUDIO_ERROR_UNAVAILABLE;
|
||||||
|
if (mAAudio_setMMapPolicy == nullptr) return false;
|
||||||
|
return mAAudio_setMMapPolicy(enabled ? AAUDIO_POLICY_AUTO : AAUDIO_POLICY_NEVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMMapEnabled() {
|
||||||
|
if (loadSymbols()) return false;
|
||||||
|
if (mAAudio_getMMapPolicy == nullptr) return false;
|
||||||
|
int32_t policy = mAAudio_getMMapPolicy();
|
||||||
|
return isPolicyEnabled(policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMMapSupported() {
|
||||||
|
return mMMapSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMMapExclusiveSupported() {
|
||||||
|
return mMMapExclusiveSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AAUDIO_POLICY_NEVER = 1,
|
||||||
|
AAUDIO_POLICY_AUTO,
|
||||||
|
AAUDIO_POLICY_ALWAYS
|
||||||
|
};
|
||||||
|
typedef int32_t aaudio_policy_t;
|
||||||
|
|
||||||
|
int getIntegerProperty(const char *name, int defaultValue) {
|
||||||
|
int result = defaultValue;
|
||||||
|
char valueText[PROP_VALUE_MAX] = {0};
|
||||||
|
if (__system_property_get(name, valueText) != 0) {
|
||||||
|
result = atoi(valueText);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the function pointers.
|
||||||
|
* This can be called multiple times.
|
||||||
|
* It should only be called from one thread.
|
||||||
|
*
|
||||||
|
* @return 0 if successful or negative error.
|
||||||
|
*/
|
||||||
|
aaudio_result_t loadSymbols() {
|
||||||
|
if (mAAudio_getMMapPolicy != nullptr) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *libHandle = AAudioLoader::getInstance()->getLibHandle();
|
||||||
|
if (libHandle == nullptr) {
|
||||||
|
LOGI("%s() could not find " LIB_AAUDIO_NAME, __func__);
|
||||||
|
return AAUDIO_ERROR_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAAudioStream_isMMap = (bool (*)(AAudioStream *stream))
|
||||||
|
dlsym(libHandle, FUNCTION_IS_MMAP);
|
||||||
|
if (mAAudioStream_isMMap == nullptr) {
|
||||||
|
LOGI("%s() could not find " FUNCTION_IS_MMAP, __func__);
|
||||||
|
return AAUDIO_ERROR_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAAudio_setMMapPolicy = (int32_t (*)(aaudio_policy_t policy))
|
||||||
|
dlsym(libHandle, FUNCTION_SET_MMAP_POLICY);
|
||||||
|
if (mAAudio_setMMapPolicy == nullptr) {
|
||||||
|
LOGI("%s() could not find " FUNCTION_SET_MMAP_POLICY, __func__);
|
||||||
|
return AAUDIO_ERROR_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mAAudio_getMMapPolicy = (aaudio_policy_t (*)())
|
||||||
|
dlsym(libHandle, FUNCTION_GET_MMAP_POLICY);
|
||||||
|
if (mAAudio_getMMapPolicy == nullptr) {
|
||||||
|
LOGI("%s() could not find " FUNCTION_GET_MMAP_POLICY, __func__);
|
||||||
|
return AAUDIO_ERROR_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mMMapSupported = false;
|
||||||
|
bool mMMapExclusiveSupported = false;
|
||||||
|
|
||||||
|
bool (*mAAudioStream_isMMap)(AAudioStream *stream) = nullptr;
|
||||||
|
int32_t (*mAAudio_setMMapPolicy)(aaudio_policy_t policy) = nullptr;
|
||||||
|
aaudio_policy_t (*mAAudio_getMMapPolicy)() = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace oboe
|
||||||
|
|
||||||
|
#endif //OBOE_AAUDIO_EXTENSIONS_H
|
||||||
|
|
@ -24,10 +24,17 @@
|
||||||
namespace oboe {
|
namespace oboe {
|
||||||
|
|
||||||
AAudioLoader::~AAudioLoader() {
|
AAudioLoader::~AAudioLoader() {
|
||||||
if (mLibHandle != nullptr) {
|
// Issue 360: thread_local variables with non-trivial destructors
|
||||||
dlclose(mLibHandle);
|
// will cause segfaults if the containing library is dlclose()ed on
|
||||||
mLibHandle = nullptr;
|
// devices running M or newer, or devices before M when using a static STL.
|
||||||
}
|
// The simple workaround is to not call dlclose.
|
||||||
|
// https://github.com/android/ndk/wiki/Changelog-r22#known-issues
|
||||||
|
//
|
||||||
|
// The libaaudio and libaaudioclient do not use thread_local.
|
||||||
|
// But, to be safe, we should avoid dlclose() if possible.
|
||||||
|
// Because AAudioLoader is a static Singleton, we can safely skip
|
||||||
|
// calling dlclose() without causing a resource leak.
|
||||||
|
LOGI("%s() dlclose(%s) not called, OK", __func__, LIB_AAUDIO_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
AAudioLoader* AAudioLoader::getInstance() {
|
AAudioLoader* AAudioLoader::getInstance() {
|
||||||
|
|
@ -90,8 +97,6 @@ int AAudioLoader::open() {
|
||||||
|
|
||||||
stream_getTimestamp = load_I_PSKPLPL("AAudioStream_getTimestamp");
|
stream_getTimestamp = load_I_PSKPLPL("AAudioStream_getTimestamp");
|
||||||
|
|
||||||
stream_isMMapUsed = load_B_PS("AAudioStream_isMMapUsed");
|
|
||||||
|
|
||||||
stream_getChannelCount = load_I_PS("AAudioStream_getChannelCount");
|
stream_getChannelCount = load_I_PS("AAudioStream_getChannelCount");
|
||||||
if (stream_getChannelCount == nullptr) {
|
if (stream_getChannelCount == nullptr) {
|
||||||
// Use old alias if needed.
|
// Use old alias if needed.
|
||||||
|
|
@ -304,7 +309,6 @@ AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *funct
|
||||||
== AAUDIO_PERFORMANCE_MODE_POWER_SAVING, ERRMSG);
|
== AAUDIO_PERFORMANCE_MODE_POWER_SAVING, ERRMSG);
|
||||||
static_assert((int32_t)PerformanceMode::LowLatency
|
static_assert((int32_t)PerformanceMode::LowLatency
|
||||||
== AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, ERRMSG);
|
== AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, ERRMSG);
|
||||||
#endif
|
|
||||||
|
|
||||||
// The aaudio_ usage, content and input_preset types were added in NDK 17,
|
// The aaudio_ usage, content and input_preset types were added in NDK 17,
|
||||||
// which is the first version to support Android Pie (API 28).
|
// which is the first version to support Android Pie (API 28).
|
||||||
|
|
@ -343,6 +347,9 @@ AAudioLoader::signature_I_PSKPLPL AAudioLoader::load_I_PSKPLPL(const char *funct
|
||||||
|
|
||||||
static_assert((int32_t)SessionId::None == AAUDIO_SESSION_ID_NONE, ERRMSG);
|
static_assert((int32_t)SessionId::None == AAUDIO_SESSION_ID_NONE, ERRMSG);
|
||||||
static_assert((int32_t)SessionId::Allocate == AAUDIO_SESSION_ID_ALLOCATE, ERRMSG);
|
static_assert((int32_t)SessionId::Allocate == AAUDIO_SESSION_ID_ALLOCATE, ERRMSG);
|
||||||
#endif
|
|
||||||
|
#endif // __NDK_MAJOR__ >= 17
|
||||||
|
|
||||||
|
#endif // AAUDIO_AAUDIO_H
|
||||||
|
|
||||||
} // namespace oboe
|
} // namespace oboe
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,12 @@ typedef int32_t aaudio_usage_t;
|
||||||
typedef int32_t aaudio_content_type_t;
|
typedef int32_t aaudio_content_type_t;
|
||||||
typedef int32_t aaudio_input_preset_t;
|
typedef int32_t aaudio_input_preset_t;
|
||||||
typedef int32_t aaudio_session_id_t;
|
typedef int32_t aaudio_session_id_t;
|
||||||
|
|
||||||
|
// There are a few definitions used by Oboe.
|
||||||
|
#define AAUDIO_OK static_cast<aaudio_result_t>(Result::OK)
|
||||||
|
#define AAUDIO_ERROR_TIMEOUT static_cast<aaudio_result_t>(Result::ErrorTimeout)
|
||||||
|
#define AAUDIO_STREAM_STATE_STARTING static_cast<aaudio_stream_state_t>(StreamState::Starting)
|
||||||
|
#define AAUDIO_STREAM_STATE_STARTED static_cast<aaudio_stream_state_t>(StreamState::Started)
|
||||||
#else
|
#else
|
||||||
#include <aaudio/AAudio.h>
|
#include <aaudio/AAudio.h>
|
||||||
#include <android/ndk-version.h>
|
#include <android/ndk-version.h>
|
||||||
|
|
@ -63,7 +69,6 @@ typedef int32_t aaudio_session_id_t;
|
||||||
|
|
||||||
namespace oboe {
|
namespace oboe {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AAudio API was not available in early versions of Android.
|
* The AAudio API was not available in early versions of Android.
|
||||||
* To avoid linker errors, we dynamically link with the functions by name using dlsym().
|
* To avoid linker errors, we dynamically link with the functions by name using dlsym().
|
||||||
|
|
@ -133,6 +138,8 @@ class AAudioLoader {
|
||||||
*/
|
*/
|
||||||
int open();
|
int open();
|
||||||
|
|
||||||
|
void *getLibHandle() const { return mLibHandle; }
|
||||||
|
|
||||||
// Function pointers into the AAudio shared library.
|
// Function pointers into the AAudio shared library.
|
||||||
signature_I_PPB createStreamBuilder = nullptr;
|
signature_I_PPB createStreamBuilder = nullptr;
|
||||||
|
|
||||||
|
|
@ -167,8 +174,6 @@ class AAudioLoader {
|
||||||
|
|
||||||
signature_I_PSKPLPL stream_getTimestamp = nullptr;
|
signature_I_PSKPLPL stream_getTimestamp = nullptr;
|
||||||
|
|
||||||
signature_B_PS stream_isMMapUsed = nullptr;
|
|
||||||
|
|
||||||
signature_I_PS stream_close = nullptr;
|
signature_I_PS stream_close = nullptr;
|
||||||
|
|
||||||
signature_I_PS stream_getChannelCount = nullptr;
|
signature_I_PS stream_getChannelCount = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "common/AudioClock.h"
|
#include "common/AudioClock.h"
|
||||||
#include "common/OboeDebug.h"
|
#include "common/OboeDebug.h"
|
||||||
#include "oboe/Utilities.h"
|
#include "oboe/Utilities.h"
|
||||||
|
#include "AAudioExtensions.h"
|
||||||
|
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
#include <sys/system_properties.h>
|
#include <sys/system_properties.h>
|
||||||
|
|
@ -677,7 +678,7 @@ ResultWithValue<double> AudioStreamAAudio::calculateLatencyMillis() {
|
||||||
bool AudioStreamAAudio::isMMapUsed() {
|
bool AudioStreamAAudio::isMMapUsed() {
|
||||||
AAudioStream *stream = mAAudioStream.load();
|
AAudioStream *stream = mAAudioStream.load();
|
||||||
if (stream != nullptr) {
|
if (stream != nullptr) {
|
||||||
return mLibLoader->stream_isMMapUsed(stream);
|
return AAudioExtensions::getInstance().isMMapUsed(stream);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include "aaudio/AAudioExtensions.h"
|
||||||
#include "aaudio/AudioStreamAAudio.h"
|
#include "aaudio/AudioStreamAAudio.h"
|
||||||
#include "FilterAudioStream.h"
|
#include "FilterAudioStream.h"
|
||||||
#include "OboeDebug.h"
|
#include "OboeDebug.h"
|
||||||
|
|
@ -109,7 +111,6 @@ Result AudioStreamBuilder::openStream(AudioStream **streamPP) {
|
||||||
// Do we need to make a child stream and convert.
|
// Do we need to make a child stream and convert.
|
||||||
if (conversionNeeded) {
|
if (conversionNeeded) {
|
||||||
AudioStream *tempStream;
|
AudioStream *tempStream;
|
||||||
|
|
||||||
result = childBuilder.openStream(&tempStream);
|
result = childBuilder.openStream(&tempStream);
|
||||||
if (result != Result::OK) {
|
if (result != Result::OK) {
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -156,7 +157,20 @@ Result AudioStreamBuilder::openStream(AudioStream **streamPP) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result = streamP->open(); // TODO review API
|
// If MMAP has a problem in this case then disable it temporarily.
|
||||||
|
bool wasMMapOriginallyEnabled = AAudioExtensions::getInstance().isMMapEnabled();
|
||||||
|
bool wasMMapTemporarilyDisabled = false;
|
||||||
|
if (wasMMapOriginallyEnabled) {
|
||||||
|
bool isMMapSafe = QuirksManager::getInstance().isMMapSafe(childBuilder);
|
||||||
|
if (!isMMapSafe) {
|
||||||
|
AAudioExtensions::getInstance().setMMapEnabled(false);
|
||||||
|
wasMMapTemporarilyDisabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = streamP->open();
|
||||||
|
if (wasMMapTemporarilyDisabled) {
|
||||||
|
AAudioExtensions::getInstance().setMMapEnabled(wasMMapOriginallyEnabled); // restore original
|
||||||
|
}
|
||||||
if (result == Result::OK) {
|
if (result == Result::OK) {
|
||||||
|
|
||||||
int32_t optimalBufferSize = -1;
|
int32_t optimalBufferSize = -1;
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,6 @@
|
||||||
#include "OboeDebug.h"
|
#include "OboeDebug.h"
|
||||||
#include "QuirksManager.h"
|
#include "QuirksManager.h"
|
||||||
|
|
||||||
#ifndef __ANDROID_API_R__
|
|
||||||
#define __ANDROID_API_R__ 30
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace oboe;
|
using namespace oboe;
|
||||||
|
|
||||||
int32_t QuirksManager::DeviceQuirks::clipBufferSize(AudioStream &stream,
|
int32_t QuirksManager::DeviceQuirks::clipBufferSize(AudioStream &stream,
|
||||||
|
|
@ -74,6 +70,9 @@ public:
|
||||||
|
|
||||||
std::string chipname = getPropertyString("ro.hardware.chipname");
|
std::string chipname = getPropertyString("ro.hardware.chipname");
|
||||||
isExynos9810 = (chipname == "exynos9810");
|
isExynos9810 = (chipname == "exynos9810");
|
||||||
|
isExynos990 = (chipname == "exynos990");
|
||||||
|
|
||||||
|
mBuildChangelist = getPropertyInteger("ro.build.changelist", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SamsungDeviceQuirks() = default;
|
virtual ~SamsungDeviceQuirks() = default;
|
||||||
|
|
@ -98,6 +97,17 @@ public:
|
||||||
&& builder.getInputPreset() != oboe::InputPreset::Camcorder;
|
&& builder.getInputPreset() != oboe::InputPreset::Camcorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isMMapSafe(const AudioStreamBuilder &builder) override {
|
||||||
|
const bool isInput = builder.getDirection() == Direction::Input;
|
||||||
|
// This detects b/159066712 , S20 LSI has corrupt low latency audio recording
|
||||||
|
// and turns off MMAP.
|
||||||
|
// See also https://github.com/google/oboe/issues/892
|
||||||
|
bool mRecordingCorrupted = isInput
|
||||||
|
&& isExynos990
|
||||||
|
&& mBuildChangelist < 19350896;
|
||||||
|
return !mRecordingCorrupted;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Stay farther away from DSP position on Exynos devices.
|
// Stay farther away from DSP position on Exynos devices.
|
||||||
static constexpr int32_t kBottomMarginExynos = 2;
|
static constexpr int32_t kBottomMarginExynos = 2;
|
||||||
|
|
@ -105,6 +115,8 @@ private:
|
||||||
static constexpr int32_t kTopMargin = 1;
|
static constexpr int32_t kTopMargin = 1;
|
||||||
bool isExynos = false;
|
bool isExynos = false;
|
||||||
bool isExynos9810 = false;
|
bool isExynos9810 = false;
|
||||||
|
bool isExynos990 = false;
|
||||||
|
int mBuildChangelist = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
QuirksManager::QuirksManager() {
|
QuirksManager::QuirksManager() {
|
||||||
|
|
@ -203,3 +215,8 @@ bool QuirksManager::isConversionNeeded(
|
||||||
|
|
||||||
return conversionNeeded;
|
return conversionNeeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool QuirksManager::isMMapSafe(AudioStreamBuilder &builder) {
|
||||||
|
if (!OboeGlobals::areWorkaroundsEnabled()) return true;
|
||||||
|
return mDeviceQuirks->isMMapSafe(builder);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@
|
||||||
#include <oboe/AudioStreamBuilder.h>
|
#include <oboe/AudioStreamBuilder.h>
|
||||||
#include <aaudio/AudioStreamAAudio.h>
|
#include <aaudio/AudioStreamAAudio.h>
|
||||||
|
|
||||||
|
#ifndef __ANDROID_API_R__
|
||||||
|
#define __ANDROID_API_R__ 30
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace oboe {
|
namespace oboe {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -98,6 +102,10 @@ public:
|
||||||
|
|
||||||
virtual bool isAAudioMMapPossible(const AudioStreamBuilder &builder) const;
|
virtual bool isAAudioMMapPossible(const AudioStreamBuilder &builder) const;
|
||||||
|
|
||||||
|
virtual bool isMMapSafe(const AudioStreamBuilder & /* builder */ ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr int32_t kDefaultBottomMarginInBursts = 0;
|
static constexpr int32_t kDefaultBottomMarginInBursts = 0;
|
||||||
static constexpr int32_t kDefaultTopMarginInBursts = 0;
|
static constexpr int32_t kDefaultTopMarginInBursts = 0;
|
||||||
|
|
||||||
|
|
@ -108,6 +116,8 @@ public:
|
||||||
static constexpr int32_t kCommonNativeRate = 48000; // very typical native sample rate
|
static constexpr int32_t kCommonNativeRate = 48000; // very typical native sample rate
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool isMMapSafe(AudioStreamBuilder &builder);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static constexpr int32_t kChannelCountMono = 1;
|
static constexpr int32_t kChannelCountMono = 1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue