EVT_ACX_CIRCUIT_CREATE_STREAM Rückruffunktion (acxcircuit.h)
Der Treiber definiert den EVT_ACX_CIRCUIT_CREATE_STREAM Rückruf zum Erstellen von Schaltstrominstanzen.
Syntax
EVT_ACX_CIRCUIT_CREATE_STREAM EvtAcxCircuitCreateStream;
NTSTATUS EvtAcxCircuitCreateStream(
WDFDEVICE Device,
ACXCIRCUIT Circuit,
ACXPIN Pin,
PACXSTREAM_INIT StreamInit,
ACXDATAFORMAT StreamFormat,
const GUID *SignalProcessingMode,
ACXOBJECTBAG VarArguments
)
{...}
Parameter
Device
Ein WDFDEVICE-Objekt (beschrieben in WDF - Zusammenfassung von Framework-Objekten), das dem angegebenen ACXCIRCUIT zugeordnet ist.
Circuit
Das ACXCIRCUIT-Objekt, das der neuen Streaminstanz zugeordnet ist. Weitere Informationen zu ACX-Objekten finden Sie unter Zusammenfassung von ACX-Objekten.
Pin
Das ACXPIN ACX-Objekt, das der neuen Streaminstanz zugeordnet ist.
StreamInit
Das ACXSTREAM_INIT ACX-Objekt. Dies ist eine undurchsichtige Struktur, die zum Definieren der Datenstrominitialisierung verwendet wird.
StreamFormat
Ein ACXDATAFORMAT ACX-Objekt, das das Datenstromformat definiert.
SignalProcessingMode
Eine GUID, die den Audiosignalverarbeitungsmodus der neuen Datenstromschaltung identifiziert. Weitere Informationen zu Audiomodi finden Sie unter Audiosignalverarbeitungsmodi.
VarArguments
Ein optionales ACXOBJECTBAG-Objekt, das zusätzliche Argumente enthält, die zum Initialisieren des Datenstroms verwendet werden sollen.
Rückgabewert
Gibt STATUS_SUCCESS
zurück, wenn der Anruf erfolgreich war. Andernfalls wird ein entsprechender Fehlercode zurückgegeben. Weitere Informationen finden Sie unter Verwenden von NTSTATUS-Werten.
Bemerkungen
Der erste Schritt bei der Streamerstellung besteht darin, die ACXSTREAM-Instanz für jeden ACXCIRCUIT im Endpunkt-Audiopfad zu erstellen. ACX ruft den EvtAcxCircuitCreateStream jedes Schaltkreises auf. ACX beginnt mit dem Leiterkreis und ruft den CreateStream jedes Schaltkreises in der Reihenfolge auf, die mit dem Tail-Schaltkreis endet.
Die Treiber haben die Möglichkeit, eine Initialisierung vor oder nach dem Aufruf des nächsten Schaltkreises in der Kette durchzuführen. Weitere Informationen finden Sie im ACXSTREAMBRIDGE-Objekt.
Die Stream Creation Request wird an die entsprechende ACXPIN gesendet, die als Teil der Topologiegenerierung des Leiterkreises verfügbar gemacht wird, indem der evtAcxCircuitCreateStream aufgerufen wird, der während der Erstellung des Leiterkreises angegeben wurde.
Der Treiber, der den Datenstromerstellungsrückruf empfängt, führt die folgenden Vorgänge aus:
- Sie initialisiert die ACXSTREAM_INIT undurchsichtige Struktur mithilfe von ACX definierten DDIs (AcxStreamInit*)
- Es erstellt das ACXSTREAM-Objekt mithilfe von AcxStreamCreate oder AcxRtStreamCreate ACX DDI. AcxRtStreamCreate wird nur für das Streaming von ACXPIN verwendet, das mit der Audiopipeline für den oberen Benutzermodus verbunden ist. Alle anderen Schaltungen des Endpunktpfads müssen stattdessen den AcxStreamCreate DDI verwenden.
- Es erstellt streamspezifische Elemente, z. B. ACXAUDIOENGINE.
- Es fügt die Elemente dem ACXSTREAM-Objekt hinzu.
- Es gibt STATUS_SUCCESS zurück, um anzugeben, dass der Datenstromerstellungsrückruf erfolgreich abgeschlossen wurde.
Der Datenstromkommunikationskanal zwischen Schaltkreisen in einem Audiopfad verwendet ACXTARGETSTREAM-Objekte.
Sobald der Standardzielkreis das ACXSTREAM-Objekt erstellt hat, erhält jeder Schaltkreis die Möglichkeit, schaltkreisspezifische Behandlung für den Datenstrom durchzuführen. Jeder Schaltkreis führt wiederum eine oder mehrere der folgenden Aktionen aus:
- Erstellen und Hinzufügen eines Context-Objekts zum ACXSTREAM mit streamtreiberspezifischer Konfiguration oder Daten.
- Zurückgeben der Steuerung an das ACX-Framework, das dieselbe Aktion mit der nächsten Schaltung im Endpunktaudiopfad ausführt.
Beispiel
Die Beispielverwendung wird unten gezeigt.
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
ACX-Anforderungen
Mindestens ACX-Version: 1.0
Weitere Informationen zu ACX-Versionen finden Sie unter ACX-Versionsübersicht.
Anforderungen
Anforderung | Wert |
---|---|
Header- | acxcircuit.h |
IRQL- | PASSIVE_LEVEL |