支持多应用同时录音_Android5.1 & Android6.0 修改方法
修改方法
源码路径: sdk\frameworks\av\services\audiopolicy\managerdefault\AudioPolicyManager.cpp
- 在 status_t AudioPolicyManager::getInputForAttr()
- mpClientInterface->openInput 前添加:
#ifdef ANDROID6_0_SUPPORT_MULIT_CHANNEL_RECORDING
// Modify Tower 20181118: check wether have an AudioInputDescriptor Use the same profile
for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
sp<AudioInputDescriptor> desc;
desc = mInputs.valueAt(input_index);
if (desc->mProfile == profile) {
// desc->mRefCount++ // Modify 20200314 Tower.
desc->mOpenRefCount++; // Open reference count add.
desc->mSessions.add(session);
*input = desc->mIoHandle;
return NO_ERROR;
}
}
#endif
20200314 补丁更新说明: mRefCount 和 mOpenRefCount 的区别
使用 AudioRecord 的流程:
startInput() -> read() -> stopInput() -> releaseInput() -> closeInput().
-
inputDesc->mRefCount (int型, 初始值是0)
这个值仅仅在 startInput() 和 stopInput() 中起做用, 不会触发 HAL 层 close_input_stream 的动作. -
inputDesc->mOpenRefCount (int型, 初始值是1)
这个值仅在 releaseInput() 函数中起作用, 用于表示当前有几个 AudioRecord 在使用 inputDesc 指向的HAL, 如果 mOpenRefCount == 0, 则会触发 closeInput() 调用 HAL::close_input_stream().
我们假定这种场景: 读同一个声卡
- A 应用启动 AudioRecord 读数据,
- 接着 B 应用启动 AudioRecord 读数据,
- 然后 B 应用停止 AudioRecord. 触发了 stopInput(), 进而触发 releaseInput().
这种场景下A会怎么样?
如果本补丁对 mRefCount++, 在 B 停止的时候, 由于最后调用 releaseInput() 对 mOpenRefCount–, 等于零的情况会立马执行 closeInput() 关闭底层声卡, 导致 A 应用暂停录音, 这个时候有两种情况发生:
1: A 应用处于未 AudioRecord::read() 情况下, 后续调用将无效.
2: A 应用处于 AudioRecord::read() 情况下, AudioRecord:: restoreRecord_l("obtainBuffer") 重启录音.
如果本补丁对 mOpenRefCount++, 以上的情况不会发生, B 在停止录音时, 如果当前还有其他应用(A)在使用的情况下, 不会关闭底层声卡. 规避了上述两种情况发生. 所以更新补丁.
- 关键代码片供参考
status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
audio_session_t session)
{
// ...
inputDesc->mRefCount--;
if (inputDesc->mRefCount == 0) {
// ...
resetInputDevice(input);
// ...
inputDesc->clearPreemptedSessions();
}
return NO_ERROR;
}
void AudioPolicyManager::releaseInput(audio_io_handle_t input,
audio_session_t session)
{
// ...
inputDesc->mOpenRefCount--;
if (inputDesc->mOpenRefCount > 0) {
ALOGV("releaseInput() exit > 0");
return;
}
closeInput(input);
// ...
ALOGV("releaseInput() exit");
}
与之相关
Android Audio - 音频子系统框架简析
Android Audio - 支持多应用同时录音_Android4.4修改方法
Android Audio - 支持多应用同时录音_Android8.1修改方法