Share via


Interfaz IMFCameraConfigurationManager (mfidl.h)

Herencia

La interfaz IMFCameraConfigurationManager hereda de la interfaz IUnknown.

Métodos

La interfaz IMFCameraConfigurationManager tiene estos métodos.

 
IMFCameraConfigurationManager::LoadDefaults

Carga los valores predeterminados del control de cámara para el origen de captura especificado.
IMFCameraConfigurationManager::SaveDefaults

Guarda la colección proporcionada de valores predeterminados del control de cámara.
IMFCameraConfigurationManager::Shutdown

La función IMFCameraConfigurationManager::Shutdown apaga el administrador de configuración de la cámara.

Comentarios

Se puede crear una instancia de la interfaz IMFCameraConfigurationManager llamando a la función COM CoCreateInstance y pasando el CLSID_CameraConfigurationManager como parámetro CLSID.

Ejemplos

En el ejemplo siguiente se muestra el uso de IMFCameraConfigurationManager y las API relacionadas para recuperar la configuración predeterminada del control de la cámara de corrección de mirada ocular.

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

En el ejemplo siguiente se muestra el uso de IMFCameraConfigurationManager y las API relacionadas para establecer el valor predeterminado para el control de exposición heredado. Un escenario de uso típico para esta implementación que permite al usuario establecer valores de control predeterminados en una aplicación complementaria de cámara implementada por IHV en lugar de tener que iniciar la página general de configuración de la cámara de Windows.

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

En el ejemplo siguiente se muestra otro escenario en el que los IHD implementan sus propias aplicaciones de configuración que proporcionan al usuario una experiencia de usuario para configurar controles personalizados. En este escenario, la aplicación IHV ha encontrado la cámara frontal (FFC) que admite un control personalizado y el IHV decidió tener la cámara en cuestión siempre de forma predeterminada con el perfil de KSCAMERAPROFILE_VideoConferencing, a menos que la aplicación invalide explícitamente este comportamiento seleccionando otro perfil. Dado que los controles personalizados tienen esquemas de carga de datos y control que son desconocidos para Windows y solo se conocen con los IHV/OEMs o ISV que obtuvieron las especificaciones para el control personalizado, el ejemplo siguiente no muestra ninguna validación del control o carga de datos.

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

Requisitos

   
Encabezado mfidl.h