You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Builder双TVideoCaptureDevice同时采集摄像头视频故障排查

问题分析与解决方案

可能的原因及对应解决方法

1. 主线程被同步任务阻塞

两个摄像头的OnSampleBufferReady都依赖TThread::Synchronize将图像处理任务抛给主线程,但第一个摄像头的CAM1SampleBufferSync包含大量位图缩放、拷贝、赋值操作,耗时较长。主线程被第一个任务占满后,第二个摄像头的同步任务持续排队,摄像头驱动因长时间未收到帧处理信号,自动停止采集。

解决方法:

  • 将图像处理逻辑移至独立工作线程,仅将最终处理好的位图同步到UI控件显示,避免阻塞主线程。
  • 改用TThread::Queue替代Synchronize,Queue仅将任务加入主线程队列但不阻塞采集线程,保证两个摄像头的采集线程正常运行,主线程空闲时再处理UI更新。

修改示例(以第二个摄像头为例):

void __fastcall TForm2::CAM2SampleBufferReady(TObject *Sender, const TMediaTime ATime)
{
    // 用Queue替代Synchronize,不阻塞采集线程
    TThread::Queue(TThread::CurrentThread, (TThreadMethod)&CAM2SampleBufferSync);
}

2. 共享资源冲突

第一个摄像头的同步函数使用了CutBitmap对象,如果第二个摄像头的同步函数也复用该对象,即使通过主线程同步,也会出现资源竞争触发异常。但代码中catch (...)吞掉了所有异常,导致无法察觉错误,最终摄像头因异常停止采集。

解决方法:

  • 为每个摄像头单独创建对应的位图对象,比如给第二个摄像头分配CutBitmap2,避免资源共享。
  • 若必须共享资源,操作时添加临界区保护,确保同一时间只有一个线程访问该资源。

3. USB带宽不足

你设置了TVideoCaptureQuality::PhotoQuality(最高分辨率模式),两个摄像头同时以该模式采集可能超出USB总线带宽限制,系统会自动中断第二个摄像头的采集。

解决方法:

  • 降低采集分辨率,比如改用TVideoCaptureQuality::HighQuality或更低档位,减少带宽占用。
  • 检查USB控制器版本,确保使用USB3.0及以上接口,USB2.0带宽难以支撑两个高分辨率摄像头同时工作。

4. 第二个摄像头的资源未初始化

如果第二个摄像头对应的ZoomBitmap2、RawBitmap2等对象未提前创建(仅初始化了第一个摄像头的资源),调用SampleBufferToBitmap会失败,进而导致摄像头停止采集,但异常被catch (...)吞掉无法排查。

解决方法:

  • 窗体初始化阶段,为第二个摄像头创建并初始化所有对应的位图对象,确保ZoomBitmap2、RawBitmap2等已分配内存。
  • 暂时移除catch (...),或在catch块中添加错误日志输出,排查具体异常原因。

5. 摄像头硬件的独占性限制

部分摄像头硬件本身不支持同时被多个采集对象打开,即使是同一程序内的两个TVideoCaptureDevice也会触发限制。

解决方法:

  • 单独启动第二个摄像头测试是否能正常采集:若单独启动正常,说明是同步或带宽问题;若单独启动也失败,可能是驱动或硬件限制,需更换摄像头。

内容的提问来源于stack exchange,提问作者Drewski7280

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 21:45:00