Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
[O recurso associado a esta página, DirectShow, é um recurso herdado. Foi substituído por MediaPlayer, IMFMediaEnginee Audio/Video Capture in Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda vivamente que o novo código utilize 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.]
O DirectShow inclui um modelo de classe, IMediaObjectImpl, para implementar DMOs. O modelo lida com muitas das tarefas de "contabilidade", como a validação de parâmetros de entrada. Usando o modelo, você pode se concentrar na funcionalidade que é específica para o seu DMO. Além disso, o modelo ajuda a garantir que você crie uma implementação robusta. O modelo é definido no arquivo de cabeçalho Dmoimpl.h, localizado no diretório Include do SDK.
O modelo de IMediaObjectImpl herda a interface IMediaObject. Para criar um DMO usando o modelo, defina uma nova classe que deriva de IMediaObjectImpl. O modelo implementa todos os IMediaObject métodos. Na maioria dos casos, o modelo chama um método privado correspondente na classe derivada. O modelo fornece os seguintes recursos:
- Verificação de parâmetros fundamentais. Os métodos do modelo verificam se os parâmetros necessários não estão NULL, se os índices de fluxo estão dentro dos limites e se os sinalizadores são válidos.
- Bloqueio. Os métodos de modelo chamam dois métodos internos, Lock e Unlock, para serializar operações no DMO. Esse recurso garante que o DMO seja thread-safe.
- Tipos de mídia. O modelo armazena os tipos de mídia definidos pelo cliente e fornece métodos de acesso para os tipos de mídia.
- Streaming. O modelo impede o streaming até que o cliente tenha definido tipos de mídia para todos os fluxos não opcionais. Ele também garante que o método IMediaObject::AllocateStreamingResources seja chamado antes do início do streaming, o que garante que os recursos sejam alocados.
A classe derivada deve implementar o IUnknown interface; o modelo não fornece essa interface. Você pode usar a ATL (Ative Template Library) para implementar IUnknownou pode fornecer alguma outra implementação. O modelo também não implementa o mecanismo de bloqueio. A classe derivada deve implementar os métodos Lock e Unlock. Se você criar sua classe usando ATL, poderá usar as implementações ATL padrão.
Declarando a classe derivada
O modelo de classe IMediaObjectImpl é declarado da seguinte forma:
template <class _DERIVED_, int NUMBEROFINPUTS, int NUMBEROFOUTPUTS>
class IMediaObjectImpl : public ImediaObject
Os três parâmetros do modelo são _DERIVED_, NUMBEROFINPUTS e NUMBEROFOUTPUTS. Defina _DERIVED_ igual ao nome da sua classe. Os outros dois parâmetros definem o número de fluxos de entrada e fluxos de saída no DMO. Por exemplo, para criar uma classe DMO chamada CMyDmo que suporta um fluxo de entrada e dois fluxos de saída, use a seguinte declaração:
class CMyDmo : public IMediaObjectImpl<CMyDmo, 1, 2>
O restante desta seção descreve como o modelo implementa os vários métodos em IMediaObject.
métodos para definir tipos de mídia
Os seguintes métodos definem ou recuperam tipos de mídia no DMO:
- GetInputType, GetOutputType. Esses métodos retornam tipos de mídia preferenciais, por número de fluxo e índice de tipo. O modelo chama InternalGetInputType ou InternalGetOutputType na classe derivada.
- DefinirTipoDeEntrada, DefinirTipoDeSaída. Esses métodos definem o tipo de mídia em um fluxo, testam um tipo de mídia ou limpam um tipo de mídia. Para validar o tipo de media, o modelo chama InternalCheckInputType ou InternalCheckOutputType na classe derivada. A classe derivada retorna S_OK para aceitar o tipo ou DMO_E_INVALIDTYPE para rejeitar o tipo. O template lida com a configuração ou limpeza do tipo de mídia.
- ObterTipoDeCorrenteDeEntrada, ObterTipoDeCorrenteDeSaída. Esses métodos retornam o tipo de mídia atual para um fluxo ou DMO_E_TYPE_NOT_SET se nenhum tipo estiver definido. O modelo implementa completamente esses métodos.
Métodos Informativos
Os métodos a seguir fornecem informações sobre o DMO.
- GetInputMaxLatency, SetInputMaxLatency. Esses métodos recuperam ou definem a latência máxima. O template chama InternalGetInputMaxLatency ou InternalSetInputMaxLatency na classe derivada.
- GetInputSizeInfo, GetOutputSizeInfo. Esses métodos retornam os requisitos de buffer do DMO para um fluxo especificado. Se nenhum tipo de mídia tiver sido definido nesse fluxo, o modelo retornará DMO_E_TYPE_NOT_SET. Caso contrário, chama InternalGetInputSizeInfo ou InternalGetOutputSizeInfo na classe derivada.
- GetInputStreamInfoGetOutputStreamInfo. Esses métodos retornam vários sinalizadores que indicam como o cliente deve formatar os dados. O modelo chama InternalGetInputStreamInfo ou InternalGetOutputStreamInfo na classe derivada.
- GetStreamCount. Esse método retorna o número de fluxos de entrada e saída. O modelo implementa esse método, usando os parâmetros do modelo.
Métodos para alocação de recursos
- O método AllocateStreamingResources aloca todos os recursos de que o DMO precisa antes do início do streaming. O método FreeStreamingResources libera os mesmos recursos. O modelo chama InternalAllocateStreamingResources e InternalFreeStreamingResources, respectivamente.
O cliente do DMO não é obrigado a chamar esses métodos, mas o modelo chama automaticamente AllocateStreamingResources antes do início do streaming. Portanto, o DMO pode assumir que os recursos foram corretamente alocados até ao momento em que ProcessInput é chamado. O DMO deve chamar FreeStreamingResources no seu destrutor.
Além disso, quando o modelo chama InternalAllocateStreamingResources, ele define um sinalizador interno, para que ele não chame esse método novamente até chamar InternalFreeStreamingResources. Isso garante que os recursos não sejam realocados acidentalmente, o que pode causar vazamentos de memória.
Métodos para streaming
Os seguintes métodos são usados para transmitir dados:
- GetInputStatus. Esse método indica se o DMO pode aceitar entrada neste momento. O template chama InternalAcceptingInput na classe derivada. Se o DMO puder aceitar entrada, a classe derivada retornará S_OK e o modelo configurará o bit de DMO_INPUT_STATUSF_ACCEPT_DATA no parâmetro dwFlags. Caso contrário, a classe derivada retorna S_FALSE e o modelo define dwFlags a zero.
- ProcessInput. Este método processa um buffer de entrada. O modelo chama AllocateStreamingResources, descrito anteriormente. Em seguida, ele chama InternalAcceptingInput na classe derivada. Se o DMO puder aceitar novas entradas, o modelo chamará InternalProcessInput.
- ProcessOutput. Este método processa um conjunto de buffers de saída, um buffer para cada fluxo de saída. O modelo chama AllocateStreamingResources e, em seguida, InternalProcessOutput.
- Descontinuidade. Este método sinaliza uma descontinuidade em um fluxo de entrada. O modelo chama InternalAcceptingInput na classe derivada. Se esse método retornar S_OK, o modelo chamará InternalDiscontinuity na classe derivada.
- Flush. Este método limpa o DMO. O modelo chama InternalFlush na classe derivada. O DMO deve descartar todos os buffers de entrada que ainda mantém para serem processados.
O modelo não fornece nenhum suporte direto para o IMediaObjectInPlace interface.
Métodos para bloquear
O bloqueio é usado para proteger o estado do DMO em um ambiente multithreaded. Em um projeto ATL, o método IMediaObject::Lock causa um conflito de nome com o método ATL Lock. Para resolver o conflito, o modelo renomeia o IMediaObject método para DMOLock. Ao compilar a classe derivada, defina FIX_LOCK_NAME antes de incluir o arquivo de cabeçalho Dmo.h:
#define FIX_LOCK_NAME
#include <dmo.h>
Essa diretiva faz com que o pré-processador substitua DMOLock por Lock na declaração da interface IMediaObject. Os aplicativos ainda podem invocar o método usando o nome Lock, porque a ordem vtable não é alterada. O método DMOLock chama Lock ou Unlock na classe derivada. Se você estiver usando ATL para implementar a classe derivada, esses métodos já estão definidos pela ATL, portanto, nenhum código adicional é necessário. Se não estiver a usar ATL, deve fornecer os métodos Lock e Unlock na sua classe derivada.
O modelo bloqueia automaticamente o DMO em cada um dos métodos IMediaObject . A classe derivada pode precisar bloquear o DMO dentro de outros métodos públicos que implementa (por exemplo, se ele suporta IMediaObjectInPlace). O modelo de classe também fornece uma classe auxiliar interna, IMediaObjectImpl::LockIt, que é útil para bloquear e desbloquear o DMO.
Resumo
Para os métodos seguintes de IMediaObject, o modelo chama um método correspondente com a mesma assinatura da classe derivada. A classe derivada deve implementar cada um dos métodos mostrados na segunda coluna.
| Método IMediaObject | Método de classe derivada |
|---|---|
| AlocarRecursosDeStreaming | InternalAllocateStreamingResources |
| Descontinuidade | Descontinuidade Interna |
| Flush | InternalFlush |
| FreeStreamingResources | InternalFreeStreamingResources |
| GetInputMaxLatency | InternalGetInputMaxLatency |
| ObterInformaçãoTamanhoEntrada | InternalGetInputSizeInfo |
| GetInputStreamInfo | InternalGetInputStreamInfo |
| GetInputType | InternalGetInputType |
| GetOutputSizeInfo | ObterInformaçõesDeTamanhoDeSaídaInterno |
| GetOutputStreamInfo | InternalGetOutputStreamInfo |
| GetOutputType | InternalGetOutputType |
| ProcessInput | EntradaProcessoInterno |
| SaídaDoProcesso | SaídaDoProcessoInterno |
| SetInputMaxLatency | InternalSetInputMaxLatency |
Para os métodos de IMediaObject restantes, não há uma correspondência direta entre métodos de template e métodos de classe derivada. A tabela a seguir resume quais métodos são totalmente implementados pelo modelo e quais métodos chamam outros métodos na classe derivada.
| Método IMediaObject | Método de classe derivada |
|---|---|
| ObterTipoCorrenteDeEntrada | Totalmente implementado |
| GetOutputCurrentType | Totalmente implementado |
| GetStreamCount | Totalmente implementado |
| GetInputStatus | InternalAcceptingInput |
| Lock (implementado como DMOLock) | Bloquear, desbloquear |
| SetInputType | InternalCheckInputType |
| SetOutputType | InternalCheckOutputType |
Tópicos relacionados