Condividi tramite


Scrittura di un progetto in un file

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.

[Questa API non è supportata e può essere modificata o non disponibile in futuro.]

Questo articolo descrive come scrivere un progetto DirectShow Editing Services in un file. Prima di tutto viene descritto come scrivere un file con il motore di rendering di base. Descrive quindi la ricompressione intelligente con il motore di rendering intelligente.

Per una panoramica del rendering di DirectShow Editing Services, vedere Informazioni sui motori di rendering.

Uso del motore di rendering di base

Iniziare creando la parte anteriore del grafico, come indicato di seguito:

  1. Creare il motore di rendering.
  2. Specificare la sequenza temporale.
  3. Impostare l'intervallo di rendering. Facoltativa
  4. Compilare la parte anteriore del grafico.

Nell'esempio di codice seguente vengono illustrati questi passaggi.

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

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

Aggiungere quindi filtri multiplexer e di scrittura file al grafico del filtro. Il modo più semplice per eseguire questa operazione è con Capture Graph Builder, un componente DirectShow per la creazione di grafici di acquisizione. Il generatore di grafici di acquisizione espone l'interfaccia ICaptureGraphBuilder2 . Eseguire questa procedura:

  1. Creare un'istanza del generatore di grafici di acquisizione.
  2. Ottenere un puntatore al grafico e passarlo al generatore di grafici.
  3. Specificare il nome e il tipo di supporto del file di output. Questo passaggio ottiene anche un puntatore al filtro mux, necessario in un secondo momento.

Nell'esempio di codice seguente vengono illustrati questi passaggi.

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);

Infine, connettere i pin di output sul front-end al filtro mux.

  1. Recuperare il numero di gruppi.
  2. Per ogni pin, ottenere un puntatore al pin.
  3. Facoltativamente, creare un'istanza di un filtro di compressione per comprimere il flusso. Il tipo di compressore dipenderà dal tipo di supporto del gruppo. È possibile usare l'enumeratore dispositivo di sistema per enumerare i filtri di compressione disponibili. Per altre informazioni, vedere Enumerazione di dispositivi e filtri.
  4. Facoltativamente, impostare i parametri di compressione, ad esempio la frequenza dei fotogrammi chiave. Questo passaggio viene descritto in dettaglio più avanti nell'articolo.
  5. Chiamare ICaptureGraphBuilder2::RenderStream. Questo metodo accetta puntatori al pin, il filtro di compressione (se presente) e il multiplexer.

Nell'esempio di codice seguente viene illustrato come connettere i pin di output.

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();
    }
}

Per impostare i parametri di compressione (passaggio 4, in precedenza), usare l'interfaccia IAMVideoCompression . Questa interfaccia viene esposta sui pin di output dei filtri di compressione. Enumerare i pin del filtro di compressione e eseguire query su ogni pin di output per IAMVideoCompression. Per informazioni sull'enumerazione dei pin, vedere Enumerazione dei pin. Assicurarsi di rilasciare tutti i puntatori di interfaccia ottenuti durante questo passaggio.

Dopo aver compilato il grafico del filtro, chiamare il metodo IMediaControl::Run nella gestione dei grafici di filtro. Man mano che viene eseguito il grafico del filtro, scrive i dati in un file. Usare la notifica dell'evento per attendere il completamento della riproduzione. Vedere Risposta agli eventi. Al termine della riproduzione, è necessario chiamare in modo esplicito IMediaControl::Stop per arrestare il grafico del filtro. In caso contrario, il file non viene scritto correttamente.

Uso del motore di rendering intelligente

Per ottenere i vantaggi della ricompressione intelligente, usare il motore di rendering intelligente al posto del motore di rendering di base. I passaggi nella compilazione del grafico sono quasi uguali. La differenza principale è che la compressione viene gestita nella parte anteriore del grafico, non nella sezione di scrittura dei file.

Importante

Non usare il motore di rendering intelligente per leggere o scrivere file di Windows Media.

 

Ogni gruppo di video ha una proprietà che specifica il formato di compressione per tale gruppo. Il formato di compressione deve corrispondere esattamente al formato non compresso del gruppo in altezza, larghezza, profondità bit e frequenza dei fotogrammi. Il motore di rendering intelligente usa il formato di compressione quando costruisce il grafico. Prima di impostare il formato di compressione, assicurarsi di impostare il formato non compresso per tale gruppo chiamando IAMTimelineGroup::SetMediaType.

Per impostare il formato di compressione di un gruppo, chiamare il metodo IAMTimelineGroup::SetSmartRecompressFormat . Questo metodo accetta un puntatore a una struttura SCompFmt0 . La struttura SCompFmt0 ha due membri: nFormatId, che deve essere zero e MediaType, ovvero una struttura AM_MEDIA_TYPE . Inizializzare la struttura AM_MEDIA_TYPE con le informazioni sul formato.

Nota

Se si vuole che il progetto finale abbia lo stesso formato di uno dei file di origine, è possibile ottenere la struttura AM_MEDIA_TYPE direttamente dal file di origine, usando il rilevatore di supporti. Vedere IMediaDet::get_StreamMediaType.

 

Eseguire il cast della variabile SCompFmt0 su un puntatore di tipo lungo, come illustrato nell'esempio seguente.

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

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

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

Il motore di rendering intelligente cerca automaticamente un filtro di compressione compatibile. È anche possibile specificare un filtro di compressione per un gruppo chiamando ISmartRenderEngine::SetGroupCompressor.

Per compilare il grafico, usare gli stessi passaggi descritti per il motore di rendering di base nella sezione precedente. Le uniche differenze sono le seguenti:

  • Usare il motore di rendering intelligente, non il motore di rendering di base. L'identificatore della classe è CLSID_SmartRenderEngine.
  • Impostare i parametri di compressione dopo aver compilato il front-end, ma prima di eseguire il rendering dei pin di output. Chiamare il metodo ISmartRenderEngine::GetGroupCompressor per ottenere un puntatore al filtro di compressione di un gruppo. Eseguire quindi una query per l'interfaccia IAMVideoCompression , come descritto in precedenza.
  • Quando si esegue il rendering dei pin di output, non è necessario inserire un filtro di compressione. Il flusso è già compresso.

Rendering di un progetto