aaudio: modify endpoint sharing logic
A new Client stream in shared mode can share an existing endpoint
if it has no preferences or compatible device, sample rate and channel
count requests.
Bug: 62961537
Test: play and capture with AAudio in mmap mode
Change-Id: I38536fb486dfc06f4399f7d02248384583fd3a17
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index 94577a6..d8b9101 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -51,13 +51,13 @@
size_t inputs = mInputs.size();
result << "Inputs: " << inputs << "\n";
for (const auto &input : mInputs) {
- result << " Input(" << input.first << ", " << input.second << ")\n";
+ result << " Input(" << input << ")\n";
}
size_t outputs = mOutputs.size();
result << "Outputs: " << outputs << "\n";
for (const auto &output : mOutputs) {
- result << " Output(" << output.first << ", " << output.second << ")\n";
+ result << " Output(" << output << ")\n";
}
if (isLocked) {
@@ -66,27 +66,40 @@
return result.str();
}
-AAudioServiceEndpoint *AAudioEndpointManager::openEndpoint(AAudioService &audioService, int32_t deviceId,
- aaudio_direction_t direction) {
+AAudioServiceEndpoint *AAudioEndpointManager::openEndpoint(AAudioService &audioService,
+ const AAudioStreamConfiguration& configuration, aaudio_direction_t direction) {
AAudioServiceEndpoint *endpoint = nullptr;
AAudioServiceEndpointCapture *capture = nullptr;
AAudioServiceEndpointPlay *player = nullptr;
std::lock_guard<std::mutex> lock(mLock);
// Try to find an existing endpoint.
+
+
+
switch (direction) {
case AAUDIO_DIRECTION_INPUT:
- endpoint = mInputs[deviceId];
+ for (AAudioServiceEndpoint *ep : mInputs) {
+ if (ep->matches(configuration)) {
+ endpoint = ep;
+ break;
+ }
+ }
break;
case AAUDIO_DIRECTION_OUTPUT:
- endpoint = mOutputs[deviceId];
+ for (AAudioServiceEndpoint *ep : mOutputs) {
+ if (ep->matches(configuration)) {
+ endpoint = ep;
+ break;
+ }
+ }
break;
default:
assert(false); // There are only two possible directions.
break;
}
ALOGD("AAudioEndpointManager::openEndpoint(), found %p for device = %d, dir = %d",
- endpoint, deviceId, (int)direction);
+ endpoint, configuration.getDeviceId(), (int)direction);
// If we can't find an existing one then open a new one.
if (endpoint == nullptr) {
@@ -105,7 +118,7 @@
}
if (endpoint != nullptr) {
- aaudio_result_t result = endpoint->open(deviceId);
+ aaudio_result_t result = endpoint->open(configuration);
if (result != AAUDIO_OK) {
ALOGE("AAudioEndpointManager::findEndpoint(), open failed");
delete endpoint;
@@ -113,17 +126,17 @@
} else {
switch(direction) {
case AAUDIO_DIRECTION_INPUT:
- mInputs[deviceId] = capture;
+ mInputs.push_back(capture);
break;
case AAUDIO_DIRECTION_OUTPUT:
- mOutputs[deviceId] = player;
+ mOutputs.push_back(player);
break;
default:
break;
}
}
ALOGD("AAudioEndpointManager::openEndpoint(), created %p for device = %d, dir = %d",
- endpoint, deviceId, (int)direction);
+ endpoint, configuration.getDeviceId(), (int)direction);
}
if (endpoint != nullptr) {
@@ -156,10 +169,12 @@
switch (direction) {
case AAUDIO_DIRECTION_INPUT:
- mInputs.erase(deviceId);
+ mInputs.erase(
+ std::remove(mInputs.begin(), mInputs.end(), serviceEndpoint), mInputs.end());
break;
case AAUDIO_DIRECTION_OUTPUT:
- mOutputs.erase(deviceId);
+ mOutputs.erase(
+ std::remove(mOutputs.begin(), mOutputs.end(), serviceEndpoint), mOutputs.end());
break;
default:
break;
diff --git a/services/oboeservice/AAudioEndpointManager.h b/services/oboeservice/AAudioEndpointManager.h
index 6dc5adf..6d3b52b 100644
--- a/services/oboeservice/AAudioEndpointManager.h
+++ b/services/oboeservice/AAudioEndpointManager.h
@@ -54,7 +54,7 @@
* @return endpoint or nullptr
*/
AAudioServiceEndpoint *openEndpoint(android::AAudioService &audioService,
- int32_t deviceId,
+ const AAudioStreamConfiguration& configuration,
aaudio_direction_t direction);
void closeEndpoint(AAudioServiceEndpoint *serviceEndpoint);
@@ -63,8 +63,8 @@
mutable std::mutex mLock;
- std::map<int32_t, AAudioServiceEndpointCapture *> mInputs;
- std::map<int32_t, AAudioServiceEndpointPlay *> mOutputs;
+ std::vector<AAudioServiceEndpointCapture *> mInputs;
+ std::vector<AAudioServiceEndpointPlay *> mOutputs;
};
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 3815711..488063f 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -45,15 +45,18 @@
#define DEFAULT_BUFFER_CAPACITY (48 * 8)
// Set up an EXCLUSIVE MMAP stream that will be shared.
-aaudio_result_t AAudioServiceEndpoint::open(int32_t deviceId) {
- mRequestedDeviceId = deviceId;
+aaudio_result_t AAudioServiceEndpoint::open(const AAudioStreamConfiguration& configuration) {
+ mRequestedDeviceId = configuration.getDeviceId();
mStreamInternal = getStreamInternal();
AudioStreamBuilder builder;
builder.setSharingMode(AAUDIO_SHARING_MODE_EXCLUSIVE);
// Don't fall back to SHARED because that would cause recursion.
builder.setSharingModeMatchRequired(true);
- builder.setDeviceId(deviceId);
+ builder.setDeviceId(mRequestedDeviceId);
+ builder.setFormat(configuration.getAudioFormat());
+ builder.setSampleRate(configuration.getSampleRate());
+ builder.setSamplesPerFrame(configuration.getSamplesPerFrame());
builder.setDirection(getDirection());
builder.setBufferCapacity(DEFAULT_BUFFER_CAPACITY);
@@ -139,3 +142,20 @@
}
mRegisteredStreams.clear();
}
+
+bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configuration) {
+ if (configuration.getDeviceId() != AAUDIO_UNSPECIFIED &&
+ configuration.getDeviceId() != mStreamInternal->getDeviceId()) {
+ return false;
+ }
+ if (configuration.getSampleRate() != AAUDIO_UNSPECIFIED &&
+ configuration.getSampleRate() != mStreamInternal->getSampleRate()) {
+ return false;
+ }
+ if (configuration.getSamplesPerFrame() != AAUDIO_UNSPECIFIED &&
+ configuration.getSamplesPerFrame() != mStreamInternal->getSamplesPerFrame()) {
+ return false;
+ }
+
+ return true;
+}
diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h
index 090b1dd..72015b1 100644
--- a/services/oboeservice/AAudioServiceEndpoint.h
+++ b/services/oboeservice/AAudioServiceEndpoint.h
@@ -36,7 +36,7 @@
public:
virtual ~AAudioServiceEndpoint() = default;
- virtual aaudio_result_t open(int32_t deviceId);
+ virtual aaudio_result_t open(const AAudioStreamConfiguration& configuration);
int32_t getSampleRate() const { return mStreamInternal->getSampleRate(); }
int32_t getSamplesPerFrame() const { return mStreamInternal->getSamplesPerFrame(); }
@@ -67,6 +67,8 @@
mReferenceCount = count;
}
+ bool matches(const AAudioStreamConfiguration& configuration);
+
virtual AudioStreamInternal *getStreamInternal() = 0;
std::atomic<bool> mCallbackEnabled;
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 2bb79bf..a144c54 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -42,8 +42,8 @@
delete mDistributionBuffer;
}
-aaudio_result_t AAudioServiceEndpointCapture::open(int32_t deviceId) {
- aaudio_result_t result = AAudioServiceEndpoint::open(deviceId);
+aaudio_result_t AAudioServiceEndpointCapture::open(const AAudioStreamConfiguration& configuration) {
+ aaudio_result_t result = AAudioServiceEndpoint::open(configuration);
if (result == AAUDIO_OK) {
delete mDistributionBuffer;
int distributionBufferSizeBytes = getStreamInternal()->getFramesPerBurst()
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.h b/services/oboeservice/AAudioServiceEndpointCapture.h
index 35857d1..8a3d72f 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.h
+++ b/services/oboeservice/AAudioServiceEndpointCapture.h
@@ -27,7 +27,7 @@
explicit AAudioServiceEndpointCapture(android::AAudioService &audioService);
virtual ~AAudioServiceEndpointCapture();
- aaudio_result_t open(int32_t deviceId) override;
+ aaudio_result_t open(const AAudioStreamConfiguration& configuration) override;
AudioStreamInternal *getStreamInternal() override {
return &mStreamInternalCapture;
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index bbe4788..7ab3bcd 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -46,8 +46,8 @@
AAudioServiceEndpointPlay::~AAudioServiceEndpointPlay() {
}
-aaudio_result_t AAudioServiceEndpointPlay::open(int32_t deviceId) {
- aaudio_result_t result = AAudioServiceEndpoint::open(deviceId);
+aaudio_result_t AAudioServiceEndpointPlay::open(const AAudioStreamConfiguration& configuration) {
+ aaudio_result_t result = AAudioServiceEndpoint::open(configuration);
if (result == AAUDIO_OK) {
mMixer.allocate(getStreamInternal()->getSamplesPerFrame(),
getStreamInternal()->getFramesPerBurst());
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.h b/services/oboeservice/AAudioServiceEndpointPlay.h
index 89935ae..c22f510 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.h
+++ b/services/oboeservice/AAudioServiceEndpointPlay.h
@@ -40,7 +40,7 @@
explicit AAudioServiceEndpointPlay(android::AAudioService &audioService);
virtual ~AAudioServiceEndpointPlay();
- aaudio_result_t open(int32_t deviceId) override;
+ aaudio_result_t open(const AAudioStreamConfiguration& configuration) override;
AudioStreamInternal *getStreamInternal() override {
return &mStreamInternalPlay;
diff --git a/services/oboeservice/AAudioServiceStreamShared.cpp b/services/oboeservice/AAudioServiceStreamShared.cpp
index 7515ea7..7475692 100644
--- a/services/oboeservice/AAudioServiceStreamShared.cpp
+++ b/services/oboeservice/AAudioServiceStreamShared.cpp
@@ -106,11 +106,10 @@
}
const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
- int32_t deviceId = configurationInput.getDeviceId();
aaudio_direction_t direction = request.getDirection();
AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
- mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, deviceId, direction);
+ mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, configurationOutput, direction);
if (mServiceEndpoint == nullptr) {
ALOGE("AAudioServiceStreamShared::open() mServiceEndPoint = %p", mServiceEndpoint);
return AAUDIO_ERROR_UNAVAILABLE;