EVT_ACX_CIRCUIT_CREATE_STREAM funzione di callback (acxcircuit.h)
Il driver definisce il callback EVT_ACX_CIRCUIT_CREATE_STREAM per creare istanze del flusso di circuito.
Sintassi
EVT_ACX_CIRCUIT_CREATE_STREAM EvtAcxCircuitCreateStream;
NTSTATUS EvtAcxCircuitCreateStream(
WDFDEVICE Device,
ACXCIRCUIT Circuit,
ACXPIN Pin,
PACXSTREAM_INIT StreamInit,
ACXDATAFORMAT StreamFormat,
const GUID *SignalProcessingMode,
ACXOBJECTBAG VarArguments
)
{...}
Parametri
Device
Oggetto WDFDEVICE (descritto in WDF - Riepilogo degli oggetti Framework) associato all'oggetto ACXCIRCUIT specificato.
Circuit
Oggetto ACXCIRCUIT associato alla nuova istanza di flusso. Per altre informazioni sugli oggetti ACX, vedere Riepilogo degli oggetti ACX.
Pin
Oggetto ACXPIN ACX associato alla nuova istanza di flusso.
StreamInit
Oggetto ACX ACXSTREAM_INIT. Si tratta di una struttura opaca usata per definire l'inizializzazione del flusso.
StreamFormat
Oggetto ACXDATAFORMAT ACX che definisce il formato dei dati di flusso.
SignalProcessingMode
GUID che identifica la modalità di elaborazione del segnale audio del nuovo circuito di flusso. Per altre informazioni sulle modalità audio, vedere Modalità di elaborazione del segnale audio.
VarArguments
Oggetto ACXOBJECTBAG facoltativo contenente argomenti aggiuntivi da utilizzare per inizializzare il flusso.
Valore restituito
Restituisce STATUS_SUCCESS
se la chiamata ha avuto esito positivo. In caso contrario, restituisce un codice di errore appropriato. Per altre informazioni, vedere Uso dei valori NTSTATUS.
Commenti
Il primo passaggio in Stream Creazione sta creando l'istanza ACXSTREAM per ogni ACXCIRCUIT nel percorso audio dell'endpoint. ACX chiamerà evtAcxCircuitCreateStream di ogni circuito. ACX inizierà con il circuito head e chiamerà ogni circuito CreateStream in ordine, terminando con il circuito di coda.
I driver hanno l'opportunità di eseguire qualsiasi inizializzazione prima o dopo il circuito successivo della catena viene richiamato, fare riferimento all'oggetto ACXSTREAMBRIDGE per altre informazioni.
La Stream Richiesta di creazione viene inviata all'ACXPIN appropriato esposto come parte della generazione della topologia del circuito head chiamando evtAcxCircuitCreateStream specificato durante la creazione del circuito head.
Il driver che riceve il callback di creazione del flusso esegue le operazioni seguenti:
- Inizializza la struttura ACXSTREAM_INIT opaca usando ACX definiti DDIs (AcxStreamInit*)
- Crea l'oggetto ACXSTREAM usando AcxStreamCreate o AcxRtStreamCreate ACX DDI. AcxRtStreamCreate viene usato solo per lo streaming ACXPIN connesso alla pipeline audio in modalità utente superiore, tutti gli altri circuiti del percorso dell'endpoint devono usare invece AcxStreamCreate DDI.
- Crea tutti gli elementi specifici del flusso, ad esempio ACXAUDIOENGINE.
- Aggiunge gli elementi all'oggetto ACXSTREAM.
- Restituisce STATUS_SUCCESS per indicare che il callback di creazione del flusso è stato completato correttamente.
Il canale di comunicazione di flusso tra circuiti in un percorso audio usa oggetti ACXTARGETSTREAM.
Dopo che il circuito di destinazione predefinito crea l'oggetto ACXSTREAM, ogni circuito verrà data l'opportunità di eseguire la gestione specifica del circuito per il flusso. Ogni circuito a sua volta esegue una o più delle azioni seguenti:
- Creare e aggiungere un oggetto Context all'ACXSTREAM con configurazione o dati specifici del driver di flusso.
- Restituire il controllo al framework ACX, che eseguirà la stessa azione con il circuito successivo nel percorso audio dell'endpoint.
Esempio
Di seguito è riportato l'esempio di utilizzo.
status = AcxCircuitInitAssignAcxCreateStreamCallback(
circuitInit,
CodecC_EvtCircuitCreateStream);
NTSTATUS
CodecC_EvtCircuitCreateStream(
_In_ WDFDEVICE Device,
_In_ ACXCIRCUIT Circuit,
_In_ ACXPIN Pin,
_In_ PACXSTREAM_INIT StreamInit,
_In_ ACXDATAFORMAT StreamFormat,
_In_ const GUID * SignalProcessingMode,
_In_ ACXOBJECTBAG VarArguments
)
/*++
Routine Description:
This routine creates a stream for the specified circuit.
Return Value:
NT status value
--*/
{
NTSTATUS status;
PCODEC_CAPTURE_DEVICE_CONTEXT devCtx;
WDF_OBJECT_ATTRIBUTES attributes;
ACXSTREAM stream;
CODEC_STREAM_CONTEXT * streamCtx;
ACXELEMENT elements[2] = {0};
ACX_ELEMENT_CONFIG elementCfg;
CODEC_ELEMENT_CONTEXT * elementCtx;
ACX_STREAM_CALLBACKS streamCallbacks;
ACX_RT_STREAM_CALLBACKS rtCallbacks;
CCaptureStreamEngine * streamEngine = NULL;
CODEC_CAPTURE_CIRCUIT_CONTEXT * circuitCtx;
CODEC_PIN_CONTEXT * pinCtx;
PAGED_CODE();
UNREFERENCED_PARAMETER(SignalProcessingMode);
UNREFERENCED_PARAMETER(VarArguments);
ASSERT(IsEqualGUID(*SignalProcessingMode, AUDIO_SIGNALPROCESSINGMODE_RAW));
devCtx = GetCaptureDeviceContext(Device);
ASSERT(devCtx != NULL);
circuitCtx = GetCaptureCircuitContext(Circuit);
ASSERT(circuitCtx != NULL);
pinCtx = GetCodecPinContext(Pin);
ASSERT(pinCtx != NULL);
//
// Set circuit-callbacks.
//
status = AcxStreamInitAssignAcxRequestPreprocessCallback(
StreamInit,
CodecC_EvtStreamRequestPreprocess,
(ACXCONTEXT)AcxRequestTypeAny, // dbg only
AcxRequestTypeAny,
NULL,
AcxItemIdNone);
if (!NT_SUCCESS(status))
{
ASSERT(FALSE);
goto exit;
}
/*
//
// Add properties, events and methods.
//
status = AcxStreamInitAssignProperties(StreamInit,
StreamProperties,
StreamPropertiesCount);
*/
//
// Init streaming callbacks.
//
ACX_STREAM_CALLBACKS_INIT(&streamCallbacks);
streamCallbacks.EvtAcxStreamPrepareHardware = Codec_EvtStreamPrepareHardware;
streamCallbacks.EvtAcxStreamReleaseHardware = Codec_EvtStreamReleaseHardware;
streamCallbacks.EvtAcxStreamRun = Codec_EvtStreamRun;
streamCallbacks.EvtAcxStreamPause = Codec_EvtStreamPause;
status = AcxStreamInitAssignAcxStreamCallbacks(StreamInit, &streamCallbacks);
if (!NT_SUCCESS(status))
{
ASSERT(FALSE);
goto exit;
}
//
// Init RT streaming callbacks.
//
ACX_RT_STREAM_CALLBACKS_INIT(&rtCallbacks);
rtCallbacks.EvtAcxStreamGetHwLatency = Codec_EvtStreamGetHwLatency;
rtCallbacks.EvtAcxStreamAllocateRtPackets = Codec_EvtStreamAllocateRtPackets;
rtCallbacks.EvtAcxStreamFreeRtPackets = Codec_EvtStreamFreeRtPackets;
rtCallbacks.EvtAcxStreamGetCapturePacket = CodecC_EvtStreamGetCapturePacket;
rtCallbacks.EvtAcxStreamGetCurrentPacket = Codec_EvtStreamGetCurrentPacket;
rtCallbacks.EvtAcxStreamGetPresentationPosition = Codec_EvtStreamGetPresentationPosition;
status = AcxStreamInitAssignAcxRtStreamCallbacks(StreamInit, &rtCallbacks);
if (!NT_SUCCESS(status))
{
ASSERT(FALSE);
goto exit;
}
//
// Buffer notifications are supported.
//
AcxStreamInitSetAcxRtStreamSupportsNotifications(StreamInit);
//
// Create the stream.
//
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, CODEC_STREAM_CONTEXT);
attributes.EvtDestroyCallback = Codec_EvtStreamDestroy;
status = AcxRtStreamCreate(Device, Circuit, &attributes, &StreamInit, &stream);
if (!NT_SUCCESS(status))
{
ASSERT(FALSE);
goto exit;
}
streamCtx = GetCodecStreamContext(stream);
ASSERT(streamCtx);
if (pinCtx->CodecPinType == CodecPinTypeKeyword)
{
PCODEC_KEYWORDSPOTTER_CONTEXT keywordSpotterCtx;
keywordSpotterCtx = GetCodecKeywordSpotterContext(circuitCtx->KeywordSpotter);
streamEngine = new(NonPagedPoolNx, DRIVER_TAG) CBufferedCaptureStreamEngine(stream, StreamFormat, (CKeywordDetector *) keywordSpotterCtx->KeywordDetector);
if (streamEngine == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(FALSE);
goto exit;
}
}
else
{
streamEngine = new(NonPagedPoolNx, DRIVER_TAG) CCaptureStreamEngine(stream, StreamFormat);
if (streamEngine == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
ASSERT(FALSE);
goto exit;
}
}
streamCtx->StreamEngine = (PVOID)streamEngine;
streamEngine = NULL;
//
// Post stream creation initialization.
// Create any custom stream-elements.
// Add stream elements
Requisiti ACX
Versione minima DI ACX: 1.0
Per altre informazioni sulle versioni ACX, vedere Panoramica della versione di ACX.
Requisiti
Requisito | Valore |
---|---|
Intestazione | acxcircuit.h |
IRQL | PASSIVE_LEVEL |