Como definir o formato de captura de vídeo

Um dispositivo de captura de vídeo pode dar suporte a vários formatos de captura. Os formatos normalmente diferem por tipo de compactação, espaço de cor (YUV ou RGB), tamanho do quadro ou taxa de quadros.

A lista de formatos com suporte está contida no descritor de apresentação. Para obter mais informações, consulte Descritores de apresentação.

Para enumerar os formatos com suporte:

  1. Crie a fonte de mídia para o dispositivo de captura. Consulte Enumerando dispositivos de captura de vídeo.
  2. Chame IMFMediaSource::CreatePresentationDescriptor na fonte de mídia para obter o descritor de apresentação.
  3. Chame IMFPresentationDescriptor::GetStreamDescriptorByIndex para obter o descritor de fluxo para o fluxo de vídeo.
  4. Chame IMFStreamDescriptor::GetMediaTypeHandler no descritor de fluxo.
  5. Chame IMFMediaTypeHandler::GetMediaTypeCount para obter o número de formatos com suporte.
  6. Em um loop, chame IMFMediaTypeHandler::GetMediaTypeByIndex para obter cada formato. O formato é representado por um tipo de mídia. Para obter mais informações, consulte Tipos de mídia de vídeo.

O exemplo a seguir enumera os formatos de captura de um dispositivo:

HRESULT EnumerateCaptureFormats(IMFMediaSource *pSource)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    DWORD cTypes = 0;
    hr = pHandler->GetMediaTypeCount(&cTypes);
    if (FAILED(hr))
    {
        goto done;
    }

    for (DWORD i = 0; i < cTypes; i++)
    {
        hr = pHandler->GetMediaTypeByIndex(i, &pType);
        if (FAILED(hr))
        {
            goto done;
        }

        LogMediaType(pType);
        OutputDebugString(L"\n");

        SafeRelease(&pType);
    }

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

A LogMediaType função usada neste exemplo está listada no tópico Código de Depuração de Tipo de Mídia.

Para definir o formato de captura:

  1. Obtenha um ponteiro para a interface IMFMediaTypeHandler , conforme mostrado no exemplo anterior.
  2. Chame IMFMediaTypeHandler::GetMediaTypeByIndex para obter o formato desejado, especificado pelo índice.
  3. Chame IMFMediaTypeHandler::SetCurrentMediaType para definir o formato.

Se você não definir o formato de captura, o dispositivo usará seu formato padrão.

O exemplo a seguir define o formato de captura:

HRESULT SetDeviceFormat(IMFMediaSource *pSource, DWORD dwFormatIndex)
{
    IMFPresentationDescriptor *pPD = NULL;
    IMFStreamDescriptor *pSD = NULL;
    IMFMediaTypeHandler *pHandler = NULL;
    IMFMediaType *pType = NULL;

    HRESULT hr = pSource->CreatePresentationDescriptor(&pPD);
    if (FAILED(hr))
    {
        goto done;
    }

    BOOL fSelected;
    hr = pPD->GetStreamDescriptorByIndex(0, &fSelected, &pSD);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pSD->GetMediaTypeHandler(&pHandler);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->GetMediaTypeByIndex(dwFormatIndex, &pType);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pHandler->SetCurrentMediaType(pType);

done:
    SafeRelease(&pPD);
    SafeRelease(&pSD);
    SafeRelease(&pHandler);
    SafeRelease(&pType);
    return hr;
}

A ordem na qual os formatos são retornados depende do dispositivo. Normalmente, eles são agrupados primeiro por tipo de compactação ou espaço de cor; e, em seguida, do menor tamanho de quadro para o maior tamanho de quadro dentro de cada grupo.

A taxa de quadros é tratada ligeiramente diferente dos outros atributos de formato. Para obter mais informações, consulte Como definir a taxa de quadros de captura de vídeo.

Observação

Em alguns dispositivos, a lista de formatos conterá uma entrada duplicada para cada formato. Por exemplo, se o dispositivo der suporte a 15 formatos de captura distintos, a lista conterá 30 entradas. Dentro de cada par, um dos tipos de mídia terá o atributo MF_MT_AM_FORMAT_TYPE igual a FORMAT_VideoInfo e o outro terá MF_MT_AM_FORMAT_TYPE igual a FORMAT_VideoInfo2. (Esses dois valores são definidos no arquivo de cabeçalho uuids.h.) O segundo tipo também pode conter informações de cor adicionais (Informações de Cor Estendidas) ou mostrar um valor diferente para interlacing (MF_MT_INTERLACE_MODE). Esses tipos duplicados existem para dar suporte a aplicativos DirectShow mais antigos. Em um aplicativo do Media Foundation, você deve ignorar o tipo de FORMAT_VideoInfo sempre que um tipo de FORMAT_VideoInfo2 duplicado estiver listado.

 

Captura de vídeo