Discover and select camera capabilities with camera profiles in a WinUI 3 app

This article shows how to use camera profiles to discover and manage the capabilities of different video capture devices. This includes tasks such as selecting profiles that support specific resolutions or frame rates, profiles that support simultaneous access to multiple cameras, and profiles that support HDR.

About camera profiles

Cameras on different devices support different capabilities including the set of supported capture resolutions, frame rate for video captures, and whether HDR or variable frame rate captures are supported. A set of supported capabilities is defined in a MediaCaptureVideoProfileMediaDescription object. A camera profile, represented by a MediaCaptureVideoProfile object, has three collections of media descriptions; one for photo capture, one for video capture, and another for video preview.

Before initializing your MediaCapture object, you can query the capture devices on the current device to see what profiles are supported. When you select a supported profile, you know that the capture device supports all of the capabilities in the profile's media descriptions. This eliminates the need for a trial and error approach to determining which combinations of capabilities are supported on a particular device.

Find a camera that supports camera profiles

To use camera profiles, you must first check for a camera device that supports the use of camera profiles. The example below shows how to use the DeviceInformation.FindAllAsync method to retrieve a list of all available video capture devices on either the front or back panel of the current device. It loops through all of the devices in the list, calling the static method, IsVideoProfileSupported, for each device to see if it supports video profiles.

If a device that supports camera profiles is found on the specified panel, the Id value, containing the device's ID string, is returned.

public async Task<string> GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel panel)
{
    string deviceId = string.Empty;

    // Finds all video capture devices
    DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);

    foreach (var device in devices)
    {
        // Check if the device on the requested panel supports Video Profile
        if (MediaCapture.IsVideoProfileSupported(device.Id) && device.EnclosureLocation.Panel == panel)
        {
            // We've located a device that supports Video Profiles on expected panel
            deviceId = device.Id;
            break;
        }
    }

    return deviceId;
}

If the device ID returned from the GetVideoProfileSupportedDeviceIdAsync helper method is null or an empty string, there is no device on the specified panel that supports camera profiles. In this case, you should initialize your media capture device without using profiles.

string videoDeviceId = await GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel.Back);

if (string.IsNullOrEmpty(videoDeviceId))
{
    // No devices on the specified panel support video profiles. .
    return;
}

Select a profile based on supported resolution and frame rate

To select a profile with particular capabilities, such as with the ability to achieve a particular resolution and frame rate, use the method shown previously in this article to get the ID of a capture device that supports using camera profiles.

Create a new MediaCaptureInitializationSettings object, passing in the selected device ID. Call the static method MediaCapture.FindAllVideoProfiles to get a list of all camera profiles supported by the device.

This example selects a profile that contains a SupportedRecordMediaDescription object where the Width, Height, and FrameRate properties match the requested values. If a match is found, VideoProfile and RecordMediaDescription of the MediaCaptureInitializationSettings are set to the values returned from the query. If no match is found, the default profile is used.

var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = videoDeviceId };

IReadOnlyList<MediaCaptureVideoProfile> profiles = MediaCapture.FindAllVideoProfiles(videoDeviceId);

var match = (from profile in profiles
             from desc in profile.SupportedRecordMediaDescription
             where desc.Width == 640 && desc.Height == 480 && Math.Round(desc.FrameRate) == 30
             select new { profile, desc }).FirstOrDefault();

if (match != null)
{
    mediaInitSettings.VideoProfile = match.profile;
    mediaInitSettings.RecordMediaDescription = match.desc;
}
else
{
    // Could not locate a WVGA 30FPS profile, use default video recording profile
    mediaInitSettings.VideoProfile = profiles[0];
}

After you populate the MediaCaptureInitializationSettings with your desired camera profile, you simply call InitializeAsync on your media capture object to configure it to the desired profile.

await m_mediaCapture.InitializeAsync(mediaInitSettings);

Select devices with KnownVideoProfile

You can use the MediaFrameSourceGroup class to get camera profiles with specific capabilities before initializing the MediaCapture object. Frame source groups allow device manufacturers to represent groups of sensors or capture capabilities as a single virtual device. This enables computational photography scenarios such as using depth and color cameras together, but can also be used to select camera profiles for simple capture scenarios. For more information on using MediaFrameSourceGroup, see Process media frames with MediaFrameReader.

The example below shows how to use MediaFrameSourceGroup to find a camera profile that supports that supports the desired scenario. Call MediaFrameSourceGroup.FindAllAsync to get a list of all media frame source groups available on the current device. Loop through each source group and call MediaCapture.FindKnownVideoProfiles to get a list of all of the video profiles for the current source group that support the specified KnownCameraProfile, in this example the value KnownVideoProfile.HighQualityPhoto is used. Other values include support for HDR and variable photo sequences, for example. If a profile that meets the requested criteria is found, create a new MediaCaptureInitializationSettings object and set the VideoProfile to the select profile and the VideoDeviceId to the Id property of the current media frame source group. Use this MediaCaptureInitializationSettings object to initialize the MediaCapture object.

IReadOnlyList<MediaFrameSourceGroup> sourceGroups = await MediaFrameSourceGroup.FindAllAsync();
MediaCaptureInitializationSettings settings = null;

foreach (MediaFrameSourceGroup sg in sourceGroups)
{

    IReadOnlyList<MediaCaptureVideoProfile> profileList = MediaCapture.FindKnownVideoProfiles(
                                  sg.Id,
                                  KnownVideoProfile.HighQualityPhoto);

    if (profileList.Count > 0)
    {
        settings = new MediaCaptureInitializationSettings();
        settings.VideoProfile = profileList[0];
        settings.VideoDeviceId = sg.Id;
        break;
    }
}

Determine if a device supports simultaneous photo and video capture

Many devices support capturing photos and video simultaneously. To determine if a capture device supports this, call MediaCapture.FindAllVideoProfiles to get all of the camera profiles supported by the device. Use a link query to find a profile that has at least one entry for both SupportedPhotoMediaDescription and SupportedRecordMediaDescription which means that the profile supports simultaneous capture.


bool simultaneousPhotoAndVideoSupported = false;

IReadOnlyList<MediaCaptureVideoProfile> profiles = MediaCapture.FindAllVideoProfiles(videoDeviceId);

var match = (from profile in profiles
             where profile.SupportedPhotoMediaDescription.Any() &&
             profile.SupportedRecordMediaDescription.Any()
             select profile).FirstOrDefault();

if (match != null)
{
    // Simultaneous photo and video supported
    simultaneousPhotoAndVideoSupported = true;
}
else
{
    // Simultaneous photo and video not supported
    simultaneousPhotoAndVideoSupported = false;
}

You can refine this query to look for profiles that support specific resolutions or other capabilities in addition to simultaneous video record. You can also use the MediaCapture.FindKnownVideoProfiles and specify the BalancedVideoAndPhoto value to retrieve profiles that support simultaneous capture, but querying all profiles will provide more complete results.