IMFCameraConfigurationManager 인터페이스(mfidl.h)
상속
IMFCameraConfigurationManager 인터페이스는 IUnknown 인터페이스에서 상속됩니다.
메서드
IMFCameraConfigurationManager 인터페이스에는 이러한 메서드가 있습니다.
IMFCameraConfigurationManager::LoadDefaults 지정된 캡처 원본에 대한 카메라 컨트롤 기본값을 로드합니다. |
IMFCameraConfigurationManager::SaveDefaults 제공된 카메라 컨트롤 기본값 컬렉션을 저장합니다. |
IMFCameraConfigurationManager::Shutdown IMFCameraConfigurationManager::Shutdown 함수는 카메라 구성 관리자를 종료합니다. |
설명
COM 함수 CoCreateInstance를 호출하고 CLSID_CameraConfigurationManager CLSID 매개 변수로 전달하여 IMFCameraConfigurationManager 인터페이스의 인스턴스를 만들 수 있습니다.
예
다음 예제에서는 IMFCameraConfigurationManager 및 관련 API를 사용하여 시선 응시 보정 카메라 컨트롤의 기본 구성을 검색하는 방법을 보여 줍니다.
#include "wil/result_macros.h"
#include <mfapi.h>
HRESULT
FindDefaultConfigForEyeGazeCorrection(
_In_ IMFActivate* cameraActivate,
_COM_Outptr_ IMFCameraControlDefaults** ppConfig
)
{
wil::com_ptr_nothrow<IMFCameraConfigurationManager> factory;
wil::com_ptr_nothrow<IMFCameraControlDefaultsCollection> configCollection;
*ppConfig = nullptr;
RETURN_IF_FAILED(CoCreateInstance(CLSID_CameraConfigurationManager,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&factory)));
/// Load the defaults, and then iterate through the available
/// configurations to find the eyegaze control.
RETURN_IF_FAILED(factory->LoadDefaults(cameraActivate, &configCollection));
for (ULONG i = 0; i < configCollection->GetControlCount(); i++)
{
wil::com_ptr_nothrow<IMFCameraControlDefaults> config;
KSPROPERTY* ksprop = nullptr;
ULONG kspropSize = 0;
void* data = nullptr;
ULONG dataSize = 0;
RETURN_IF_FAILED(configCollection->GetControl(i, &config));
RETURN_IF_FAILED(config->LockControlData((void**)&ksprop, &kspropSize, &data, &dataSize));
RETURN_HR_IF(HRESULT_FROM_WIN32(ERROR_INVALID_DATA), kspropSize < sizeof(KSPROPERTY));
if (ksprop->Set == KSPROPERTYSETID_ExtendedCameraControl &&
ksprop->Id == KSPROPERTY_CAMERACONTROL_EXTENDED_EYEGAZECORRECTION)
{
(void)config->UnlockControlData();
*ppConfig = config.detach();
return S_OK;
}
(void)config->UnlockControlData();
}
/// If we reach this point, we didn't find the eyegaze
/// correction control.
return MF_E_NOT_FOUND;
}
다음 예제에서는 IMFCameraConfigurationManager 및 관련 API를 사용하여 레거시 노출 컨트롤의 기본값을 설정하는 방법을 보여 줍니다. 이 구현에 대한 일반적인 사용 시나리오를 통해 사용자는 일반 Windows 카메라 설정 페이지를 시작할 필요 없이 IHV 구현 카메라 도우미 앱에서 기본 컨트롤 값을 설정할 수 있습니다.
HRESULT SetDefaultLegacyExposure(
_In_z_ LPCWSTR deviceSymbolicName,
_In_ LONG exposureValue
)
{
wil::com_ptr_nothrow<IMFAttributes> attrib;
wil::com_ptr_nothrow<IMFCameraConfigurationManager> manager;
wil::com_ptr_nothrow<IMFCameraControlDefaultsCollection> defaultsCollection;
wil::com_ptr_nothrow<IMFCameraControlDefaults> exposureDefaults;
KSPROPERTY_CAMERACONTROL_S* data = nullptr;
ULONG dataSize = 0;
KSPROPERTY_CAMERACONTROL_S* control = nullptr;
ULONG controlSize = 0;
LONG value = 0;
MF_CAMERA_CONTROL_RANGE_INFO rangeInfo = { };
bool fLocked = false;
auto cleanUpOnExit = wil::scope_exit([&]()
{
if (fLocked)
{
/// Best effort to avoid leaving the control in a locked state.
(void)exposureDefaults->UnlockControlData();
}
/// Free up the manager's resources when we're done.
if (manager)
{
manager->Shutdown();
}
});
RETURN_IF_FAILED(CoCreateInstance(CLSID_CameraConfigurationManager,
nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&manager)));
RETURN_IF_FAILED(MFCreateAttributes(&attrib, 1));
RETURN_IF_FAILED(attrib->SetString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
deviceSymbolicName));
RETURN_IF_FAILED(manager->LoadDefaults(attrib.get(), &defaultsCollection));
/// If the legacy exposure control not available, this call will
/// return HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND).
///
/// Exposure control is always a post-start control since the
/// algorithm requires frames to be captured/analyzed for the
/// exposure to converge.
RETURN_IF_FAILED(defaultsCollection->GetOrAddControl(MF_CAMERA_CONTROL_CONFIGURATION_TYPE_POSTSTART,
PROPSETID_VIDCAP_CAMERACONTROL,
KSPROPERTY_CAMERACONTROL_EXPOSURE,
sizeof(KSPROPERTY_CAMERACONTROL_S),
sizeof(KSPROPERTY_CAMERACONTROL_S),
&exposureDefaults));
/// Exposure off the PROPSETID_VIDCAP_CAMERACONTROL must always
/// provide a min/max/step/default. We can validate the
/// parameter provided is valid.
/// NOTE: RangeInfo is only guaranteed for
/// PROPSETID_VIDCAP_CAMERACONTROL or
/// PROPSETID_VIDCAP_VIDEOPROCAMP. Other controls may provide
/// range information (they must support
/// KSPROPERTY_TYPE_BASICSUPPORT operation), but the app must
/// handle the situation where range information may not be
/// available.
RETURN_IF_FAILED(exposureDefaults->GetRangeInfo(&rangeInfo));
if ((rangeInfo.minValue > exposureValue) ||
(rangeInfo.maxValue < exposureValue) ||
(0 != (exposureValue - rangeInfo.minValue) % rangeInfo.stepValue))
{
RETURN_IF_FAILED(E_INVALIDARG);
}
/// Since we're setting a specific value, we need to also check
/// 1. Does this control support manual mode (most webcam do,
/// but per DDI spec, not required).
/// 2. Flip the flags to manual mode so the camera won't ignore
/// the new value being set.
RETURN_IF_FAILED(exposureDefaults->LockControlData((void**)&control,
&controlSize,
(void**)&data,
&dataSize));
fLocked = true;
if (controlSize < sizeof(KSPROPERTY_CAMERACONTROL_S) ||
dataSize < sizeof(KSPROPERTY_CAMERACONTROL_S))
{
/// This should never happen, but just to keep everything sane.
RETURN_IF_FAILED(MF_E_UNEXPECTED);
}
if (WI_IsFlagClear(control->Capabilities, KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL))
{
RETURN_IF_FAILED(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED));
}
control->Flags = KSPROPERTY_CAMERACONTROL_FLAGS_MANUAL;
control->Property.Flags = KSPROPERTY_TYPE_SET;
control->Value = exposureValue;
/// For legacy control, we send in the same information in the
/// data as the control.
data->Property.Set = control->Property.Set;
data->Property.Id = control->Property.Id;
data->Property.Flags = control->Property.Flags;
data->Value = control->Value;
data->Flags = control->Flags;
RETURN_IF_FAILED(exposureDefaults->UnlockControlData());
fLocked = false;
RETURN_IF_FAILED(manager->SaveDefaults(defaultsCollection.get()));
return S_OK;
}
다음 예제에서는 IHV가 사용자 지정 컨트롤을 구성하는 UX를 사용자에게 제공하는 자체 구성 애플리케이션을 구현하는 또 다른 시나리오를 보여 줍니다. 이 시나리오에서 IHV 앱은 사용자 지정 컨트롤을 지원하는 FFC(전면 카메라)를 발견했으며, 애플리케이션이 다른 프로필을 선택하여 이 동작을 명시적으로 재정의하지 않는 한 IHV는 문제의 카메라가 항상 KSCAMERAPROFILE_VideoConferencing 프로필로 기본 설정되도록 선택했습니다. 사용자 지정 컨트롤에는 Windows에 알려지지 않고 사용자 지정 컨트롤에 대한 사양을 얻은 IHV/OEM 및/또는 ISV에만 알려진 컨트롤 및 데이터 페이로드 스키마가 있으므로 아래 샘플에서는 컨트롤 또는 데이터 페이로드의 유효성 검사를 표시하지 않습니다.
HRESULT SetCustomControl(
_In_ IMFAttributes* attribFrontFacingCamera,
_In_ REFGUID customSet,
_In_ ULONG customId,
_In_reads_bytes_(customDataSize) void* customData,
_In_ ULONG customDataSize)
{
wil::com_ptr_nothrow<IMFCameraConfigurationManager> manager;
wil::com_ptr_nothrow<IMFCameraControlDefaultsCollection> defaultsCollection;
wil::com_ptr_nothrow<IMFCameraControlDefaults> customControlDefaults;
BYTE* data = nullptr;
ULONG dataSize = 0;
KSPROPERTY* control = nullptr;
ULONG controlSize = 0;
LONG value = 0;
MF_CAMERA_CONTROL_RANGE_INFO rangeInfo = { };
bool fLocked = false;
auto cleanUpOnExit = wil::scope_exit([&]()
{
if (fLocked)
{
/// Best effort to avoid leaving the control in a locked state.
(void)customControlDefaults->UnlockControlData();
}
/// Free up the manager's resources when we're done.
if (manager)
{
manager->Shutdown();
}
});
RETURN_IF_FAILED(CoCreateInstance(CLSID_CameraConfigurationManager, nullptr,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&manager)));
RETURN_IF_FAILED(manager->LoadDefaults(attribFrontFacingCamera, &defaultsCollection));
/// Set the selected profile to the video conferencing profile.
/// This is making the assumption that the most common use of
/// the front facing camera would be for video conferencing
/// calls, but for apps like CameraApp, they can (and do)
/// override this selection by explicitly setting a different
/// profile (either Photo or Video Recording) as needed.
///
/// NOTE: As this is done by the IHV/OEM (who also publishes
/// the camera profiles), the assumption is that there's
/// knowledge of the camera's support for the video conferencing
/// profile and the index value for that profile (profiles are
/// identified by their type such as
/// KSCAMERAPROFILE_VideoConferencing and their index which
/// allows for multiple profiles for the same "type").
RETURN_IF_FAILED(defaultsCollection->SetGUID(MF_CAPTURE_ENGINE_SELECTEDCAMERAPROFILE,
KSCAMERAPROFILE_VideoConferencing));
RETURN_IF_FAILED(defaultsCollection -> SetUINT32(MF_CAPTURE_ENGINE_SELECTEDCAMERAPROFILE_INDEX,
0));
/// Custom controls are never validated, it is assumed the
/// caller of this method has some out of band knowledge of the
/// DDI's control/data schema. This is typically done by IHVs
/// documenting their controls for ISVs/OEMs to leverage.
RETURN_IF_FAILED (defaultsCollection->GetOrAddControl(MF_CAMERA_CONTROL_CONFIGURATION_TYPE_POSTSTART,
customSet,
customId,
sizeof(KSPROPERTY),
customDataSize,
&customControlDefaults));
RETURN_IF_FAILED(customControlDefaults->LockControlData((void**)&control,
&controlSize,
(void**)&data,
&dataSize));
fLocked = true;
if (controlSize < sizeof(KSPROPERTY) || dataSize < customDataSize)
{
/// This should never happen, but just to keep everything sane.
RETURN_IF_FAILED(MF_E_UNEXPECTED);
}
control->Set = customSet;
control->Id = customId;
control->Flags = KSPROPERTY_TYPE_SET;
CopyMemory(data, customData, customDataSize);
RETURN_IF_FAILED(customControlDefaults->UnlockControlData());
fLocked = false;
RETURN_IF_FAILED(manager->SaveDefaults(defaultsCollection.get()));
return S_OK;
}
요구 사항
머리글 | mfidl.h |