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


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

Комментарии

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

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

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

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

  • Он инициализирует ACXSTREAM_INIT непрозрачную структуру с помощью определяемых ACX DDIs (AcxStreamInit*)
  • Он создает объект ACXSTREAM с помощью AcxStreamCreate или AcxRtStreamCreate ACX DDI. AcxRtStreamCreate используется только для потоковой передачи ACXPIN, подключенного к верхнему пользовательскому звуковому конвейеру. Все остальные каналы пути конечной точки должны использовать DDI AcxStreamCreate.
  • Он создает все элементы, зависящие от потока, например 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

См. также раздел