Bagikan melalui


Antarmuka IMFCameraConfigurationManager (mfidl.h)

Warisan

Antarmuka IMFCameraConfigurationManager mewarisi dari antarmuka IUnknown.

Metode

Antarmuka IMFCameraConfigurationManager memiliki metode ini.

 
IMFCameraConfigurationManager::LoadDefaults

Memuat default kontrol kamera untuk sumber pengambilan yang ditentukan.
IMFCameraConfigurationManager::SaveDefaults

Menyimpan kumpulan nilai default kontrol kamera yang disediakan.
IMFCameraConfigurationManager::Shutdown

Fungsi IMFCameraConfigurationManager::Shutdown mematikan manajer konfigurasi kamera.

Keterangan

Instans antarmuka IMFCameraConfigurationManager dapat dibuat dengan memanggil fungsi COM CoCreateInstance, dan meneruskan CLSID_CameraConfigurationManager sebagai parameter CLSID.

Contoh

Contoh berikut menunjukkan penggunaan IMFCameraConfigurationManager dan API terkait untuk mengambil konfigurasi default kontrol kamera koreksi tatapan mata.

#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;
}

Contoh berikut menunjukkan penggunaan IMFCameraConfigurationManager dan API terkait untuk mengatur nilai default untuk kontrol paparan warisan. Skenario penggunaan umum untuk implementasi ini memungkinkan pengguna untuk mengatur nilai kontrol default dalam aplikasi pendamping kamera yang diimplementasikan IHV daripada perlu meluncurkan halaman pengaturan kamera Windows umum.

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;
}

Contoh berikut mengilustrasikan skenario lain di mana IHV menerapkan aplikasi konfigurasi mereka sendiri yang memberi pengguna UX untuk mengonfigurasi kontrol kustom. Dalam skenario ini, aplikasi IHV telah menemukan kamera menghadap depan (FFC) yang mendukung kontrol kustom dan IHV memilih agar kamera selalu default ke profil KSCAMERAPROFILE_VideoConferencing kecuali aplikasi secara eksplisit mengambil alih perilaku ini dengan memilih profil yang berbeda. Karena kontrol kustom memiliki kontrol dan skema payload data yang tidak diketahui oleh Windows dan hanya diketahui oleh IHV/OEM dan/atau ISV yang memperoleh spesifikasi untuk kontrol kustom, sampel di bawah ini tidak menunjukkan validasi kontrol atau payload data.

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;
}

Persyaratan

   
Header mfidl.h