windows-nt/Source/XPSP1/NT/drivers/wdm/audio/sysaudio/pn.cpp
2020-09-26 16:20:57 +08:00

297 lines
7.3 KiB
C++

//---------------------------------------------------------------------------
//
// 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);
}
//---------------------------------------------------------------------------
#ifdef DEBUG
ENUMFUNC
CPinNode::Dump(
)
{
Assert(this);
dprintf("PN: %08x PI %08x LFN %08x ulOverhead %08x #%d\n",
this,
pPinInfo,
pLogicalFilterNode,
ulOverhead,
pPinInfo->PinId);
dprintf(" Interface: %s\n", DbgIdentifier2Sz(pInterface));
dprintf(" Medium: %s\n", DbgIdentifier2Sz(pMedium));
if(pDataRange != NULL) {
dprintf(" MajorFormat: %s\n", DbgGuid2Sz(&pDataRange->MajorFormat));
dprintf(" SubFormat: %s\n", DbgGuid2Sz(&pDataRange->SubFormat));
dprintf(" Specifier: %s\n", DbgGuid2Sz(&pDataRange->Specifier));
DumpDataRangeAudio((PKSDATARANGE_AUDIO)pDataRange);
}
if(ulDebugFlags == DEBUG_FLAGS_OBJECT ||
ulDebugFlags & DEBUG_FLAGS_LOGICAL_FILTER) {
pPinInfo->Dump();
}
dprintf("\n");
return(STATUS_CONTINUE);
}
#endif
//---------------------------------------------------------------------------