Loading audio/aidl/default/Module.cpp +26 −22 Original line number Diff line number Diff line Loading @@ -214,24 +214,33 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs, mVendorDebug.forceTransientBurst, mVendorDebug.forceSynchronousDrain}; std::unique_ptr<StreamContext::DataMQ> dataMQ = nullptr; std::shared_ptr<IStreamCallback> streamAsyncCallback = nullptr; std::shared_ptr<ISoundDose> soundDose; if (!getSoundDose(&soundDose).isOk()) { LOG(ERROR) << __func__ << ": could not create sound dose instance"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } if (!hasMmapFlag(flags)) { dataMQ = std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames); streamAsyncCallback = asyncCallback; } StreamContext temp( StreamContext temp; if (hasMmapFlag(flags)) { MmapBufferDescriptor mmapDesc; RETURN_STATUS_IF_ERROR( createMmapBuffer(*portConfigIt, in_bufferSizeFrames, frameSize, &mmapDesc)); temp = StreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, nominalLatencyMs, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(mmapDesc), outEventCallback, mSoundDose.getInstance(), params); } else { temp = StreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, nominalLatencyMs, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(dataMQ), streamAsyncCallback, outEventCallback, mSoundDose.getInstance(), params); portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, mSoundDose.getInstance(), params); } if (temp.isValid()) { *out_context = std::move(temp); } else { Loading Loading @@ -394,9 +403,10 @@ ndk::ScopedAStatus Module::calculateBufferSizeFrames( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } ndk::ScopedAStatus Module::createMmapBuffer( const ::aidl::android::hardware::audio::core::StreamContext& context __unused, ::aidl::android::hardware::audio::core::StreamDescriptor* desc __unused) { ndk::ScopedAStatus Module::createMmapBuffer(const AudioPortConfig& portConfig __unused, int32_t bufferSizeFrames __unused, int32_t frameSizeBytes __unused, MmapBufferDescriptor* desc __unused) { LOG(ERROR) << __func__ << ": " << mType << ": is not implemented"; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } Loading Loading @@ -977,9 +987,6 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context)); context.fillDescriptor(&_aidl_return->desc); if (hasMmapFlag(context.getFlags())) { RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc)); } std::shared_ptr<StreamIn> stream; RETURN_STATUS_IF_ERROR(createInputStream(std::move(context), in_args.sinkMetadata, getMicrophoneInfos(), &stream)); Loading Loading @@ -1027,9 +1034,6 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ isNonBlocking ? in_args.callback : nullptr, in_args.eventCallback, &context)); context.fillDescriptor(&_aidl_return->desc); if (hasMmapFlag(context.getFlags())) { RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc)); } std::shared_ptr<StreamOut> stream; RETURN_STATUS_IF_ERROR(createOutputStream(std::move(context), in_args.sourceMetadata, in_args.offloadInfo, &stream)); Loading audio/aidl/default/Stream.cpp +23 −12 Original line number Diff line number Diff line Loading @@ -65,18 +65,26 @@ void StreamContext::fillDescriptor(StreamDescriptor* desc) { if (mReplyMQ) { desc->reply = mReplyMQ->dupeDesc(); } if (mDataMQ) { desc->frameSizeBytes = getFrameSize(); desc->bufferSizeFrames = getBufferSizeInFrames(); if (mDataMQ) { desc->audio.set<StreamDescriptor::AudioBuffer::Tag::fmq>(mDataMQ->dupeDesc()); } else { MmapBufferDescriptor mmapDesc; // Move-only due to `fd`. mmapDesc.sharedMemory.fd = mMmapBufferDesc.sharedMemory.fd.dup(); mmapDesc.sharedMemory.size = mMmapBufferDesc.sharedMemory.size; mmapDesc.burstSizeFrames = mMmapBufferDesc.burstSizeFrames; mmapDesc.flags = mMmapBufferDesc.flags; desc->audio.set<StreamDescriptor::AudioBuffer::Tag::mmap>(std::move(mmapDesc)); } } size_t StreamContext::getBufferSizeInFrames() const { if (mDataMQ) { return mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() / getFrameSize(); } else { return mMmapBufferDesc.sharedMemory.size / getFrameSize(); } return 0; } size_t StreamContext::getFrameSize() const { Loading @@ -96,9 +104,13 @@ bool StreamContext::isValid() const { LOG(ERROR) << "frame size is invalid"; return false; } if (!hasMmapFlag(mFlags) && mDataMQ && !mDataMQ->isValid()) { if (!isMmap() && mDataMQ && !mDataMQ->isValid()) { LOG(ERROR) << "data FMQ is invalid"; return false; } else if (isMmap() && (mMmapBufferDesc.sharedMemory.fd.get() == -1 || mMmapBufferDesc.sharedMemory.size == 0 || mMmapBufferDesc.burstSizeFrames == 0)) { LOG(ERROR) << "mmap info is invalid" << mMmapBufferDesc.toString(); } return true; } Loading @@ -115,6 +127,7 @@ void StreamContext::reset() { mCommandMQ.reset(); mReplyMQ.reset(); mDataMQ.reset(); mMmapBufferDesc.sharedMemory.fd.set(-1); } pid_t StreamWorkerCommonLogic::getTid() const { Loading @@ -128,7 +141,7 @@ pid_t StreamWorkerCommonLogic::getTid() const { std::string StreamWorkerCommonLogic::init() { if (mContext->getCommandMQ() == nullptr) return "Command MQ is null"; if (mContext->getReplyMQ() == nullptr) return "Reply MQ is null"; if (!hasMmapFlag(mContext->getFlags())) { if (!mContext->isMmap()) { StreamContext::DataMQ* const dataMQ = mContext->getDataMQ(); if (dataMQ == nullptr) return "Data MQ is null"; if (sizeof(DataBufferElement) != dataMQ->getQuantumSize()) { Loading Loading @@ -167,7 +180,7 @@ void StreamWorkerCommonLogic::populateReply(StreamDescriptor::Reply* reply, } else { reply->observable = reply->hardware = kUnknownPosition; } if (hasMmapFlag(mContext->getFlags())) { if (mContext->isMmap()) { if (auto status = mDriver->getMmapPositionAndLatency(&reply->hardware, &reply->latencyMs); status != ::android::OK) { reply->hardware = kUnknownPosition; Loading Loading @@ -252,9 +265,8 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { mState == StreamDescriptor::State::ACTIVE || mState == StreamDescriptor::State::PAUSED || mState == StreamDescriptor::State::DRAINING) { if (bool success = hasMmapFlag(mContext->getFlags()) ? readMmap(&reply) : read(fmqByteCount, &reply); if (bool success = mContext->isMmap() ? readMmap(&reply) : read(fmqByteCount, &reply); !success) { mState = StreamDescriptor::State::ERROR; } Loading Loading @@ -548,8 +560,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { if (mState != StreamDescriptor::State::ERROR && mState != StreamDescriptor::State::TRANSFERRING && mState != StreamDescriptor::State::TRANSFER_PAUSED) { if (bool success = hasMmapFlag(mContext->getFlags()) ? writeMmap(&reply) if (bool success = mContext->isMmap() ? writeMmap(&reply) : write(fmqByteCount, &reply); !success) { mState = StreamDescriptor::State::ERROR; Loading audio/aidl/default/include/core-impl/Module.h +2 −2 Original line number Diff line number Diff line Loading @@ -212,8 +212,8 @@ class Module : public BnModule { const ::aidl::android::media::audio::common::AudioFormatDescription &format, int32_t latencyMs, int32_t sampleRateHz, int32_t *bufferSizeFrames); virtual ndk::ScopedAStatus createMmapBuffer( const ::aidl::android::hardware::audio::core::StreamContext& context, ::aidl::android::hardware::audio::core::StreamDescriptor* desc); const ::aidl::android::media::audio::common::AudioPortConfig& portConfig, int32_t bufferSizeFrames, int32_t frameSizeBytes, MmapBufferDescriptor* desc); // Utility and helper functions accessible to subclasses. static int32_t calculateBufferSizeFramesForPcm(int32_t latencyMs, int32_t sampleRateHz) { Loading audio/aidl/default/include/core-impl/Stream.h +24 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,27 @@ class StreamContext { mOutEventCallback(outEventCallback), mStreamDataProcessor(streamDataProcessor), mDebugParameters(debugParameters) {} StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ, const ::aidl::android::media::audio::common::AudioFormatDescription& format, const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout, int sampleRate, const ::aidl::android::media::audio::common::AudioIoFlags& flags, int32_t nominalLatencyMs, int32_t mixPortHandle, MmapBufferDescriptor&& mmapDesc, std::shared_ptr<IStreamOutEventCallback> outEventCallback, std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor, DebugParameters debugParameters) : mCommandMQ(std::move(commandMQ)), mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */), mReplyMQ(std::move(replyMQ)), mFormat(format), mChannelLayout(channelLayout), mSampleRate(sampleRate), mFlags(flags), mNominalLatencyMs(nominalLatencyMs), mMixPortHandle(mixPortHandle), mMmapBufferDesc(std::move(mmapDesc)), mOutEventCallback(outEventCallback), mStreamDataProcessor(streamDataProcessor), mDebugParameters(debugParameters) {} void fillDescriptor(StreamDescriptor* desc); std::shared_ptr<IStreamCallback> getAsyncCallback() const { return mAsyncCallback; } Loading Loading @@ -136,6 +157,7 @@ class StreamContext { bool isInput() const { return mFlags.getTag() == ::aidl::android::media::audio::common::AudioIoFlags::input; } bool isMmap() const { return ::aidl::android::hardware::audio::common::hasMmapFlag(mFlags); } bool isValid() const; // 'reset' is called on a Binder thread when closing the stream. Does not use // locking because it only cleans MQ pointers which were also set on the Binder thread. Loading @@ -155,7 +177,9 @@ class StreamContext { ::aidl::android::media::audio::common::AudioIoFlags mFlags; int32_t mNominalLatencyMs; int32_t mMixPortHandle; // Only one of `mDataMQ` or `mMapBufferDesc` can be active, depending on `isMmap` std::unique_ptr<DataMQ> mDataMQ; MmapBufferDescriptor mMmapBufferDesc; std::shared_ptr<IStreamCallback> mAsyncCallback; std::shared_ptr<IStreamOutEventCallback> mOutEventCallback; // Only used by output streams std::weak_ptr<sounddose::StreamDataProcessorInterface> mStreamDataProcessor; Loading bluetooth/audio/flags/btaudiohal.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -14,3 +14,10 @@ flag { description: "Flag for reporting lea broadcast audio config to HAL" bug: "321168976" } flag { name: "leaudio_sw_offload" namespace: "pixel_bluetooth" description: "Flag for using sw offload path to send premium audio" bug: "398885696" } Loading
audio/aidl/default/Module.cpp +26 −22 Original line number Diff line number Diff line Loading @@ -214,24 +214,33 @@ ndk::ScopedAStatus Module::createStreamContext( StreamContext::DebugParameters params{mDebug.streamTransientStateDelayMs, mVendorDebug.forceTransientBurst, mVendorDebug.forceSynchronousDrain}; std::unique_ptr<StreamContext::DataMQ> dataMQ = nullptr; std::shared_ptr<IStreamCallback> streamAsyncCallback = nullptr; std::shared_ptr<ISoundDose> soundDose; if (!getSoundDose(&soundDose).isOk()) { LOG(ERROR) << __func__ << ": could not create sound dose instance"; return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } if (!hasMmapFlag(flags)) { dataMQ = std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames); streamAsyncCallback = asyncCallback; } StreamContext temp( StreamContext temp; if (hasMmapFlag(flags)) { MmapBufferDescriptor mmapDesc; RETURN_STATUS_IF_ERROR( createMmapBuffer(*portConfigIt, in_bufferSizeFrames, frameSize, &mmapDesc)); temp = StreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, nominalLatencyMs, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(mmapDesc), outEventCallback, mSoundDose.getInstance(), params); } else { temp = StreamContext( std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/), std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/), portConfigIt->format.value(), portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags, nominalLatencyMs, portConfigIt->ext.get<AudioPortExt::mix>().handle, std::move(dataMQ), streamAsyncCallback, outEventCallback, mSoundDose.getInstance(), params); portConfigIt->ext.get<AudioPortExt::mix>().handle, std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames), asyncCallback, outEventCallback, mSoundDose.getInstance(), params); } if (temp.isValid()) { *out_context = std::move(temp); } else { Loading Loading @@ -394,9 +403,10 @@ ndk::ScopedAStatus Module::calculateBufferSizeFrames( return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } ndk::ScopedAStatus Module::createMmapBuffer( const ::aidl::android::hardware::audio::core::StreamContext& context __unused, ::aidl::android::hardware::audio::core::StreamDescriptor* desc __unused) { ndk::ScopedAStatus Module::createMmapBuffer(const AudioPortConfig& portConfig __unused, int32_t bufferSizeFrames __unused, int32_t frameSizeBytes __unused, MmapBufferDescriptor* desc __unused) { LOG(ERROR) << __func__ << ": " << mType << ": is not implemented"; return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } Loading Loading @@ -977,9 +987,6 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar RETURN_STATUS_IF_ERROR(createStreamContext(in_args.portConfigId, in_args.bufferSizeFrames, nullptr, nullptr, &context)); context.fillDescriptor(&_aidl_return->desc); if (hasMmapFlag(context.getFlags())) { RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc)); } std::shared_ptr<StreamIn> stream; RETURN_STATUS_IF_ERROR(createInputStream(std::move(context), in_args.sinkMetadata, getMicrophoneInfos(), &stream)); Loading Loading @@ -1027,9 +1034,6 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ isNonBlocking ? in_args.callback : nullptr, in_args.eventCallback, &context)); context.fillDescriptor(&_aidl_return->desc); if (hasMmapFlag(context.getFlags())) { RETURN_STATUS_IF_ERROR(createMmapBuffer(context, &_aidl_return->desc)); } std::shared_ptr<StreamOut> stream; RETURN_STATUS_IF_ERROR(createOutputStream(std::move(context), in_args.sourceMetadata, in_args.offloadInfo, &stream)); Loading
audio/aidl/default/Stream.cpp +23 −12 Original line number Diff line number Diff line Loading @@ -65,18 +65,26 @@ void StreamContext::fillDescriptor(StreamDescriptor* desc) { if (mReplyMQ) { desc->reply = mReplyMQ->dupeDesc(); } if (mDataMQ) { desc->frameSizeBytes = getFrameSize(); desc->bufferSizeFrames = getBufferSizeInFrames(); if (mDataMQ) { desc->audio.set<StreamDescriptor::AudioBuffer::Tag::fmq>(mDataMQ->dupeDesc()); } else { MmapBufferDescriptor mmapDesc; // Move-only due to `fd`. mmapDesc.sharedMemory.fd = mMmapBufferDesc.sharedMemory.fd.dup(); mmapDesc.sharedMemory.size = mMmapBufferDesc.sharedMemory.size; mmapDesc.burstSizeFrames = mMmapBufferDesc.burstSizeFrames; mmapDesc.flags = mMmapBufferDesc.flags; desc->audio.set<StreamDescriptor::AudioBuffer::Tag::mmap>(std::move(mmapDesc)); } } size_t StreamContext::getBufferSizeInFrames() const { if (mDataMQ) { return mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() / getFrameSize(); } else { return mMmapBufferDesc.sharedMemory.size / getFrameSize(); } return 0; } size_t StreamContext::getFrameSize() const { Loading @@ -96,9 +104,13 @@ bool StreamContext::isValid() const { LOG(ERROR) << "frame size is invalid"; return false; } if (!hasMmapFlag(mFlags) && mDataMQ && !mDataMQ->isValid()) { if (!isMmap() && mDataMQ && !mDataMQ->isValid()) { LOG(ERROR) << "data FMQ is invalid"; return false; } else if (isMmap() && (mMmapBufferDesc.sharedMemory.fd.get() == -1 || mMmapBufferDesc.sharedMemory.size == 0 || mMmapBufferDesc.burstSizeFrames == 0)) { LOG(ERROR) << "mmap info is invalid" << mMmapBufferDesc.toString(); } return true; } Loading @@ -115,6 +127,7 @@ void StreamContext::reset() { mCommandMQ.reset(); mReplyMQ.reset(); mDataMQ.reset(); mMmapBufferDesc.sharedMemory.fd.set(-1); } pid_t StreamWorkerCommonLogic::getTid() const { Loading @@ -128,7 +141,7 @@ pid_t StreamWorkerCommonLogic::getTid() const { std::string StreamWorkerCommonLogic::init() { if (mContext->getCommandMQ() == nullptr) return "Command MQ is null"; if (mContext->getReplyMQ() == nullptr) return "Reply MQ is null"; if (!hasMmapFlag(mContext->getFlags())) { if (!mContext->isMmap()) { StreamContext::DataMQ* const dataMQ = mContext->getDataMQ(); if (dataMQ == nullptr) return "Data MQ is null"; if (sizeof(DataBufferElement) != dataMQ->getQuantumSize()) { Loading Loading @@ -167,7 +180,7 @@ void StreamWorkerCommonLogic::populateReply(StreamDescriptor::Reply* reply, } else { reply->observable = reply->hardware = kUnknownPosition; } if (hasMmapFlag(mContext->getFlags())) { if (mContext->isMmap()) { if (auto status = mDriver->getMmapPositionAndLatency(&reply->hardware, &reply->latencyMs); status != ::android::OK) { reply->hardware = kUnknownPosition; Loading Loading @@ -252,9 +265,8 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() { mState == StreamDescriptor::State::ACTIVE || mState == StreamDescriptor::State::PAUSED || mState == StreamDescriptor::State::DRAINING) { if (bool success = hasMmapFlag(mContext->getFlags()) ? readMmap(&reply) : read(fmqByteCount, &reply); if (bool success = mContext->isMmap() ? readMmap(&reply) : read(fmqByteCount, &reply); !success) { mState = StreamDescriptor::State::ERROR; } Loading Loading @@ -548,8 +560,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() { if (mState != StreamDescriptor::State::ERROR && mState != StreamDescriptor::State::TRANSFERRING && mState != StreamDescriptor::State::TRANSFER_PAUSED) { if (bool success = hasMmapFlag(mContext->getFlags()) ? writeMmap(&reply) if (bool success = mContext->isMmap() ? writeMmap(&reply) : write(fmqByteCount, &reply); !success) { mState = StreamDescriptor::State::ERROR; Loading
audio/aidl/default/include/core-impl/Module.h +2 −2 Original line number Diff line number Diff line Loading @@ -212,8 +212,8 @@ class Module : public BnModule { const ::aidl::android::media::audio::common::AudioFormatDescription &format, int32_t latencyMs, int32_t sampleRateHz, int32_t *bufferSizeFrames); virtual ndk::ScopedAStatus createMmapBuffer( const ::aidl::android::hardware::audio::core::StreamContext& context, ::aidl::android::hardware::audio::core::StreamDescriptor* desc); const ::aidl::android::media::audio::common::AudioPortConfig& portConfig, int32_t bufferSizeFrames, int32_t frameSizeBytes, MmapBufferDescriptor* desc); // Utility and helper functions accessible to subclasses. static int32_t calculateBufferSizeFramesForPcm(int32_t latencyMs, int32_t sampleRateHz) { Loading
audio/aidl/default/include/core-impl/Stream.h +24 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,27 @@ class StreamContext { mOutEventCallback(outEventCallback), mStreamDataProcessor(streamDataProcessor), mDebugParameters(debugParameters) {} StreamContext(std::unique_ptr<CommandMQ> commandMQ, std::unique_ptr<ReplyMQ> replyMQ, const ::aidl::android::media::audio::common::AudioFormatDescription& format, const ::aidl::android::media::audio::common::AudioChannelLayout& channelLayout, int sampleRate, const ::aidl::android::media::audio::common::AudioIoFlags& flags, int32_t nominalLatencyMs, int32_t mixPortHandle, MmapBufferDescriptor&& mmapDesc, std::shared_ptr<IStreamOutEventCallback> outEventCallback, std::weak_ptr<sounddose::StreamDataProcessorInterface> streamDataProcessor, DebugParameters debugParameters) : mCommandMQ(std::move(commandMQ)), mInternalCommandCookie(std::rand() | 1 /* make sure it's not 0 */), mReplyMQ(std::move(replyMQ)), mFormat(format), mChannelLayout(channelLayout), mSampleRate(sampleRate), mFlags(flags), mNominalLatencyMs(nominalLatencyMs), mMixPortHandle(mixPortHandle), mMmapBufferDesc(std::move(mmapDesc)), mOutEventCallback(outEventCallback), mStreamDataProcessor(streamDataProcessor), mDebugParameters(debugParameters) {} void fillDescriptor(StreamDescriptor* desc); std::shared_ptr<IStreamCallback> getAsyncCallback() const { return mAsyncCallback; } Loading Loading @@ -136,6 +157,7 @@ class StreamContext { bool isInput() const { return mFlags.getTag() == ::aidl::android::media::audio::common::AudioIoFlags::input; } bool isMmap() const { return ::aidl::android::hardware::audio::common::hasMmapFlag(mFlags); } bool isValid() const; // 'reset' is called on a Binder thread when closing the stream. Does not use // locking because it only cleans MQ pointers which were also set on the Binder thread. Loading @@ -155,7 +177,9 @@ class StreamContext { ::aidl::android::media::audio::common::AudioIoFlags mFlags; int32_t mNominalLatencyMs; int32_t mMixPortHandle; // Only one of `mDataMQ` or `mMapBufferDesc` can be active, depending on `isMmap` std::unique_ptr<DataMQ> mDataMQ; MmapBufferDescriptor mMmapBufferDesc; std::shared_ptr<IStreamCallback> mAsyncCallback; std::shared_ptr<IStreamOutEventCallback> mOutEventCallback; // Only used by output streams std::weak_ptr<sounddose::StreamDataProcessorInterface> mStreamDataProcessor; Loading
bluetooth/audio/flags/btaudiohal.aconfig +8 −1 Original line number Diff line number Diff line Loading @@ -14,3 +14,10 @@ flag { description: "Flag for reporting lea broadcast audio config to HAL" bug: "321168976" } flag { name: "leaudio_sw_offload" namespace: "pixel_bluetooth" description: "Flag for using sw offload path to send premium audio" bug: "398885696" }