Author: janderwald Date: Thu Aug 13 12:05:42 2009 New Revision: 42650
URL: http://svn.reactos.org/svn/reactos?rev=42650&view=rev Log: [SPLITTER] - Implement Splitter (WIP)
Modified: trunk/reactos/drivers/wdm/audio/filters/splitter/filter.c trunk/reactos/drivers/wdm/audio/filters/splitter/pin.c trunk/reactos/drivers/wdm/audio/filters/splitter/precomp.h trunk/reactos/drivers/wdm/audio/filters/splitter/splitter.c
Modified: trunk/reactos/drivers/wdm/audio/filters/splitter/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/s... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/splitter/filter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/splitter/filter.c [iso-8859-1] Thu Aug 13 12:05:42 2009 @@ -14,7 +14,48 @@ IN PKSFILTER Filter, IN PKSPROCESSPIN_INDEXENTRY ProcessPinsIndex) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + ULONG Index; + PKSPROCESSPIN CurPin, Pin; + BOOLEAN PendingFrames = FALSE; + + if (ProcessPinsIndex->Count) + { + /* check if there are outstanding frames */ + for(Index = 1; Index < ProcessPinsIndex->Count; Index++) + { + /* get current pin */ + CurPin = ProcessPinsIndex->Pins[Index]; + + if (CurPin->BytesAvailable && CurPin->Pin->DeviceState == KSSTATE_RUN) + { + /* pin has pending frames + * to keep all pins synchronized, every pin has to wait untill each chained pin has send its frames downwards + */ + PendingFrames = TRUE; + } + } + } + + if (!PendingFrames && ProcessPinsIndex->Count) + { + /* get first pin */ + Pin = ProcessPinsIndex->Pins[0]; + + /* check if there is new data available */ + if (Pin->BytesAvailable) + { + for(Index = 1; Index < ProcessPinsIndex->Count; Index++) + { + /* get current pin */ + CurPin = ProcessPinsIndex->Pins[Index]; + + /* copy the frame to pin */ + RtlMoveMemory(CurPin->Data, Pin->Data, Pin->BytesAvailable); + CurPin->BytesUsed = Pin->BytesAvailable; + } + } + } + /* done */ + return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/filters/splitter/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/s... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/splitter/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/splitter/pin.c [iso-8859-1] Thu Aug 13 12:05:42 2009 @@ -14,8 +14,45 @@ IN PKSPIN Pin, IN PIRP Irp) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PKSFILTER Filter; + PKSPIN FirstPin; + PPIN_CONTEXT PinContext; + + /* first get the parent filter */ + Filter = KsPinGetParentFilter(Pin); + + /* now get first child pin */ + FirstPin = KsFilterGetFirstChildPin(Filter, Pin->Id); + + /* sanity check */ + ASSERT(FirstPin); + + if (FirstPin != Pin) + { + /* a previous pin already exists */ + if (RtlCompareMemory(FirstPin->ConnectionFormat, Pin->ConnectionFormat, Pin->ConnectionFormat->FormatSize) != Pin->ConnectionFormat->FormatSize) + { + /* each instantiated pin must have the same connection format */ + return STATUS_INVALID_PARAMETER; + } + } + + /* allocate pin context */ + PinContext = ExAllocatePool(NonPagedPool, sizeof(PIN_CONTEXT)); + if (!PinContext) + return STATUS_INSUFFICIENT_RESOURCES; + + /* store pin context */ + Pin->Context = PinContext; + + /* clear pin context */ + RtlZeroMemory(PinContext, sizeof(PIN_CONTEXT)); + + /* FIXME + * check allocator framing and apply to all pins + */ + + return STATUS_SUCCESS; }
NTSTATUS @@ -24,8 +61,14 @@ IN PKSPIN Pin, IN PIRP Irp) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + /* is there a context */ + if (Pin->Context) + { + /* free pin context */ + ExFreePool(Pin->Context); + } + + return STATUS_SUCCESS; }
VOID @@ -33,7 +76,22 @@ PinReset( IN PKSPIN Pin) { - UNIMPLEMENTED + PKSFILTER Filter; + + /* sanity check */ + ASSERT(Pin->Context); + + /* clear pin context */ + RtlZeroMemory(Pin->Context, sizeof(PIN_CONTEXT)); + + /* get parent filter */ + Filter = KsPinGetParentFilter(Pin); + + /* sanity check */ + ASSERT(Filter); + + /* attempt processing */ + KsFilterAttemptProcessing(Filter, TRUE); }
NTSTATUS @@ -43,8 +101,25 @@ IN KSSTATE ToState, IN KSSTATE FromState) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PKSFILTER Filter; + + /* should the pin stop */ + if (ToState == KSSTATE_STOP) + { + /* clear pin context */ + RtlZeroMemory(Pin->Context, sizeof(PIN_CONTEXT)); + } + + /* get parent filter */ + Filter = KsPinGetParentFilter(Pin); + + /* sanity check */ + ASSERT(Filter); + + /* attempt processing */ + KsFilterAttemptProcessing(Filter, TRUE); + + return STATUS_SUCCESS; }
NTSTATUS @@ -54,8 +129,49 @@ IN PKSIDENTIFIER Request, IN OUT PVOID Data) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; + PKSFILTER Filter; + PKSPIN Pin, FirstPin; + PFILE_OBJECT FileObject; + NTSTATUS Status; + ULONG BytesReturned; + + /* first get the pin */ + Pin = KsGetPinFromIrp(Irp); + + /* sanity check */ + ASSERT(Pin); + + /* get parent filter */ + Filter = KsPinGetParentFilter(Pin); + + /* acquire filter control mutex */ + KsFilterAcquireControl(Filter); + + /* get first pin */ + FirstPin = KsFilterGetFirstChildPin(Filter, Pin->Id); + + /* get connected pin of first pin */ + FileObject = KsPinGetConnectedPinFileObject(FirstPin); + + if (!FileObject) + { + /* no pin connected */ + Status = STATUS_INVALID_PARAMETER; + } + else + { + /* perform request */ + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)Request, sizeof(KSPROPERTY), Data, sizeof(KSAUDIO_POSITION), &BytesReturned); + + /* store result size */ + Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); + } + + /* release control */ + KsFilterReleaseControl(Filter); + + /* done */ + return Status; }
NTSTATUS @@ -70,7 +186,54 @@ OUT PVOID Data OPTIONAL, OUT PULONG DataSize) { - UNIMPLEMENTED - return STATUS_NOT_IMPLEMENTED; -} - + PKSPIN FirstPin; + NTSTATUS Status; + + /* get first pin */ + FirstPin = KsFilterGetFirstChildPin((PKSFILTER)Context, Pin->PinId); + + /* sanity check */ + ASSERT(FirstPin); + + /* check for matching dataformat */ + if (!IsEqualGUIDAligned(&FirstPin->ConnectionFormat->SubFormat, &DataRange->SubFormat) || + !IsEqualGUIDAligned(&FirstPin->ConnectionFormat->Specifier, &DataRange->Specifier) || + !IsEqualGUIDAligned(&GUID_NULL, &DataRange->SubFormat) || + !IsEqualGUIDAligned(&GUID_NULL, &DataRange->Specifier)) + { + /* no match */ + return STATUS_NO_MATCH; + } + + + if (DataBufferSize) + { + /* there is output buffer */ + if (DataBufferSize >= FirstPin->ConnectionFormat->FormatSize) + { + /* copy dataformat */ + RtlMoveMemory(Data, FirstPin->ConnectionFormat, FirstPin->ConnectionFormat->FormatSize); + + /* store output length */ + *DataSize = FirstPin->ConnectionFormat->FormatSize; + + Status = STATUS_SUCCESS; + } + else + { + /* buffer too small */ + Status = STATUS_BUFFER_TOO_SMALL; + } + } + else + { + /* store output length */ + *DataSize = FirstPin->ConnectionFormat->FormatSize; + + Status = STATUS_BUFFER_OVERFLOW; + } + + /* done */ + return Status; +} +
Modified: trunk/reactos/drivers/wdm/audio/filters/splitter/precomp.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/s... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/splitter/precomp.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/splitter/precomp.h [iso-8859-1] Thu Aug 13 12:05:42 2009 @@ -58,4 +58,13 @@ OUT PVOID Data OPTIONAL, OUT PULONG DataSize);
+ + +typedef struct +{ + ULONG BytesAvailable; + ULONG BytesProcessed; +}PIN_CONTEXT, *PPIN_CONTEXT; + + #endif
Modified: trunk/reactos/drivers/wdm/audio/filters/splitter/splitter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/s... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/splitter/splitter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/splitter/splitter.c [iso-8859-1] Thu Aug 13 12:05:42 2009 @@ -12,6 +12,8 @@ const GUID KSPROPSETID_Audio = {0x45FFAAA0, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; const GUID KSCATEGORY_AUDIO_SPLITTER = {0x9EA331FA, 0xB91B, 0x45F8, {0x92, 0x85, 0xBD, 0x2B, 0xC7, 0x7A, 0xFC, 0xDE}}; const GUID KSNAME_Filter = {0x9b365890, 0x165f, 0x11d0, {0xa1, 0x95, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}}; +const GUID GUID_NULL = {0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; +
KSPROPERTY_ITEM PinPropertyTable[] =