IMFCameraConfigurationManager
COM公式ドキュメント
IMFCameraConfigurationManager インターフェースは、COM 関数 CoCreateInstance を呼び出し、CLSID パラメーターに CLSID_CameraConfigurationManager を渡すことで作成できます。
解説(Remarks)
IMFCameraConfigurationManager インターフェースのインスタンスは、COM 関数 CoCreateInstance を呼び出し、CLSID パラメーターに CLSID_CameraConfigurationManager を渡すことで作成できます。
Examples
次の例は、視線補正カメラコントロールの既定の構成を取得するための 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)));
/// 既定値を読み込み、利用可能な構成を反復処理して
/// 視線コントロールを探します。
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();
}
/// この時点に到達した場合、視線補正コントロールは
/// 見つかりませんでした。
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)
{
/// コントロールをロック状態のままにしないための最善の対応。
(void)exposureDefaults->UnlockControlData();
}
/// 処理完了時にマネージャーのリソースを解放します。
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));
/// レガシー露出コントロールが利用できない場合、この呼び出しは
/// HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND) を返します。
///
/// 露出コントロールは常にポストスタートコントロールです。
/// アルゴリズムが露出を収束させるためにフレームの
/// キャプチャ/解析を必要とするためです。
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));
/// PROPSETID_VIDCAP_CAMERACONTROL の露出は常に
/// min/max/step/default を提供する必要があります。提供された
/// パラメーターが有効かどうかを検証できます。
/// 注意: RangeInfo は PROPSETID_VIDCAP_CAMERACONTROL または
/// PROPSETID_VIDCAP_VIDEOPROCAMP に対してのみ保証されます。
/// その他のコントロールも範囲情報を提供する場合があります
/// (KSPROPERTY_TYPE_BASICSUPPORT 操作をサポートする必要があります)
/// が、アプリは範囲情報が利用できない状況に対処する必要があります。
RETURN_IF_FAILED(exposureDefaults->GetRangeInfo(&rangeInfo));
if ((rangeInfo.minValue > exposureValue) ||
(rangeInfo.maxValue < exposureValue) ||
(0 != (exposureValue - rangeInfo.minValue) % rangeInfo.stepValue))
{
RETURN_IF_FAILED(E_INVALIDARG);
}
/// 特定の値を設定するため、次の点も確認する必要があります。
/// 1. このコントロールがマニュアルモードをサポートするか
/// (ほとんどの Web カメラはサポートしますが、DDI 仕様上は必須ではありません)。
/// 2. カメラが設定される新しい値を無視しないよう、フラグを
/// マニュアルモードに切り替えます。
RETURN_IF_FAILED(exposureDefaults->LockControlData((void**)&control,
&controlSize,
(void**)&data,
&dataSize));
fLocked = true;
if (controlSize < sizeof(KSPROPERTY_CAMERACONTROL_S) ||
dataSize < sizeof(KSPROPERTY_CAMERACONTROL_S))
{
/// これは決して発生しないはずですが、念のための確認です。
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;
/// レガシーコントロールでは、コントロールと同じ情報を
/// data に送信します。
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 のみが知る control およびデータペイロードスキーマを持つため、以下のサンプルでは control やデータペイロードの検証は示していません。
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)
{
/// コントロールをロック状態のままにしないための最善の対応。
(void)customControlDefaults->UnlockControlData();
}
/// 処理完了時にマネージャーのリソースを解放します。
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));
/// 選択したプロファイルをビデオ会議プロファイルに設定します。
/// これは、前面カメラの最も一般的な用途がビデオ会議通話であると
/// いう前提に基づいていますが、CameraApp のようなアプリは、
/// 必要に応じて別のプロファイル (Photo または Video Recording)
/// を明示的に設定することでこの選択を上書きできます (実際に
/// 上書きします)。
///
/// 注意: これはカメラプロファイルも公開する IHV/OEM によって
/// 行われるため、そのカメラがビデオ会議プロファイルをサポート
/// していることと、そのプロファイルのインデックス値についての
/// 知識があることが前提です (プロファイルは、
/// KSCAMERAPROFILE_VideoConferencing のような型と、同じ「型」に
/// 対して複数のプロファイルを許容するインデックスによって
/// 識別されます)。
RETURN_IF_FAILED(defaultsCollection->SetGUID(MF_CAPTURE_ENGINE_SELECTEDCAMERAPROFILE,
KSCAMERAPROFILE_VideoConferencing));
RETURN_IF_FAILED(defaultsCollection -> SetUINT32(MF_CAPTURE_ENGINE_SELECTEDCAMERAPROFILE_INDEX,
0));
/// カスタムコントロールは検証されません。このメソッドの呼び出し元は
/// DDI の control/data スキーマについての帯域外の知識を持っていると
/// 想定されます。これは通常、IHV が ISV/OEM が活用できるよう
/// コントロールを文書化することで行われます。
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)
{
/// これは決して発生しないはずですが、念のための確認です。
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;
}
メソッド 3
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
指定したキャプチャソースのカメラコントロール既定値を読み込みます。
| cameraAttributes | IMFAttributes* | in | IMFAttributes へのポインター。この中の MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性が、既定のコントロール値を取得するキャプチャソースを識別します。 |
| configurations | IMFCameraControlDefaultsCollection** | out | カメラコントロール既定値のコレクションを表す IMFCameraControlDefaultsCollection オブジェクトへのポインターを受け取ります。 |
戻り値
HRESULT。次のものを含みます。
| Value | Description |
|---|---|
| S_OK | 成功 |
| MF_E_ATTRIBUTENOTFOUND | cameraAttributes で提供された IMFAttributes に MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性が見つかりませんでした |
| MF_E_SHUTDOWN | IMFCameraConfigurationManager::Shutdown が呼び出された後に関数が呼び出されました。 |
解説(Remarks)
既定のコントロールが指定されていない場合、結果のコレクションは空になります。つまり、IMFCameraControlDefaultsCollection::GetControlCount は 0 を返します。
提供されたカメラコントロール既定値のコレクションを保存します。
| configurations | IMFCameraControlDefaultsCollection* | in | 保存するカメラコントロール既定値のコレクションを表す IMFCameraControlDefaultsCollection。 |
戻り値
HRESULT。次のものを含みます。
| Value | Description |
|---|---|
| S_OK | 成功。 |
| MF_E_SHUTDOWN | IMFCameraConfigurationManager::Shutdown が呼び出された後に関数が呼び出されました。 |
解説(Remarks)
提供された既定値は、IMFCameraConfigurationManager::LoadDefaults の呼び出しでコレクションが読み込まれた際に提供された MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 値で指定されたカメラに割り当てられます。空のコレクションを保存すると、関連付けられたカメラの既存のコントロール既定値がすべてクリアされます。
IMFCameraConfigurationManager::Shutdown 関数は、カメラ構成マネージャーをシャットダウンします。
解説(Remarks)
Shutdown を呼び出した後、IMFCameraConfigurationManager::LoadDefaults または IMFCameraConfigurationManager::SaveDefaults を後続で呼び出すと、MF_E_SHUTDOWN エラーが返されます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IMFCameraConfigurationManager "{A624F617-4704-4206-8A6D-EBDA4A093985}"
#usecom global IMFCameraConfigurationManager IID_IMFCameraConfigurationManager "{}"
#comfunc global IMFCameraConfigurationManager_LoadDefaults 3 sptr,sptr
#comfunc global IMFCameraConfigurationManager_SaveDefaults 4 sptr
#comfunc global IMFCameraConfigurationManager_Shutdown 5
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。
; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。