Video streaming 枚举相机特性集的UVC特性项

Video streaming 枚举相机特性集的UVC特性项,video-streaming,directshow,ms-media-foundation,wdm,Video Streaming,Directshow,Ms Media Foundation,Wdm,我正在使用IKsTopologyInfo和IKsControl界面枚举相机的UVC属性。我正在使用MFT和Direct Show这段代码。在枚举过程中,我会得到各种GUID,例如CLSID_IAMCameraControl、CLSID_IAMDevideoProCamp和更多 现在,IAMVideoProcAmp支持10,IAMCameraControl支持7 并非所有摄像头都支持所有属性项。我想知道任何摄像头支持的确切属性(枚举索引/值)。我们可以使用IKsTopologyInfo和IKsCo

我正在使用IKsTopologyInfo和IKsControl界面枚举相机的UVC属性。我正在使用MFT和Direct Show这段代码。在枚举过程中,我会得到各种GUID,例如CLSID_IAMCameraControl、CLSID_IAMDevideoProCamp和更多

现在,IAMVideoProcAmp支持10,IAMCameraControl支持7

并非所有摄像头都支持所有属性项。我想知道任何摄像头支持的确切属性(枚举索引/值)。我们可以使用IKsTopologyInfo和IKsControl进行查询吗?还有其他方法吗

下面是枚举属性的代码,即此代码为我提供了接口CLSID\u IAMCameraControl、CLSID\u IAMDevideoPROCAMP

HRESULT                     hRet        = S_OK; 
CComPtr<IKsTopologyInfo>    ksTopology  = NULL;
BYTE*                       pList       = NULL;

do
{           

    if(!m_pMediaSource)
        break;  

    if(m_SuppPropSetGUIDS.size())
        break;

    hRet = m_pMediaSource->QueryInterface(IID_PPV_ARGS(&ksTopology));
    if(FAILED(hRet))
        break;

    ksTopology->get_NumNodes(&m_dwNumNodes);
    for (ULONG ulNode=0; ulNode < m_dwNumNodes; ulNode++ )
    {
        CComPtr<IKsControl> ksControl       = 0;
        GUID                nodeType        = GUID_NULL;
        DWORD               dwBytesReturned = 0;

        KSPROPERTY      KsProp = {0};
        KsProp.Set      = GUID_NULL;
        KsProp.Id       = 0; // Ignored
        KsProp.Flags    = KSPROPERTY_TYPE_SETSUPPORT;

        KSP_NODE            KsNode          = {0};
        KsNode.Property.Set = GUID_NULL;
        KsNode.NodeId = ulNode;
        KsNode.Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;

        ksTopology->get_NodeType(ulNode, &nodeType);

        hRet = ksTopology->CreateNodeInstance(ulNode, IID_PPV_ARGS(&ksControl));
        if(FAILED(hRet))
            continue;               

        hRet = ksControl->KsProperty(&KsProp, sizeof(KSPROPERTY), NULL, NULL, &dwBytesReturned);    
        if( hRet == HRESULT_FROM_WIN32(ERROR_MORE_DATA) && dwBytesReturned )
        {           
            pList = (BYTE*)calloc(dwBytesReturned, sizeof(BYTE) );
            if ( pList == NULL )
                continue;
            hRet = ksControl->KsProperty(&KsProp, sizeof(KSPROPERTY), pList, dwBytesReturned, &dwBytesReturned);    


            if(FAILED(hRet))
                break;              
        }
        else
            continue;

        GUID* pGuidList = (GUID*)pList;
        int iCount = dwBytesReturned/sizeof(GUID);
        for(int i = 0; i < iCount; i++ )
        {
            if( !LookUpPS( &pGuidList[i] ) )
                m_SuppPropSetGUIDS.push_back( pGuidList[i] );
        }
        if(pList)
            free(pList);
        pList = NULL;

    }
}while(FALSE);

if(pList)
    free(pList);
pList = NULL;

return hRet;
HRESULT hRet=S_正常;
CComPtr ksTopology=NULL;
字节*pList=NULL;
做
{           
如果(!m_pMediaSource)
打破
if(m_supplopSetGuids.size())
打破
hRet=m_pMediaSource->QueryInterface(IID_PPV_参数(&ksTopology));
如果(失败(hRet))
打破
ksTopology->get_NumNodes(&m_dwNumNodes);
对于(ULONG ulNode=0;ulNodeget_节点类型(ulNode,&NodeType);
hRet=ksTopology->CreateNodeInstance(ulNode、IID_PPV_参数(&ksControl));
如果(失败(hRet))
继续;
hRet=ksControl->KsProperty(&KsProp,sizeof(KsProperty),NULL,NULL,&dwBytesReturned);
if(hRet==HRESULT\u FROM\u WIN32(错误\u更多数据)&&dwbytes返回)
{           
pList=(字节*)calloc(返回的dwbytes,sizeof(字节));
if(pList==NULL)
继续;
hRet=ksControl->KsProperty(&KsProp,sizeof(KsProperty),pList,dwBytesReturned,&dwBytesReturned);
如果(失败(hRet))
打破
}
其他的
继续;
GUID*pGuidList=(GUID*)pList;
int iCount=dwBytesReturned/sizeof(GUID);
for(int i=0;i
为此,请使用iamdevideoprocampIAMCameraControl的DirectShow界面

这里有一个C#类,它封装了CameraControl并删除了大部分痛苦的部分。VideoProcAmp将完全类似于:

public class CameraControlSetting : IDisposable
{
    private readonly CameraControlProperty property;
    private IAMCameraControl controlInterface;
    private int min;
    private int max;
    private int steppingDelta;
    private int defaultValue;
    public CameraControlFlags CapabilityFlags;

    public int Min
    {
        get { return min; }
    }

    public int Max
    {
        get { return max; }
    }

    public int SteppingDelta
    {
        get { return steppingDelta; }
        set { steppingDelta = value; }  // Shouldn't be exposed, but WhiteBalanceSteppingDelta is often 1!
    }

    public int DefaultValue
    {
        get { return defaultValue; }
    }


    public CameraControlSetting(CameraControlProperty property, IAMCameraControl controlInterface)
    {
        this.property = property;
        this.controlInterface = controlInterface;
    }

    public void GetRange()
    {
        if (controlInterface == null) return;
        controlInterface.GetRange(property, out min, out max, out steppingDelta, out defaultValue,
                                  out CapabilityFlags);
        GetCurrentValueAndFlags();
    }

    private void GetCurrentValueAndFlags()
    {
        if (controlInterface == null) return;
        controlInterface.Get(property, out currentValue, out currentFlags);
    }

    private void SetCurrentValueAndFlags()
    {
        if (controlInterface == null) return;
        controlInterface.Set(property, currentValue, currentFlags);
    }

    private CameraControlFlags currentFlags;
    public CameraControlFlags CurrentFlags
    {
        get { return currentFlags; }
        set
        {
            GetCurrentValueAndFlags();  
            currentFlags = value;
            SetCurrentValueAndFlags();
        }
    }

    private int currentValue;
    public int CurrentValue
    {
        get { return currentValue; }
        set
        {
            currentFlags = CameraControlFlags.Manual;
            currentValue = value;
            SetCurrentValueAndFlags();
        }
    }

    public void Dispose()
    {
        controlInterface = null;
    }
}
然后,您可以按如下方式使用上述类:

public IAMCameraControl CameraControl { get { return m_pCaptureFilter as IAMCameraControl; } }

public CameraControlSetting Zoom { get; private set; }
public CameraControlSetting Focus { get; private set; }

public bool HasAutoFocus { get { return (Focus != null) && ((Focus.CapabilityFlags & CameraControlFlags.Auto) == CameraControlFlags.Auto); } }

private void GetCameraFeatures()
{
    Zoom = new CameraControlSetting(CameraControlProperty.Zoom, CameraControl);
    Focus = new CameraControlSetting(CameraControlProperty.Focus, CameraControl);

    // Get the CameraControl Properties
    Zoom.GetRange();
    Focus.GetRange();
    if (HasAutoFocus)
    {
        Focus.CurrentFlags = CameraControlFlags.Auto;
    }
    ...
}

谢谢…我已经在C++中实现了。我只是想知道为什么IKsTopologyInfo不在这里工作。一种可能性:一些相机不使用KsPROX.ax,而是提供自己的DirectShow视频捕获过滤器。因此,它们可能没有实现IKsPropertySet接口。