我使用IKsTopologyInfo和IKsControl接口枚举摄像机的UVC属性。我正在使用MFT和Direct显示此代码。在枚举中我获得了各种GUID,例如CLSID_IAMCameraControl,CLSID_IAMVideoProcAmp等等。
现在IAMVideoProcAmp支持10 properties,IAMCameraControl支持7 properties
并非所有相机都支持所有属性项。我想知道任何相机支持的确切属性(枚举索引/值)。我们可以使用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;
答案 0 :(得分:1)
使用 IAMVideoProcAmp 和 IAMCameraControl 的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;
}
...
}