枚举相机属性集的 UVC 属性项
Posted
技术标签:
【中文标题】枚举相机属性集的 UVC 属性项【英文标题】:Enumerating UVC Properties items of a property set of a camera 【发布时间】:2013-02-14 12:22:49 【问题描述】:我正在使用 IKsTopologyInfo 和 IKsControl 接口枚举相机的 UVC 属性。我同时使用 MFT 和直接显示此代码。在枚举期间,我得到各种 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;
【问题讨论】:
【参考方案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;
...
【讨论】:
谢谢..我已经用 C++ 实现了它。我只是想知道为什么 IKsTopologyInfo 在这里不起作用。 一种可能性:一些摄像机不使用 KsProxy.ax,而是提供了自己的 DirectShow 视频捕获过滤器。因此他们可能没有实现 IKsPropertySet 接口。以上是关于枚举相机属性集的 UVC 属性项的主要内容,如果未能解决你的问题,请参考以下文章