Sobre tipos de mídia (DirectShow)

[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.]

Como o DirectShow é modular, ele requer uma maneira de descrever o formato dos dados em cada ponto no grafo de filtro. Por exemplo, considere a reprodução de AVI. Os dados entram no grafo como um fluxo de partes RIFF. Eles são analisados em fluxos de áudio e vídeo. O fluxo de vídeo consiste em quadros de vídeo, que provavelmente são compactados. Após a decodificação, o fluxo de vídeo é uma série de bitmaps descompactados. O fluxo de áudio passa por um processo semelhante.

Tipos de mídia: como o DirectShow representa formatos

O tipo de mídia é uma maneira universal e extensível de descrever formatos de mídia digital. Quando dois filtros se conectam, eles concordam com um tipo de mídia. O tipo de mídia identifica que tipo de dados o filtro upstream fornecerá ao filtro downstream e ao layout físico dos dados. Se dois filtros não puderem concordar com um tipo de mídia, eles não se conectarão.

Para alguns aplicativos, você nunca precisará se preocupar com tipos de mídia. Na reprodução de arquivo, por exemplo, o DirectShow manipula todos os detalhes. Outros tipos de aplicativos podem precisar trabalhar diretamente com tipos de mídia.

Os tipos de mídia são definidos usando a estrutura AM_MEDIA_TYPE . Essa estrutura contém as seguintes informações:

  • Tipo principal: o tipo principal é um GUID que define a categoria geral dos dados. Os principais tipos incluem vídeo, áudio, fluxo de bytes não preparados, dados MIDI e assim por diante.

  • Subtipo: o subtipo é outro GUID, que define ainda mais o formato. Por exemplo, dentro do tipo principal de vídeo, há subtipos para RGB-24, RGB-32, UYVY e assim por diante. No áudio, há áudio PCM, conteúdo MPEG-1 e outros. O subtipo fornece mais informações do que o tipo principal, mas não define tudo sobre o formato. Por exemplo, os subtipos de vídeo não definem o tamanho da imagem ou a taxa de quadros. Eles são definidos pelo bloco de formato, descrito abaixo.

  • Bloco de formato: o bloco de formato é um bloco de dados que descreve o formato em detalhes. O bloco de formato é alocado separadamente da estrutura AM_MEDIA_TYPE . O membro pbFormat da estrutura AM_MEDIA_TYPE aponta para o bloco de formato.

    O membro pbFormat é digitado void* porque o layout do bloco de formato é alterado dependendo do tipo de mídia. Por exemplo, o áudio PCM usa uma estrutura WAVEFORMATEX . O vídeo usa várias estruturas, incluindo VIDEOINFOHEADER e VIDEOINFOHEADER2. O membro formattype da estrutura AM_MEDIA_TYPE é um GUID que especifica qual estrutura está contida no bloco de formato. Cada estrutura de formato recebe um GUID. O membro cbFormat especifica o tamanho do bloco de formato. Sempre marcar esses valores antes de desreferenciar o ponteiro pbFormat.

Se o bloco de formato for preenchido, o tipo principal e o subtipo conterão informações redundantes. No entanto, o tipo principal e o subtipo fornecem uma maneira conveniente de identificar formatos sem um bloco de formato completo. Por exemplo, você pode especificar um formato RGB genérico de 24 bits (MEDIASUBTYPE_RGB24), sem saber todas as informações exigidas pela estrutura VIDEOINFOHEADER , como tamanho da imagem e taxa de quadros.

Por exemplo, um filtro pode usar o seguinte código para marcar um tipo de mídia:

HRESULT CheckMediaType(AM_MEDIA_TYPE *pmt)
{
    if (pmt == NULL) return E_POINTER;

    // Check the major type. We're looking for video.
    if (pmt->majortype != MEDIATYPE_Video)
    {
        return VFW_E_INVALIDMEDIATYPE;
    }

    // Check the subtype. We're looking for 24-bit RGB.
    if (pmt->subtype != MEDIASUBTYPE_RGB24)
    {
        return VFW_E_INVALIDMEDIATYPE;
    }

    // Check the format type and the size of the format block.
    if ((pmt->formattype == FORMAT_VideoInfo) &&
         (pmt->cbFormat >= sizeof(VIDEOINFOHEADER) &&
         (pmt->pbFormat != NULL))
    {
        // Now it's safe to coerce the format block pointer to the
        // correct structure, as defined by the formattype GUID.
        VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    
        // Examine pVIH (not shown). If it looks OK, return S_OK.
        return S_OK;
    }

    return VFW_E_INVALIDMEDIATYPE;
}

A estrutura AM_MEDIA_TYPE também contém alguns campos opcionais. Eles podem ser usados para fornecer informações adicionais, mas os filtros não são necessários para usá-los:

  • lSampleSize. Se esse campo for diferente de zero, ele definirá o tamanho de cada amostra. Se for zero, indica que o tamanho da amostra pode mudar de amostra para amostra.
  • bFixedSizeSamples. Se esse sinalizador booliano for TRUE, isso significará que o valor em lSampleSize é válido. Caso contrário, você deve ignorar lSampleSize.
  • bTemporalCompression. Se esse sinalizador booliano for FALSE, isso significa que todos os quadros são quadros-chave.

O grafo de filtro e seus componentes