Descobrir e selecionar as funcionalidades da câmera com perfis de câmera

Esse artigo discute como usar perfis de câmera para descobrir e gerenciar os recursos de diferentes dispositivos de captura de vídeo. Isso inclui tarefas como selecionar perfis com suporte a resoluções ou taxas de quadro específicos, perfis que dão suporte ao acesso simultâneo a várias câmeras e perfis compatíveis com HDR.

Observação

Este artigo se baseia em conceitos e códigos discutidos em Captura básica de fotos, áudio e vídeo com o MediaCapture, que descreve as etapas para implementar uma captura básica de fotos e vídeos. É recomendável que você se familiarize com o padrão de captura de mídia básica neste artigo antes de passar para cenários de captura mais avançados. O código neste artigo presume que seu aplicativo já tenha uma instância de MediaCapture inicializada corretamente.

 

Sobre perfis de câmera

As câmeras em diferentes dispositivos dão suporte a diferentes funcionalidades, incluindo o conjunto de resoluções de captura com suporte, a taxa de quadros para capturas de vídeo e se há suporte para capturas de taxa de quadros variáveis ou HDR. A estrutura de captura de mídia da Plataforma Universal do Windows (UWP) armazena esse conjunto de recursos em um MediaCaptureVideoProfileMediaDescription. Um perfil de câmera, representado por um objeto MediaCaptureVideoProfile, tem três coleções de descrições de mídia; uma para captura de fotos, uma para captura de vídeo e outra para visualização de vídeo.

Antes de inicializar o objeto MediaCapture, você pode consultar os dispositivos de captura no dispositivo atual para ver quais perfis têm suporte. Ao selecionar um perfil com suporte, você sabe que o dispositivo de captura dá suporte a todos os recursos nas descrições de mídia do perfil. Isso elimina a necessidade de uma abordagem de tentativa e erro para determinar quais combinações de recursos têm suporte em um dispositivo específico.

var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };

Os exemplos de código nesse artigo substituem essa inicialização mínima pela descoberta de perfis de câmera que dão suporte a vários recursos, que são usados para inicializar o dispositivo de captura de mídia.

Localizar um dispositivo de vídeo compatível com perfis de câmera

Antes de pesquisar perfis de câmera com suporte, você deve encontrar um dispositivo de captura compatível com o uso de perfis de câmera. O método auxiliar GetVideoProfileSupportedDeviceIdAsync definido no exemplo a seguir usa o método DeviceInformaion.FindAllAsync para recuperar uma lista de todos os dispositivos de captura de vídeo disponíveis. Ele percorre todos os dispositivos da lista, chamando o método estático, IsVideoProfileSupported, para cada dispositivo para ver se ele é compatível com perfis de vídeo. Além disso, a propriedade EnclosureLocation.Panel para cada dispositivo permite especificar se você deseja uma câmera na parte frontal ou traseira do dispositivo.

Se um dispositivo compatível com perfis de câmera for encontrado no painel especificado, o valor da ID, que contém a cadeia de caracteres de ID do dispositivo, será retornado.

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

Se a ID do dispositivo retornada do método auxiliar GetVideoProfileSupportedDeviceIdAsync for nulo ou uma cadeia de caracteres vazia, não haverá nenhum dispositivo no painel especificado que dê suporte a perfis de câmera. Nesse caso, você deve inicializar seu dispositivo de captura de mídia sem usar perfis.

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

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

Selecione um perfil com base na resolução e na taxa de quadros com suporte

Para selecionar um perfil com recursos específicos, como a capacidade de obter uma determinada resolução e taxa de quadros, você deve primeiro chamar o método auxiliar definido acima para obter a ID de um dispositivo de captura compatível com o uso de perfis de câmera.

Crie um novo objeto MediaCaptureInitializationSettings, passando a ID do dispositivo selecionado. Em seguida, chame o método estáticoMediaCapture.FindAllVideoProfiles para obter uma lista de todos os perfis de câmera compatíveis com o dispositivo.

Este exemplo usa um método de consulta Linq, incluído no usando System.Linq no namespace, para selecionar um perfil que contém um objeto SupportedRecordMediaDescription em que as propriedadesWidth, HeighteFrameRatecorrespondem aos valores solicitados. Se uma correspondência for encontrada, VideoProfile e RecordMediaDescription de MediaCaptureInitializationSettings serão definidos como os valores do tipo anônimo retornado da consulta Linq. Se nenhuma correspondência for encontrada, o perfil padrão será usado.


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

Depois de preencher o MediaCaptureInitializationSettings com o perfil de câmera desejado, basta chamarInitializeAsyncem seu objeto de captura de mídia para configurá-lo para o perfil desejado.

await _mediaCapture.InitializeAsync(mediaInitSettings);

Usar grupos de origem de quadro de mídia para obter perfis

A partir do Windows 10, versão 1803, você pode usar a classe MediaFrameSourceGroup para obter perfis de câmera com recursos específicos antes de inicializar o objeto MediaCapture. Os grupos de origem de quadros permitem que os fabricantes de dispositivos representem grupos de sensores ou capturem recursos como um único dispositivo virtual. Isso permite cenários de fotografia computacional, como o uso de câmeras de profundidade e cores juntos, mas também pode ser usado para selecionar perfis de câmera para cenários de captura simples. Para obter mais informações sobre como usar MediaFrameSourceGroup, consulte Processar quadros de mídia com MediaFrameReader.

O método de exemplo abaixo mostra como usar objetos MediaFrameSourceGroup para encontrar um perfil de câmera que dê suporte a um perfil de vídeo conhecido, como um que dá suporte a HDR ou sequência de fotos variáveis. Primeiro, chame MediaFrameSourceGroup.FindAllAsync para obter uma lista de todos os grupos de origem de quadros de mídia disponíveis no dispositivo atual. Execute um loop em cada grupo de origem e chame MediaCapture.FindKnownVideoProfiles para obter uma lista de todos os perfis de vídeo para o grupo de origem atual que dá suporte ao perfil especificado, nesse caso, HDR com foto WCG. Se um perfil que atende aos critérios for encontrado, crie um novo objeto MediaCaptureInitializationSettings e defina o VideoProfile como o perfil selecionado e o VideoDeviceId para a ´propriedade ID do grupo de origem do quadro de mídia atual. Portanto, por exemplo, você pode passar o valor KnownVideoProfile.HdrWithWcgVideo para esse método para obter configurações de captura de mídia compatíveis com vídeo HDR. Passe KnownVideoProfile.VariablePhotoSequence para obter configurações que dão suporte à sequência de fotos variável.

private async Task<MediaCaptureInitializationSettings> GetKnownVideoProfile(KnownVideoProfile knownVideoProfile)
{
    IReadOnlyList<MediaFrameSourceGroup> sourceGroups = await MediaFrameSourceGroup.FindAllAsync();
    MediaCaptureInitializationSettings settings = null;

    foreach (MediaFrameSourceGroup sg in sourceGroups)
    {
        // Find a device that support VariablePhotoSequence
        IReadOnlyList<MediaCaptureVideoProfile> profileList = MediaCapture.FindKnownVideoProfiles(
                                      sg.Id,
                                      knownVideoProfile); // e.g. KnownVideoProfile.HdrWithWcgVideo

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

    
}

Usar perfis conhecidos para encontrar um perfil que dê suporte a vídeo HDR (técnica herdada)

Observação

As APIs descritas nesta seção são preteridas a partir do Windows 10, versão 1803. Consulte a seção anterior, Usar grupos de origem de quadros de mídia para obter perfis.

A seleção de um perfil que dá suporte ao HDR começa como os outros cenários. Crie MediaCaptureInitializationSettings e uma cadeia de caracteres para conter a ID do dispositivo de captura. Adicione uma variável booliana que acompanhará se há suporte para vídeo HDR.

MediaCaptureInitializationSettings mediaInitSettings = new MediaCaptureInitializationSettings();
string videoDeviceId = string.Empty;
bool HdrVideoSupported = false;

Use o método auxiliar GetVideoProfileSupportedDeviceIdAsync definido acima para obter a ID do dispositivo para um dispositivo de captura que dê suporte a perfis de câmera.

// Select the first video capture device found on the back of the device
videoDeviceId = await GetVideoProfileSupportedDeviceIdAsync(Windows.Devices.Enumeration.Panel.Back);

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

O método estático MediaCapture.FindKnownVideoProfiles retorna os perfis de câmera compatíveis com o dispositivo especificado categorizado pelo valor KnownVideoProfile especificado. Para esse cenário, o valor VideoRecording é especificado para limitar os perfis de câmera retornados aos que dão suporte à gravação de vídeo.

Execute um loop pela lista retornada de perfis de câmera. Para cada perfil de câmera, faça um loop por cada VideoProfileMediaDescription na verificação de perfil para ver se a propriedade IsHdrVideoSupported é verdadeira. Depois que uma descrição de mídia adequada for encontrada, saia do loop e atribua os objetos de perfil e descrição ao objeto MediaCaptureInitializationSettings.

IReadOnlyList<MediaCaptureVideoProfile> profiles =
    MediaCapture.FindKnownVideoProfiles(videoDeviceId, KnownVideoProfile.VideoRecording);

// Walk through available profiles, look for first profile with HDR supported Video Profile
foreach (MediaCaptureVideoProfile profile in profiles)
{
    IReadOnlyList<MediaCaptureVideoProfileMediaDescription> recordMediaDescription =
        profile.SupportedRecordMediaDescription;
    foreach (MediaCaptureVideoProfileMediaDescription videoProfileMediaDescription in recordMediaDescription)
    {
        if (videoProfileMediaDescription.IsHdrVideoSupported)
        {
            // We've located the profile and description for HDR Video, set profile and flag
            mediaInitSettings.VideoProfile = profile;
            mediaInitSettings.RecordMediaDescription = videoProfileMediaDescription;
            HdrVideoSupported = true;
            break;
        }
    }

    if (HdrVideoSupported)
    {
        // Profile with HDR support found. Stop looking.
        break;
    }
}

Determinar se um dispositivo é compatível com a captura simultânea de fotos e vídeos

Muitos dispositivos são compatíveis com a captura de fotos e vídeos simultaneamente. Para determinar se um dispositivo é compatível com isso, chame MediaCapture.FindAllVideoProfiles para obter todos os perfis de câmera compatíveis com o dispositivo. Use uma consulta de link para localizar um perfil que tenha pelo menos uma entrada para SupportedPhotoMediaDescription e SupportedRecordMediaDescription, o que significa que o perfil dá suporte à captura simultânea.

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

Você pode refinar essa consulta para procurar perfis que dão suporte a resoluções específicas ou outros recursos, além do registro simultâneo de vídeo. Você também pode usar o MediaCapture.FindKnownVideoProfiles e especificar o valor BalancedVideoAndPhoto para recuperar perfis que dão suporte à captura simultânea, mas consultar todos os perfis fornecerá resultados mais completos.