//--------------------------------------------------------------------------- // // Module: pn.cpp // // Description: // // //@@BEGIN_MSINTERNAL // Development Team: // Mike McLaughlin // // History: Date Author Comment // // To Do: Date Author Comment // //@@END_MSINTERNAL // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------- #include "common.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- CPinNode::CPinNode( PPIN_INFO pPinInfo ) { Assert(pPinInfo); this->pPinInfo = pPinInfo; AddList(&pPinInfo->lstPinNode); } CPinNode::CPinNode( PGRAPH_NODE pGraphNode, PPIN_NODE pPinNode ) { this->pPinInfo = pPinNode->pPinInfo; this->ulOverhead = pPinNode->GetOverhead(); this->pDataRange = pPinNode->pDataRange; this->pInterface = pPinNode->pInterface; this->pMedium = pPinNode->pMedium; this->pLogicalFilterNode = pPinNode->pLogicalFilterNode; AddList(&pGraphNode->lstPinNode); } NTSTATUS CPinNode::CreateAll( PPIN_INFO pPinInfo, PDATARANGES pDataRanges, PIDENTIFIERS pInterfaces, PIDENTIFIERS pMediums ) { NTSTATUS Status = STATUS_SUCCESS; PKSDATARANGE pDataRange; PPIN_NODE pPinNode; ULONG d, i, m; Assert(pPinInfo); // Data Ranges loop pDataRange = &pDataRanges->aDataRanges[0]; for(d = 0; d < pDataRanges->MultipleItem.Count; d++) { if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, &pDataRange->Specifier) || IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, &pDataRange->Specifier)) { // // Reject KSDATARANGE_AUDIO's that have the wrong size // if(pDataRange->FormatSize < sizeof(KSDATARANGE_AUDIO)) { DPF(5, "CPinNode::Create: KSDATARANGE_AUDIO wrong size"); continue; } } // Interfaces loop for(i = 0; i < pInterfaces->MultipleItem.Count; i++) { // Mediums loop for(m = 0; m < pMediums->MultipleItem.Count; m++) { pPinNode = new PIN_NODE(pPinInfo); if(pPinNode == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; Trap(); goto exit; } if(pDataRanges != &DataRangesNull) { pPinNode->pDataRange = pDataRange; AssertAligned(pPinNode->pDataRange); } else Trap(); if(pInterfaces != &IdentifiersNull) { pPinNode->pInterface = &pInterfaces->aIdentifiers[i]; AssertAligned(pPinNode->pInterface); } if(pMediums != &IdentifiersNull) { pPinNode->pMedium = &pMediums->aIdentifiers[m]; AssertAligned(pPinNode->pMedium); } else Trap(); if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, &pDataRange->Specifier) || IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, &pDataRange->Specifier)) { // // Puts in order based on SR, BPS and CHs, // scaled down to 0 - 256 // pPinNode->ulOverhead = 256 - (( (((PKSDATARANGE_AUDIO)pDataRange)-> MaximumChannels > 6 ? 6 : ((PKSDATARANGE_AUDIO)pDataRange)-> MaximumChannels) * ((PKSDATARANGE_AUDIO)pDataRange)-> MaximumSampleFrequency * ((PKSDATARANGE_AUDIO)pDataRange)-> MaximumBitsPerSample) / ((96000 * 32 * 6)/256)); // // Try the WaveFormatEx format first, then DSOUND // if(IsEqualGUID( &KSDATAFORMAT_SPECIFIER_DSOUND, &pDataRange->Specifier)) { pPinNode->ulOverhead += 1; } } else { // Put in order that the filter had the data ranges pPinNode->ulOverhead = d; } // Put in order that the filter had the interface/mediums pPinNode->ulOverhead += (m << 16) + (i << 8); } } // Get the pointer to the next data range *((PUCHAR*)&pDataRange) += ((pDataRange->FormatSize + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT); } exit: return(Status); } BOOL CPinNode::ComparePins( PPIN_NODE pPinNode2 ) { PPIN_NODE pPinNode1 = this; // Check if dataflow is compatible switch(pPinNode1->pPinInfo->DataFlow) { case KSPIN_DATAFLOW_IN: switch(pPinNode2->pPinInfo->DataFlow) { case KSPIN_DATAFLOW_OUT: break; default: DPF(100, "ComparePins: dataflow mismatch"); return(FALSE); } break; case KSPIN_DATAFLOW_OUT: switch(pPinNode2->pPinInfo->DataFlow) { case KSPIN_DATAFLOW_IN: break; default: DPF(100, "ComparePins: dataflow mismatch"); return(FALSE); } break; default: Trap(); DPF(100, "ComparePins: dataflow mismatch"); return(FALSE); } // Check if communication type is compatible switch(pPinNode1->pPinInfo->Communication) { case KSPIN_COMMUNICATION_BOTH: switch(pPinNode2->pPinInfo->Communication) { case KSPIN_COMMUNICATION_BOTH: case KSPIN_COMMUNICATION_SINK: case KSPIN_COMMUNICATION_SOURCE: break; default: DPF(100, "ComparePins: comm mismatch"); return(FALSE); } break; case KSPIN_COMMUNICATION_SOURCE: switch(pPinNode2->pPinInfo->Communication) { case KSPIN_COMMUNICATION_BOTH: case KSPIN_COMMUNICATION_SINK: break; default: DPF(100, "ComparePins: comm mismatch"); return(FALSE); } break; case KSPIN_COMMUNICATION_SINK: switch(pPinNode2->pPinInfo->Communication) { case KSPIN_COMMUNICATION_BOTH: case KSPIN_COMMUNICATION_SOURCE: break; default: DPF(100, "ComparePins: comm mismatch"); return(FALSE); } break; default: DPF(100, "ComparePins: comm mismatch"); return(FALSE); } // Check if interface is the same if(!CompareIdentifier(pPinNode1->pInterface, pPinNode2->pInterface)) { DPF(100, "ComparePins: interface mismatch"); return(FALSE); } // Check if medium is the same if(!CompareIdentifier(pPinNode1->pMedium, pPinNode2->pMedium)) { Trap(); DPF(100, "ComparePins: medium mismatch"); return(FALSE); } // Check if data range is the same if(!CompareDataRange(pPinNode1->pDataRange, pPinNode2->pDataRange)) { DPF(100, "ComparePins: datarange mismatch"); return(FALSE); } return(TRUE); } //---------------------------------------------------------------------------