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