Loading media/libmedia/include/media/PatchBuilder.h 0 → 100644 +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 ANDROID_PATCH_BUILDER_H #define ANDROID_PATCH_BUILDER_H #include <functional> #include <utility> #include <system/audio.h> #include <utils/StrongPointer.h> // This is a header-only utility. namespace android { class PatchBuilder { public: using mix_usecase_t = decltype(audio_port_config_mix_ext::usecase); PatchBuilder() = default; // All existing methods operating on audio patches take a pointer to const. // It's OK to construct a temporary PatchBuilder while preparing a parameter // to such a function because the Builder will be kept alive until the code // execution reaches the function call statement semicolon. const struct audio_patch* patch() const { return &mPatch; } template<typename T, typename... S> PatchBuilder& addSink(T&& t, S&&... s) { sinks().add(std::forward<T>(t), std::forward<S>(s)...); return *this; } // Explicit type of the second parameter allows clients to provide the struct inline. template<typename T> PatchBuilder& addSink(T&& t, const mix_usecase_t& update) { sinks().add(std::forward<T>(t), update); return *this; } template<typename T, typename... S> PatchBuilder& addSource(T&& t, S&&... s) { sources().add(std::forward<T>(t), std::forward<S>(s)...); return *this; } // Explicit type of the second parameter allows clients to provide the struct inline. template<typename T> PatchBuilder& addSource(T&& t, const mix_usecase_t& update) { sources().add(std::forward<T>(t), update); return *this; } private: struct PortCfgs { PortCfgs(unsigned int *countPtr, struct audio_port_config *portCfgs) : mCountPtr(countPtr), mPortCfgs(portCfgs) {} audio_port_config& add(const audio_port_config& portCfg) { return *advance() = portCfg; } template<typename T> audio_port_config& add(const sp<T>& entity) { audio_port_config* added = advance(); entity->toAudioPortConfig(added); return *added; } template<typename T> void add(const sp<T>& entity, const mix_usecase_t& usecaseUpdate) { add(entity).ext.mix.usecase = usecaseUpdate; } template<typename T> void add(const sp<T>& entity, std::function<mix_usecase_t(const mix_usecase_t&)> usecaseUpdater) { mix_usecase_t* usecase = &add(entity).ext.mix.usecase; *usecase = usecaseUpdater(*usecase); } struct audio_port_config* advance() { return &mPortCfgs[(*mCountPtr)++]; } unsigned int *mCountPtr; struct audio_port_config *mPortCfgs; }; PortCfgs sinks() { return PortCfgs(&mPatch.num_sinks, mPatch.sinks); } PortCfgs sources() { return PortCfgs(&mPatch.num_sources, mPatch.sources); } struct audio_patch mPatch = {}; }; } // namespace android #endif // ANDROID_PATCH_BUILDER_H services/audioflinger/PatchPanel.cpp +8 −12 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "AudioFlinger.h" #include "ServiceUtilities.h" #include <media/AudioParameter.h> #include <media/PatchBuilder.h> // ---------------------------------------------------------------------------- Loading Loading @@ -373,15 +374,10 @@ AudioFlinger::PatchPanel::Patch::~Patch() status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel) { // create patch from source device to record thread input struct audio_patch subPatch; subPatch.num_sources = 1; subPatch.sources[0] = mAudioPatch.sources[0]; subPatch.num_sinks = 1; mRecord.thread()->getAudioPortConfig(&subPatch.sinks[0]); subPatch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_MIC; status_t status = panel->createAudioPatch(&subPatch, mRecord.handlePtr()); status_t status = panel->createAudioPatch( PatchBuilder().addSource(mAudioPatch.sources[0]). addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(), mRecord.handlePtr()); if (status != NO_ERROR) { *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE; return status; Loading @@ -389,9 +385,9 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel) // create patch from playback thread output to sink device if (mAudioPatch.num_sinks != 0) { mPlayback.thread()->getAudioPortConfig(&subPatch.sources[0]); subPatch.sinks[0] = mAudioPatch.sinks[0]; status = panel->createAudioPatch(&subPatch, mPlayback.handlePtr()); status = panel->createAudioPatch( PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(), mPlayback.handlePtr()); if (status != NO_ERROR) { *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE; return status; Loading services/audioflinger/Threads.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -1527,7 +1527,7 @@ void AudioFlinger::ThreadBase::setMode(audio_mode_t mode) } } void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config) { config->type = AUDIO_PORT_TYPE_MIX; config->ext.mix.handle = mId; Loading Loading @@ -3780,9 +3780,9 @@ void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track) destroyTrack_l(track); } void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); config->role = AUDIO_PORT_ROLE_SOURCE; config->ext.mix.hw_module = mOutput->audioHwDev->handle(); config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; Loading Loading @@ -7875,9 +7875,9 @@ void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record) destroyTrack_l(record); } void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); config->role = AUDIO_PORT_ROLE_SINK; config->ext.mix.hw_module = mInput->audioHwDev->handle(); config->ext.mix.usecase.source = mAudioSource; Loading Loading @@ -8462,9 +8462,9 @@ status_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_ return status; } void AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); if (isOutput()) { config->role = AUDIO_PORT_ROLE_SOURCE; config->ext.mix.hw_module = mAudioHwDev->handle(); Loading services/audioflinger/Threads.h +4 −4 Original line number Diff line number Diff line Loading @@ -281,7 +281,7 @@ public: virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle) = 0; virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0; virtual void getAudioPortConfig(struct audio_port_config *config) = 0; virtual void toAudioPortConfig(struct audio_port_config *config) = 0; // see note at declaration of mStandby, mOutDevice and mInDevice Loading Loading @@ -782,7 +782,7 @@ public: void addPatchTrack(const sp<PatchTrack>& track); void deletePatchTrack(const sp<PatchTrack>& track); virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); // Return the asynchronous signal wait time. virtual int64_t computeWaitTimeNs_l() const { return INT64_MAX; } Loading Loading @@ -1459,7 +1459,7 @@ public: virtual size_t frameCount() const { return mFrameCount; } bool hasFastCapture() const { return mFastCapture != 0; } virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc, audio_session_t sessionId); Loading Loading @@ -1602,7 +1602,7 @@ class MmapThread : public ThreadBase virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); virtual sp<StreamHalInterface> stream() const { return mHalStream; } virtual status_t addEffectChain_l(const sp<EffectChain>& chain); Loading services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h→services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h +8 −7 Original line number Diff line number Diff line Loading @@ -19,26 +19,27 @@ namespace android { /** * Interface for input descriptors to implement so dependent audio sessions can query information * about their context * Interface for I/O descriptors to implement so information about their context * can be queried and updated. */ class AudioSessionInfoProvider class AudioIODescriptorInterface { public: virtual ~AudioSessionInfoProvider() {}; virtual ~AudioIODescriptorInterface() {}; virtual audio_config_base_t getConfig() const = 0; virtual audio_patch_handle_t getPatchHandle() const = 0; virtual void setPatchHandle(audio_patch_handle_t handle) = 0; }; class AudioSessionInfoUpdateListener class AudioIODescriptorUpdateListener { public: virtual ~AudioSessionInfoUpdateListener() {}; virtual ~AudioIODescriptorUpdateListener() {}; virtual void onSessionInfoUpdate() const = 0;; virtual void onIODescriptorUpdate() const = 0; }; } // namespace android Loading
media/libmedia/include/media/PatchBuilder.h 0 → 100644 +103 −0 Original line number Diff line number Diff line /* * Copyright (C) 2018 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 ANDROID_PATCH_BUILDER_H #define ANDROID_PATCH_BUILDER_H #include <functional> #include <utility> #include <system/audio.h> #include <utils/StrongPointer.h> // This is a header-only utility. namespace android { class PatchBuilder { public: using mix_usecase_t = decltype(audio_port_config_mix_ext::usecase); PatchBuilder() = default; // All existing methods operating on audio patches take a pointer to const. // It's OK to construct a temporary PatchBuilder while preparing a parameter // to such a function because the Builder will be kept alive until the code // execution reaches the function call statement semicolon. const struct audio_patch* patch() const { return &mPatch; } template<typename T, typename... S> PatchBuilder& addSink(T&& t, S&&... s) { sinks().add(std::forward<T>(t), std::forward<S>(s)...); return *this; } // Explicit type of the second parameter allows clients to provide the struct inline. template<typename T> PatchBuilder& addSink(T&& t, const mix_usecase_t& update) { sinks().add(std::forward<T>(t), update); return *this; } template<typename T, typename... S> PatchBuilder& addSource(T&& t, S&&... s) { sources().add(std::forward<T>(t), std::forward<S>(s)...); return *this; } // Explicit type of the second parameter allows clients to provide the struct inline. template<typename T> PatchBuilder& addSource(T&& t, const mix_usecase_t& update) { sources().add(std::forward<T>(t), update); return *this; } private: struct PortCfgs { PortCfgs(unsigned int *countPtr, struct audio_port_config *portCfgs) : mCountPtr(countPtr), mPortCfgs(portCfgs) {} audio_port_config& add(const audio_port_config& portCfg) { return *advance() = portCfg; } template<typename T> audio_port_config& add(const sp<T>& entity) { audio_port_config* added = advance(); entity->toAudioPortConfig(added); return *added; } template<typename T> void add(const sp<T>& entity, const mix_usecase_t& usecaseUpdate) { add(entity).ext.mix.usecase = usecaseUpdate; } template<typename T> void add(const sp<T>& entity, std::function<mix_usecase_t(const mix_usecase_t&)> usecaseUpdater) { mix_usecase_t* usecase = &add(entity).ext.mix.usecase; *usecase = usecaseUpdater(*usecase); } struct audio_port_config* advance() { return &mPortCfgs[(*mCountPtr)++]; } unsigned int *mCountPtr; struct audio_port_config *mPortCfgs; }; PortCfgs sinks() { return PortCfgs(&mPatch.num_sinks, mPatch.sinks); } PortCfgs sources() { return PortCfgs(&mPatch.num_sources, mPatch.sources); } struct audio_patch mPatch = {}; }; } // namespace android #endif // ANDROID_PATCH_BUILDER_H
services/audioflinger/PatchPanel.cpp +8 −12 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include "AudioFlinger.h" #include "ServiceUtilities.h" #include <media/AudioParameter.h> #include <media/PatchBuilder.h> // ---------------------------------------------------------------------------- Loading Loading @@ -373,15 +374,10 @@ AudioFlinger::PatchPanel::Patch::~Patch() status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel) { // create patch from source device to record thread input struct audio_patch subPatch; subPatch.num_sources = 1; subPatch.sources[0] = mAudioPatch.sources[0]; subPatch.num_sinks = 1; mRecord.thread()->getAudioPortConfig(&subPatch.sinks[0]); subPatch.sinks[0].ext.mix.usecase.source = AUDIO_SOURCE_MIC; status_t status = panel->createAudioPatch(&subPatch, mRecord.handlePtr()); status_t status = panel->createAudioPatch( PatchBuilder().addSource(mAudioPatch.sources[0]). addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(), mRecord.handlePtr()); if (status != NO_ERROR) { *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE; return status; Loading @@ -389,9 +385,9 @@ status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel) // create patch from playback thread output to sink device if (mAudioPatch.num_sinks != 0) { mPlayback.thread()->getAudioPortConfig(&subPatch.sources[0]); subPatch.sinks[0] = mAudioPatch.sinks[0]; status = panel->createAudioPatch(&subPatch, mPlayback.handlePtr()); status = panel->createAudioPatch( PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(), mPlayback.handlePtr()); if (status != NO_ERROR) { *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE; return status; Loading
services/audioflinger/Threads.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -1527,7 +1527,7 @@ void AudioFlinger::ThreadBase::setMode(audio_mode_t mode) } } void AudioFlinger::ThreadBase::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::ThreadBase::toAudioPortConfig(struct audio_port_config *config) { config->type = AUDIO_PORT_TYPE_MIX; config->ext.mix.handle = mId; Loading Loading @@ -3780,9 +3780,9 @@ void AudioFlinger::PlaybackThread::deletePatchTrack(const sp<PatchTrack>& track) destroyTrack_l(track); } void AudioFlinger::PlaybackThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::PlaybackThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); config->role = AUDIO_PORT_ROLE_SOURCE; config->ext.mix.hw_module = mOutput->audioHwDev->handle(); config->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; Loading Loading @@ -7875,9 +7875,9 @@ void AudioFlinger::RecordThread::deletePatchTrack(const sp<PatchRecord>& record) destroyTrack_l(record); } void AudioFlinger::RecordThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::RecordThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); config->role = AUDIO_PORT_ROLE_SINK; config->ext.mix.hw_module = mInput->audioHwDev->handle(); config->ext.mix.usecase.source = mAudioSource; Loading Loading @@ -8462,9 +8462,9 @@ status_t AudioFlinger::MmapThread::releaseAudioPatch_l(const audio_patch_handle_ return status; } void AudioFlinger::MmapThread::getAudioPortConfig(struct audio_port_config *config) void AudioFlinger::MmapThread::toAudioPortConfig(struct audio_port_config *config) { ThreadBase::getAudioPortConfig(config); ThreadBase::toAudioPortConfig(config); if (isOutput()) { config->role = AUDIO_PORT_ROLE_SOURCE; config->ext.mix.hw_module = mAudioHwDev->handle(); Loading
services/audioflinger/Threads.h +4 −4 Original line number Diff line number Diff line Loading @@ -281,7 +281,7 @@ public: virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle) = 0; virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle) = 0; virtual void getAudioPortConfig(struct audio_port_config *config) = 0; virtual void toAudioPortConfig(struct audio_port_config *config) = 0; // see note at declaration of mStandby, mOutDevice and mInDevice Loading Loading @@ -782,7 +782,7 @@ public: void addPatchTrack(const sp<PatchTrack>& track); void deletePatchTrack(const sp<PatchTrack>& track); virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); // Return the asynchronous signal wait time. virtual int64_t computeWaitTimeNs_l() const { return INT64_MAX; } Loading Loading @@ -1459,7 +1459,7 @@ public: virtual size_t frameCount() const { return mFrameCount; } bool hasFastCapture() const { return mFastCapture != 0; } virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); virtual status_t checkEffectCompatibility_l(const effect_descriptor_t *desc, audio_session_t sessionId); Loading Loading @@ -1602,7 +1602,7 @@ class MmapThread : public ThreadBase virtual status_t createAudioPatch_l(const struct audio_patch *patch, audio_patch_handle_t *handle); virtual status_t releaseAudioPatch_l(const audio_patch_handle_t handle); virtual void getAudioPortConfig(struct audio_port_config *config); virtual void toAudioPortConfig(struct audio_port_config *config); virtual sp<StreamHalInterface> stream() const { return mHalStream; } virtual status_t addEffectChain_l(const sp<EffectChain>& chain); Loading
services/audiopolicy/common/managerdefinitions/include/AudioSessionInfoProvider.h→services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h +8 −7 Original line number Diff line number Diff line Loading @@ -19,26 +19,27 @@ namespace android { /** * Interface for input descriptors to implement so dependent audio sessions can query information * about their context * Interface for I/O descriptors to implement so information about their context * can be queried and updated. */ class AudioSessionInfoProvider class AudioIODescriptorInterface { public: virtual ~AudioSessionInfoProvider() {}; virtual ~AudioIODescriptorInterface() {}; virtual audio_config_base_t getConfig() const = 0; virtual audio_patch_handle_t getPatchHandle() const = 0; virtual void setPatchHandle(audio_patch_handle_t handle) = 0; }; class AudioSessionInfoUpdateListener class AudioIODescriptorUpdateListener { public: virtual ~AudioSessionInfoUpdateListener() {}; virtual ~AudioIODescriptorUpdateListener() {}; virtual void onSessionInfoUpdate() const = 0;; virtual void onIODescriptorUpdate() const = 0; }; } // namespace android