PatchPanel.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /*
  2. **
  3. ** Copyright 2014, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. ** http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */
  17. #ifndef INCLUDING_FROM_AUDIOFLINGER_H
  18. #error This header file should only be included from AudioFlinger.h
  19. #endif
  20. // PatchPanel is concealed within AudioFlinger, their lifetimes are the same.
  21. class PatchPanel {
  22. public:
  23. class SoftwarePatch {
  24. public:
  25. SoftwarePatch(const PatchPanel &patchPanel, audio_patch_handle_t patchHandle,
  26. audio_io_handle_t playbackThreadHandle, audio_io_handle_t recordThreadHandle)
  27. : mPatchPanel(patchPanel), mPatchHandle(patchHandle),
  28. mPlaybackThreadHandle(playbackThreadHandle),
  29. mRecordThreadHandle(recordThreadHandle) {}
  30. SoftwarePatch(const SoftwarePatch&) = default;
  31. SoftwarePatch& operator=(const SoftwarePatch&) = default;
  32. // Must be called under AudioFlinger::mLock
  33. status_t getLatencyMs_l(double *latencyMs) const;
  34. audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
  35. audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
  36. audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };
  37. private:
  38. const PatchPanel &mPatchPanel;
  39. const audio_patch_handle_t mPatchHandle;
  40. const audio_io_handle_t mPlaybackThreadHandle;
  41. const audio_io_handle_t mRecordThreadHandle;
  42. };
  43. explicit PatchPanel(AudioFlinger* audioFlinger) : mAudioFlinger(*audioFlinger) {}
  44. /* List connected audio ports and their attributes */
  45. status_t listAudioPorts(unsigned int *num_ports,
  46. struct audio_port *ports);
  47. /* Get supported attributes for a given audio port */
  48. status_t getAudioPort(struct audio_port *port);
  49. /* Create a patch between several source and sink ports */
  50. status_t createAudioPatch(const struct audio_patch *patch,
  51. audio_patch_handle_t *handle);
  52. /* Release a patch */
  53. status_t releaseAudioPatch(audio_patch_handle_t handle);
  54. /* List connected audio devices and they attributes */
  55. status_t listAudioPatches(unsigned int *num_patches,
  56. struct audio_patch *patches);
  57. // Retrieves all currently estrablished software patches for a stream
  58. // opened on an intermediate module.
  59. status_t getDownstreamSoftwarePatches(audio_io_handle_t stream,
  60. std::vector<SoftwarePatch> *patches) const;
  61. // Notifies patch panel about all opened and closed streams.
  62. void notifyStreamOpened(AudioHwDevice *audioHwDevice, audio_io_handle_t stream);
  63. void notifyStreamClosed(audio_io_handle_t stream);
  64. void dump(int fd) const;
  65. private:
  66. template<typename ThreadType, typename TrackType>
  67. class Endpoint {
  68. public:
  69. Endpoint() = default;
  70. Endpoint(const Endpoint&) = delete;
  71. Endpoint& operator=(const Endpoint&) = delete;
  72. Endpoint(Endpoint&& other) noexcept { swap(other); }
  73. Endpoint& operator=(Endpoint&& other) noexcept {
  74. swap(other);
  75. return *this;
  76. }
  77. ~Endpoint() {
  78. ALOGE_IF(mHandle != AUDIO_PATCH_HANDLE_NONE,
  79. "A non empty Patch Endpoint leaked, handle %d", mHandle);
  80. }
  81. status_t checkTrack(TrackType *trackOrNull) const {
  82. if (trackOrNull == nullptr) return NO_MEMORY;
  83. return trackOrNull->initCheck();
  84. }
  85. audio_patch_handle_t handle() const { return mHandle; }
  86. sp<ThreadType> thread() { return mThread; }
  87. sp<TrackType> track() { return mTrack; }
  88. sp<const ThreadType> const_thread() const { return mThread; }
  89. sp<const TrackType> const_track() const { return mTrack; }
  90. void closeConnections(PatchPanel *panel) {
  91. if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
  92. panel->releaseAudioPatch(mHandle);
  93. mHandle = AUDIO_PATCH_HANDLE_NONE;
  94. }
  95. if (mThread != 0) {
  96. if (mTrack != 0) {
  97. mThread->deletePatchTrack(mTrack);
  98. }
  99. if (mCloseThread) {
  100. panel->mAudioFlinger.closeThreadInternal_l(mThread);
  101. }
  102. }
  103. }
  104. audio_patch_handle_t* handlePtr() { return &mHandle; }
  105. void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
  106. mThread = thread;
  107. mCloseThread = closeThread;
  108. }
  109. template <typename T>
  110. void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
  111. mTrack = track;
  112. mThread->addPatchTrack(mTrack);
  113. mTrack->setPeerProxy(peer, true /* holdReference */);
  114. }
  115. void clearTrackPeer() { if (mTrack) mTrack->clearPeerProxy(); }
  116. void stopTrack() { if (mTrack) mTrack->stop(); }
  117. void swap(Endpoint &other) noexcept {
  118. using std::swap;
  119. swap(mThread, other.mThread);
  120. swap(mCloseThread, other.mCloseThread);
  121. swap(mHandle, other.mHandle);
  122. swap(mTrack, other.mTrack);
  123. }
  124. friend void swap(Endpoint &a, Endpoint &b) noexcept {
  125. a.swap(b);
  126. }
  127. private:
  128. sp<ThreadType> mThread;
  129. bool mCloseThread = true;
  130. audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
  131. sp<TrackType> mTrack;
  132. };
  133. class Patch {
  134. public:
  135. explicit Patch(const struct audio_patch &patch) : mAudioPatch(patch) {}
  136. ~Patch();
  137. Patch(const Patch&) = delete;
  138. Patch(Patch&&) = default;
  139. Patch& operator=(const Patch&) = delete;
  140. Patch& operator=(Patch&&) = default;
  141. status_t createConnections(PatchPanel *panel);
  142. void clearConnections(PatchPanel *panel);
  143. bool isSoftware() const {
  144. return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
  145. mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; }
  146. // returns the latency of the patch (from record to playback).
  147. status_t getLatencyMs(double *latencyMs) const;
  148. String8 dump(audio_patch_handle_t myHandle) const;
  149. // Note that audio_patch::id is only unique within a HAL module
  150. struct audio_patch mAudioPatch;
  151. // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
  152. audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
  153. // below members are used by a software audio patch connecting a source device from a
  154. // given audio HW module to a sink device on an other audio HW module.
  155. // the objects are created by createConnections() and released by clearConnections()
  156. // playback thread is created if no existing playback thread can be used
  157. // connects playback thread output to sink device
  158. Endpoint<PlaybackThread, PlaybackThread::PatchTrack> mPlayback;
  159. // connects source device to record thread input
  160. Endpoint<RecordThread, RecordThread::PatchRecord> mRecord;
  161. };
  162. AudioHwDevice* findAudioHwDeviceByModule(audio_module_handle_t module);
  163. sp<DeviceHalInterface> findHwDeviceByModule(audio_module_handle_t module);
  164. void addSoftwarePatchToInsertedModules(
  165. audio_module_handle_t module, audio_patch_handle_t handle);
  166. void removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle);
  167. AudioFlinger &mAudioFlinger;
  168. std::map<audio_patch_handle_t, Patch> mPatches;
  169. // This map allows going from a thread to "downstream" software patches
  170. // when a processing module inserted in between. Example:
  171. //
  172. // from map value.streams map key
  173. // [Mixer thread] --> [Virtual output device] --> [Processing module] ---\
  174. // [Harware module] <-- [Physical output device] <-- [S/W Patch] <--/
  175. // from map value.sw_patches
  176. //
  177. // This allows the mixer thread to look up the threads of the software patch
  178. // for propagating timing info, parameters, etc.
  179. //
  180. // The current assumptions are:
  181. // 1) The processing module acts as a mixer with several outputs which
  182. // represent differently downmixed and / or encoded versions of the same
  183. // mixed stream. There is no 1:1 correspondence between the input streams
  184. // and the software patches, but rather a N:N correspondence between
  185. // a group of streams and a group of patches.
  186. // 2) There are only a couple of inserted processing modules in the system,
  187. // so when looking for a stream or patch handle we can iterate over
  188. // all modules.
  189. struct ModuleConnections {
  190. std::set<audio_io_handle_t> streams;
  191. std::set<audio_patch_handle_t> sw_patches;
  192. };
  193. std::map<audio_module_handle_t, ModuleConnections> mInsertedModules;
  194. };