EVT_ACX_CIRCUIT_CREATE_STREAM fonction de rappel (acxcircuit.h)
Le pilote définit le rappel EVT_ACX_CIRCUIT_CREATE_STREAM pour créer des instances de flux de circuit.
Syntaxe
EVT_ACX_CIRCUIT_CREATE_STREAM EvtAcxCircuitCreateStream;
NTSTATUS EvtAcxCircuitCreateStream(
WDFDEVICE Device,
ACXCIRCUIT Circuit,
ACXPIN Pin,
PACXSTREAM_INIT StreamInit,
ACXDATAFORMAT StreamFormat,
const GUID *SignalProcessingMode,
ACXOBJECTBAG VarArguments
)
{...}
Paramètres
Device
Objet WDFDEVICE (décrit dans WDF - Résumé des objets framework) associé à l’ACXCIRCUIT spécifié.
Circuit
Objet ACXCIRCUIT associé à la nouvelle instance de flux. Pour plus d’informations sur les objets ACX, consultez Résumé des objets ACX.
Pin
Objet ACXPIN ACX ASSOCIÉ à la nouvelle instance de flux.
StreamInit
Objet ACX ACXSTREAM_INIT. Il s’agit d’une structure opaque, utilisée pour définir l’initialisation du flux.
StreamFormat
Objet ACXDATAFORMAT ACX qui définit le format de données de flux.
SignalProcessingMode
GUID identifiant le mode de traitement du signal audio du nouveau circuit de flux. Pour plus d’informations sur les modes audio, consultez modes de traitement de signal audio.
VarArguments
Objet ACXOBJECTBAG facultatif contenant des arguments supplémentaires à utiliser pour initialiser le flux.
Valeur de retour
Retourne STATUS_SUCCESS
si l’appel a réussi. Sinon, elle retourne un code d’erreur approprié. Pour plus d’informations, consultez Using NTSTATUS Values.
Remarques
La première étape de la création de flux consiste à créer l’instance ACXSTREAM pour chaque ACXCIRCUIT dans le chemin audio du point de terminaison. ACX appellera EvtAcxCircuitCreateStream de chaque circuit. ACX commence par le circuit principal et appelle le CreateStream de chaque circuit dans l’ordre, se terminant par le circuit de queue.
Les pilotes ont la possibilité d’effectuer une initialisation avant ou après l’appel du prochain circuit de la chaîne, reportez-vous à l’objet ACXSTREAMBRIDGE pour plus d’informations.
La demande de création de flux est envoyée à l’ACXPIN approprié exposé dans le cadre de la génération de topologie du circuit principal en appelant l’EvtAcxCircuitCreateStream spécifié lors de la création du circuit principal.
Le pilote recevant le rappel de création de flux effectue les opérations suivantes :
- Il initialise la structure opaque ACXSTREAM_INIT à l’aide des DDIs définis par ACX (AcxStreamInit*)
- Il crée l’objet ACXSTREAM à l’aide d’AcxStreamCreate ou d’AcxRtStreamCreate ACX DDI. AcxRtStreamCreate est utilisé uniquement pour la diffusion en continu d’ACXPIN connectée au pipeline audio en mode utilisateur supérieur, tous les autres circuits du chemin d’accès au point de terminaison doivent utiliser le DDI AcxStreamCreate à la place.
- Il crée des éléments spécifiques au flux, par exemple ACXAUDIOENGINE.
- Il ajoute les éléments à l’objet ACXSTREAM.
- Elle retourne STATUS_SUCCESS pour indiquer que le rappel de création de flux s’est terminé correctement.
Le canal de communication de flux entre les circuits d’un chemin audio utilise des objets ACXTARGETSTREAM.
Une fois que le circuit cible par défaut crée l’objet ACXSTREAM, chaque circuit aura la possibilité d’effectuer une gestion spécifique au circuit pour le flux. Chaque circuit effectue à son tour une ou plusieurs des actions suivantes :
- Créez et ajoutez un objet Context à ACXSTREAM avec une configuration ou des données spécifiques du pilote de flux.
- Revenez au framework ACX, qui effectue la même action avec le circuit suivant dans le chemin audio du point de terminaison.
Exemple
L’exemple d’utilisation est illustré ci-dessous.
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
Configuration requise pour ACX
version minimale d’ACX : 1.0
Pour plus d’informations sur les versions ACX, consultez vue d’ensemble de la version ACX.
Exigences
Exigence | Valeur |
---|---|
d’en-tête | acxcircuit.h |
IRQL | PASSIVE_LEVEL |