Loading media/libaaudio/src/client/AudioStreamInternal.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -620,17 +620,19 @@ aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& cli audio_port_handle_t *portHandle) { ALOGV("%s() called", __func__); if (getServiceHandle() == AAUDIO_HANDLE_INVALID) { ALOGE("%s() getServiceHandle() is invalid", __func__); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandleInfo, client, attr, portHandle); ALOGV("%s(%d) returning %d", __func__, *portHandle, result); ALOGV("%s(), got %d, returning %d", __func__, *portHandle, result); return result; } aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t portHandle) { ALOGV("%s(%d) called", __func__, portHandle); if (getServiceHandle() == AAUDIO_HANDLE_INVALID) { ALOGE("%s(%d) getServiceHandle() is invalid", __func__, portHandle); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandleInfo, portHandle); Loading services/oboeservice/AAudioServiceEndpointMMAP.cpp +87 −20 Original line number Diff line number Diff line Loading @@ -205,6 +205,8 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( "sample_rate=%u, channel_mask=%#x, device=%d", __func__, config->format, config->sample_rate, config->channel_mask, deviceId); const std::lock_guard<std::mutex> lock(mMmapStreamLock); const status_t status = MmapStreamInterface::openMmapStream(streamDirection, &attributes, config, Loading Loading @@ -246,7 +248,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( __func__, config->format, getDeviceId(), getSessionId()); // Create MMAP/NOIRQ buffer. result = createMmapBuffer(); result = createMmapBuffer_l(); if (result != AAUDIO_OK) { goto error; } Loading Loading @@ -283,7 +285,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( return result; error: close(); close_l(); // restore original requests setDeviceId(mRequestedDeviceId); setSessionId(requestedSessionId); Loading @@ -291,11 +293,26 @@ error: } void AAudioServiceEndpointMMAP::close() { bool closedIt = false; { const std::lock_guard<std::mutex> lock(mMmapStreamLock); closedIt = close_l(); } if (closedIt) { // TODO Why is this needed? AudioClock::sleepForNanos(100 * AAUDIO_NANOS_PER_MILLISECOND); } } bool AAudioServiceEndpointMMAP::close_l() { // requires mMmapStreamLock bool closedIt = false; if (mMmapStream != nullptr) { // Needs to be explicitly cleared or CTS will fail but it is not clear why. ALOGD("%s() clear mMmapStream", __func__); mMmapStream.clear(); AudioClock::sleepForNanos(100 * AAUDIO_NANOS_PER_MILLISECOND); closedIt = true; } return closedIt; } aaudio_result_t AAudioServiceEndpointMMAP::startStream(sp<AAudioServiceStreamBase> stream, Loading @@ -318,7 +335,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::startStream(sp<AAudioServiceStreamBas } aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase> /*stream*/, audio_port_handle_t /*clientHandle*/) { audio_port_handle_t clientHandle) { mFramesTransferred.reset32(); // Round 64-bit counter up to a multiple of the buffer capacity. Loading @@ -328,36 +345,68 @@ aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase mFramesTransferred.roundUp64(getBufferCapacity()); // Use the port handle that was provided by openMmapStream(). ALOGV("%s() mPortHandle = %d", __func__, mPortHandle); return stopClient(mPortHandle); aaudio_result_t result = stopClient(mPortHandle); ALOGD("%s(%d): called stopClient(%d=mPortHandle), returning %d", __func__, (int)clientHandle, mPortHandle, result); return result; } aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->start(client, attr, clientHandle)); audio_port_handle_t *portHandlePtr) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } else if (!isConnected()) { ALOGD("%s(): MMAP stream was disconnected", __func__); return AAUDIO_ERROR_DISCONNECTED; } else { aaudio_result_t result = AAudioConvert_androidToAAudioResult( mMmapStream->start(client, attr, portHandlePtr)); if (!isConnected() && (portHandlePtr != nullptr)) { ALOGD("%s(): MMAP stream DISCONNECTED after starting port %d, will stop it", __func__, *portHandlePtr); mMmapStream->stop(*portHandlePtr); *portHandlePtr = AUDIO_PORT_HANDLE_NONE; result = AAUDIO_ERROR_DISCONNECTED; } ALOGD("%s(): returning port %d, result %d", __func__, (portHandlePtr == nullptr) ? -1 : *portHandlePtr, result); return result; } } aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle)); aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t portHandle) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGE("%s(%d): called after mMmapStream set to NULL", __func__, (int)portHandle); return AAUDIO_ERROR_NULL; } else { aaudio_result_t result = AAudioConvert_androidToAAudioResult( mMmapStream->stop(portHandle)); ALOGD("%s(%d): returning %d", __func__, (int)portHandle, result); return result; } } aaudio_result_t AAudioServiceEndpointMMAP::standby() { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->standby()); const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } else { return AAudioConvert_androidToAAudioResult(mMmapStream->standby()); } } aaudio_result_t AAudioServiceEndpointMMAP::exitStandby(AudioEndpointParcelable* parcelable) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { return AAUDIO_ERROR_NULL; } mAudioDataWrapper->reset(); const aaudio_result_t result = createMmapBuffer(); const aaudio_result_t result = createMmapBuffer_l(); if (result == AAUDIO_OK) { getDownDataDescription(parcelable); } Loading @@ -367,10 +416,12 @@ aaudio_result_t AAudioServiceEndpointMMAP::exitStandby(AudioEndpointParcelable* // Get free-running DSP or DMA hardware position from the HAL. aaudio_result_t AAudioServiceEndpointMMAP::getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) { struct audio_mmap_position position; const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } struct audio_mmap_position position; const status_t status = mMmapStream->getMmapPosition(&position); ALOGV("%s() status= %d, pos = %d, nanos = %lld\n", __func__, status, position.position_frames, (long long) position.time_nanoseconds); Loading Loading @@ -475,9 +526,14 @@ aaudio_result_t AAudioServiceEndpointMMAP::getDownDataDescription( aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mHalExternalPositionStatus != AAUDIO_OK) { return mHalExternalPositionStatus; } if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } uint64_t tempPositionFrames; int64_t tempTimeNanos; const status_t status = mMmapStream->getExternalPosition(&tempPositionFrames, &tempTimeNanos); Loading Loading @@ -552,13 +608,20 @@ aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positio return mHalExternalPositionStatus; } aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer() // mMmapStreamLock should be held when calling this function. aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer_l() { memset(&mMmapBufferinfo, 0, sizeof(struct audio_mmap_buffer_info)); int32_t minSizeFrames = getBufferCapacity(); if (minSizeFrames <= 0) { // zero will get rejected minSizeFrames = AAUDIO_BUFFER_CAPACITY_MIN; } if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } const status_t status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo); const bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE; if (status != OK) { Loading Loading @@ -598,6 +661,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer() // Call to HAL to make sure the transport FD was able to be closed by binder. // This is a tricky workaround for a problem in Binder. // TODO:[b/192048842] When that problem is fixed we may be able to remove or change this code. ALOGD("%s() - call getMmapPosition() as a hack to clear FD stuck in Binder", __func__); struct audio_mmap_position position; mMmapStream->getMmapPosition(&position); Loading @@ -613,11 +677,14 @@ int64_t AAudioServiceEndpointMMAP::nextDataReportTime() { } void AAudioServiceEndpointMMAP::reportData() { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { // This must not happen ALOGE("%s() invalid state, mmap stream is not initialized", __func__); return; } auto fifo = mAudioDataWrapper->getFifoBuffer(); if (fifo == nullptr) { ALOGE("%s() fifo buffer is not initialized, cannot report data", __func__); Loading services/oboeservice/AAudioServiceEndpointMMAP.h +25 −12 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public: aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override; void close() override; void close() override EXCLUDES(mMmapStreamLock); aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream, audio_port_handle_t *clientHandle) override; Loading @@ -60,15 +60,19 @@ public: aaudio_result_t startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) override; audio_port_handle_t *clientHandle) override EXCLUDES(mMmapStreamLock); aaudio_result_t stopClient(audio_port_handle_t clientHandle) override; aaudio_result_t stopClient(audio_port_handle_t clientHandle) override EXCLUDES(mMmapStreamLock); aaudio_result_t standby() override; aaudio_result_t standby() override EXCLUDES(mMmapStreamLock); aaudio_result_t exitStandby(AudioEndpointParcelable* parcelable) override; aaudio_result_t exitStandby(AudioEndpointParcelable* parcelable) override EXCLUDES(mMmapStreamLock); aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override; aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override EXCLUDES(mMmapStreamLock); aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos) override; Loading @@ -88,22 +92,31 @@ public: return mHardwareTimeOffsetNanos; } aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos); aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos) EXCLUDES(mMmapStreamLock); int64_t nextDataReportTime(); int64_t nextDataReportTime() EXCLUDES(mMmapStreamLock); void reportData(); void reportData() EXCLUDES(mMmapStreamLock); private: aaudio_result_t openWithConfig(audio_config_base_t* config); /** * * @return true if mMapStream was cleared */ bool close_l() REQUIRES(mMmapStreamLock); aaudio_result_t openWithConfig(audio_config_base_t* config) EXCLUDES(mMmapStreamLock); aaudio_result_t createMmapBuffer(); aaudio_result_t createMmapBuffer_l() REQUIRES(mMmapStreamLock); MonotonicCounter mFramesTransferred; // Interface to the AudioFlinger MMAP support. android::sp<android::MmapStreamInterface> mMmapStream; mutable std::mutex mMmapStreamLock; android::sp<android::MmapStreamInterface> mMmapStream GUARDED_BY(mMmapStreamLock); struct audio_mmap_buffer_info mMmapBufferinfo; // There is only one port associated with an MMAP endpoint. Loading services/oboeservice/AAudioServiceStreamBase.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,10 @@ aaudio_result_t AAudioServiceStreamBase::startDevice_l() { ALOGE("%s() has no endpoint", __func__); return AAUDIO_ERROR_INVALID_STATE; } if (!endpoint->isConnected()) { ALOGE("%s() endpoint was already disconnected", __func__); return AAUDIO_ERROR_DISCONNECTED; } return endpoint->startStream(this, &mClientHandle); } Loading Loading @@ -334,6 +338,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { aaudio_result_t AAudioServiceStreamBase::stop_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { ALOGW("%s() stream not running, returning early", __func__); return result; } const int64_t beginNs = AudioClock::getNanoseconds(); Loading services/oboeservice/AAudioServiceStreamMMAP.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -150,9 +150,9 @@ aaudio_result_t AAudioServiceStreamMMAP::exitStandby_l(AudioEndpointParcelable* aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) { audio_port_handle_t *portHandlePtr) { if (com::android::media::aaudio::start_stop_client_from_command_thread()) { return sendStartClientCommand(client, attr, clientHandle); return sendStartClientCommand(client, attr, portHandlePtr); } else { sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote(); if (endpoint == nullptr) { Loading @@ -160,7 +160,9 @@ aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& return AAUDIO_ERROR_INVALID_STATE; } // Start the client on behalf of the application. Generate a new porthandle. aaudio_result_t result = endpoint->startClient(client, attr, clientHandle); aaudio_result_t result = endpoint->startClient(client, attr, portHandlePtr); ALOGD("%s() flag off, got port %d", __func__, ((portHandlePtr == nullptr) ? -1 : *portHandlePtr)); return result; } } Loading Loading
media/libaaudio/src/client/AudioStreamInternal.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -620,17 +620,19 @@ aaudio_result_t AudioStreamInternal::startClient(const android::AudioClient& cli audio_port_handle_t *portHandle) { ALOGV("%s() called", __func__); if (getServiceHandle() == AAUDIO_HANDLE_INVALID) { ALOGE("%s() getServiceHandle() is invalid", __func__); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = mServiceInterface.startClient(mServiceStreamHandleInfo, client, attr, portHandle); ALOGV("%s(%d) returning %d", __func__, *portHandle, result); ALOGV("%s(), got %d, returning %d", __func__, *portHandle, result); return result; } aaudio_result_t AudioStreamInternal::stopClient(audio_port_handle_t portHandle) { ALOGV("%s(%d) called", __func__, portHandle); if (getServiceHandle() == AAUDIO_HANDLE_INVALID) { ALOGE("%s(%d) getServiceHandle() is invalid", __func__, portHandle); return AAUDIO_ERROR_INVALID_STATE; } aaudio_result_t result = mServiceInterface.stopClient(mServiceStreamHandleInfo, portHandle); Loading
services/oboeservice/AAudioServiceEndpointMMAP.cpp +87 −20 Original line number Diff line number Diff line Loading @@ -205,6 +205,8 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( "sample_rate=%u, channel_mask=%#x, device=%d", __func__, config->format, config->sample_rate, config->channel_mask, deviceId); const std::lock_guard<std::mutex> lock(mMmapStreamLock); const status_t status = MmapStreamInterface::openMmapStream(streamDirection, &attributes, config, Loading Loading @@ -246,7 +248,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( __func__, config->format, getDeviceId(), getSessionId()); // Create MMAP/NOIRQ buffer. result = createMmapBuffer(); result = createMmapBuffer_l(); if (result != AAUDIO_OK) { goto error; } Loading Loading @@ -283,7 +285,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::openWithConfig( return result; error: close(); close_l(); // restore original requests setDeviceId(mRequestedDeviceId); setSessionId(requestedSessionId); Loading @@ -291,11 +293,26 @@ error: } void AAudioServiceEndpointMMAP::close() { bool closedIt = false; { const std::lock_guard<std::mutex> lock(mMmapStreamLock); closedIt = close_l(); } if (closedIt) { // TODO Why is this needed? AudioClock::sleepForNanos(100 * AAUDIO_NANOS_PER_MILLISECOND); } } bool AAudioServiceEndpointMMAP::close_l() { // requires mMmapStreamLock bool closedIt = false; if (mMmapStream != nullptr) { // Needs to be explicitly cleared or CTS will fail but it is not clear why. ALOGD("%s() clear mMmapStream", __func__); mMmapStream.clear(); AudioClock::sleepForNanos(100 * AAUDIO_NANOS_PER_MILLISECOND); closedIt = true; } return closedIt; } aaudio_result_t AAudioServiceEndpointMMAP::startStream(sp<AAudioServiceStreamBase> stream, Loading @@ -318,7 +335,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::startStream(sp<AAudioServiceStreamBas } aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase> /*stream*/, audio_port_handle_t /*clientHandle*/) { audio_port_handle_t clientHandle) { mFramesTransferred.reset32(); // Round 64-bit counter up to a multiple of the buffer capacity. Loading @@ -328,36 +345,68 @@ aaudio_result_t AAudioServiceEndpointMMAP::stopStream(sp<AAudioServiceStreamBase mFramesTransferred.roundUp64(getBufferCapacity()); // Use the port handle that was provided by openMmapStream(). ALOGV("%s() mPortHandle = %d", __func__, mPortHandle); return stopClient(mPortHandle); aaudio_result_t result = stopClient(mPortHandle); ALOGD("%s(%d): called stopClient(%d=mPortHandle), returning %d", __func__, (int)clientHandle, mPortHandle, result); return result; } aaudio_result_t AAudioServiceEndpointMMAP::startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->start(client, attr, clientHandle)); audio_port_handle_t *portHandlePtr) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } else if (!isConnected()) { ALOGD("%s(): MMAP stream was disconnected", __func__); return AAUDIO_ERROR_DISCONNECTED; } else { aaudio_result_t result = AAudioConvert_androidToAAudioResult( mMmapStream->start(client, attr, portHandlePtr)); if (!isConnected() && (portHandlePtr != nullptr)) { ALOGD("%s(): MMAP stream DISCONNECTED after starting port %d, will stop it", __func__, *portHandlePtr); mMmapStream->stop(*portHandlePtr); *portHandlePtr = AUDIO_PORT_HANDLE_NONE; result = AAUDIO_ERROR_DISCONNECTED; } ALOGD("%s(): returning port %d, result %d", __func__, (portHandlePtr == nullptr) ? -1 : *portHandlePtr, result); return result; } } aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t clientHandle) { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->stop(clientHandle)); aaudio_result_t AAudioServiceEndpointMMAP::stopClient(audio_port_handle_t portHandle) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGE("%s(%d): called after mMmapStream set to NULL", __func__, (int)portHandle); return AAUDIO_ERROR_NULL; } else { aaudio_result_t result = AAudioConvert_androidToAAudioResult( mMmapStream->stop(portHandle)); ALOGD("%s(%d): returning %d", __func__, (int)portHandle, result); return result; } } aaudio_result_t AAudioServiceEndpointMMAP::standby() { return mMmapStream == nullptr ? AAUDIO_ERROR_NULL : AAudioConvert_androidToAAudioResult(mMmapStream->standby()); const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } else { return AAudioConvert_androidToAAudioResult(mMmapStream->standby()); } } aaudio_result_t AAudioServiceEndpointMMAP::exitStandby(AudioEndpointParcelable* parcelable) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { return AAUDIO_ERROR_NULL; } mAudioDataWrapper->reset(); const aaudio_result_t result = createMmapBuffer(); const aaudio_result_t result = createMmapBuffer_l(); if (result == AAUDIO_OK) { getDownDataDescription(parcelable); } Loading @@ -367,10 +416,12 @@ aaudio_result_t AAudioServiceEndpointMMAP::exitStandby(AudioEndpointParcelable* // Get free-running DSP or DMA hardware position from the HAL. aaudio_result_t AAudioServiceEndpointMMAP::getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) { struct audio_mmap_position position; const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } struct audio_mmap_position position; const status_t status = mMmapStream->getMmapPosition(&position); ALOGV("%s() status= %d, pos = %d, nanos = %lld\n", __func__, status, position.position_frames, (long long) position.time_nanoseconds); Loading Loading @@ -475,9 +526,14 @@ aaudio_result_t AAudioServiceEndpointMMAP::getDownDataDescription( aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos) { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mHalExternalPositionStatus != AAUDIO_OK) { return mHalExternalPositionStatus; } if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } uint64_t tempPositionFrames; int64_t tempTimeNanos; const status_t status = mMmapStream->getExternalPosition(&tempPositionFrames, &tempTimeNanos); Loading Loading @@ -552,13 +608,20 @@ aaudio_result_t AAudioServiceEndpointMMAP::getExternalPosition(uint64_t *positio return mHalExternalPositionStatus; } aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer() // mMmapStreamLock should be held when calling this function. aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer_l() { memset(&mMmapBufferinfo, 0, sizeof(struct audio_mmap_buffer_info)); int32_t minSizeFrames = getBufferCapacity(); if (minSizeFrames <= 0) { // zero will get rejected minSizeFrames = AAUDIO_BUFFER_CAPACITY_MIN; } if (mMmapStream == nullptr) { ALOGW("%s(): called after mMmapStream set to NULL", __func__); return AAUDIO_ERROR_NULL; } const status_t status = mMmapStream->createMmapBuffer(minSizeFrames, &mMmapBufferinfo); const bool isBufferShareable = mMmapBufferinfo.flags & AUDIO_MMAP_APPLICATION_SHAREABLE; if (status != OK) { Loading Loading @@ -598,6 +661,7 @@ aaudio_result_t AAudioServiceEndpointMMAP::createMmapBuffer() // Call to HAL to make sure the transport FD was able to be closed by binder. // This is a tricky workaround for a problem in Binder. // TODO:[b/192048842] When that problem is fixed we may be able to remove or change this code. ALOGD("%s() - call getMmapPosition() as a hack to clear FD stuck in Binder", __func__); struct audio_mmap_position position; mMmapStream->getMmapPosition(&position); Loading @@ -613,11 +677,14 @@ int64_t AAudioServiceEndpointMMAP::nextDataReportTime() { } void AAudioServiceEndpointMMAP::reportData() { const std::lock_guard<std::mutex> lock(mMmapStreamLock); if (mMmapStream == nullptr) { // This must not happen ALOGE("%s() invalid state, mmap stream is not initialized", __func__); return; } auto fifo = mAudioDataWrapper->getFifoBuffer(); if (fifo == nullptr) { ALOGE("%s() fifo buffer is not initialized, cannot report data", __func__); Loading
services/oboeservice/AAudioServiceEndpointMMAP.h +25 −12 Original line number Diff line number Diff line Loading @@ -50,7 +50,7 @@ public: aaudio_result_t open(const aaudio::AAudioStreamRequest &request) override; void close() override; void close() override EXCLUDES(mMmapStreamLock); aaudio_result_t startStream(android::sp<AAudioServiceStreamBase> stream, audio_port_handle_t *clientHandle) override; Loading @@ -60,15 +60,19 @@ public: aaudio_result_t startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) override; audio_port_handle_t *clientHandle) override EXCLUDES(mMmapStreamLock); aaudio_result_t stopClient(audio_port_handle_t clientHandle) override; aaudio_result_t stopClient(audio_port_handle_t clientHandle) override EXCLUDES(mMmapStreamLock); aaudio_result_t standby() override; aaudio_result_t standby() override EXCLUDES(mMmapStreamLock); aaudio_result_t exitStandby(AudioEndpointParcelable* parcelable) override; aaudio_result_t exitStandby(AudioEndpointParcelable* parcelable) override EXCLUDES(mMmapStreamLock); aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override; aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) override EXCLUDES(mMmapStreamLock); aaudio_result_t getTimestamp(int64_t *positionFrames, int64_t *timeNanos) override; Loading @@ -88,22 +92,31 @@ public: return mHardwareTimeOffsetNanos; } aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos); aaudio_result_t getExternalPosition(uint64_t *positionFrames, int64_t *timeNanos) EXCLUDES(mMmapStreamLock); int64_t nextDataReportTime(); int64_t nextDataReportTime() EXCLUDES(mMmapStreamLock); void reportData(); void reportData() EXCLUDES(mMmapStreamLock); private: aaudio_result_t openWithConfig(audio_config_base_t* config); /** * * @return true if mMapStream was cleared */ bool close_l() REQUIRES(mMmapStreamLock); aaudio_result_t openWithConfig(audio_config_base_t* config) EXCLUDES(mMmapStreamLock); aaudio_result_t createMmapBuffer(); aaudio_result_t createMmapBuffer_l() REQUIRES(mMmapStreamLock); MonotonicCounter mFramesTransferred; // Interface to the AudioFlinger MMAP support. android::sp<android::MmapStreamInterface> mMmapStream; mutable std::mutex mMmapStreamLock; android::sp<android::MmapStreamInterface> mMmapStream GUARDED_BY(mMmapStreamLock); struct audio_mmap_buffer_info mMmapBufferinfo; // There is only one port associated with an MMAP endpoint. Loading
services/oboeservice/AAudioServiceStreamBase.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -227,6 +227,10 @@ aaudio_result_t AAudioServiceStreamBase::startDevice_l() { ALOGE("%s() has no endpoint", __func__); return AAUDIO_ERROR_INVALID_STATE; } if (!endpoint->isConnected()) { ALOGE("%s() endpoint was already disconnected", __func__); return AAUDIO_ERROR_DISCONNECTED; } return endpoint->startStream(this, &mClientHandle); } Loading Loading @@ -334,6 +338,7 @@ aaudio_result_t AAudioServiceStreamBase::stop() { aaudio_result_t AAudioServiceStreamBase::stop_l() { aaudio_result_t result = AAUDIO_OK; if (!isRunning()) { ALOGW("%s() stream not running, returning early", __func__); return result; } const int64_t beginNs = AudioClock::getNanoseconds(); Loading
services/oboeservice/AAudioServiceStreamMMAP.cpp +5 −3 Original line number Diff line number Diff line Loading @@ -150,9 +150,9 @@ aaudio_result_t AAudioServiceStreamMMAP::exitStandby_l(AudioEndpointParcelable* aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& client, const audio_attributes_t *attr, audio_port_handle_t *clientHandle) { audio_port_handle_t *portHandlePtr) { if (com::android::media::aaudio::start_stop_client_from_command_thread()) { return sendStartClientCommand(client, attr, clientHandle); return sendStartClientCommand(client, attr, portHandlePtr); } else { sp<AAudioServiceEndpoint> endpoint = mServiceEndpointWeak.promote(); if (endpoint == nullptr) { Loading @@ -160,7 +160,9 @@ aaudio_result_t AAudioServiceStreamMMAP::startClient(const android::AudioClient& return AAUDIO_ERROR_INVALID_STATE; } // Start the client on behalf of the application. Generate a new porthandle. aaudio_result_t result = endpoint->startClient(client, attr, clientHandle); aaudio_result_t result = endpoint->startClient(client, attr, portHandlePtr); ALOGD("%s() flag off, got port %d", __func__, ((portHandlePtr == nullptr) ? -1 : *portHandlePtr)); return result; } } Loading