Partilhar via


Configurar o formato de saída de vídeo

[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Audio/Video Capture in Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

Observação

A funcionalidade descrita neste tópico foi preterida. Para configurar o formato de saída de um dispositivo de captura, um aplicativo deve usar a estrutura AM_MEDIA_TYPE retornada por IAMStreamConfig::GetFormat no parâmetro pmt .

 

Um dispositivo de captura pode dar suporte a um intervalo de formatos de saída. Por exemplo, um dispositivo pode dar suporte a RGB de 16 bits, RGB de 32 bits e YUYV. Em cada um desses formatos, o dispositivo pode dar suporte a um intervalo de tamanhos de quadro.

Em um dispositivo WDM, a interface IAMStreamConfig é usada para relatar quais formatos o dispositivo dá suporte e para definir o formato. (Para dispositivos VFW herdados, use a caixa de diálogo VFW de Formato de Vídeo, conforme descrito em Exibir Caixas de Diálogo de Captura VFW.) A interface IAMStreamConfig é exposta no pin de captura do filtro de captura, no pino de visualização ou em ambos. Use o método ICaptureGraphBuilder2::FindInterface para obter o ponteiro da interface:

IAMStreamConfig *pConfig = NULL;
hr = pBuild->FindInterface(
    &PIN_CATEGORY_PREVIEW, // Preview pin.
    0,    // Any media type.
    pCap, // Pointer to the capture filter.
    IID_IAMStreamConfig, (void**)&pConfig);

O dispositivo tem uma lista de tipos de mídia compatíveis. Para cada tipo de mídia, o dispositivo também fornece um conjunto de recursos. Isso inclui o intervalo de tamanhos de quadro que estão disponíveis para esse formato, o quão bem o dispositivo pode esticar ou reduzir a imagem e o intervalo de taxas de quadros.

Para obter o número de tipos de mídia, chame o método IAMStreamConfig::GetNumberOfCapabilities . O método retorna dois valores:

  • O número de tipos de mídia.
  • O tamanho da estrutura que contém as informações de funcionalidades.

O valor de tamanho é necessário porque a interface IAMStreamConfig é usada para áudio e vídeo (e pode ser estendida para outros tipos de mídia). Para vídeo, os recursos são descritos usando a estrutura VIDEO_STREAM_CONFIG_CAPS , enquanto o áudio usa a estrutura AUDIO_STREAM_CONFIG_CAPS .

Para enumerar os tipos de mídia, chame o método IAMStreamConfig::GetStreamCaps com um índice baseado em zero. O método GetStreamCaps retorna um tipo de mídia e a estrutura de funcionalidade correspondente:

int iCount = 0, iSize = 0;
hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize);

// Check the size to make sure we pass in the correct structure.
if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
{
    // Use the video capabilities structure.

    for (int iFormat = 0; iFormat < iCount; iFormat++)
    {
        VIDEO_STREAM_CONFIG_CAPS scc;
        AM_MEDIA_TYPE *pmtConfig;
        hr = pConfig->GetStreamCaps(iFormat, &pmtConfig, (BYTE*)&scc);
        if (SUCCEEDED(hr))
        {
            /* Examine the format, and possibly use it. */

            // Delete the media type when you are done.
            DeleteMediaType(pmtConfig);
        }
}

Observe como as estruturas são alocadas para o método GetStreamCaps . O método aloca a estrutura de tipo de mídia, enquanto o chamador aloca a estrutura de recursos. Coagir a estrutura de recursos para um ponteiro de matriz de bytes. Depois de terminar o tipo de mídia, exclua a estrutura AM_MEDIA_TYPE , juntamente com o bloco de formato do tipo de mídia.

Você pode configurar o dispositivo para usar um formato retornado no método GetStreamCaps . Basta chamar IAMStreamConfig::SetFormat com o tipo de mídia:

hr = pConfig->SetFormat(pmtConfig);

Se o pino não estiver conectado, ele tentará usar esse formato quando ele se conectar. Se o pino já estiver conectado, ele tentará se reconectar usando o novo formato. Em ambos os casos, é possível que o filtro downstream rejeite o formato.

Você também pode modificar o tipo de mídia antes de passá-lo para o método SetFormat . É aí que entra a estrutura VIDEO_STREAM_CONFIG_CAPS . Ele descreve todas as maneiras válidas de alterar o tipo de mídia. Para usar essas informações, você deve entender os detalhes desse tipo de mídia específico.

Por exemplo, suponha que GetStreamCaps retorne um formato RGB de 24 bits, com um tamanho de quadro de 320 x 240 pixels. Você pode obter essas informações examinando o tipo principal, o subtipo e o bloco de formato do tipo de mídia:

if ((pmtConfig.majortype == MEDIATYPE_Video) &&
    (pmtConfig.subtype == MEDIASUBTYPE_RGB24) &&
    (pmtConfig.formattype == FORMAT_VideoInfo) &&
    (pmtConfig.cbFormat >= sizeof (VIDEOINFOHEADER)) &&
    (pmtConfig.pbFormat != NULL))
{
    VIDEOINFOHEADER *pVih = (VIDEOINFOHEADER*)pmtConfig.pbFormat;
    // pVih contains the detailed format information.
    LONG lWidth = pVih->bmiHeader.biWidth;
    LONG lHeight = pVih->bmiHeader.biHeight;
}

A estrutura VIDEO_STREAM_CONFIG_CAPS fornece a largura e a altura mínimas e máximas que podem ser usadas para esse tipo de mídia. Ele também fornece o tamanho da "etapa", que define os incrementos pelos quais você pode ajustar a largura ou a altura. Por exemplo, o dispositivo pode retornar o seguinte:

  • MinOutputSize: 160 x 120
  • MaxOutputSize: 320 x 240
  • OutputGranularityX: 8 pixels (tamanho da etapa horizontal)
  • OutputGranularityY: 8 pixels (tamanho da etapa vertical)

Considerando esses números, você pode definir a largura como qualquer coisa no intervalo (160, 168, 176, ... 304, 312, 320) e a altura para qualquer coisa no intervalo (120, 128, 136, ... 104, 112, 120). O diagrama a seguir ilustra esse processo.

tamanhos de formato de vídeo

Para definir um novo tamanho de quadro, modifique diretamente a estrutura AM_MEDIA_TYPE retornada em GetStreamCaps:

pVih->bmiHeader.biWidth = 160;
pVih->bmiHeader.biHeight = 120;
pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader);

Em seguida, passe o tipo de mídia para o método SetFormat , conforme descrito anteriormente.

Os membros MinFrameInterval e MaxFrameInterval de VIDEO_STREAM_CONFIG_CAPS são o comprimento mínimo e máximo de cada quadro de vídeo, que você pode traduzir em taxas de quadros da seguinte maneira:

frames per second = 10,000,000 / frame duration

Para solicitar uma taxa de quadros específica, modifique o valor de AvgTimePerFrame na estrutura VIDEOINFOHEADER ou VIDEOINFOHEADER2 no tipo de mídia. O dispositivo pode não dar suporte a todos os valores possíveis entre o mínimo e o máximo, portanto, o driver usará o valor mais próximo que puder. Para ver qual valor o driver realmente usou, chame IAMStreamConfig::GetFormat depois de chamar SetFormat.

Alguns drivers podem relatar MAXLONGLONG (0x7FFFFFFFFFFFFFFF) para o valor de MaxFrameInterval, o que, na verdade, significa que não há duração máxima. No entanto, talvez você queira impor uma taxa mínima de quadros em seu aplicativo, como 1 fps.

Sobre tipos de mídia

Configurando um dispositivo de captura de vídeo