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:
- Crie o mecanismo de renderização.
- Especifique o linha do tempo.
- Defina o intervalo de renderização. (Opcional)
- 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:
- Crie uma instância do construtor de grafo de captura.
- Obtenha um ponteiro para o grafo e passe-o para o construtor de grafo.
- 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.
- Recupere o número de grupos.
- Para cada pino, obtenha um ponteiro para o pino.
- 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.
- Opcionalmente, defina parâmetros de compactação, como a taxa de quadros chave. Esta etapa é discutida em detalhes mais adiante no artigo.
- 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.
Tópicos relacionados