Author: janderwald
Date: Sat Oct 16 12:36:21 2010
New Revision: 49166
URL: 
http://svn.reactos.org/svn/reactos?rev=49166&view=rev
Log:
[MMIXER]
- Add support for topologies where pins directly connect to other pins without nodes in
between
- Check if the topology contains node. Fixes assert hit in VmWare Player(sound is not
working)
- Thanks to Caemyr for testing
Modified:
    trunk/reactos/lib/drivers/sound/mmixer/controls.c
    trunk/reactos/lib/drivers/sound/mmixer/priv.h
    trunk/reactos/lib/drivers/sound/mmixer/topology.c
Modified: trunk/reactos/lib/drivers/sound/mmixer/controls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/c…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/controls.c [iso-8859-1] Sat Oct 16 12:36:21
2010
@@ -644,6 +644,7 @@
     MMixerGetAllUpOrDownstreamNodesFromNodeIndex(MixerContext, Topology, LineTerminator,
TRUE, &AllNodesCount, AllNodes);
     /* get all pins which indirectly / directly connect to this node */
+    AllPinsCount = 0;
     MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, LineTerminator,
TRUE, &AllPinsCount, AllPins);
     DPRINT("LineTerminator %lu\n", LineTerminator);
@@ -818,6 +819,7 @@
         /* the mixer is an output mixer
          * find end pin of the node path
          */
+        PinsCount = 0;
         Status = MMixerGetAllUpOrDownstreamPinsFromPinIndex(MixerContext, Topology,
OutConnection->Pin, FALSE, &PinsCount, Pins);
         /* check for success */
@@ -925,6 +927,7 @@
      * For source pins (wave in) search down stream
      * The search direction is always the opposite of the current mixer type
      */
+    PinsFound = 0;
     MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, NodeIndex,
!bInputMixer, &PinsFound, Pins);
     /* if there is now pin found, we have a broken topology */
@@ -961,6 +964,7 @@
     Status = MMixerAllocateTopologyPinArray(MixerContext, Topology, &Pins);
     ASSERT(Status == MM_STATUS_SUCCESS);
+    PinsFound = 0;
     MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, NodeIndex,
bInputMixer, &PinsFound, Pins);
     /* if there is no pin found, we have a broken topology */
Modified: trunk/reactos/lib/drivers/sound/mmixer/priv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/p…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/priv.h [iso-8859-1] Sat Oct 16 12:36:21 2010
@@ -47,6 +47,12 @@
     ULONG NodesConnectedFromCount;
     PTOPOLOGY_NODE * NodesConnectedFrom;
+
+    ULONG PinConnectedFromCount;
+    PULONG PinConnectedFrom;
+
+    ULONG PinConnectedToCount;
+    PULONG PinConnectedTo;
     ULONG Visited;
 }PIN, *PPIN;
Modified: trunk/reactos/lib/drivers/sound/mmixer/topology.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/sound/mmixer/t…
==============================================================================
--- trunk/reactos/lib/drivers/sound/mmixer/topology.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/sound/mmixer/topology.c [iso-8859-1] Sat Oct 16 12:36:21
2010
@@ -70,16 +70,19 @@
     }
     /* allocate topology nodes */
-    Topology->TopologyNodes = (PTOPOLOGY_NODE)
MixerContext->Alloc(sizeof(TOPOLOGY_NODE) * NodesCount);
-
-    if (!Topology->TopologyNodes)
-    {
-        /* release memory */
-        MixerContext->Free(Topology->TopologyPins);
-        MixerContext->Free(Topology);
-
-        /* out of memory */
-        return MM_STATUS_NO_MEMORY;
+    if (NodesCount)
+    {
+        Topology->TopologyNodes = (PTOPOLOGY_NODE)
MixerContext->Alloc(sizeof(TOPOLOGY_NODE) * NodesCount);
+
+        if (!Topology->TopologyNodes)
+        {
+            /* release memory */
+            MixerContext->Free(Topology->TopologyPins);
+            MixerContext->Free(Topology);
+
+            /* out of memory */
+            return MM_STATUS_NO_MEMORY;
+        }
     }
     /* initialize topology */
@@ -336,6 +339,79 @@
 }
 MIXER_STATUS
+MMixerAddPinToPinConnection(
+    IN PMIXER_CONTEXT MixerContext,
+    IN OUT PPIN InPin,
+    IN OUT PPIN OutPin)
+{
+    ULONG Count;
+    PULONG NewPinsIndex;
+
+    /* now enlarge PinConnectedTo */
+    Count = InPin->PinConnectedToCount;
+
+    /* allocate pin connection index */
+    NewPinsIndex = MixerContext->Alloc(sizeof(ULONG) * (Count + 1));
+
+    if (!NewPinsIndex)
+    {
+        /* out of memory */
+        return MM_STATUS_NO_MEMORY;
+    }
+
+    if (Count)
+    {
+        /* copy existing nodes */
+        MixerContext->Copy(NewPinsIndex, InPin->PinConnectedTo, sizeof(ULONG) *
Count);
+
+        /* release old nodes array */
+        MixerContext->Free(InPin->PinConnectedTo);
+    }
+
+    /* add new topology node */
+    NewPinsIndex[Count] = OutPin->PinId;
+
+    /* replace old nodes array */
+    InPin->PinConnectedTo = NewPinsIndex;
+
+    /* increment pin count */
+    InPin->PinConnectedToCount++;
+
+    /* now enlarge PinConnectedFrom */
+    Count = OutPin->PinConnectedFromCount;
+
+    /* allocate pin connection index */
+    NewPinsIndex = MixerContext->Alloc(sizeof(ULONG) * (Count + 1));
+
+    if (!NewPinsIndex)
+    {
+        /* out of memory */
+        return MM_STATUS_NO_MEMORY;
+    }
+
+    if (Count)
+    {
+        /* copy existing nodes */
+        MixerContext->Copy(NewPinsIndex, OutPin->PinConnectedFrom, sizeof(ULONG) *
Count);
+
+        /* release old nodes array */
+        MixerContext->Free(OutPin->PinConnectedFrom);
+    }
+
+    /* add new topology node */
+    NewPinsIndex[Count] = InPin->PinId;
+
+    /* replace old nodes array */
+    OutPin->PinConnectedFrom = NewPinsIndex;
+
+    /* increment pin count */
+    OutPin->PinConnectedFromCount++;
+
+    /* done */
+    return MM_STATUS_SUCCESS;
+}
+
+MIXER_STATUS
 MMixerHandleNodePinConnection(
     IN PMIXER_CONTEXT MixerContext,
     IN PKSTOPOLOGY_CONNECTION Connection,
@@ -345,7 +421,22 @@
     PTOPOLOGY_NODE Node;
     /* check type */
-    if (Connection->FromNode == KSFILTER_NODE)
+    if (Connection->FromNode == KSFILTER_NODE &&
+        Connection->ToNode == KSFILTER_NODE)
+    {
+        /* Pin -> Pin direction */
+
+        /* sanity checks */
+        ASSERT(Topology->TopologyPinsCount > Connection->FromNodePin);
+        ASSERT(Topology->TopologyPinsCount > Connection->ToNodePin);
+
+        /* add connection */
+        return MMixerAddPinToPinConnection(MixerContext,
+
&Topology->TopologyPins[Connection->FromNodePin],
+
&Topology->TopologyPins[Connection->ToNodePin]);
+
+    }
+    else if (Connection->FromNode == KSFILTER_NODE)
     {
         /* Pin -> Node direction */
@@ -543,6 +634,18 @@
         ASSERT(Pin->Visited == FALSE);
         ASSERT(Pins[Index] == Pin->PinId);
+        /* FIXME support Pin -> Pin connections in iteration */
+        if (bUpStream)
+        {
+            /* indicates a very broken topology Pin -> Pin -> Node <-... */
+            ASSERT(Pin->PinConnectedFromCount == 0);
+        }
+        else
+        {
+            /* indicates a very broken topology -> Node -> Pin -> Pin */
+            ASSERT(Pin->PinConnectedToCount == 0);
+        }
+
         /* add them to pin array */
         MMixerAddPinIndexToArray(MixerContext, Pin->PinId,
Topology->TopologyPinsCount, OutPinCount, OutPins);
@@ -592,9 +695,6 @@
 {
     PTOPOLOGY_NODE TopologyNode;
-    /* mark them as empty */
-    *OutPinsCount = 0;
-
     /* reset visited status */
     MMixerResetTopologyVisitStatus(Topology);
@@ -694,27 +794,34 @@
     OUT PULONG OutPinsCount,
     OUT PULONG OutPins)
 {
-    ULONG Index, TopologyNodesCount;
+    ULONG Index, TopologyNodesCount, TopologyPinsCount;
     PPIN Pin;
     PTOPOLOGY_NODE *TopologyNodes;
-
-    /* mark them as empty */
-    *OutPinsCount = 0;
+    PULONG TopologyPins;
     /* get pin */
     Pin = &Topology->TopologyPins[PinIndex];
     if (bUpStream)
     {
-        /* use nodes to which a pin is attached to */
+        /* use nodes to which this pin is attached to */
         TopologyNodes = Pin->NodesConnectedFrom;
         TopologyNodesCount = Pin->NodesConnectedFromCount;
+
+        /* use pins to which this pin is attached to */
+        TopologyPins = Pin->PinConnectedFrom;
+        TopologyPinsCount = Pin->PinConnectedFromCount;
+
     }
     else
     {
-        /* use nodes which are attached to a node */
+        /* use nodes which are attached to a pin */
         TopologyNodes = Pin->NodesConnectedTo;
         TopologyNodesCount = Pin->NodesConnectedToCount;
+
+        /* use pins which are attached to this pin */
+        TopologyPins = Pin->PinConnectedTo;
+        TopologyPinsCount = Pin->PinConnectedToCount;
     }
@@ -723,6 +830,13 @@
     /* sanity check */
     ASSERT(Topology->TopologyPinsCount > PinIndex);
+
+    /* add pins which are directly connected to this pin */
+    for(Index = 0; Index < TopologyPinsCount; Index++)
+    {
+        /* add them to pin array */
+        MMixerAddPinIndexToArray(MixerContext, TopologyPins[Index],
Topology->TopologyPinsCount, OutPinsCount, OutPins);
+    }
     /* now visit all up / down stream pins & nodes */
     for(Index = 0; Index < TopologyNodesCount; Index++)
@@ -991,6 +1105,7 @@
     }
     /* now get connected pins */
+    PinsCount = 0;
     MMixerGetAllUpOrDownstreamPinsFromNodeIndex(MixerContext, Topology, NodeIndex,
bUpStream, &PinsCount, Pins);
     /* set to false */
@@ -1082,7 +1197,7 @@
         return Status;
     }
-    //MMixerPrintTopology(Topology);
+    MMixerPrintTopology(Topology);
     /* store result */
     *OutTopology = Topology;