Android Audio - 支持多应用同时录音_Android5.1 & Android6.0 修改方法

支持多应用同时录音_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().

我们假定这种场景: 读同一个声卡

  1. A 应用启动 AudioRecord 读数据,
  2. 接着 B 应用启动 AudioRecord 读数据,
  3. 然后 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修改方法

发布了53 篇原创文章 · 获赞 19 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_33443989/article/details/103721189