Come i decodificatori usano IAMVideoAccelerator
[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.
L'interfaccia IAMVideoAccelerator consente operazioni generiche di accelerazione video, inclusa l'accelerazione video DirectX (VA). Per l'accelerazione VA non DirectX, il decodificatore e il driver video devono entrambi rispettare un protocollo comune.
In questa sezione viene descritto l'ordine generale delle operazioni che devono essere seguite da qualsiasi decodificatore quando si usa questa interfaccia. Altre informazioni specifiche per i decodificatori basati su DirectX VA sono disponibili in Mapping dell'accelerazione video DirectX a IAMVideoAccelerator.
Nota
Questa interfaccia è disponibile in Windows 2000 e versioni successive.
L'interfaccia IAMVideoAccelerator viene esposta sul pin di input del mixer di sovrapposizione o del renderer di missaggio video (VMR). L'interfaccia IAMVideoAcceleratorNotify viene esposta sul pin di output del decodificatore. La sequenza di eventi per la connessione dei pin di filtro è la seguente:
Filter Graph Manager chiama IPin::Connect sul pin di output del filtro del decodificatore. Un AM_MEDIA_TYPE è un parametro facoltativo.
- AM_MEDIA_TYPE è una struttura di dati che descrive un tipo di supporto. Contiene un GUID di tipo principale (che in questo caso deve essere MEDIATYPE_Video), un GUID di sottotipo (che in questo caso deve essere un GUID dell'acceleratore video) e un'ampia gamma di altri aspetti. Uno di questi elementi è un GUID di tipo di formato contenente informazioni sul supporto, tra cui in questo caso la larghezza e l'altezza di un'immagine video non compressa, molto probabilmente in una struttura MPEG1VIDEOINFO, VIDEOINFOHEADER, MPEG2VIDEOINFO o VIDEOINFOHEADER2 .
- La struttura AM_MEDIA_TYPE , se presente, indica al decodificatore di operare utilizzando il tipo di supporto specificato, che può essere "completamente specificato" o "parzialmente specificato". Se "completamente specificato", il decodificatore tenta normalmente di funzionare con tale tipo di supporto. Se "specificato parzialmente", tenterà di trovare una modalità di funzionamento compatibile "completamente specificata" che può essere usata per connettersi in modo coerente con il tipo di supporto "parzialmente specificato".
- Il modo comune per tentare di trovare un tipo di supporto "completamente specificato" da usare per una connessione consiste semplicemente nell'eseguire un elenco di ogni tipo di supporto "completamente specificato" supportato dal pin di output che è compatibile con il tipo di supporto "parzialmente specificato" e tentare di connettersi a ognuno di essi fino a quando non riesce. Il processo sarebbe in genere simile se non è contenuto alcun AM_MEDIA_TYPE nella chiamata IPin::Connect , ma con il pin di output che deve controllare tutti i relativi tipi di supporti.
Se il decodificatore vuole verificare se un AM_MEDIA_TYPE specifico (incluso un GUID dell'acceleratore video) è supportato dal pin di input downstream, può chiamare il pin IPin::QueryAccept (con il GUID dell'acceleratore video come sottotipo del AM_MEDIA_TYPE) o semplicemente tentare di connettersi a tale pin come descritto nell'elemento 5 riportato di seguito.
Se il decodificatore non conosce i GUID dell'acceleratore video supportati dal pin di input downstream e non vuole proporre solo un PARTICOLARE GUID dell'acceleratore video candidato chiamando il PIN di input downstream ::QueryAccept, il decodificatore può chiamare IAMVideoAccelerator::GetVideoAcceleratorGUIDs per ottenere un elenco dei GUID dell'acceleratore video supportati dal pin.
Per alcuni GUID specifici dell'acceleratore video, il decodificatore può chiamare il pin di input downstream IAMVideoAccelerator::GetUncompFormatsSupported per ottenere un elenco dei formati pixel DDPIXELFORMAT che possono essere usati per eseguire il rendering di un GUID specifico dell'acceleratore video. L'elenco restituito deve essere considerato in ordine di preferenza decrescente, ovvero con il formato più preferito elencato per primo.
Il decodificatore chiama il pin di input downstream IPin::ReceiveConnection, passandolo un AM_MEDIA_TYPE con il GUID dell'acceleratore video appropriato come sottotipo del tipo di supporto. In questo modo viene impostata la connessione per l'operazione, inclusa la creazione delle superfici di output non compresse (allocate usando la larghezza e l'altezza rilevate in AM_MEDIA_TYPE e il numero di superfici da allocare trovate da una chiamata descritta di seguito e qualsiasi altra informazione disponibile per l'acceleratore video, ad esempio il GUID dell'acceleratore video stesso). Se il pin di input downstream rifiuta il GUID dell'acceleratore video o un altro aspetto della connessione, questo può causare l'esito negativo di IPin::ReceiveConnection . Se IPin::ReceiveConnection ha esito negativo, viene indicato in un HRESULT restituito e il decodificatore può provare a eseguire nuovamente la chiamata, ad esempio con un nuovo GUID dell'acceleratore video nella struttura AM_MEDIA_TYPE .
[! Nota]
Si tratta di un altro modo (e il modo più definitivo) per il decodificatore di determinare ciò che è supportato dal pin di input downstream, semplicemente chiamando IPin::ReceiveConnection e tentando di connettersi e quindi verificando se il tentativo di connessione è riuscito.
Durante IPin::ReceiveConnection, il renderer chiama il decodificatore IAMVideoAcceleratorNotify::GetUncompSurfacesInfo, passandolo il GUID dell'acceleratore video e una struttura AMVAUncompBufferInfo , per determinare il numero di superfici non compresse da allocare. Il decodificatore riempie e restituisce la struttura che contiene il numero minimo e massimo di superfici da allocare del tipo specifico e una struttura DDPIXELFORMAT che descrive il formato pixel delle superfici da allocare.
[! Nota]
Nulla viene effettivamente passato al decodificatore nella chiamata a IAMVideoAcceleratorNotify::GetUncompSurfacesInfo diverso dal GUID dell'acceleratore video.
Il renderer chiama il decodificatore IAMVideoAcceleratorNotify::SetUncompSurfacesInfo, passando al decodificatore il numero effettivo di superfici non compresse allocate.
Il renderer chiama IAMVideoAcceleratorNotify::GetCreateVideoAcceleratorData per ottenere i dati necessari per inizializzare l'acceleratore video.
Il decodificatore chiama IAMVideoAccelerator::GetCompBufferInfo, passandolo un GUID dell'acceleratore video, una struttura AMVAUncompDataInfo e il numero di tipi di buffer compressi, per ottenere un set di strutture di dati AMVACompBufferInfo , una corrispondente a ogni tipo di buffer di dati compresso usato dal GUID dell'acceleratore video.
- La struttura AMVAUncompDataInfo contiene la larghezza e l'altezza dei dati non compressi decodificati (in pixel) e DDPIXELFORMAT dell'immagine non compressa.
- Le strutture di dati AMVACompBufferInfo restituite contengono:
Numero di buffer compressi necessari per il tipo specifico.
Larghezza e altezza della superficie da creare (campi che possono avere o meno un significato effettivo).
Nota
L'operazione di allocazione della superficie DirectDraw per i buffer compressi non fornisce attualmente la larghezza o l'altezza di queste superfici per essere maggiore o uguale a 2^15, anche se la chiamata di allocazione della superficie potrebbe non riuscire eccessivamente se questo limite viene violato. Di conseguenza, il driver potrebbe strutturare le richieste di memoria del buffer compresso per evitare tali dimensioni estreme. Ad esempio, anziché richiedere un buffer con width="1" e height="65536", il driver deve richiedere un buffer di width="1024" e height="64".
Numero totale di byte da utilizzare dalla superficie.
Struttura di tipo DDSCAPS2 che definisce un oggetto DirectDrawSurface, che descrive le funzionalità per creare superfici in cui archiviare i dati compressi.
DDPIXELFORMAT, che descrive il formato pixel usato per creare superfici per archiviare dati compressi (un campo che può o meno avere un significato effettivo).
Nota
Le chiamate del renderer ad alcuni dei metodi di interfaccia IAMVideoAcceleratorNotify del decodificatore possono (e normalmente) verificarsi all'interno della chiamata del decodificatore all'IPin::ReceiveConnection del renderer. In particolare, questo vale per gli elementi seguenti:
Nota
Per supportare le modifiche al formato dinamico, il decodificatore può anche chiamare IPin::ReceiveConnection e altri metodi per sopra mentre i filtri sono connessi e in esecuzione. Questa funzionalità viene fornita per supportare le modifiche al formato dinamico (anche se non nell'H.263, Allegato P, senso - poiché tutti i set di dati vengono avviati di nuovo da zero e le informazioni sull'immagine di riferimento vengono pertanto perse).
Di seguito è riportata una descrizione dell'uso di IAMVideoAccelerator durante l'operazione dopo l'inizializzazione:
Per ogni superficie non compressa, il decodificatore chiama IAMVideoAccelerator::BeginFrame per avviare l'elaborazione per creare l'immagine di output. In questo caso, il decodificatore invia una struttura AMVABeginFrameInfo .
La struttura AMVABeginFrameInfo contiene un indice per un buffer di destinazione, un puntatore ad alcuni dati da inviare a valle e un puntatore a una posizione in cui l'acceleratore può inserire alcuni dati per la lettura del decodificatore.
NOTA 1: l'acceleratore non riceve effettivamente l'indice del buffer di destinazione, perché viene convertito dal renderer prima di andare a valle.
NOTA 2: IAMVideoAccelerator::BeginFrame può essere chiamato più volte tra le chiamate a IAMVideoAccelerator::EndFrame.
NOTA 3: non è necessario chiamare IAMVideoAccelerator::BeginFrame e IAMVideoAccelerator::EndFrame per l'elaborazione di ogni singola immagine nel bitstream.
Le operazioni di IAMVideoAccelerator::BeginFrame , per quanto riguarda l'interfaccia, creano un'associazione all'interno del renderer tra un indice e una superficie non compressa. Fornisce anche un mezzo per chiamare una funzione specifica in un driver di dispositivo (con il supporto di un mezzo per passare dati arbitrari tra il decodificatore e il driver di dispositivo).
Nell'operazione DirectX VA, tuttavia, è necessario chiamare IAMVideoAccelerator::BeginFrame e IAMVideoAccelerator::EndFrame per l'elaborazione di ogni singola immagine nel bitstream.
Per l'invio di dati non compressi all'acceleratore, il decodificatore chiama:
- IAMVideoAccelerator::QueryRenderStatus per determinare se un buffer è sicuro per la lettura o la scrittura.
- IAMVideoAccelerator::GetBuffer per bloccare e ottenere l'accesso a un buffer specificato (se non è stato chiamato in precedenza per ottenere tale accesso). È anche possibile usare GetBuffer per ottenere una copia del contenuto dell'ultima immagine di output non compressa per cui è stato chiamato IAMVideoAccelerator::BeginFrame, specificando che IAMVideoAccelerator::EndFrame non è stato chiamato per l'indice del buffer di destinazione. Se l'DDI restituisce uno stato di rendering di DDERR_WASSTILLDRAWING per il buffer richiesto, un ciclo di sospensione verrà gestito all'interno di GetBuffer fino a quando questa condizione non viene cancellata. Per chiamare GetBuffer, il decodificatore richiederà alcune informazioni da una struttura di dati AMVACompBufferInfo ottenuta chiamando IAMVideoAccelerator::GetCompBufferInfo.
- IAMVideoAccelerator::Execute per indicare che i dati in un set di buffer compressi, come indicato in una matrice di strutture di dati AMVABUFFERINFO devono essere elaborati. Un codice di funzione dwFunction viene passato al driver in questa chiamata. Un puntatore lpPrivateInputData viene passato anche ad alcuni dati per inviare downstream e un puntatore lpPrivateOutputData viene passato a una posizione in cui il processo downstream può inserire alcuni dati per la lettura del decodificatore.
- IAMVideoAccelerator::ReleaseBuffer per indicare che il decodificatore ha completato l'uso di un buffer specificato per il momento e non richiede più l'accesso bloccato al buffer. Se il decodificatore vuole continuare a usare il buffer, può semplicemente non chiamare IAMVideoAccelerator::ReleaseBuffer per il momento, evitando così la necessità di chiamare IAMVideoAccelerator::GetBuffer fino a quando non intende più usare il buffer. Il decodificatore non deve scrivere nel buffer dopo la chiamata a Execute finché QueryRenderStatus indica che il buffer è sicuro per la scrittura.
Per completare l'elaborazione dell'output per un buffer di destinazione, il decodificatore chiama IAMVideoAccelerator::EndFrame. Può passare alcuni dati arbitrari downstream con questa chiamata ed è essenzialmente tutto ciò che avviene in seguito a questa chiamata. Non invia un indice del buffer di destinazione in questa chiamata, quindi non può indicare all'acceleratore esattamente il buffer di destinazione completato, a meno che questa indicazione non sia contenuta nei dati arbitrari passati.
Per visualizzare un frame, il decodificatore chiama IAMVideoAccelerator::D isplayFrame con l'indice del frame da visualizzare e una struttura IMediaSample contenente timestamp di inizio e arresto e flag pertinenti, ad esempio dwTypeSpecificFlags nella struttura AM_SAMPLE2_PROPERTIES e dwInterlaceFlags nella struttura VIDEOINFOHEADER2 . Il decodificatore deve verificare che tutte le operazioni di decompressione che influiscono sul contenuto del frame siano state completate prima di chiamare DisplayFrame.
Infine, il decodificatore deve, al termine di tutta l'elaborazione, indicare il completamento di tutti i fotogrammi di output rimanenti avviati chiamando IAMVideoAccelerator::EndFrame e rilasciando tutti i buffer bloccati chiamando IAMVideoAccelerator::ReleaseBuffer per ogni buffer non rilasciato.
Argomenti correlati