Gravando um projeto em um arquivo

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

[Não há suporte para essa API e pode ser alterada ou indisponível no futuro.]

Este artigo descreve como gravar um projeto dos Serviços de Edição do DirectShow em um arquivo. Primeiro, ele descreve como gravar um arquivo com o mecanismo de renderização básico. Em seguida, ele descreve a recompactação inteligente com o mecanismo de renderização inteligente.

Para obter uma visão geral de como o DirectShow Editing Services renderiza projetos, consulte Sobre os Mecanismos de Renderização.

Usando o Mecanismo de Renderização Básico

Comece criando o front-end do grafo, da seguinte maneira:

  1. Crie o mecanismo de renderização.
  2. Especifique o linha do tempo.
  3. Defina o intervalo de renderização. (Opcional)
  4. Crie o front-end do grafo.

O exemplo de código a seguir mostra essas etapas.

IRenderEngine *pRender = NULL; 
hr = CoCreateInstance(CLSID_RenderEngine, NULL, CLSCTX_INPROC,
    IID_IRenderEngine, (void**) &pRender);

hr = pRender->SetTimelineObject(pTL);
hr = pRender->ConnectFrontEnd( );

Em seguida, adicione filtros multiplexador e de gravação de arquivo ao grafo de filtro. A maneira mais fácil de fazer isso é com o Construtor de Gráficos de Captura, um componente do DirectShow para criar grafos de captura. O construtor de grafo de captura expõe a interface ICaptureGraphBuilder2 . Execute as seguintes etapas:

  1. Crie uma instância do construtor de grafo de captura.
  2. Obtenha um ponteiro para o grafo e passe-o para o construtor de grafo.
  3. Especifique o nome e o tipo de mídia do arquivo de saída. Essa etapa também obtém um ponteiro para o filtro mux, que é necessário posteriormente.

O exemplo de código a seguir mostra essas etapas.

CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, 
    IID_ICaptureGraphBuilder2, (void **)&pBuilder);

// Get a pointer to the graph front end.
IGraphBuilder *pGraph;
pRender->GetFilterGraph(&pGraph);
pBuilder->SetFiltergraph(pGraph);

// Create the file-writing section.
IBaseFilter *pMux;
pBuilder->SetOutputFileName(&MEDIASUBTYPE_Avi, 
    OLESTR("Output.avi"), &pMux, NULL);

Por fim, conecte os pinos de saída no front-end ao filtro mux.

  1. Recupere o número de grupos.
  2. Para cada pino, obtenha um ponteiro para o pino.
  3. Opcionalmente, crie uma instância de um filtro de compactação para compactar o fluxo. O tipo de compressor dependerá do tipo de mídia do grupo. Você pode usar o Enumerador de Dispositivo do Sistema para enumerar os filtros de compactação disponíveis. Para obter mais informações, consulte Enumerando dispositivos e filtros.
  4. Opcionalmente, defina parâmetros de compactação, como a taxa de quadros chave. Esta etapa é discutida em detalhes mais adiante no artigo.
  5. Chame ICaptureGraphBuilder2::RenderStream. Esse método usa ponteiros para o pino, o filtro de compactação (se houver) e o multiplexador.

O exemplo de código a seguir mostra como conectar os pinos de saída.

long NumGroups;
pTimeline->GetGroupCount(&NumGroups);

// Loop through the groups and get the output pins.
for (i = 0; i < NumGroups; i++)
{
    IPin *pPin;
    if (pRender->GetGroupOutputPin(i, &pPin) == S_OK) 
    {
        IBaseFilter *pCompressor;
        // Create a compressor filter. (Not shown.)
        // Set compression parameters. (Not shown.)

        // Connect the pin.
        pBuilder->RenderStream(NULL, NULL, pPin, pCompressor, pMux);
        pCompressor->Release();
        pPin->Release();
    }
}

Para definir parâmetros de compactação (etapa 4, anteriormente), use a interface IAMVideoCompression . Essa interface é exposta nos pinos de saída dos filtros de compactação. Enumerar os pinos do filtro de compactação e consultar cada pino de saída para IAMVideoCompression. (Para obter informações sobre como enumerar pinos, consulte Enumerando pins.) Certifique-se de liberar todos os ponteiros de interface obtidos durante esta etapa.

Depois de criar o grafo de filtro, chame o método IMediaControl::Run no gerenciador de grafo de filtro. À medida que o grafo de filtro é executado, ele grava os dados em um arquivo. Use a notificação de evento para aguardar a conclusão da reprodução. (Consulte Respondendo a eventos.) Quando a reprodução for concluída, você deverá chamar explicitamente IMediaControl::Stop para interromper o grafo de filtro. Caso contrário, o arquivo não será gravado corretamente.

Usando o Mecanismo de Renderização Inteligente

Para obter os benefícios da recompactação inteligente, use o mecanismo de renderização inteligente no lugar do mecanismo de renderização básico. As etapas na criação do grafo são quase as mesmas. A principal diferença é que a compactação é tratada no front-end do grafo, não na seção de gravação de arquivo.

Importante

Não use o mecanismo de renderização inteligente para ler ou gravar arquivos do Windows Media.

 

Cada grupo de vídeos tem uma propriedade que especifica o formato de compactação para esse grupo. O formato de compactação deve corresponder exatamente ao formato descompactado do grupo em altura, largura, profundidade de bits e taxa de quadros. O mecanismo de renderização inteligente usa o formato de compactação quando constrói o grafo. Antes de definir o formato de compactação, defina o formato descompactado para esse grupo chamando IAMTimelineGroup::SetMediaType.

Para definir o formato de compactação de um grupo, chame o método IAMTimelineGroup::SetSmartRecompressFormat . Esse método usa um ponteiro para uma estrutura SCompFmt0 . A estrutura SCompFmt0 tem dois membros: nFormatId, que deve ser zero, e MediaType, que é uma estrutura AM_MEDIA_TYPE . Inicialize a estrutura AM_MEDIA_TYPE com as informações de formato.

Observação

Se você quiser que o projeto final tenha o mesmo formato que um dos arquivos de origem, poderá obter a estrutura de AM_MEDIA_TYPE diretamente do arquivo de origem, usando o detector de mídia. Consulte IMediaDet::get_StreamMediaType.

 

Converta a variável SCompFmt0 em um ponteiro do tipo long, conforme mostrado no exemplo a seguir.

SCompFmt0 *pFormat = new SCompFmt0;
memset(pFormat, 0, sizeof(SCompFmt0));
pFormat->nFormatId = 0;

// Initialize pFormat->MediaType. (Not shown.)

pGroup->SetSmartRecompressFormat( (long*) pFormat );

O mecanismo de renderização inteligente pesquisa automaticamente um filtro de compactação compatível. Você também pode especificar um filtro de compactação para um grupo chamando ISmartRenderEngine::SetGroupCompressor.

Para criar o grafo, use as mesmas etapas descritas para o Mecanismo de Renderização Básico na seção anterior. As únicas diferenças são as seguintes:

  • Use o mecanismo de renderização inteligente, não o mecanismo de renderização básico. O identificador de classe é CLSID_SmartRenderEngine.
  • Defina parâmetros de compactação depois de compilar o front-end, mas antes de renderizar os pinos de saída. Chame o método ISmartRenderEngine::GetGroupCompressor para obter um ponteiro para o filtro de compactação de um grupo. Em seguida, consulte a interface IAMVideoCompression , conforme descrito anteriormente.
  • Quando você renderiza os pinos de saída, não é necessário inserir um filtro de compactação. O fluxo já está compactado.

Renderizando um projeto