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
새 스트림 instance 연결된 ACXCIRCUIT 개체입니다. ACX 개체에 대한 자세한 내용은 ACX 개체 요약을 참조하세요.
Pin
새 스트림 instance 연결된 ACXPIN ACX 개체입니다.
StreamInit
ACXSTREAM_INIT ACX 개체입니다. 이는 스트림 초기화를 정의하는 데 사용되는 불투명 구조체입니다.
StreamFormat
스트림 데이터 형식을 정의하는 ACXDATAFORMAT ACX 개체입니다.
SignalProcessingMode
새 스트림 회로의 오디오 신호 처리 모드를 식별하는 GUID입니다. 오디오 모드에 대한 자세한 내용은 오디오 신호 처리 모드를 참조하세요.
VarArguments
스트림을 초기화하는 데 사용할 추가 인수를 포함하는 선택적 ACXOBJECTBAG 개체입니다.
반환 값
호출이 성공하면 를 반환합니다 STATUS_SUCCESS
. 그렇지 않으면 적절한 오류 코드를 반환합니다. 자세한 내용은 NTSTATUS 값 사용을 참조하세요.
설명
Stream 만들기의 첫 번째 단계는 엔드포인트 오디오 경로의 각 ACXCIRCUIT에 대한 ACXSTREAM instance 만드는 것입니다. 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 개체를 만들면 각 회로에 스트림에 대한 회로별 처리를 수행할 수 있는 기회가 제공됩니다. 각 회로는 다음 작업 중 하나 이상을 수행합니다.
- 스트림 드라이버별 구성 또는 데이터를 사용하여 ACXSTREAM에 Context 개체를 만들고 추가합니다.
- 제어를 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 |