From d1f1cb68f567363a0b1e4cd4db6286afc6c8a1e2 Mon Sep 17 00:00:00 2001 From: jiabin Date: Tue, 24 Mar 2020 11:57:57 -0700 Subject: [PATCH] Add audio attributes info when starting aaudio tracks on MMAP mix. In aaudio, when adding tracks to mixed stream, it is needed to update audio attributes to HAL whenever the tracks are added or removed. Currently, only the audio attributes used to open the stream will be sent to the HAL. In that case, adding audio attributes of the clients when starting the stream can help solve the problem. In audio flinger, the client's audio attributes will be used to create MmapTrack. Test: play multiple aaudio tracks, add log Bug: 77279923 Change-Id: Ic1c536049e194a2bb7513425ee4828d52769d27f --- include/media/MmapStreamInterface.h | 5 ++- .../src/binding/AAudioBinderClient.h | 5 ++- .../src/binding/AAudioServiceInterface.h | 5 ++- .../src/client/AudioStreamInternal.cpp | 3 +- .../src/client/AudioStreamInternal.h | 1 + services/audioflinger/AudioFlinger.h | 3 +- services/audioflinger/Threads.cpp | 12 +++--- services/audioflinger/Threads.h | 4 +- services/oboeservice/AAudioService.cpp | 7 ++-- services/oboeservice/AAudioService.h | 5 ++- .../oboeservice/AAudioServiceEndpoint.cpp | 33 ++++++++++++++++ services/oboeservice/AAudioServiceEndpoint.h | 3 ++ .../oboeservice/AAudioServiceEndpointMMAP.cpp | 39 ++++++------------- .../oboeservice/AAudioServiceEndpointMMAP.h | 3 +- .../AAudioServiceEndpointShared.cpp | 4 +- .../oboeservice/AAudioServiceStreamBase.h | 3 +- .../oboeservice/AAudioServiceStreamMMAP.cpp | 7 ++-- .../oboeservice/AAudioServiceStreamMMAP.h | 1 + 18 files changed, 91 insertions(+), 52 deletions(-) diff --git a/include/media/MmapStreamInterface.h b/include/media/MmapStreamInterface.h index 0196a0c9d4..b3bf16d04b 100644 --- a/include/media/MmapStreamInterface.h +++ b/include/media/MmapStreamInterface.h @@ -107,12 +107,15 @@ class MmapStreamInterface : public virtual RefBase * createMmapBuffer() must be called before calling start() * * \param[in] client a AudioClient struct describing the client starting on this stream. + * \param[in] attr audio attributes provided by the client. * \param[out] handle unique handle for this instance. Used with stop(). * \return OK in case of success. * NO_INIT in case of initialization error * INVALID_OPERATION if called out of sequence */ - virtual status_t start(const AudioClient& client, audio_port_handle_t *handle) = 0; + virtual status_t start(const AudioClient& client, + const audio_attributes_t *attr, + audio_port_handle_t *handle) = 0; /** * Stop a stream operating in mmap mode. diff --git a/media/libaaudio/src/binding/AAudioBinderClient.h b/media/libaaudio/src/binding/AAudioBinderClient.h index f9da8b4519..e8c91fc935 100644 --- a/media/libaaudio/src/binding/AAudioBinderClient.h +++ b/media/libaaudio/src/binding/AAudioBinderClient.h @@ -98,8 +98,9 @@ public: pid_t clientThreadId) override; aaudio_result_t startClient(aaudio_handle_t streamHandle __unused, - const android::AudioClient& client __unused, - audio_port_handle_t *clientHandle) override { + const android::AudioClient& client __unused, + const audio_attributes_t *attr __unused, + audio_port_handle_t *clientHandle __unused) override { return AAUDIO_ERROR_UNAVAILABLE; } diff --git a/media/libaaudio/src/binding/AAudioServiceInterface.h b/media/libaaudio/src/binding/AAudioServiceInterface.h index a64405b1da..9c28cc7305 100644 --- a/media/libaaudio/src/binding/AAudioServiceInterface.h +++ b/media/libaaudio/src/binding/AAudioServiceInterface.h @@ -89,8 +89,9 @@ public: pid_t clientThreadId) = 0; virtual aaudio_result_t startClient(aaudio_handle_t streamHandle, - const android::AudioClient& client, - audio_port_handle_t *clientHandle) = 0; + const android::AudioClient& client, + const audio_attributes_t *attr, + audio_port_handle_t *clientHandle) = 0; virtual aaudio_result_t stopClient(aaudio_handle_t streamHandle, audio_port_handle_t clientHandle) = 0; diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp index b6548e6325..fcccf03112 100644 --- a/media/libaaudio/src/client/AudioStreamInternal.cpp +++ b/media/libaaudio/src/client/AudioStreamInternal.cpp @@ -429,13 +429,14 @@ aaudio_result_t AudioStreamInternal::unregisterThread() { } aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& client, + const audio_attributes_t *attr, audio_port_handle_t *portHandle) { ALOGV("%s() called", __func__); if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) { return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandle, - client, portHandle); + client, attr, portHandle); ALOGV("%s(%d) returning %d", __func__, *portHandle, result); return result; } diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h index 8843a8a3b6..095f30c280 100644 --- a/media/libaaudio/src/client/AudioStreamInternal.h +++ b/media/libaaudio/src/client/AudioStreamInternal.h @@ -90,6 +90,7 @@ public: int64_t calculateReasonableTimeout(); aaudio_result_t startClient(const android::AudioClient& client, + const audio_attributes_t *attr, audio_port_handle_t *clientHandle); aaudio_result_t stopClient(audio_port_handle_t clientHandle); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 40519b0be7..5c20a2d514 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -681,7 +681,8 @@ using effect_buffer_t = int16_t; struct audio_mmap_buffer_info *info); virtual status_t getMmapPosition(struct audio_mmap_position *position); virtual status_t start(const AudioClient& client, - audio_port_handle_t *handle); + const audio_attributes_t *attr, + audio_port_handle_t *handle); virtual status_t stop(audio_port_handle_t handle); virtual status_t standby(); diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index d8d4d35cb9..105fa14fec 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -8633,10 +8633,10 @@ status_t AudioFlinger::MmapThreadHandle::getMmapPosition(struct audio_mmap_posit } status_t AudioFlinger::MmapThreadHandle::start(const AudioClient& client, - audio_port_handle_t *handle) + const audio_attributes_t *attr, audio_port_handle_t *handle) { - return mThread->start(client, handle); + return mThread->start(client, attr, handle); } status_t AudioFlinger::MmapThreadHandle::stop(audio_port_handle_t handle) @@ -8741,6 +8741,7 @@ status_t AudioFlinger::MmapThread::exitStandby() } status_t AudioFlinger::MmapThread::start(const AudioClient& client, + const audio_attributes_t *attr, audio_port_handle_t *handle) { ALOGV("%s clientUid %d mStandby %d mPortId %d *handle %d", __FUNCTION__, @@ -8831,9 +8832,10 @@ status_t AudioFlinger::MmapThread::start(const AudioClient& client, } // Given that MmapThread::mAttr is mutable, should a MmapTrack have attributes ? - sp track = new MmapTrack(this, mAttr, mSampleRate, mFormat, mChannelMask, mSessionId, - isOutput(), client.clientUid, client.clientPid, - IPCThreadState::self()->getCallingPid(), portId); + sp track = new MmapTrack(this, attr == nullptr ? mAttr : *attr, mSampleRate, mFormat, + mChannelMask, mSessionId, isOutput(), client.clientUid, + client.clientPid, IPCThreadState::self()->getCallingPid(), + portId); if (isOutput()) { // force volume update when a new track is added diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index 8149e95b8e..e5a6196031 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -1776,7 +1776,9 @@ class MmapThread : public ThreadBase status_t createMmapBuffer(int32_t minSizeFrames, struct audio_mmap_buffer_info *info); status_t getMmapPosition(struct audio_mmap_position *position); - status_t start(const AudioClient& client, audio_port_handle_t *handle); + status_t start(const AudioClient& client, + const audio_attributes_t *attr, + audio_port_handle_t *handle); status_t stop(audio_port_handle_t handle); status_t standby(); diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp index af8c67b3a3..aba8e0887b 100644 --- a/services/oboeservice/AAudioService.cpp +++ b/services/oboeservice/AAudioService.cpp @@ -310,14 +310,15 @@ aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandl } aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle, - const android::AudioClient& client, - audio_port_handle_t *clientHandle) { + const android::AudioClient& client, + const audio_attributes_t *attr, + audio_port_handle_t *clientHandle) { sp serviceStream = convertHandleToServiceStream(streamHandle); if (serviceStream.get() == nullptr) { ALOGE("%s(), illegal stream handle = 0x%0x", __func__, streamHandle); return AAUDIO_ERROR_INVALID_HANDLE; } - aaudio_result_t result = serviceStream->startClient(client, clientHandle); + aaudio_result_t result = serviceStream->startClient(client, attr, clientHandle); return checkForPendingClose(serviceStream, result); } diff --git a/services/oboeservice/AAudioService.h b/services/oboeservice/AAudioService.h index 43a59c3eef..eddb5a0593 100644 --- a/services/oboeservice/AAudioService.h +++ b/services/oboeservice/AAudioService.h @@ -77,8 +77,9 @@ public: pid_t tid) override; aaudio_result_t startClient(aaudio::aaudio_handle_t streamHandle, - const android::AudioClient& client, - audio_port_handle_t *clientHandle) override; + const android::AudioClient& client, + const audio_attributes_t *attr, + audio_port_handle_t *clientHandle) override; aaudio_result_t stopClient(aaudio::aaudio_handle_t streamHandle, audio_port_handle_t clientHandle) override; diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp index 2753f1f536..647dcf770b 100644 --- a/services/oboeservice/AAudioServiceEndpoint.cpp +++ b/services/oboeservice/AAudioServiceEndpoint.cpp @@ -138,3 +138,36 @@ bool AAudioServiceEndpoint::matches(const AAudioStreamConfiguration& configurati } return true; } + +// static +audio_attributes_t AAudioServiceEndpoint::getAudioAttributesFrom( + const AAudioStreamParameters *params) { + if (params == nullptr) { + return {}; + } + const aaudio_direction_t direction = params->getDirection(); + + const audio_content_type_t contentType = + AAudioConvert_contentTypeToInternal(params->getContentType()); + // Usage only used for OUTPUT + const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT) + ? AAudioConvert_usageToInternal(params->getUsage()) + : AUDIO_USAGE_UNKNOWN; + const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT) + ? AAudioConvert_inputPresetToAudioSource(params->getInputPreset()) + : AUDIO_SOURCE_DEFAULT; + audio_flags_mask_t flags; + if (direction == AAUDIO_DIRECTION_OUTPUT) { + flags = AUDIO_FLAG_LOW_LATENCY + | AAudioConvert_allowCapturePolicyToAudioFlagsMask(params->getAllowedCapturePolicy()); + } else { + flags = AUDIO_FLAG_LOW_LATENCY + | AAudioConvert_privacySensitiveToAudioFlagsMask(params->isPrivacySensitive()); + } + return { + .content_type = contentType, + .usage = usage, + .source = source, + .flags = flags, + .tags = "" }; +} diff --git a/services/oboeservice/AAudioServiceEndpoint.h b/services/oboeservice/AAudioServiceEndpoint.h index a2f66a50f5..a6bb019ebf 100644 --- a/services/oboeservice/AAudioServiceEndpoint.h +++ b/services/oboeservice/AAudioServiceEndpoint.h @@ -60,6 +60,7 @@ public: audio_port_handle_t clientHandle) = 0; virtual aaudio_result_t startClient(const android::AudioClient& client, + const audio_attributes_t *attr, audio_port_handle_t *clientHandle) { ALOGD("AAudioServiceEndpoint::startClient(...) AAUDIO_ERROR_UNAVAILABLE"); return AAUDIO_ERROR_UNAVAILABLE; @@ -118,6 +119,8 @@ protected: void disconnectRegisteredStreams(); + static audio_attributes_t getAudioAttributesFrom(const AAudioStreamParameters *params); + mutable std::mutex mLockStreams; std::vector> mRegisteredStreams; diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp index 5bdb8eb860..af2710dc42 100644 --- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp +++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp @@ -79,32 +79,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques copyFrom(request.getConstantConfiguration()); - aaudio_direction_t direction = getDirection(); - - const audio_content_type_t contentType = - AAudioConvert_contentTypeToInternal(getContentType()); - // Usage only used for OUTPUT - const audio_usage_t usage = (direction == AAUDIO_DIRECTION_OUTPUT) - ? AAudioConvert_usageToInternal(getUsage()) - : AUDIO_USAGE_UNKNOWN; - const audio_source_t source = (direction == AAUDIO_DIRECTION_INPUT) - ? AAudioConvert_inputPresetToAudioSource(getInputPreset()) - : AUDIO_SOURCE_DEFAULT; - audio_flags_mask_t flags; - if (direction == AAUDIO_DIRECTION_OUTPUT) { - flags = AUDIO_FLAG_LOW_LATENCY - | AAudioConvert_allowCapturePolicyToAudioFlagsMask(getAllowedCapturePolicy()); - } else { - flags = AUDIO_FLAG_LOW_LATENCY - | AAudioConvert_privacySensitiveToAudioFlagsMask(isPrivacySensitive()); - } - const audio_attributes_t attributes = { - .content_type = contentType, - .usage = usage, - .source = source, - .flags = flags, - .tags = "" - }; + const audio_attributes_t attributes = getAudioAttributesFrom(this); mMmapClient.clientUid = request.getUserId(); mMmapClient.clientPid = request.getProcessId(); @@ -127,6 +102,8 @@ aaudio_result_t AAudioServiceEndpointMMAP::open(const aaudio::AAudioStreamReques int32_t aaudioSamplesPerFrame = getSamplesPerFrame(); + const aaudio_direction_t direction = getDirection(); + if (direction == AAUDIO_DIRECTION_OUTPUT) { config.channel_mask = (aaudioSamplesPerFrame == AAUDIO_UNSPECIFIED) ? AUDIO_CHANNEL_OUT_STEREO @@ -269,7 +246,12 @@ aaudio_result_t AAudioServiceEndpointMMAP::startStream(spstart(client, clientHandle); + status_t status = mMmapStream->start(client, attr, clientHandle); return AAudioConvert_androidToAAudioResult(status); } diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.h b/services/oboeservice/AAudioServiceEndpointMMAP.h index 5e815e00c4..f599066e30 100644 --- a/services/oboeservice/AAudioServiceEndpointMMAP.h +++ b/services/oboeservice/AAudioServiceEndpointMMAP.h @@ -59,7 +59,8 @@ public: audio_port_handle_t clientHandle) override; aaudio_result_t startClient(const android::AudioClient& client, - audio_port_handle_t *clientHandle) override; + const audio_attributes_t *attr, + audio_port_handle_t *clientHandle) override; aaudio_result_t stopClient(audio_port_handle_t clientHandle) override; diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp index 9b3b3b86b5..21253c85b0 100644 --- a/services/oboeservice/AAudioServiceEndpointShared.cpp +++ b/services/oboeservice/AAudioServiceEndpointShared.cpp @@ -152,7 +152,9 @@ aaudio_result_t AAudioServiceEndpointShared::startStream(spstartClient(sharedStream->getAudioClient(), clientHandle); + const audio_attributes_t attr = getAudioAttributesFrom(sharedStream.get()); + result = getStreamInternal()->startClient( + sharedStream->getAudioClient(), &attr, clientHandle); if (result != AAUDIO_OK) { if (--mRunningStreamCount == 0) { // atomic stopSharingThread(); diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h index 097bc64004..aaab567f31 100644 --- a/services/oboeservice/AAudioServiceStreamBase.h +++ b/services/oboeservice/AAudioServiceStreamBase.h @@ -111,7 +111,8 @@ public: virtual aaudio_result_t flush(); - virtual aaudio_result_t startClient(const android::AudioClient& client __unused, + virtual aaudio_result_t startClient(const android::AudioClient& client, + const audio_attributes_t *attr __unused, audio_port_handle_t *clientHandle __unused) { ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); return AAUDIO_ERROR_UNAVAILABLE; diff --git a/services/oboeservice/AAudioServiceStreamMMAP.cpp b/services/oboeservice/AAudioServiceStreamMMAP.cpp index f4e72b7bd3..639a0a89f4 100644 --- a/services/oboeservice/AAudioServiceStreamMMAP.cpp +++ b/services/oboeservice/AAudioServiceStreamMMAP.cpp @@ -86,7 +86,7 @@ aaudio_result_t AAudioServiceStreamMMAP::startDevice() { aaudio_result_t result = AAudioServiceStreamBase::startDevice(); if (!mInService && result == AAUDIO_OK) { // Note that this can sometimes take 200 to 300 msec for a cold start! - result = startClient(mMmapClient, &mClientHandle); + result = startClient(mMmapClient, nullptr /*const audio_attributes_t* */, &mClientHandle); } return result; } @@ -117,14 +117,15 @@ aaudio_result_t AAudioServiceStreamMMAP::stop() { } aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client, - audio_port_handle_t *clientHandle) { + const audio_attributes_t *attr, + audio_port_handle_t *clientHandle) { sp endpoint = mServiceEndpointWeak.promote(); if (endpoint == nullptr) { ALOGE("%s() has no endpoint", __func__); return AAUDIO_ERROR_INVALID_STATE; } // Start the client on behalf of the application. Generate a new porthandle. - aaudio_result_t result = endpoint->startClient(client, clientHandle); + aaudio_result_t result = endpoint->startClient(client, attr, clientHandle); return result; } diff --git a/services/oboeservice/AAudioServiceStreamMMAP.h b/services/oboeservice/AAudioServiceStreamMMAP.h index 3d56623129..91054691ad 100644 --- a/services/oboeservice/AAudioServiceStreamMMAP.h +++ b/services/oboeservice/AAudioServiceStreamMMAP.h @@ -63,6 +63,7 @@ public: aaudio_result_t stop() override; aaudio_result_t startClient(const android::AudioClient& client, + const audio_attributes_t *attr, audio_port_handle_t *clientHandle) override; aaudio_result_t stopClient(audio_port_handle_t clientHandle) override;