Negociando tipos de mídia

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

Quando o Gerenciador do Gráfico de Filtro chama o método IPin::Connect , ele tem várias opções para especificar um tipo de mídia:

  • Tipo completo: Se o tipo de mídia for totalmente especificado, os pinos tentarão se conectar com esse tipo. Se não puderem, a tentativa de conexão falhará.
  • Tipo de mídia parcial: Um tipo de mídia será parcial se o tipo principal, subtipo ou tipo de formato for GUID_NULL. O valor GUID_NULL atua como um "curinga", indicando que qualquer valor é aceitável. Os pinos negociam um tipo consistente com o tipo parcial.
  • Nenhum tipo de mídia: Se o Gerenciador de Grafo de Filtro passar um ponteiro NULL , os pinos poderão concordar com qualquer tipo de mídia aceitável para ambos os pinos.

Se os pinos se conectarem, a conexão sempre terá um tipo de mídia completo. A finalidade do tipo de mídia fornecido pelo Gerenciador de Grafo de Filtro é limitar os tipos de conexão possíveis.

Durante o processo de negociação, o pin de saída propõe um tipo de mídia chamando o método IPin::ReceiveConnection do pino de entrada. O pin de entrada pode aceitar ou rejeitar o tipo proposto. Esse processo se repete até que o pin de entrada aceite um tipo ou o pino de saída seja executado fora dos tipos e a conexão falhe.

A forma como um pino de saída seleciona os tipos de mídia a serem propor depende da implementação. Nas classes base do DirectShow, o pino de saída chama IPin::EnumMediaTypes no pino de entrada. Esse método retorna um enumerador que enumera os tipos de mídia preferenciais do pino de entrada. Caso contrário, o pino de saída enumera seus próprios tipos preferenciais.

Trabalhando com tipos de mídia

Em qualquer função que receba um parâmetro AM_MEDIA_TYPE , sempre valide os valores de cbFormat e formattype antes de desreferenciar o membro pbFormat . O código a seguir está incorreto:

if (pmt->formattype == FORMAT_VideoInfo)
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Wrong!
}

O código a seguir está correto:

if ((pmt->formattype == FORMAT_VideoInfo) && 
    (pmt->cbFormat > sizeof(VIDEOINFOHEADER) &&
    (pbFormat != NULL))
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Now you can dereference pVIH.
}