Поделиться через


функция обратного вызова 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

Объект WDFDEVICE (описанный в WDF — сводка объектов платформы), связанный с указанным ACXCIRCUIT.

Circuit

Объект ACXCIRCUIT, связанный с новым экземпляром потока. Дополнительные сведения о объектах ACX см. в сводке по объектам ACX.

Pin

Объект ACXPIN ACX, связанный с новым экземпляром потока.

StreamInit

Объект ACX ACXSTREAM_INIT. Это непрозрачная структура, которая используется для определения инициализации потока.

StreamFormat

Объект ACXDATAFORMAT ACX, определяющий формат данных потока.

SignalProcessingMode

ИДЕНТИФИКАТОР GUID, определяющий режим обработки звукового сигнала нового канала потока. Дополнительные сведения о звуковых режимах см. в режимах обработки звуковых сигналов.

VarArguments

Необязательный объект ACXOBJECTBAG, содержащий дополнительные аргументы для инициализации потока.

Возвращаемое значение

Возвращает STATUS_SUCCESS, если вызов выполнен успешно. В противном случае возвращается соответствующий код ошибки. Дополнительные сведения см. в использовании значений NTSTATUS.

Замечания

Первым шагом в создании потока является создание экземпляра ACXSTREAM для каждого ACXCIRCUIT в звуковом пути конечной точки. ACX вызывает evtAcxCircuitCreateStream каждого канала. ACX начнется с головного канала и вызовет каждый канал CreateStream в порядке, заканчивая хвостовой цепью.

Драйверы могут выполнять любую инициализацию до или после вызова следующего канала в цепочке, дополнительные сведения см. в объекте ACXSTREAMBRIDGE.

Запрос на создание потока отправляется в соответствующий ACXPIN, предоставляемый в рамках создания топологии головного канала путем вызова EvtAcxCircuitCreateStream, указанного во время создания головного канала.

Драйвер, получая обратный вызов создания потока, выполняет следующие операции:

  • Она инициализирует непрозрачную структуру ACXSTREAM_INIT с помощью определяемых DDIS (AcxStreamInit*)
  • Он создает объект ACXSTREAM с помощью acxStreamCreate или AcxRtStreamCreate ACX DDI. AcxRtStreamCreate используется только для потоковой передачи ACXPIN, подключенного к звуковому конвейеру верхнего пользовательского режима, все остальные каналы пути конечной точки должны использовать acxStreamCreate DDI.
  • Он создает все элементы, относящиеся к потоку, например ACXAUDIOENGINE.
  • Он добавляет элементы в объект ACXSTREAM.
  • Он возвращает STATUS_SUCCESS, чтобы указать, что обратный вызов создания потока выполнен успешно.

Канал обмена данными между каналами в звуковом пути использует объекты ACXTARGETSTREAM.

Когда целевой канал по умолчанию создает объект ACXSTREAM, каждый канал будет иметь возможность выполнять обработку потока для конкретного канала. Каждый канал в свою очередь выполняет одно или несколько следующих действий:

  • Создайте и добавьте объект 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.

Требования

Требование Ценность
заголовка acxcircuit.h
IRQL PASSIVE_LEVEL

См. также