Condividi tramite


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

Vedi anche