0

IKsTopologyInfo および IKsControl インターフェイスを使用して、カメラの UVC プロパティを列挙しています。私は MFT と直接の両方を使用しています。このコードを表示します。列挙中に、CLSID_IAMCameraControl、CLSID_IAMVideoProcAmp などのさまざまな GUID を取得します。

IAMVideoProcAmp は 10 個のプロパティ をサポートし、IAMCameraControl は 7個のプロパティをサポートするようになりました

すべてのカメラがすべてのプロパティ項目をサポートしているわけではありません.任意のカメラでサポートされている正確なプロパティ (列挙インデックス/値) を知りたいと思っていました.IKsTopologyInfo と IKsControl を使用してこれを照会できますか?他の方法はありますか?

プロパティを列挙するコードは次のとおりです。つまり、このコードはインターフェイス CLSID_IAMCameraControl,CLSID_IAMVideoProcAmp を提供します。

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;
4

1 に答える 1

1

これには、 IAMVideoProcAmpおよびIAMCameraControlの DirectShow インターフェイスを使用します。

これは、CameraControl をカプセル化し、面倒な部分のほとんどを削除する C# クラスです。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;
    }
    ...
}
于 2013-03-15T09:00:08.580 に答える