在处理视频捕获时,我如何使用一些新的模拟视频格式或路由到一些新的物理连接器



我最近正在用Directshow开发一个多媒体播放器应用程序,我可以成功地构建过滤器图来从网络摄像头捕获视频流。

我阅读了MSDN上的Directshow文档,发现WDM视频捕获过滤器暴露了IAMAnalogVideoDecoder接口,我可以设置AnalogVideoStandard枚举中列出的模拟视频格式,但该枚举不包含一些新的HD标准,如720p、1080i、1080p:

typedef /* [v1_enum] */ 
enum tagAnalogVideoStandard
{
AnalogVideo_None    = 0,
AnalogVideo_NTSC_M  = 0x1,
AnalogVideo_NTSC_M_J    = 0x2,
AnalogVideo_NTSC_433    = 0x4,
AnalogVideo_PAL_B   = 0x10,
AnalogVideo_PAL_D   = 0x20,
AnalogVideo_PAL_G   = 0x40,
AnalogVideo_PAL_H   = 0x80,
AnalogVideo_PAL_I   = 0x100,
AnalogVideo_PAL_M   = 0x200,
AnalogVideo_PAL_N   = 0x400,
AnalogVideo_PAL_60  = 0x800,
AnalogVideo_SECAM_B = 0x1000,
AnalogVideo_SECAM_D = 0x2000,
AnalogVideo_SECAM_G = 0x4000,
AnalogVideo_SECAM_H = 0x8000,
AnalogVideo_SECAM_K = 0x10000,
AnalogVideo_SECAM_K1    = 0x20000,
AnalogVideo_SECAM_L = 0x40000,
AnalogVideo_SECAM_L1    = 0x80000,
AnalogVideo_PAL_N_COMBO = 0x100000,
AnalogVideoMask_MCE_NTSC    = ( ( ( ( ( ( AnalogVideo_NTSC_M | AnalogVideo_NTSC_M_J )  | AnalogVideo_NTSC_433 )  | AnalogVideo_PAL_M )  | AnalogVideo_PAL_N )  | AnalogVideo_PAL_60 )  | AnalogVideo_PAL_N_COMBO ) ,
AnalogVideoMask_MCE_PAL = ( ( ( ( AnalogVideo_PAL_B | AnalogVideo_PAL_D )  | AnalogVideo_PAL_G )  | AnalogVideo_PAL_H )  | AnalogVideo_PAL_I ) ,
AnalogVideoMask_MCE_SECAM   = ( ( ( ( ( ( ( AnalogVideo_SECAM_B | AnalogVideo_SECAM_D )  | AnalogVideo_SECAM_G )  | AnalogVideo_SECAM_H )  | AnalogVideo_SECAM_K )  | AnalogVideo_SECAM_K1 )  | AnalogVideo_SECAM_L )  | AnalogVideo_SECAM_L1 ) 
}   AnalogVideoStandard;

更重要的是,当捕获卡有多个物理输入时,会自动添加交叉滤波器,我可以使用PhysicalConnectorType枚举路由我想要的输入,但不包括HDMI等一些新输入:

typedef 
enum tagPhysicalConnectorType
{
PhysConn_Video_Tuner    = 1,
PhysConn_Video_Composite    = ( PhysConn_Video_Tuner + 1 ) ,
PhysConn_Video_SVideo   = ( PhysConn_Video_Composite + 1 ) ,
PhysConn_Video_RGB  = ( PhysConn_Video_SVideo + 1 ) ,
PhysConn_Video_YRYBY    = ( PhysConn_Video_RGB + 1 ) ,
PhysConn_Video_SerialDigital    = ( PhysConn_Video_YRYBY + 1 ) ,
PhysConn_Video_ParallelDigital  = ( PhysConn_Video_SerialDigital + 1 ) ,
PhysConn_Video_SCSI = ( PhysConn_Video_ParallelDigital + 1 ) ,
PhysConn_Video_AUX  = ( PhysConn_Video_SCSI + 1 ) ,
PhysConn_Video_1394 = ( PhysConn_Video_AUX + 1 ) ,
PhysConn_Video_USB  = ( PhysConn_Video_1394 + 1 ) ,
PhysConn_Video_VideoDecoder = ( PhysConn_Video_USB + 1 ) ,
PhysConn_Video_VideoEncoder = ( PhysConn_Video_VideoDecoder + 1 ) ,
PhysConn_Video_SCART    = ( PhysConn_Video_VideoEncoder + 1 ) ,
PhysConn_Video_Black    = ( PhysConn_Video_SCART + 1 ) ,
PhysConn_Audio_Tuner    = 0x1000,
PhysConn_Audio_Line = ( PhysConn_Audio_Tuner + 1 ) ,
PhysConn_Audio_Mic  = ( PhysConn_Audio_Line + 1 ) ,
PhysConn_Audio_AESDigital   = ( PhysConn_Audio_Mic + 1 ) ,
PhysConn_Audio_SPDIFDigital = ( PhysConn_Audio_AESDigital + 1 ) ,
PhysConn_Audio_SCSI = ( PhysConn_Audio_SPDIFDigital + 1 ) ,
PhysConn_Audio_AUX  = ( PhysConn_Audio_SCSI + 1 ) ,
PhysConn_Audio_1394 = ( PhysConn_Audio_AUX + 1 ) ,
PhysConn_Audio_USB  = ( PhysConn_Audio_1394 + 1 ) ,
PhysConn_Audio_AudioDecoder = ( PhysConn_Audio_USB + 1 ) 
}   PhysicalConnectorType;

我知道Directshow是一个旧的多媒体框架,标题可能已经过时了。那么,有什么方法可以将一些新标准应用于Directshow吗?Directshow还有其他的重新发行吗?或者我应该放弃使用Directshow,转而使用Media Foundation?

因此,您更正了Microsoft停止支持DirectShow的消息。DirectShow默认不支持720p、1080i、1080p等高清标准。为了解决这个问题,视频捕获设备的供应商开发了支持这种新设备的私人直接显示过滤器,并将其包含在设备的驱动程序中-这个过滤器是在安装驱动器时安装的-这意味着你必须研究操作系统以查找DirectShow源过滤器-当然,如果你安装了驱动程序,其中一个过滤器将是你需要的过滤器。关于Media Foundation-目前它只支持USB视频类驱动程序Media Foundation中的音频/视频捕获用于捕获视频-这样的驱动程序只支持USB网络摄像头。

谨致问候。

p.S.要获得输出引脚,可以使用下一个代码:`

CComPtrCustom<ICaptureGraphBuilder2> lCaptureGraph;
LOG_INVOKE_FUNCTION(lCaptureGraph.CoCreateInstance, __uuidof(CLSID_CaptureGraphBuilder2Proxy));
LOG_CHECK_PTR_MEMORY(lCaptureGraph);
CComPtrCustom<IGraphBuilder> lGraphBuilder;
LOG_INVOKE_FUNCTION(lGraphBuilder.CoCreateInstance, __uuidof(CLSID_FilterGraphProxy));
LOG_CHECK_PTR_MEMORY(lGraphBuilder);
LOG_INVOKE_POINTER_METHOD(lCaptureGraph, SetFiltergraph,
lGraphBuilder);                             
CComPtrCustom<IBaseFilter> lVideoCaptureFilter;
CComPtrCustom<IBindCtx> pbc;
LOG_INVOKE_FUNCTION(CreateBindCtx, NULL, &pbc);
LOG_INVOKE_POINTER_METHOD(mMoniker, BindToObject,
pbc,
nullptr, 
IID_PPV_ARGS(&lVideoCaptureFilter));
LOG_CHECK_PTR_MEMORY(lVideoCaptureFilter);
LOG_INVOKE_POINTER_METHOD(lGraphBuilder, AddFilter,
lVideoCaptureFilter,
L"Video Capture");
std::vector<CComPtrCustom<IMFMediaType>> lMediaTypes;
do
{
CComPtrCustom<IPin> lPin;
LOG_INVOKE_POINTER_METHOD(lCaptureGraph, FindPin,
lVideoCaptureFilter,
PINDIR_OUTPUT,
&PIN_CATEGORY_CAPTURE,
&__uuidof(MEDIATYPE_VideoProxy),
FALSE,
aStreamIndex,
&lPin);
if (lPin != nullptr)
{
PIN_INFO lPIN_INFO;
ZeroMemory(&lPIN_INFO, sizeof(lPIN_INFO));
HRESULT lr = lPin->QueryPinInfo(&lPIN_INFO);
if (SUCCEEDED(lr) && lPIN_INFO.achName[0] != L'')
{
if (aPtrStreamNameString != nullptr)
{
*aPtrStreamNameString = SysAllocString(lPIN_INFO.achName);
}
}
getMediaTypes(
lPin,
lMediaTypes);
}
} while (false);

`

一些供应商为DS过滤器的扩展定义了自己的接口,例如AJA DS过滤器:

EXTERN_C const IID IID_IAJACaptureFilter;
MIDL_INTERFACE("D941E04F-3B38-4F27-82DD-943FBEA7E755")
IAJACaptureFilter : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE SetBoardNumber( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetBoardNumber( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetNumBoards( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE ReserveBoard( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetVideoFormat( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetReferenceSource( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetReferenceSource( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetVideoSource( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVideoSource( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetAnalogVideoFormat( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAnalogVideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSourceVideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetInput1VideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetInput2VideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetHDMIInVideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetReferenceVideoFormat( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetFourCC( 
/* [in] */ DWORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetFourCC( 
/* [out] */ DWORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetEnableEtoE( 
/* [in] */ BOOL value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetEnableEtoE( 
/* [out] */ BOOL *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetEnableVANCMode( 
/* [in] */ BOOL value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetEnableVANCMode( 
/* [out] */ BOOL *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetScaleMode( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetScaleMode( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetAudioSource( 
/* [in] */ WORD value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetAudioSource( 
/* [out] */ WORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE SetInputAlarm( 
/* [in] */ BOOL value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetInputAlarm( 
/* [out] */ BOOL *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCurrentFrame( 
/* [out] */ DWORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDroppedFrames( 
/* [out] */ DWORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetBufferLevel( 
/* [out] */ DWORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetBoardID( 
/* [out] */ DWORD *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetSerialNumber( 
/* [retval][out] */ BSTR *value) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDebug( 
/* [out] */ int *pnDebug1,
/* [out] */ int *pnDebug2,
/* [out] */ int *pnDebug3) = 0;
};

AJA公司的过滤器可以用于设置输出过滤器的格式。

最新更新