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

如何使用DirectShow检测PAL/NTSC信号实现采集卡制式自动切换

背景

为录制各类模拟摄像机的复合视频信号,我使用圆刚(AverMedia)生产的基础款USB视频采集设备C039。
C039采集设备
我拥有两台模拟摄像机,分别输出两种不同的视频信号:

  • PAL B,625线,25 fps
  • NTSC M,525线,29.97 fps(即30/1.001)

但遗憾的是,AverMedia C039采集卡的驱动无法根据接入的摄像机自动设置匹配的视频标准。

目标

我希望采集驱动可以根据接入的摄像机,自动配置为对应的PAL或NTSC视频标准。

实现思路

基础方案是先设置某一视频标准(例如PAL),检测是否有对应信号存在,若未检测到则切换为另一制式。
参考DirectShow文档的示例代码拼接开发后,我已经可以通过命令行手动设置正确的视频标准,因此只需要解决切换PAL或NTSC后,如何检测对应信号是否存在的问题。
我知道信号类型自动检测是可实现的,《Video Demystified》一书中也有相关描述,此外商业软件AMCap viewer也已经实现了该功能,但我自己尝试后始终无法完成。
想请教大家如何用C++基于DirectShow检测当前是否存在PAL或NTSC信号?我对Windows/COM/DirectShow编程接触尚浅,非常感谢任何帮助。

已尝试方案

通过IAMAnalogVideoDecoder接口,我可以读取当前制式(get_TVFormat())、设置制式(put_TVFormat())、读取扫描线数等信息。
我采取的步骤可总结为如下代码:

// summary of steps used to set the video standard, given a device moniker
// NOTE: declarations, error handling, cleanup, and details of device enumeration are omitted, for brevity
InitCaptureGraphBuilder(&pGraph, &pBuild);
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCap);
pGraph->AddFilter(pCap, L"Capture Filter");
pBuild->FindInterface(&PIN_CATEGORY_ANALOGVIDEOIN, &MEDIATYPE_AnalogVideo, pCap, IID_IAMAnalogVideoDecoder, (void**)&pDecoder);
pDecoder->put_TVFormat(AnalogVideo_PAL_B);  // or AnalogVideo_NTSC_M

上述步骤无需运行graph即可生效。
IAMAnalogVideoDecoder接口还提供了get_HorizontalLocked()方法,调用返回成功,但无论是否接入摄像机,输出值都没有变化。我推测可能需要运行graph才能获取水平同步等信息的更新状态,但尝试后没有明显效果,我也不确定我的实现是否正确。

观测结果

下方对话框截图来自AMCap viewer软件(操作路径:选项->视频设备->属性),它和Windows SDK自带的DirectShow示例AmCap sample不是同一软件(不过它可能是基于该示例开发的)。
当我接入或断开与当前设置制式匹配的摄像机时,对话框中的“Signal Detected”值会发生变化(但无论是否接入摄像机,“Lines detected”值都保持不变)。
属性页
这个“Signal Detected”的值正是我需要获取的,但我在DirectShow官方文档、模拟视频解码器设备属性集中都没有找到相关说明,它会不会和水平同步有一定关联?
这个对话框和我用ffmpeg打开视频设备时弹出的对话框完全一致,对应ffmpeg命令:

ffmpeg -f dshow -show_video_device_dialog true -i video="..." ...

但这种情况下,接入或断开摄像机时“Signal detected”值不会发生变化。我推测两款软件都是通过filter property pages生成的这个对话框。
AverMedia SDK中定义了AVerGetSignalPresence()函数,不确定它能否实现需求,但如果可以用纯DirectShow实现的话,我更希望不引入额外依赖。

更新

在GraphEdit中调试采集设备后我发现,只有连接了(视频)Renderer,且graph处于运行或暂停状态时,“Signal Detected”的值才会更新。
GraphEdit界面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:45:04