Negociando alocadores

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na 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 Captura de Áudio/Vídeo no 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 dois pinos se conectam, eles precisam de um mecanismo para trocar dados de mídia. Esse mecanismo é chamado de transporte. Em geral, a arquitetura do DirectShow é neutra em relação aos transportes. Dois filtros podem concordar em se conectar usando qualquer transporte que ambos dão suporte.

O transporte mais comum é o transporte de memória local, no qual os dados de mídia residem em main memória. Existem dois tipos de transporte de memória local, o modelo de push e o modelo de pull. No modelo de push, o filtro de origem envia dados por push para o filtro downstream, usando a interface IMemInputPin no pin de entrada do filtro downstream. No modelo de pull, o filtro downstream solicita dados do filtro de origem, usando a interface IAsyncReader no pino de saída do filtro de origem. Para obter mais informações sobre esses dois modelos de fluxo de dados, consulte Fluxo de Dados no Grafo de Filtro.

No transporte de memória local, o objeto responsável por alocar buffers de memória é chamado de alocador. Um alocador dá suporte à interface IMemAllocator . Ambos os pinos compartilham um único alocador. Qualquer um dos pinos pode fornecer um alocador, mas o pino de saída seleciona qual alocador usar.

O pino de saída também define as propriedades do alocador, que determinam quantos buffers são criados pelo alocador, o tamanho de cada buffer e o alinhamento da memória. O pino de saída pode adiar para o pin de entrada para os requisitos de buffer.

Em uma conexão IMemInputPin , a negociação do alocador funciona da seguinte maneira:

  1. Opcionalmente, o pino de saída chama IMemInputPin::GetAllocatorRequirements. Esse método recupera os requisitos de buffer do pino de entrada, como o alinhamento de memória. Em geral, o pino de saída deve respeitar a solicitação do pino de entrada, a menos que haja um bom motivo para não fazer isso.
  2. Opcionalmente, o pino de saída chama IMemInputPin::GetAllocator. Esse método solicita um alocador do pino de entrada. O pin de entrada fornece um ou retorna um código de erro.
  3. O pino de saída seleciona um alocador. Ele pode usar um fornecido pelo pin de entrada ou criar o próprio.
  4. O pino de saída chama IMemAllocator::SetProperties para definir as propriedades do alocador. No entanto, o alocador pode não respeitar as propriedades solicitadas. (Por exemplo, isso pode acontecer se o pin de entrada fornecer o alocador.) O alocador retorna as propriedades reais como um parâmetro de saída no método SetProperties .
  5. O outpin chama IMemInputPin::NotifyAllocator para informar o pin de entrada da seleção.
  6. O pin de entrada deve chamar IMemAllocator::GetProperties para verificar se as propriedades do alocador são aceitáveis.
  7. O pino de saída é responsável por confirmar e descompactar o alocador. Isso ocorre quando o streaming é iniciado e interrompido.

Em uma conexão IAsyncReader , a negociação do alocador funciona da seguinte maneira:

  1. O pino de entrada chama IAsyncReader::RequestAllocator no pino de saída. O pino de entrada especifica seus requisitos de buffer e, opcionalmente, fornece um alocador.
  2. O pino de saída seleciona um alocador. Ele pode usar aquele fornecido pelo pino de entrada, se houver, ou criar o próprio.
  3. O pino de saída retorna o alocador como um parâmetro de saída no método RequestAllocator . O pino de entrada deve marcar as propriedades do alocador.
  4. O pin de entrada é responsável por confirmar e descompactar o alocador.
  5. A qualquer momento durante o processo de negociação do alocador, qualquer pin pode falhar na conexão.
  6. Se o pino de saída usar o alocador do pino de entrada, ele poderá usar esse alocador apenas para entregar amostras a esse pino de entrada. O filtro proprietário não deve usar o alocador para entregar amostras a outros pinos.

Fornecendo um alocador personalizado