Share via


EVT_ACX_CIRCUIT_CREATE_STREAM función de devolución de llamada (acxcircuit.h)

El controlador define el EVT_ACX_CIRCUIT_CREATE_STREAM devolución de llamada para crear instancias de flujo de circuito.

Sintaxis

EVT_ACX_CIRCUIT_CREATE_STREAM EvtAcxCircuitCreateStream;

NTSTATUS EvtAcxCircuitCreateStream(
  WDFDEVICE Device,
  ACXCIRCUIT Circuit,
  ACXPIN Pin,
  PACXSTREAM_INIT StreamInit,
  ACXDATAFORMAT StreamFormat,
  const GUID *SignalProcessingMode,
  ACXOBJECTBAG VarArguments
)
{...}

Parámetros

Device

Objeto WDFDEVICE (descrito en WDF - Resumen de objetos de marco) asociado al ACXCIRCUIT especificado.

Circuit

Objeto ACXCIRCUIT asociado a la nueva instancia de flujo. Para obtener más información sobre los objetos ACX, vea Resumen de objetos ACX.

Pin

Objeto ACXPIN ACX asociado a la nueva instancia de flujo.

StreamInit

Objeto ACXSTREAM_INIT ACX. Se trata de una estructura opaca, que se usa para definir la inicialización de la secuencia.

StreamFormat

Objeto ACXDATAFORMAT ACX que define el formato de datos de flujo.

SignalProcessingMode

GUID que identifica el modo de procesamiento de señales de audio del nuevo circuito de secuencia. Para obtener más información sobre los modos de audio, consulte Modos de procesamiento de señal de audio.

VarArguments

Objeto ACXOBJECTBAG opcional que contiene argumentos adicionales que se usarán para inicializar la secuencia.

Valor devuelto

Devuelve STATUS_SUCCESS si la llamada se realizó correctamente. De lo contrario, devuelve un código de error adecuado. Para obtener más información, vea Uso de valores NTSTATUS.

Comentarios

El primer paso de Stream Creación es crear la instancia de ACXSTREAM para cada ACXCIRCUIT en la ruta de acceso de audio del punto de conexión. ACX llamará a EvtAcxCircuitCreateStream de cada circuito. ACX comenzará con el circuito principal y llamará a CreateStream de cada circuito en orden, finalizando con el circuito de cola.

Los controladores tienen la oportunidad de realizar cualquier inicialización antes o después de invocar el siguiente circuito de la cadena, consulte el objeto ACXSTREAMBRIDGE para obtener más información.

La solicitud de creación de Stream se envía al ACXPIN adecuado expuesto como parte de la generación de topología del circuito principal llamando al EvtAcxCircuitCreateStream especificado durante la creación del circuito principal.

El controlador que recibe la devolución de llamada de creación de flujos realiza las siguientes operaciones:

  • Inicializa la estructura ACXSTREAM_INIT opaca mediante DDIs definidos por ACX (AcxStreamInit*)
  • Crea el objeto ACXSTREAM mediante AcxStreamCreate o AcxRtStreamCreate ACX DDI. AcxRtStreamCreate solo se usa para transmitir ACXPIN conectado a la canalización de audio en modo de usuario superior, todos los demás circuitos de la ruta de acceso del punto de conexión deben usar acxStreamCreate DDI en su lugar.
  • Crea cualquier elemento específico de la secuencia, por ejemplo ACXAUDIOENGINE.
  • Agrega los elementos al objeto ACXSTREAM.
  • Devuelve STATUS_SUCCESS para indicar que la devolución de llamada de creación de flujos se completó correctamente.

El canal de comunicación de secuencia entre circuitos de una ruta de acceso de audio usa objetos ACXTARGETSTREAM.

Una vez que el circuito de destino predeterminado crea el objeto ACXSTREAM, cada circuito tendrá la oportunidad de realizar un control específico del circuito para la secuencia. Cada circuito a su vez realiza una o varias de las siguientes acciones:

  • Cree y agregue un objeto Context al ACXSTREAM con una configuración o datos específicos del controlador de secuencia.
  • Devuelve el control al marco ACX, que realizará la misma acción con el siguiente circuito en la ruta de acceso de audio del punto de conexión.

Ejemplo

A continuación se muestra el uso de ejemplo.

    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

Requisitos de ACX

Versión mínima de ACX: 1.0

Para obtener más información sobre las versiones de ACX, consulte Introducción a la versión de ACX.

Requisitos

Requisito Valor
Header acxcircuit.h
IRQL PASSIVE_LEVEL

Consulte también