Condividi tramite


Selezione di un decodificatore in DirectShow Editing Services

[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, IMFMediaEngine 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, IMFMediaEngine e Audio/Video Capture in Media Foundation invece di 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 potrebbe essere modificata o non disponibile in futuro.]

Quando DirectShow Editing Services (DES) esegue il rendering di un progetto di modifica video, il motore di rendering seleziona automaticamente i decodificatori necessari. Ciò può verificarsi all'interno del metodo IRenderEngine::ConnectFrontEnd o in modo dinamico durante il rendering.

Un utente può installare diversi decodificatori in grado di decodificare un determinato file. Quando sono disponibili più decodificatori, DES usa l'algoritmo Intelligent Connect per selezionare il decodificatore.

Non esiste alcun modo per l'applicazione di specificare direttamente il decodificatore da usare. È tuttavia possibile scegliere il decodificatore indirettamente tramite l'interfaccia di callback IAMGraphBuilderCallback . Implementando questa interfaccia nell'applicazione, è possibile ricevere notifiche durante il processo di compilazione del grafo e rifiutare determinati filtri dal grafico.

Iniziare implementando una classe che espone l'interfaccia IAMGraphBuilderCallback :

class GraphBuilderCB : public IAMGraphBuilderCallback
{
public:
     // Method declarations (not shown).
};

Creare quindi un'istanza di Filter Graph Manager e registrare la classe per ricevere notifiche di callback:

// Declare an instance of the callback object.
GraphBuilderCB GraphCB; 

// Create the Filter Graph Manager.
CComPtr<IGraphBuilder> pGraph;
hr = pGraph.CoCreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
    // Handle error (not shown).
}
// Register to receive the callbacks.
CComQIPtr<IObjectWithSite> pSite(pGraph);
if (pSite)
{
    hr = pSite->SetSite((IUnknown*)&GraphCB);
}

Creare quindi il motore di rendering e chiamare il metodo IRenderEngine::SetFilterGraph con un puntatore a Filter Graph Manager. Ciò garantisce che il motore di rendering non crei il proprio Filter Graph Manager, ma usi invece l'istanza configurata per i callback.

CComPtr<IRenderEngine> pRender;
hr = pRender.CoCreateInstance(CLSID_RenderEngine);
if (FAILED(hr))
{
    // Handle error (not shown).
}

hr = pRender->SetFilterGraph(pGraph);

Quando viene eseguito il rendering del progetto, il metodo IAMGraphBuilderCallback::SelectedFilter dell'applicazione viene chiamato immediatamente prima che Filter Graph Manager crei un nuovo filtro. Il metodo SelectedFilter riceve un puntatore a un'interfaccia IMoniker che rappresenta un moniker per il filtro. Esaminare il moniker e, se si decide di rifiutare il filtro, restituire un codice di errore dal metodo SelectedFilter .

La parte difficile consiste nell'identificare i moniker che rappresentano decodificatori, in particolare i moniker che rappresentano decodificatori che si desidera rifiutare. Una soluzione è la seguente:

  • Prima di eseguire il rendering del progetto, utilizzare il metodo IFilterMapper2::EnumMatchingFilters per creare un elenco di filtri registrati come accettazione del tipo di input desiderato. Per i tipi di compressione video o audio, questo elenco deve essere mappato a un set di decodificatori.

  • Il metodo EnumMatchingFilters restituisce una raccolta di moniker. Per ogni moniker nell'insieme, ottenere la proprietà DisplayName , come descritto in Utilizzo del mapper filtro.

  • Archiviare un elenco dei nomi visualizzati, ma omettere il nome visualizzato corrispondente al filtro da usare per la decodifica. I nomi visualizzati per i filtri software hanno il formato seguente:

    OLESTR("@device:sw:{CategoryGUID}\{FilterCLSID}");
    

    dove

    CategoryGUID
    

    è il GUID della categoria di filtri e

    FilterCLSID
    

    è il CLSID del filtro. Per le DMO, il formato è lo stesso, ma passare sw a dmo.

    L'elenco contiene ora nomi visualizzati per ogni filtro che restituisce il tipo di supporto desiderato, ma non è il filtro preferito.

  • Nel metodo SelectedFilter ottenere la proprietà DisplayName nel moniker proposto e controllarla rispetto all'elenco archiviato. Se il nome visualizzato corrisponde a una voce nell'elenco, rifiutare tale filtro. In caso contrario, accettarlo restituendo S_OK.

Rendering di un progetto