PatchPanel.cpp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  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. #define LOG_TAG "AudioFlinger::PatchPanel"
  18. //#define LOG_NDEBUG 0
  19. #include "Configuration.h"
  20. #include <utils/Log.h>
  21. #include <audio_utils/primitives.h>
  22. #include "AudioFlinger.h"
  23. #include <media/AudioParameter.h>
  24. #include <media/PatchBuilder.h>
  25. #include <mediautils/ServiceUtilities.h>
  26. // ----------------------------------------------------------------------------
  27. // Note: the following macro is used for extremely verbose logging message. In
  28. // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
  29. // 0; but one side effect of this is to turn all LOGV's as well. Some messages
  30. // are so verbose that we want to suppress them even when we have ALOG_ASSERT
  31. // turned on. Do not uncomment the #def below unless you really know what you
  32. // are doing and want to see all of the extremely verbose messages.
  33. //#define VERY_VERY_VERBOSE_LOGGING
  34. #ifdef VERY_VERY_VERBOSE_LOGGING
  35. #define ALOGVV ALOGV
  36. #else
  37. #define ALOGVV(a...) do { } while(0)
  38. #endif
  39. namespace android {
  40. /* List connected audio ports and their attributes */
  41. status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,
  42. struct audio_port *ports)
  43. {
  44. Mutex::Autolock _l(mLock);
  45. return mPatchPanel.listAudioPorts(num_ports, ports);
  46. }
  47. /* Get supported attributes for a given audio port */
  48. status_t AudioFlinger::getAudioPort(struct audio_port *port)
  49. {
  50. Mutex::Autolock _l(mLock);
  51. return mPatchPanel.getAudioPort(port);
  52. }
  53. /* Connect a patch between several source and sink ports */
  54. status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
  55. audio_patch_handle_t *handle)
  56. {
  57. Mutex::Autolock _l(mLock);
  58. return mPatchPanel.createAudioPatch(patch, handle);
  59. }
  60. /* Disconnect a patch */
  61. status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
  62. {
  63. Mutex::Autolock _l(mLock);
  64. return mPatchPanel.releaseAudioPatch(handle);
  65. }
  66. /* List connected audio ports and they attributes */
  67. status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
  68. struct audio_patch *patches)
  69. {
  70. Mutex::Autolock _l(mLock);
  71. return mPatchPanel.listAudioPatches(num_patches, patches);
  72. }
  73. status_t AudioFlinger::PatchPanel::SoftwarePatch::getLatencyMs_l(double *latencyMs) const
  74. {
  75. const auto& iter = mPatchPanel.mPatches.find(mPatchHandle);
  76. if (iter != mPatchPanel.mPatches.end()) {
  77. return iter->second.getLatencyMs(latencyMs);
  78. } else {
  79. return BAD_VALUE;
  80. }
  81. }
  82. /* List connected audio ports and their attributes */
  83. status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
  84. struct audio_port *ports __unused)
  85. {
  86. ALOGV(__func__);
  87. return NO_ERROR;
  88. }
  89. /* Get supported attributes for a given audio port */
  90. status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
  91. {
  92. ALOGV(__func__);
  93. return NO_ERROR;
  94. }
  95. /* Connect a patch between several source and sink ports */
  96. status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
  97. audio_patch_handle_t *handle)
  98. {
  99. if (handle == NULL || patch == NULL) {
  100. return BAD_VALUE;
  101. }
  102. ALOGV("%s() num_sources %d num_sinks %d handle %d",
  103. __func__, patch->num_sources, patch->num_sinks, *handle);
  104. status_t status = NO_ERROR;
  105. audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
  106. if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) {
  107. return BAD_VALUE;
  108. }
  109. // limit number of sources to 1 for now or 2 sources for special cross hw module case.
  110. // only the audio policy manager can request a patch creation with 2 sources.
  111. if (patch->num_sources > 2) {
  112. return INVALID_OPERATION;
  113. }
  114. if (*handle != AUDIO_PATCH_HANDLE_NONE) {
  115. auto iter = mPatches.find(*handle);
  116. if (iter != mPatches.end()) {
  117. ALOGV("%s() removing patch handle %d", __func__, *handle);
  118. Patch &removedPatch = iter->second;
  119. // free resources owned by the removed patch if applicable
  120. // 1) if a software patch is present, release the playback and capture threads and
  121. // tracks created. This will also release the corresponding audio HAL patches
  122. if (removedPatch.isSoftware()) {
  123. removedPatch.clearConnections(this);
  124. }
  125. // 2) if the new patch and old patch source or sink are devices from different
  126. // hw modules, clear the audio HAL patches now because they will not be updated
  127. // by call to create_audio_patch() below which will happen on a different HW module
  128. if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
  129. audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
  130. const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
  131. if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
  132. (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
  133. oldPatch.sources[0].ext.device.hw_module !=
  134. patch->sources[0].ext.device.hw_module)) {
  135. hwModule = oldPatch.sources[0].ext.device.hw_module;
  136. } else if (patch->num_sinks == 0 ||
  137. (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
  138. (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
  139. oldPatch.sinks[0].ext.device.hw_module !=
  140. patch->sinks[0].ext.device.hw_module))) {
  141. // Note on (patch->num_sinks == 0): this situation should not happen as
  142. // these special patches are only created by the policy manager but just
  143. // in case, systematically clear the HAL patch.
  144. // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
  145. // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
  146. hwModule = oldPatch.sinks[0].ext.device.hw_module;
  147. }
  148. sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
  149. if (hwDevice != 0) {
  150. hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
  151. }
  152. }
  153. mPatches.erase(iter);
  154. removeSoftwarePatchFromInsertedModules(*handle);
  155. }
  156. }
  157. Patch newPatch{*patch};
  158. audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
  159. switch (patch->sources[0].type) {
  160. case AUDIO_PORT_TYPE_DEVICE: {
  161. audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
  162. AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
  163. if (!audioHwDevice) {
  164. status = BAD_VALUE;
  165. goto exit;
  166. }
  167. for (unsigned int i = 0; i < patch->num_sinks; i++) {
  168. // support only one sink if connection to a mix or across HW modules
  169. if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
  170. (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
  171. patch->sinks[i].ext.device.hw_module != srcModule)) &&
  172. patch->num_sinks > 1) {
  173. ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
  174. status = INVALID_OPERATION;
  175. goto exit;
  176. }
  177. // reject connection to different sink types
  178. if (patch->sinks[i].type != patch->sinks[0].type) {
  179. ALOGW("%s() different sink types in same patch not supported", __func__);
  180. status = BAD_VALUE;
  181. goto exit;
  182. }
  183. }
  184. // manage patches requiring a software bridge
  185. // - special patch request with 2 sources (reuse one existing output mix) OR
  186. // - Device to device AND
  187. // - source HW module != destination HW module OR
  188. // - audio HAL does not support audio patches creation
  189. if ((patch->num_sources == 2) ||
  190. ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
  191. ((patch->sinks[0].ext.device.hw_module != srcModule) ||
  192. !audioHwDevice->supportsAudioPatches()))) {
  193. audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
  194. String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
  195. if (patch->num_sources == 2) {
  196. if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
  197. (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
  198. patch->sources[1].ext.mix.hw_module)) {
  199. ALOGW("%s() invalid source combination", __func__);
  200. status = INVALID_OPERATION;
  201. goto exit;
  202. }
  203. sp<ThreadBase> thread =
  204. mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
  205. if (thread == 0) {
  206. ALOGW("%s() cannot get playback thread", __func__);
  207. status = INVALID_OPERATION;
  208. goto exit;
  209. }
  210. // existing playback thread is reused, so it is not closed when patch is cleared
  211. newPatch.mPlayback.setThread(
  212. reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
  213. } else {
  214. audio_config_t config = AUDIO_CONFIG_INITIALIZER;
  215. audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
  216. audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
  217. if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
  218. config.sample_rate = patch->sinks[0].sample_rate;
  219. }
  220. if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
  221. config.channel_mask = patch->sinks[0].channel_mask;
  222. }
  223. if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
  224. config.format = patch->sinks[0].format;
  225. }
  226. if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
  227. flags = patch->sinks[0].flags.output;
  228. }
  229. sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
  230. patch->sinks[0].ext.device.hw_module,
  231. &output,
  232. &config,
  233. outputDevice,
  234. outputDeviceAddress,
  235. flags);
  236. ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
  237. if (thread == 0) {
  238. status = NO_MEMORY;
  239. goto exit;
  240. }
  241. newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
  242. }
  243. audio_devices_t device = patch->sources[0].ext.device.type;
  244. String8 address = String8(patch->sources[0].ext.device.address);
  245. audio_config_t config = AUDIO_CONFIG_INITIALIZER;
  246. // open input stream with source device audio properties if provided or
  247. // default to peer output stream properties otherwise.
  248. if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
  249. config.sample_rate = patch->sources[0].sample_rate;
  250. } else {
  251. config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
  252. }
  253. if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
  254. config.channel_mask = patch->sources[0].channel_mask;
  255. } else {
  256. config.channel_mask = audio_channel_in_mask_from_count(
  257. newPatch.mPlayback.thread()->channelCount());
  258. }
  259. if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
  260. config.format = patch->sources[0].format;
  261. } else {
  262. config.format = newPatch.mPlayback.thread()->format();
  263. }
  264. audio_input_flags_t flags =
  265. patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
  266. patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
  267. audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
  268. sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
  269. &input,
  270. &config,
  271. device,
  272. address,
  273. AUDIO_SOURCE_MIC,
  274. flags,
  275. outputDevice,
  276. outputDeviceAddress);
  277. ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
  278. thread.get(), config.channel_mask);
  279. if (thread == 0) {
  280. status = NO_MEMORY;
  281. goto exit;
  282. }
  283. newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
  284. status = newPatch.createConnections(this);
  285. if (status != NO_ERROR) {
  286. goto exit;
  287. }
  288. if (audioHwDevice->isInsert()) {
  289. insertedModule = audioHwDevice->handle();
  290. }
  291. } else {
  292. if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
  293. sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
  294. patch->sinks[0].ext.mix.handle);
  295. if (thread == 0) {
  296. thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
  297. if (thread == 0) {
  298. ALOGW("%s() bad capture I/O handle %d",
  299. __func__, patch->sinks[0].ext.mix.handle);
  300. status = BAD_VALUE;
  301. goto exit;
  302. }
  303. }
  304. status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
  305. // remove stale audio patch with same input as sink if any
  306. for (auto& iter : mPatches) {
  307. if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
  308. mPatches.erase(iter.first);
  309. break;
  310. }
  311. }
  312. } else {
  313. sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
  314. status = hwDevice->createAudioPatch(patch->num_sources,
  315. patch->sources,
  316. patch->num_sinks,
  317. patch->sinks,
  318. &halHandle);
  319. if (status == INVALID_OPERATION) goto exit;
  320. }
  321. }
  322. } break;
  323. case AUDIO_PORT_TYPE_MIX: {
  324. audio_module_handle_t srcModule = patch->sources[0].ext.mix.hw_module;
  325. ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
  326. if (index < 0) {
  327. ALOGW("%s() bad src hw module %d", __func__, srcModule);
  328. status = BAD_VALUE;
  329. goto exit;
  330. }
  331. // limit to connections between devices and output streams
  332. audio_devices_t type = AUDIO_DEVICE_NONE;
  333. for (unsigned int i = 0; i < patch->num_sinks; i++) {
  334. if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
  335. ALOGW("%s() invalid sink type %d for mix source",
  336. __func__, patch->sinks[i].type);
  337. status = BAD_VALUE;
  338. goto exit;
  339. }
  340. // limit to connections between sinks and sources on same HW module
  341. if (patch->sinks[i].ext.device.hw_module != srcModule) {
  342. status = BAD_VALUE;
  343. goto exit;
  344. }
  345. type |= patch->sinks[i].ext.device.type;
  346. }
  347. sp<ThreadBase> thread =
  348. mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
  349. if (thread == 0) {
  350. thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
  351. if (thread == 0) {
  352. ALOGW("%s() bad playback I/O handle %d",
  353. __func__, patch->sources[0].ext.mix.handle);
  354. status = BAD_VALUE;
  355. goto exit;
  356. }
  357. }
  358. if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
  359. AudioParameter param = AudioParameter();
  360. param.addInt(String8(AudioParameter::keyRouting), (int)type);
  361. mAudioFlinger.broacastParametersToRecordThreads_l(param.toString());
  362. }
  363. status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
  364. // remove stale audio patch with same output as source if any
  365. for (auto& iter : mPatches) {
  366. if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id()) {
  367. mPatches.erase(iter.first);
  368. break;
  369. }
  370. }
  371. } break;
  372. default:
  373. status = BAD_VALUE;
  374. goto exit;
  375. }
  376. exit:
  377. ALOGV("%s() status %d", __func__, status);
  378. if (status == NO_ERROR) {
  379. *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
  380. newPatch.mHalHandle = halHandle;
  381. mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
  382. if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
  383. addSoftwarePatchToInsertedModules(insertedModule, *handle);
  384. }
  385. ALOGV("%s() added new patch handle %d halHandle %d", __func__, *handle, halHandle);
  386. } else {
  387. newPatch.clearConnections(this);
  388. }
  389. return status;
  390. }
  391. AudioFlinger::PatchPanel::Patch::~Patch()
  392. {
  393. ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
  394. mRecord.handle(), mPlayback.handle());
  395. }
  396. status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
  397. {
  398. // create patch from source device to record thread input
  399. status_t status = panel->createAudioPatch(
  400. PatchBuilder().addSource(mAudioPatch.sources[0]).
  401. addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
  402. mRecord.handlePtr());
  403. if (status != NO_ERROR) {
  404. *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
  405. return status;
  406. }
  407. // create patch from playback thread output to sink device
  408. if (mAudioPatch.num_sinks != 0) {
  409. status = panel->createAudioPatch(
  410. PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
  411. mPlayback.handlePtr());
  412. if (status != NO_ERROR) {
  413. *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
  414. return status;
  415. }
  416. } else {
  417. *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
  418. }
  419. // use a pseudo LCM between input and output framecount
  420. size_t playbackFrameCount = mPlayback.thread()->frameCount();
  421. int playbackShift = __builtin_ctz(playbackFrameCount);
  422. size_t recordFrameCount = mRecord.thread()->frameCount();
  423. int shift = __builtin_ctz(recordFrameCount);
  424. if (playbackShift < shift) {
  425. shift = playbackShift;
  426. }
  427. size_t frameCount = (playbackFrameCount * recordFrameCount) >> shift;
  428. ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
  429. __func__, playbackFrameCount, recordFrameCount, frameCount);
  430. // create a special record track to capture from record thread
  431. uint32_t channelCount = mPlayback.thread()->channelCount();
  432. audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
  433. audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
  434. uint32_t sampleRate = mPlayback.thread()->sampleRate();
  435. audio_format_t format = mPlayback.thread()->format();
  436. audio_format_t inputFormat = mRecord.thread()->format();
  437. if (!audio_is_linear_pcm(inputFormat)) {
  438. // The playbackThread format will say PCM for IEC61937 packetized stream.
  439. // Use recordThread format.
  440. format = inputFormat;
  441. }
  442. audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
  443. mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
  444. if (sampleRate == mRecord.thread()->sampleRate() &&
  445. inChannelMask == mRecord.thread()->channelMask() &&
  446. mRecord.thread()->fastTrackAvailable() &&
  447. mRecord.thread()->hasFastCapture()) {
  448. // Create a fast track if the record thread has fast capture to get better performance.
  449. // Only enable fast mode when there is no resample needed.
  450. inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
  451. } else {
  452. // Fast mode is not available in this case.
  453. inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
  454. }
  455. sp<RecordThread::PatchRecord> tempRecordTrack = new (std::nothrow) RecordThread::PatchRecord(
  456. mRecord.thread().get(),
  457. sampleRate,
  458. inChannelMask,
  459. format,
  460. frameCount,
  461. NULL,
  462. (size_t)0 /* bufferSize */,
  463. inputFlags);
  464. status = mRecord.checkTrack(tempRecordTrack.get());
  465. if (status != NO_ERROR) {
  466. return status;
  467. }
  468. audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
  469. mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
  470. audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
  471. if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
  472. // "reuse one existing output mix" case
  473. streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
  474. }
  475. if (mPlayback.thread()->hasFastMixer()) {
  476. // Create a fast track if the playback thread has fast mixer to get better performance.
  477. // Note: we should have matching channel mask, sample rate, and format by the logic above.
  478. outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
  479. } else {
  480. outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
  481. }
  482. // create a special playback track to render to playback thread.
  483. // this track is given the same buffer as the PatchRecord buffer
  484. sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
  485. mPlayback.thread().get(),
  486. streamType,
  487. sampleRate,
  488. outChannelMask,
  489. format,
  490. frameCount,
  491. tempRecordTrack->buffer(),
  492. tempRecordTrack->bufferSize(),
  493. outputFlags);
  494. status = mPlayback.checkTrack(tempPatchTrack.get());
  495. if (status != NO_ERROR) {
  496. return status;
  497. }
  498. // tie playback and record tracks together
  499. mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
  500. mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
  501. // start capture and playback
  502. mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
  503. mPlayback.track()->start();
  504. return status;
  505. }
  506. void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
  507. {
  508. ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
  509. __func__, mRecord.handle(), mPlayback.handle());
  510. mRecord.stopTrack();
  511. mPlayback.stopTrack();
  512. mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
  513. mRecord.closeConnections(panel);
  514. mPlayback.closeConnections(panel);
  515. }
  516. status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
  517. {
  518. if (!isSoftware()) return INVALID_OPERATION;
  519. auto recordTrack = mRecord.const_track();
  520. if (recordTrack.get() == nullptr) return INVALID_OPERATION;
  521. auto playbackTrack = mPlayback.const_track();
  522. if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
  523. // Latency information for tracks may be called without obtaining
  524. // the underlying thread lock.
  525. //
  526. // We use record server latency + playback track latency (generally smaller than the
  527. // reverse due to internal biases).
  528. //
  529. // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
  530. // For PCM tracks get server latency.
  531. if (audio_is_linear_pcm(recordTrack->format())) {
  532. double recordServerLatencyMs, playbackTrackLatencyMs;
  533. if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
  534. && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
  535. *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
  536. return OK;
  537. }
  538. }
  539. // See if kernel latencies are available.
  540. // If so, do a frame diff and time difference computation to estimate
  541. // the total patch latency. This requires that frame counts are reported by the
  542. // HAL are matched properly in the case of record overruns and playback underruns.
  543. ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
  544. recordTrack->getKernelFrameTime(&recordFT);
  545. playbackTrack->getKernelFrameTime(&playFT);
  546. if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
  547. const int64_t frameDiff = recordFT.frames - playFT.frames;
  548. const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
  549. // It is possible that the patch track and patch record have a large time disparity because
  550. // one thread runs but another is stopped. We arbitrarily choose the maximum timestamp
  551. // time difference based on how often we expect the timestamps to update in normal operation
  552. // (typical should be no more than 50 ms).
  553. //
  554. // If the timestamps aren't sampled close enough, the patch latency is not
  555. // considered valid.
  556. //
  557. // TODO: change this based on more experiments.
  558. constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
  559. if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
  560. *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
  561. - timeDiffNs * 1e-6;
  562. return OK;
  563. }
  564. }
  565. return INVALID_OPERATION;
  566. }
  567. String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
  568. {
  569. // TODO: Consider table dump form for patches, just like tracks.
  570. String8 result = String8::format("Patch %d: thread %p => thread %p",
  571. myHandle, mRecord.const_thread().get(), mPlayback.const_thread().get());
  572. // add latency if it exists
  573. double latencyMs;
  574. if (getLatencyMs(&latencyMs) == OK) {
  575. result.appendFormat(" latency: %.2lf ms", latencyMs);
  576. }
  577. return result;
  578. }
  579. /* Disconnect a patch */
  580. status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
  581. {
  582. ALOGV("%s handle %d", __func__, handle);
  583. status_t status = NO_ERROR;
  584. auto iter = mPatches.find(handle);
  585. if (iter == mPatches.end()) {
  586. return BAD_VALUE;
  587. }
  588. Patch &removedPatch = iter->second;
  589. const struct audio_patch &patch = removedPatch.mAudioPatch;
  590. const struct audio_port_config &src = patch.sources[0];
  591. switch (src.type) {
  592. case AUDIO_PORT_TYPE_DEVICE: {
  593. sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
  594. if (hwDevice == 0) {
  595. ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
  596. status = BAD_VALUE;
  597. break;
  598. }
  599. if (removedPatch.isSoftware()) {
  600. removedPatch.clearConnections(this);
  601. break;
  602. }
  603. if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
  604. audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
  605. sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
  606. if (thread == 0) {
  607. thread = mAudioFlinger.checkMmapThread_l(ioHandle);
  608. if (thread == 0) {
  609. ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
  610. status = BAD_VALUE;
  611. break;
  612. }
  613. }
  614. status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
  615. } else {
  616. status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
  617. }
  618. } break;
  619. case AUDIO_PORT_TYPE_MIX: {
  620. if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
  621. ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
  622. status = BAD_VALUE;
  623. break;
  624. }
  625. audio_io_handle_t ioHandle = src.ext.mix.handle;
  626. sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
  627. if (thread == 0) {
  628. thread = mAudioFlinger.checkMmapThread_l(ioHandle);
  629. if (thread == 0) {
  630. ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
  631. status = BAD_VALUE;
  632. break;
  633. }
  634. }
  635. status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
  636. } break;
  637. default:
  638. status = BAD_VALUE;
  639. }
  640. mPatches.erase(iter);
  641. removeSoftwarePatchFromInsertedModules(handle);
  642. return status;
  643. }
  644. /* List connected audio ports and they attributes */
  645. status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
  646. struct audio_patch *patches __unused)
  647. {
  648. ALOGV(__func__);
  649. return NO_ERROR;
  650. }
  651. status_t AudioFlinger::PatchPanel::getDownstreamSoftwarePatches(
  652. audio_io_handle_t stream,
  653. std::vector<AudioFlinger::PatchPanel::SoftwarePatch> *patches) const
  654. {
  655. for (const auto& module : mInsertedModules) {
  656. if (module.second.streams.count(stream)) {
  657. for (const auto& patchHandle : module.second.sw_patches) {
  658. const auto& patch_iter = mPatches.find(patchHandle);
  659. if (patch_iter != mPatches.end()) {
  660. const Patch &patch = patch_iter->second;
  661. patches->emplace_back(*this, patchHandle,
  662. patch.mPlayback.const_thread()->id(),
  663. patch.mRecord.const_thread()->id());
  664. } else {
  665. ALOGE("Stale patch handle in the cache: %d", patchHandle);
  666. }
  667. }
  668. return OK;
  669. }
  670. }
  671. // The stream is not associated with any of inserted modules.
  672. return BAD_VALUE;
  673. }
  674. void AudioFlinger::PatchPanel::notifyStreamOpened(
  675. AudioHwDevice *audioHwDevice, audio_io_handle_t stream)
  676. {
  677. if (audioHwDevice->isInsert()) {
  678. mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
  679. }
  680. }
  681. void AudioFlinger::PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
  682. {
  683. for (auto& module : mInsertedModules) {
  684. module.second.streams.erase(stream);
  685. }
  686. }
  687. AudioHwDevice* AudioFlinger::PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
  688. {
  689. if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
  690. ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
  691. if (index < 0) {
  692. ALOGW("%s() bad hw module %d", __func__, module);
  693. return nullptr;
  694. }
  695. return mAudioFlinger.mAudioHwDevs.valueAt(index);
  696. }
  697. sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
  698. {
  699. AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
  700. return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
  701. }
  702. void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
  703. audio_module_handle_t module, audio_patch_handle_t handle)
  704. {
  705. mInsertedModules[module].sw_patches.insert(handle);
  706. }
  707. void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
  708. audio_patch_handle_t handle)
  709. {
  710. for (auto& module : mInsertedModules) {
  711. module.second.sw_patches.erase(handle);
  712. }
  713. }
  714. void AudioFlinger::PatchPanel::dump(int fd) const
  715. {
  716. String8 patchPanelDump;
  717. const char *indent = " ";
  718. // Only dump software patches.
  719. bool headerPrinted = false;
  720. for (const auto& iter : mPatches) {
  721. if (iter.second.isSoftware()) {
  722. if (!headerPrinted) {
  723. patchPanelDump += "\nSoftware patches:\n";
  724. headerPrinted = true;
  725. }
  726. patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).string());
  727. }
  728. }
  729. headerPrinted = false;
  730. for (const auto& module : mInsertedModules) {
  731. if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
  732. if (!headerPrinted) {
  733. patchPanelDump += "\nTracked inserted modules:\n";
  734. headerPrinted = true;
  735. }
  736. String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
  737. for (const auto& stream : module.second.streams) {
  738. moduleDump.appendFormat("%d ", stream);
  739. }
  740. moduleDump.append("; SW Patches: ");
  741. for (const auto& patch : module.second.sw_patches) {
  742. moduleDump.appendFormat("%d ", patch);
  743. }
  744. patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.string());
  745. }
  746. }
  747. if (!patchPanelDump.isEmpty()) {
  748. write(fd, patchPanelDump.string(), patchPanelDump.size());
  749. }
  750. }
  751. } // namespace android