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/splitter/filter.c?rev=42650&r1=42649&r2=42650&view=diff
==============================================================================
--- 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/splitter/pin.c?rev=42650&r1=42649&r2=42650&view=diff
==============================================================================
--- 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/splitter/precomp.h?rev=42650&r1=42649&r2=42650&view=diff
==============================================================================
--- 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/splitter/splitter.c?rev=42650&r1=42649&r2=42650&view=diff
==============================================================================
--- 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[] =


Reply via email to