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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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[] =