Author: janderwald Date: Fri May 8 17:02:08 2009 New Revision: 40837
URL: http://svn.reactos.org/svn/reactos?rev=40837&view=rev Log: - Partly implement IMasterClock - Implement IAllocatorMXF for IPortPinDMus - Implement rendering midi streams using IMXF object - WIP, not tested yet
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/guids.c [iso-8859-1] Fri May 8 17:02:08 2009 @@ -65,12 +65,14 @@
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; -const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; +const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; + +const GUID IID_IAllocatorMXF = {0xa5f0d62cL, 0xb30f, 0x11d2, {0xb7, 0xa3, 0x00, 0x60, 0x08, 0x33, 0x16, 0xc1}};
/// /// undocumented guids
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Fri May 8 17:02:08 2009 @@ -678,4 +678,6 @@ IN PDEVICE_OBJECT DeviceObject) PURE; };
+#undef INTERFACE + #endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_dmus.c [iso-8859-1] Fri May 8 17:02:08 2009 @@ -14,6 +14,9 @@ { IPortPinDMusVtbl *lpVtbl; IServiceSinkVtbl *lpVtblServiceSink; + IMasterClockVtbl *lpVtblMasterClock; + IAllocatorMXFVtbl *lpVtblAllocatorMXF; + IMXFVtbl *lpVtblMXF;
LONG ref; IPortDMus * Port; @@ -23,6 +26,11 @@
PSERVICEGROUP ServiceGroup;
+ PMXF Mxf; + ULONGLONG SchedulePreFetch; + NPAGED_LOOKASIDE_LIST LookAsideEvent; + NPAGED_LOOKASIDE_LIST LookAsideBuffer; + PMINIPORTMIDI MidiMiniport; PMINIPORTMIDISTREAM MidiStream;
@@ -39,8 +47,15 @@ ULONG PreCompleted; ULONG PostCompleted;
+ ULONG LastTag; + }IPortPinDMusImpl;
+typedef struct +{ + DMUS_KERNEL_EVENT Event; + PVOID Tag; +}DMUS_KERNEL_EVENT_WITH_TAG, *PDMUS_KERNEL_EVENT_WITH_TAG;
typedef struct { @@ -49,10 +64,263 @@ KSSTATE State; }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
-NTSTATUS -NTAPI -IPortDMus_fnProcessNewIrp( - IPortPinDMusImpl * This); +//================================================================================================================================== + + +static +NTSTATUS +NTAPI +IMasterClock_fnQueryInterface( + IMasterClock* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); + + DPRINT("IServiceSink_fnQueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtblServiceSink; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +static +ULONG +NTAPI +IMasterClock_fnAddRef( + IMasterClock* iface) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); + DPRINT("IServiceSink_fnAddRef entered\n"); + + return InterlockedIncrement(&This->ref); +} + +static +ULONG +NTAPI +IMasterClock_fnRelease( + IMasterClock* iface) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblMasterClock); + + InterlockedDecrement(&This->ref); + + DPRINT("IServiceSink_fnRelease entered %u\n", This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +static +NTSTATUS +NTAPI +IMasterClock_fnGetTime( + IMasterClock* iface, + OUT REFERENCE_TIME *prtTime) +{ + UNIMPLEMENTED + return STATUS_SUCCESS; +} + +static IMasterClockVtbl vt_IMasterClock = +{ + IMasterClock_fnQueryInterface, + IMasterClock_fnAddRef, + IMasterClock_fnRelease, + IMasterClock_fnGetTime +}; + +//================================================================================================================================== + + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnQueryInterface( + IAllocatorMXF* iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + DPRINT("IServiceSink_fnQueryInterface entered\n"); + + if (IsEqualGUIDAligned(refiid, &IID_IAllocatorMXF) || + IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtblServiceSink; + InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +static +ULONG +NTAPI +IAllocatorMXF_fnAddRef( + IAllocatorMXF* iface) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + DPRINT("IServiceSink_fnAddRef entered\n"); + + return InterlockedIncrement(&This->ref); +} + +static +ULONG +NTAPI +IAllocatorMXF_fnRelease( + IAllocatorMXF* iface) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + InterlockedDecrement(&This->ref); + + DPRINT("IServiceSink_fnRelease entered %u\n", This->ref); + + if (This->ref == 0) + { + FreeItem(This, TAG_PORTCLASS); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnGetMessage( + IAllocatorMXF* iface, + OUT PDMUS_KERNEL_EVENT * ppDMKEvt) +{ + PVOID Buffer; + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideEvent); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + *ppDMKEvt = Buffer; + RtlZeroMemory(Buffer, sizeof(DMUS_KERNEL_EVENT)); + return STATUS_SUCCESS; +} + +static +USHORT +NTAPI +IAllocatorMXF_fnGetBufferSize( + IAllocatorMXF* iface) +{ + return PAGE_SIZE; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnGetBuffer( + IAllocatorMXF* iface, + OUT PBYTE * ppBuffer) +{ + PVOID Buffer; + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + Buffer = ExAllocateFromNPagedLookasideList(&This->LookAsideBuffer); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + *ppBuffer = Buffer; + RtlZeroMemory(Buffer, PAGE_SIZE); + return STATUS_SUCCESS; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnPutBuffer( + IAllocatorMXF* iface, + IN PBYTE pBuffer) +{ + PDMUS_KERNEL_EVENT_WITH_TAG Event = (PDMUS_KERNEL_EVENT_WITH_TAG)pBuffer; + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + This->IrpQueue->lpVtbl->ReleaseMappingWithTag(This->IrpQueue, Event->Tag); + + ExFreeToNPagedLookasideList(&This->LookAsideBuffer, pBuffer); + return STATUS_SUCCESS; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnSetState( + IAllocatorMXF* iface, + IN KSSTATE State) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnPutMessage( + IAllocatorMXF* iface, + IN PDMUS_KERNEL_EVENT pDMKEvt) +{ + IPortPinDMusImpl * This = (IPortPinDMusImpl*)CONTAINING_RECORD(iface, IPortPinDMusImpl, lpVtblAllocatorMXF); + + ExFreeToNPagedLookasideList(&This->LookAsideEvent, pDMKEvt); + return STATUS_SUCCESS; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnConnectOutput( + IAllocatorMXF* iface, + IN PMXF sinkMXF) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +static +NTSTATUS +NTAPI +IAllocatorMXF_fnDisconnectOutput( + IAllocatorMXF* iface, + IN PMXF sinkMXF) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +static IAllocatorMXFVtbl vt_IAllocatorMXF = +{ + IAllocatorMXF_fnQueryInterface, + IAllocatorMXF_fnAddRef, + IAllocatorMXF_fnRelease, + IAllocatorMXF_fnSetState, + IAllocatorMXF_fnPutMessage, + IAllocatorMXF_fnConnectOutput, + IAllocatorMXF_fnDisconnectOutput, + IAllocatorMXF_fnGetMessage, + IAllocatorMXF_fnGetBufferSize, + IAllocatorMXF_fnGetBuffer, + IAllocatorMXF_fnPutBuffer +};
//==================================================================================================================================
@@ -110,6 +378,8 @@ /* Return new reference count */ return This->ref; } + + static VOID NTAPI @@ -118,8 +388,9 @@ IN PVOID Context) { IPortPinDMusImpl * This; + KSSTATE State; + NTSTATUS Status; PSETSTREAM_CONTEXT Ctx = (PSETSTREAM_CONTEXT)Context; - KSSTATE State;
This = Ctx->Pin; State = Ctx->State; @@ -132,9 +403,18 @@ return;
/* Set the state */ - if (NT_SUCCESS(This->MidiStream->lpVtbl->SetState(This->MidiStream, State))) - { - /* Set internal state to stop */ + if (This->MidiStream) + { + Status = This->MidiStream->lpVtbl->SetState(This->MidiStream, State); + } + else + { + Status = This->Mxf->lpVtbl->SetState(This->Mxf, State); + } + + if (NT_SUCCESS(Status)) + { + /* Set internal state to requested state */ This->State = State;
if (This->State == KSSTATE_STOP) @@ -237,6 +517,59 @@
}
+VOID +TransferMidiDataToDMus( + IPortPinDMusImpl * This) +{ + NTSTATUS Status; + PHYSICAL_ADDRESS PhysicalAddress; + ULONG BufferSize, Flags; + PVOID Buffer; + PDMUS_KERNEL_EVENT_WITH_TAG Event, LastEvent = NULL, Root = NULL; + + do + { + This->LastTag++; + Status = This->IrpQueue->lpVtbl->GetMappingWithTag(This->IrpQueue, UlongToPtr(This->LastTag), &PhysicalAddress, &Buffer, &BufferSize, &Flags); + if (!NT_SUCCESS(Status)) + { + break; + } + + Status = IAllocatorMXF_fnGetMessage((IAllocatorMXF*)&This->lpVtblAllocatorMXF, (PDMUS_KERNEL_EVENT*)&Event); + if (!NT_SUCCESS(Status)) + break; + + //FIXME + //set up struct + //Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE; + Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT); + Event->Event.cbEvent = BufferSize; + Event->Event.uData.pbData = Buffer; + + + if (!Root) + Root = Event; + else + LastEvent->Event.pNextEvt = (struct _DMUS_KERNEL_EVENT *)Event; + + LastEvent = Event; + LastEvent->Event.pNextEvt = NULL; + LastEvent->Tag = UlongToPtr(This->LastTag); + + }while(TRUE); + + if (!Root) + { + SetStreamState(This, KSSTATE_STOP); + return; + } + + Status = This->Mxf->lpVtbl->PutMessage(This->Mxf, (PDMUS_KERNEL_EVENT)Root); + DPRINT("Status %x\n", Status); +} + + static VOID NTAPI @@ -251,8 +584,10 @@ { TransferMidiData(This); } - - + else if (This->Mxf) + { + TransferMidiDataToDMus(This); + } }
static IServiceSinkVtbl vt_IServiceSink = @@ -486,7 +821,7 @@ PCLOSESTREAM_CONTEXT Ctx; IPortPinDMusImpl * This = (IPortPinDMusImpl*)iface;
- if (This->MidiStream) + if (This->MidiStream || This->Mxf) { Ctx = AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); if (!Ctx) @@ -756,6 +1091,38 @@
if (!NT_SUCCESS(Status)) return Status; + } + else + { + Status = This->Miniport->lpVtbl->NewStream(This->Miniport, + &This->Mxf, + NULL, + NonPagedPool, + ConnectDetails->PinId, + Capture, //FIXME + This->Format, + &This->ServiceGroup, + (PAllocatorMXF)&This->lpVtblAllocatorMXF, + (PMASTERCLOCK)&This->lpVtblMasterClock, + &This->SchedulePreFetch); + + DPRINT("IPortPinDMus_fnInit Status %x\n", Status); + + if (!NT_SUCCESS(Status)) + return Status; + + if (Capture == DMUS_STREAM_MIDI_CAPTURE) + { + Status = This->Mxf->lpVtbl->ConnectOutput(This->Mxf, (PMXF)&This->lpVtblMXF); + if (!NT_SUCCESS(Status)) + { + DPRINT("IMXF_ConnectOutput failed with Status %x\n", Status); + return Status; + } + } + + ExInitializeNPagedLookasideList(&This->LookAsideEvent, NULL, NULL, 0, sizeof(DMUS_KERNEL_EVENT_WITH_TAG), TAG_PORTCLASS, 0); + ExInitializeNPagedLookasideList(&This->LookAsideBuffer, NULL, NULL, 0, PAGE_SIZE, TAG_PORTCLASS, 0); }
if (This->ServiceGroup) @@ -832,6 +1199,8 @@ This->ref = 1; This->lpVtbl = &vt_IPortPinDMus; This->lpVtblServiceSink = &vt_IServiceSink; + This->lpVtblMasterClock = &vt_IMasterClock; + This->lpVtblAllocatorMXF = &vt_IAllocatorMXF;
/* store result */ @@ -839,6 +1208,3 @@
return STATUS_SUCCESS; } - - -