2013-02-14 84 views
0

我使用IKsTopologyInfo和IKsControl接口枚舉相機的UVC屬性。我正在使用MFT和直接顯示此代碼。枚舉我得到各種GUID,例如CLSID_IAMCameraControl,CLSID_IAMVideoProcAmp等等。枚舉相機屬性集的UVC屬性項

現在IAMVideoProcAmp支持10 properties和IAMCameraControl支持7 properties

並非所有的攝像頭支持items.I想知道確切屬性(枚舉索引/值)由任何camera.Can我們這個使用查詢所支持的所有財產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; 

回答

1

使用IAMVideoProcAmp此DirectShow的接口IAMCameraControl

下面是一個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; 
    } 
    ... 
} 
+0

Thanks..I實施到C++我只是想知道爲什麼IK​​sTopologyInfo不工作。這裏。 – 2013-03-15 10:21:53

+1

一種可能性:有些相機不使用KsProxy.ax,而是提供他們自己的DirectShow視頻捕獲過濾器。因此他們可能不會實現IKsPropertySet接口。 – 2013-03-15 18:40:06