关于自行摄像头采集和Agora摄像头采集的切换问题

目前在做音视频SDK集成
由于不支持单进程实现多摄像头的支持,考虑换了一种思路支持。
即,自行进行摄像头数据采集,并合并进Agora的发布视频流中。

实际使用发现一些问题,由于在我们场景中可能会涉及到屏幕共享的情况,因此存在使用AgoraSDK进行摄像头-屏幕共享切换的情况,并同时切换自行采集的数据流。大致流程如下:

(自行采集使用DShow框架)

1)切换至Agora屏幕共享数据
启用Agora屏幕共享(此时Agora会自动停止摄像头占用)
等待300ms
启动自行采集的摄像头
合并数据流

2)切换回Agora摄像头
停止自行采集的摄像头(资源释放)
等待300ms
启动Agora屏幕共享

在2)中启动Agora屏幕共享时有大概率会出现agora_rtc_sdk.dll崩溃,能否帮忙确认下是什么原因
SDK版本:SDK ver 2.9.3 build 109
崩溃堆栈如下:
[下面的框架可能不正确和/或缺失,没有为 ntdll.dll 加载符号]
[外部代码]
agora_rtc_sdk.dll!7a6eee63() 未知
agora_rtc_sdk.dll!7aa394b4() 未知
agora_rtc_sdk.dll!7a9d4272() 未知
agora_rtc_sdk.dll!7a9d41fa() 未知
agora_rtc_sdk.dll!7a95cb47() 未知
agora_rtc_sdk.dll!7a9678de() 未知
agora_rtc_sdk.dll!7a967224() 未知
agora_rtc_sdk.dll!7a933a06() 未知
agora_rtc_sdk.dll!7a997c12() 未知
agora_rtc_sdk.dll!7a998650() 未知
agora_rtc_sdk.dll!7a998b9e() 未知
agora_rtc_sdk.dll!7a966241() 未知
agora_rtc_sdk.dll!7a96687e() 未知
agora_rtc_sdk.dll!7a966b2b() 未知
agora_rtc_sdk.dll!7af8010e() 未知
[外部代码]

麻烦请确认以下信息:

  1. 摄像头和屏幕共享画面 是否都是通过自采集方式实现的?如果是,请问具体是通过哪个 API 实现的?
  2. 请告知从摄像头切换到屏幕共享的 API 调用时序,如果方便的话,最好提供相关的代码片段。
  3. 将 SDK 升级到 3.0.0.2:
    https://download.agora.io/sdk/release/Agora_Native_SDK_for_Android_v3_0_0_2_FULL.zip?_ga=2.135205173.561847841.1589164869-1583961819.1580439641
    测试看下是否还会有问题?
  1. 屏幕共享使用Agora实现,摄像头使用Agora实现和自采集实现(存在自采集和Agora的切换)
    自采集为DShow Filter方式,ISampleGrabber抓取
    Agora使用Demo类的EnableScreenCapture(startScreenCaptureByScreenRect)

2.调用时序如下(及代码片段):
前置条件:已启动Agora摄像头
1)切换至Agora屏幕共享及自采集摄像头
_agoraObject->EnableScreenCapture(NULL, 15, 0);
Sleep(300);
IMediaControl->Run();

2)切换回Agora摄像头,停止屏幕共享
IMediaControl->Stop();
Sleep(300);
_agoraObject->EnableScreenCapture(NULL, 15, 0, 0);

3.尝试更新教育版(2.9.0 104)及3.0.0.2 都会产生相同结果(即在相同点崩溃)

我这边又进行了排查,应该是我在进行图像处理的时候,出现了一些内存读写越界的问题。
屏蔽相关代码之后,目前正常。

非常感谢解答!谢谢

好的好的,不客气,有问题再联系哈

你好~我想问下Windows平台,有多个摄像头的情况下,如何手动切换摄像头?是通过 AVideoDeviceManager 的 setDevice 进行切换么?切换的时候要注意什么?比如调用时序,切换延时之类的?

对的,通过 setDevice 指定对应的摄像头设备 ID 即可实现切换。切换时确保设备 ID 正确、该设备没有被其它应用占用(是可用的)即可。

嗯嗯,我这边尝试了下连续切换的时候必然切不过去。顺序如下:

先切换至屏幕共享,然后切换到第一个摄像头,然后再切换到第二个摄像头,这种情况下第二个摄像头无法启动(中间有自采集的启动和停止)

但是如果按照另外的调用逻辑是能够正常切换的:
先切换至屏幕共享,然后切换到第一个摄像头,切换至屏幕共享,立刻关闭屏幕共享,然后再切换到第二个摄像头

能贴一下你的 API 调用代码吗?自采集的启动和停止具体是指什么呢?

就是上面贴过的代码~

_agoraObject->EnableScreenCapture(NULL, 15, 0);
Sleep(300);
IMediaControl->Run();

2)切换回Agora摄像头,停止屏幕共享
IMediaControl->Stop();
Sleep(300);
_agoraObject->EnableScreenCapture(NULL, 15, 0, 0);

3)切换至第二个摄像头
IMediaControl->Stop();
Sleep(300);
setDevice


_agoraObject->EnableScreenCapture(NULL, 15, 0, 1);
_agoraObject->EnableScreenCapture(NULL, 15, 0, 0);

只有加上以上代码才能正常切换过去

那看着没有什么问题呀,是否方便提供 SDK 日志,并告知切换设备失败的时间点,我们来分析一下。