Partager via


Interface IMFCameraConfigurationManager (mfidl.h)

Héritage

L’interface IMFCameraConfigurationManager hérite de l’interface IUnknown.

Méthodes

L’interface IMFCameraConfigurationManager contient ces méthodes.

 
IMFCameraConfigurationManager::LoadDefaults

Charge les valeurs par défaut du contrôle de la caméra pour la source de capture spécifiée.
IMFCameraConfigurationManager::SaveDefaults

Enregistre la collection fournie de valeurs par défaut de contrôle de l’appareil photo.
IMFCameraConfigurationManager::Shutdown

La fonction IMFCameraConfigurationManager::Shutdown arrête le gestionnaire de configuration de caméra.

Notes

Une instance de l’interface IMFCameraConfigurationManager peut être créée en appelant la fonction COM CoCreateInstance et en passant le CLSID_CameraConfigurationManager comme paramètre CLSID.

Exemples

L’exemple suivant illustre l’utilisation d’IMFCameraConfigurationManager et des API associées pour récupérer la configuration par défaut du contrôle de la caméra de correction du regard.

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

L’exemple suivant montre comment utiliser IMFCameraConfigurationManager et les API associées pour définir la valeur par défaut du contrôle d’exposition hérité. Scénario d’utilisation classique pour cette implémentation qui permet à l’utilisateur de définir des valeurs de contrôle par défaut dans une application complémentaire de caméra implémentée par IHV plutôt que de devoir lancer la page générale des paramètres de l’appareil photo 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;
}

L’exemple suivant illustre un autre scénario où les IHVs implémentent leurs propres applications de configuration fournissant à l’utilisateur une expérience utilisateur pour configurer des contrôles personnalisés. Dans ce scénario, l’application IHV a trouvé la caméra frontale (FFC) qui prend en charge un contrôle personnalisé et l’IHV a choisi d’avoir la caméra en question toujours par défaut au profil KSCAMERAPROFILE_VideoConferencing, sauf si l’application remplace explicitement ce comportement en sélectionnant un autre profil. Étant donné que les contrôles personnalisés ont des schémas de charge utile de contrôle et de données inconnus de Windows et connus uniquement des IHV/OEM et/ou éditeurs de logiciels indépendants qui ont obtenu les spécifications du contrôle personnalisé, l’exemple ci-dessous n’affiche aucune validation de la charge utile du contrôle ou des données.

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

Spécifications

   
En-tête mfidl.h