EVT_ACX_CIRCUIT_CREATE_STREAM コールバック関数 (acxcircuit.h)

ドライバーは、回線ストリーム インスタンスを作成する EVT_ACX_CIRCUIT_CREATE_STREAM コールバックを定義します。

構文

EVT_ACX_CIRCUIT_CREATE_STREAM EvtAcxCircuitCreateStream;

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

パラメーター

Device

指定した ACXCIRCUIT に関連付けられた WDFDEVICE オブジェクト (WDF - フレームワーク オブジェクトの概要に関するページで説明)。

Circuit

新しいストリーム インスタンスに関連付けられている ACXCIRCUIT オブジェクト。 ACX オブジェクトの詳細については、「 ACX オブジェクトの概要」を参照してください。

Pin

新しいストリーム インスタンスに関連付けられている ACXPIN ACX オブジェクト。

StreamInit

ACXSTREAM_INIT ACX オブジェクト。 これは、ストリームの初期化を定義するために使用される不透明な構造体です。

StreamFormat

ストリーム データ形式を定義する ACXDATAFORMAT ACX オブジェクト。

SignalProcessingMode

新しいストリーム回路のオーディオ信号処理モードを識別する GUID。 オーディオ モードの詳細については、「 オーディオ信号処理モード」を参照してください。

VarArguments

ストリームの初期化に使用する追加の引数を含む省略可能な ACXOBJECTBAG オブジェクト。

戻り値

STATUS_SUCCESS呼び出しが成功した場合は を返します。 それ以外の場合は、適切なエラー コードを返します。 詳細については、「 NTSTATUS 値の使用」を参照してください。

注釈

Stream作成の最初の手順は、エンドポイント オーディオ パスで各 ACXCIRCUIT の ACXSTREAM インスタンスを作成することです。 ACX は、各回線の EvtAcxCircuitCreateStream を呼び出します。 ACX はヘッド回線から始まり、各回線の CreateStream を順番に呼び出し、末尾回線で終わる予定です。

ドライバーには、チェーン内の次の回線が呼び出される前または後に初期化を行う機会があります。詳細については、ACXSTREAMBRIDGE オブジェクトを参照してください。

Stream作成要求は、ヘッド回線の作成時に指定された EvtAcxCircuitCreateStream を呼び出すことによって、ヘッド回線のトポロジ生成の一部として公開されている適切な ACXPIN に送信されます。

ストリーム作成コールバックを受け取るドライバーは、次の操作を実行します。

  • ACX で定義された DDI (AcxStreamInit*) を使用して、ACXSTREAM_INIT不透明な構造体を初期化します
  • AcxStreamCreate または AcxRtStreamCreate ACX DDI を使用して ACXSTREAM オブジェクトを作成します。 AcxRtStreamCreate は、上位ユーザー モードのオーディオ パイプラインに接続された ACXPIN のストリーミングにのみ使用されます。エンドポイント パスの他のすべての回線では、代わりに AcxStreamCreate DDI を使用する必要があります。
  • ストリーム固有の要素 (ACXAUDIOENGINE など) が作成されます。
  • 要素が ACXSTREAM オブジェクトに追加されます。
  • ストリーム作成コールバックが正常に完了したことを示すSTATUS_SUCCESSを返します。

オーディオ パス内の回線間のストリーム通信チャネルでは、ACXTARGETSTREAM オブジェクトが使用されます。

既定のターゲット回線で ACXSTREAM オブジェクトが作成されると、各回線には、ストリームに対して回線固有の処理を実行する機会が与えられます。 各回線は、次の 1 つ以上のアクションを実行します。

  • ストリーム ドライバー固有の構成またはデータを使用して、Context オブジェクトを作成して ACXSTREAM に追加します。
  • ACX フレームワークに制御を戻します。これにより、エンドポイント オーディオ パスの次の回線で同じアクションが実行されます。

使用例を次に示します。

    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 の要件

最小 ACX バージョン: 1.0

ACX バージョンの詳細については、「 ACX バージョンの概要」を参照してください。

要件

要件
Header acxcircuit.h
IRQL PASSIVE_LEVEL

こちらもご覧ください