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/co... ============================================================================== --- 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/pr... ============================================================================== --- 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/to... ============================================================================== --- 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;