EVT_ACX_CIRCUIT_CREATE_STREAM Rückruffunktion (acxcircuit.h)

Der Treiber definiert den EVT_ACX_CIRCUIT_CREATE_STREAM Rückruf zum Erstellen von Leitungsstreaminstanzen.

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 Frameworkobjekten), das dem angegebenen ACXCIRCUIT zugeordnet ist.

Circuit

Das ACXCIRCUIT-Objekt, das dem neuen Stream instance. Weitere Informationen zu ACX-Objekten finden Sie unter Zusammenfassung von ACX-Objekten.

Pin

Das ACXPIN ACX-Objekt, das dem neuen Stream instance.

StreamInit

Das ACXSTREAM_INIT ACX-Objekt. Dies ist eine undurchsichtige Struktur, die zum Definieren der Streaminitialisierung verwendet wird.

StreamFormat

Ein ACXDATAFORMAT ACX-Objekt, das das Datenstromdatenformat definiert.

SignalProcessingMode

Eine GUID, die den Audiosignalverarbeitungsmodus der neuen Streamschaltung 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 zurück STATUS_SUCCESS , wenn der Aufruf erfolgreich war. Andernfalls wird ein geeigneter Fehlercode zurückgegeben. Weitere Informationen finden Sie unter Verwenden von NTSTATUS-Werten.

Hinweise

Der erste Schritt in Stream Erstellung besteht darin, die ACXSTREAM-instance für jeden ACXCIRCUIT im Endpunktaudiopfad zu erstellen. ACX ruft den EvtAcxCircuitCreateStream jeder Verbindung auf. ACX beginnt mit der Hauptschaltung und ruft den CreateStream der einzelnen Leitungen in der reihenfolge auf und endet mit der Endschaltung.

Die Treiber haben die Möglichkeit, eine Initialisierung vor oder nach dem Aufruf der nächsten Verbindung in der Kette durchzuführen. Weitere Informationen finden Sie im ACXSTREAMBRIDGE-Objekt.

Die Stream-Erstellungsanforderung wird an die entsprechende ACXPIN-Instanz gesendet, die im Rahmen der Topologiegenerierung der Hauptschaltung verfügbar gemacht wird, indem der bei der Erstellung der Hauptleitung angegebene EvtAcxCircuitCreateStream aufgerufen wird.

Der Treiber, der den Rückruf zur Streamerstellung empfängt, führt die folgenden Vorgänge aus:

  • Die ACXSTREAM_INIT undurchsichtige Struktur wird mithilfe von ACX definierten DDIs (AcxStreamInit*) initialisiert.
  • Das ACXSTREAM-Objekt wird mithilfe von AcxStreamCreate oder AcxRtStreamCreate ACX DDI erstellt. AcxRtStreamCreate wird nur für das Streaming von ACXPIN verwendet, das mit der Audiopipeline im oberen Benutzermodus verbunden ist. Alle anderen Leitungen des Endpunktpfads müssen stattdessen acxStreamCreate DDI verwenden.
  • Es erstellt alle datenstromspezifischen Elemente, z. B. ACXAUDIOENGINE.
  • Die Elemente werden dem ACXSTREAM-Objekt hinzugefügt.
  • Es wird STATUS_SUCCESS zurückgegeben, um anzugeben, dass der Rückruf zur Streamerstellung erfolgreich abgeschlossen wurde.

Der Datenstromkommunikationskanal zwischen Leitungen in einem Audiopfad verwendet ACXTARGETSTREAM-Objekte.

Sobald die Standardzielschaltung das ACXSTREAM-Objekt erstellt, erhält jede Verbindung die Möglichkeit, eine leitungsspezifische Behandlung für den Stream durchzuführen. Jede Verbindung führt wiederum eine oder mehrere der folgenden Aktionen aus:

  • Erstellen Sie ein Context-Objekt, und fügen Sie dem ACXSTREAM ein Context-Objekt mit streamtreiberspezifischen Konfigurationen oder Daten hinzu.
  • Geben Sie die Steuerung an das ACX-Framework zurück, das dieselbe Aktion mit der nächsten Leitung im Endpunktaudiopfad ausführt.

Beispiel

Das Beispiel für die Verwendung ist unten dargestellt.

    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

ACX-Mindestversion: 1.0

Weitere Informationen zu ACX-Versionen finden Sie unter ACX-Versionsübersicht.

Anforderungen

Anforderung Wert
Header acxcircuit.h
IRQL PASSIVE_LEVEL

Weitere Informationen