0

I am enumerating the UVC properties for a camera using IKsTopologyInfo and IKsControl interface. I am using both MFT and Direct Show this code.during enumeration I get various GUID for example CLSID_IAMCameraControl, CLSID_IAMVideoProcAmp and many more.

Now IAMVideoProcAmp Support 10 properties and IAMCameraControl supports 7 properties

Not all camera supports all the property items.I wanted to know exact properties(enum index/value) supported by a any camera.Can we query this using IKsTopologyInfo and IKsControl ?Is ther other way to so this.

Here is the code to enumerate properties i.e. this code gives me interface 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;
Vikram Ranabhatt
  • 7,268
  • 15
  • 70
  • 133

1 Answers1

1

Use the DirectShow interfaces of IAMVideoProcAmp and IAMCameraControl for this.

Here's a C# class which encapsulates CameraControl and removes most of the painful parts. VideoProcAmp would be completely analogous:

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

Then, you could use the above class as follows:

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;
    }
    ...
}
Jay Borseth
  • 1,894
  • 20
  • 29
  • Thanks..I Already implemented it in C++.I just wanted to know why IKsTopologyInfo is not working here. – Vikram Ranabhatt Mar 15 '13 at 10:21
  • 1
    One possibility: Some cameras don't use KsProxy.ax and instead provide their own DirectShow video capture filter. Hence they probably don't implement the IKsPropertySet interface. – Jay Borseth Mar 15 '13 at 18:40