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
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 定義的 DIS (AcxStreamInit*) ,初始化ACXSTREAM_INIT不透明結構
- 它會使用 AcxStreamCreate 或 AcxRtStreamCreate ACX DDI 建立 ACXSTREAM 物件。 AcxRtStreamCreate 僅用於串流連線到上層使用者模式音訊管線的 ACXPIN,端點路徑的所有其他線路都必須改用 AcxStreamCreate DDI。
- 它會建立任何數據流特定的元素,例如 ACXAUDIOENGINE。
- 它會將專案新增至 ACXSTREAM 物件。
- 它會傳回STATUS_SUCCESS,指出數據流建立回呼已順利完成。
音訊路徑中線路之間的串流通道會使用 ACXTARGETSTREAM 物件。
一旦默認目標線路建立 ACXSTREAM 物件,每個線路都會有機會執行數據流的線路特定處理。 每個線路會接著執行下列一或多個動作:
- 使用數據流驅動程式特定的組態或數據,建立內容物件並新增至 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 |