Partager via


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 - Summary of Framework Objects) associé à l’ACXCIRCUIT spécifié.

Circuit

Objet ACXCIRCUIT associé au nouveau flux instance. Pour plus d’informations sur les objets ACX, consultez Résumé des objets ACX.

Pin

Objet ACXPIN ACX associé au nouveau flux instance.

StreamInit

Objet ACX ACXSTREAM_INIT. Il s’agit d’une structure opaque qui est 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 du signal audio.

VarArguments

Objet ACXOBJECTBAG facultatif contenant des arguments supplémentaires à utiliser pour initialiser le flux.

Valeur retournée

Retourne STATUS_SUCCESS si l’appel a réussi. Sinon, elle retourne un code d’erreur approprié. Pour plus d’informations, consultez Utilisation de valeurs NTSTATUS.

Remarques

La première étape de Stream création consiste à créer le instance ACXSTREAM pour chaque ACXCIRCUIT dans le chemin d’accès audio du point de terminaison. ACX appellera l’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 circuit suivant dans la chaîne. Pour plus d’informations, reportez-vous à l’objet ACXSTREAMBRIDGE.

La demande de création Stream 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 qui reçoit le rappel de création de flux effectue les opérations suivantes :

  • Il initialise la structure opaque ACXSTREAM_INIT à l’aide de DDIs définis par ACX (AcxStreamInit*)
  • Il crée l’objet ACXSTREAM à l’aide du DDI AcxStreamCreate ou AcxRtStreamCreate ACX. AcxRtStreamCreate est utilisé uniquement pour la diffusion en continu d’ACXPIN connecté au pipeline audio en mode utilisateur supérieur. Tous les autres circuits du chemin du 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é avec succès.

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 a créé l’objet ACXSTREAM, chaque circuit a 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 au pilote de flux.
  • Retournez le contrôle à l’infrastructure ACX, qui effectuera la même action avec le circuit suivant dans le chemin d’accès 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 ACX minimale : 1.0

Pour plus d’informations sur les versions d’ACX, consultez Vue d’ensemble des versions d’ACX.

Configuration requise

Condition requise Valeur
En-tête acxcircuit.h
IRQL PASSIVE_LEVEL

Voir aussi