mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 08:50:27 +00:00
[USBAUDIO]
- implement building topology connections svn path=/trunk/; revision=72973
This commit is contained in:
parent
38d01b32ac
commit
9bd7a7db6d
2 changed files with 301 additions and 10 deletions
|
@ -92,7 +92,8 @@ static KSPIN_DISPATCH UsbAudioPinDispatch =
|
|||
|
||||
ULONG
|
||||
CountTopologyComponents(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||
OUT PULONG OutDescriptorCount)
|
||||
{
|
||||
PUSB_INTERFACE_DESCRIPTOR Descriptor;
|
||||
PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
|
||||
|
@ -101,6 +102,7 @@ CountTopologyComponents(
|
|||
PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
|
||||
PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
|
||||
ULONG NodeCount = 0;
|
||||
ULONG DescriptorCount = 0;
|
||||
UCHAR Value;
|
||||
|
||||
for (Descriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
|
||||
|
@ -119,10 +121,12 @@ CountTopologyComponents(
|
|||
if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
|
||||
{
|
||||
NodeCount++;
|
||||
DescriptorCount++;
|
||||
}
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
|
||||
{
|
||||
FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
DescriptorCount++;
|
||||
Value = FeatureUnitDescriptor->bmaControls[0];
|
||||
if (Value & 0x01) /* MUTE*/
|
||||
NodeCount++;
|
||||
|
@ -146,6 +150,7 @@ CountTopologyComponents(
|
|||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
|
||||
{
|
||||
MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
DescriptorCount++;
|
||||
NodeCount += MixerUnitDescriptor->bNrInPins + 1; /* KSNODETYPE_SUPERMIX for each source pin and KSNODETYPE_SUM for target */
|
||||
}
|
||||
else
|
||||
|
@ -159,10 +164,27 @@ CountTopologyComponents(
|
|||
}
|
||||
}
|
||||
}
|
||||
*OutDescriptorCount = DescriptorCount;
|
||||
return NodeCount;
|
||||
}
|
||||
|
||||
PNODE_CONTEXT
|
||||
FindNodeContextWithId(
|
||||
IN PNODE_CONTEXT NodeContext,
|
||||
IN ULONG NodeContextCount,
|
||||
IN UCHAR TerminalId)
|
||||
{
|
||||
ULONG Index;
|
||||
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR TerminalDescriptor;
|
||||
|
||||
for (Index = 0; Index < NodeContextCount; Index++)
|
||||
{
|
||||
TerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)NodeContext[Index].Descriptor;
|
||||
if (TerminalDescriptor->bTerminalID == TerminalId)
|
||||
return &NodeContext[Index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BuildUSBAudioFilterTopology(
|
||||
|
@ -170,7 +192,7 @@ BuildUSBAudioFilterTopology(
|
|||
PKSFILTER_DESCRIPTOR FilterDescriptor)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
ULONG NodeCount, Index;
|
||||
ULONG NodeCount, Index, DescriptorCount, StreamingTerminalIndex, NonStreamingTerminalDescriptorCount, TotalTerminalDescriptorCount, StreamingTerminalPinOffset, ControlDescriptorCount;
|
||||
UCHAR Value;
|
||||
PUSB_INTERFACE_DESCRIPTOR Descriptor;
|
||||
PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR InterfaceHeaderDescriptor;
|
||||
|
@ -178,13 +200,16 @@ BuildUSBAudioFilterTopology(
|
|||
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR InputTerminalDescriptor;
|
||||
PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR FeatureUnitDescriptor;
|
||||
PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR MixerUnitDescriptor;
|
||||
PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR OutputTerminalDescriptor;
|
||||
PKSNODE_DESCRIPTOR NodeDescriptors;
|
||||
PNODE_CONTEXT NodeContext, PreviousNodeContext;
|
||||
PKSTOPOLOGY_CONNECTION Connections;
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = Device->Context;
|
||||
|
||||
/* count topology nodes */
|
||||
NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor);
|
||||
NodeCount = CountTopologyComponents(DeviceExtension->ConfigurationDescriptor, &ControlDescriptorCount);
|
||||
|
||||
/* init node descriptors*/
|
||||
FilterDescriptor->NodeDescriptors = NodeDescriptors = AllocFunction(NodeCount * sizeof(KSNODE_DESCRIPTOR));
|
||||
|
@ -195,6 +220,15 @@ BuildUSBAudioFilterTopology(
|
|||
}
|
||||
FilterDescriptor->NodeDescriptorSize = sizeof(KSNODE_DESCRIPTOR);
|
||||
|
||||
NodeContext = AllocFunction(sizeof(NODE_CONTEXT) * ControlDescriptorCount);
|
||||
if (!NodeContext)
|
||||
{
|
||||
/* no memory */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
DescriptorCount = 0;
|
||||
|
||||
/* first enumerate all topology nodes */
|
||||
for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
|
||||
Descriptor != NULL;
|
||||
Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
|
||||
|
@ -208,13 +242,20 @@ BuildUSBAudioFilterTopology(
|
|||
while (CommonDescriptor)
|
||||
{
|
||||
InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
|
||||
if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/ || InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
|
||||
if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
|
||||
{
|
||||
if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
|
||||
{
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
NodeContext[DescriptorCount].NodeCount = 1;
|
||||
NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
|
||||
DescriptorCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x200)
|
||||
|
@ -222,6 +263,14 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_ADC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_ADC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
NodeContext[DescriptorCount].NodeCount = 1;
|
||||
NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
|
||||
DescriptorCount++;
|
||||
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
|
||||
|
@ -229,6 +278,13 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
NodeContext[DescriptorCount].NodeCount = 1;
|
||||
NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
|
||||
DescriptorCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else
|
||||
|
@ -243,6 +299,13 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SRC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SRC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
NodeContext[DescriptorCount].NodeCount = 1;
|
||||
NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
|
||||
DescriptorCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else if ((InputTerminalDescriptor->wTerminalType & 0xFF00) == 0x300)
|
||||
|
@ -250,6 +313,13 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_DAC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_DAC;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
NodeContext[DescriptorCount].NodeCount = 1;
|
||||
NodeContext[DescriptorCount].Nodes[0] = FilterDescriptor->NodeDescriptorsCount;
|
||||
DescriptorCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else
|
||||
|
@ -260,13 +330,18 @@ BuildUSBAudioFilterTopology(
|
|||
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
|
||||
{
|
||||
FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)CommonDescriptor;
|
||||
Value = FeatureUnitDescriptor->bmaControls[0];
|
||||
if (Value & 0x01) /* MUTE*/
|
||||
{
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_MUTE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_MUTE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
if (Value & 0x02) /* VOLUME */
|
||||
|
@ -274,6 +349,11 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_VOLUME;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_VOLUME;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -282,6 +362,11 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -290,6 +375,11 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -298,6 +388,12 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -306,6 +402,11 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -314,6 +415,12 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
|
@ -322,23 +429,43 @@ BuildUSBAudioFilterTopology(
|
|||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_TONE;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
DescriptorCount++;
|
||||
|
||||
}
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
|
||||
{
|
||||
MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)CommonDescriptor;
|
||||
for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
|
||||
{
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUPERMIX;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUPERMIX;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Type = &KSNODETYPE_SUM;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].Name = &KSNODETYPE_SUM;
|
||||
NodeDescriptors[FilterDescriptor->NodeDescriptorsCount].AutomationTable = AllocFunction(sizeof(KSAUTOMATION_TABLE));
|
||||
|
||||
/* insert into node context*/
|
||||
NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount] = FilterDescriptor->NodeDescriptorsCount;
|
||||
NodeContext[DescriptorCount].NodeCount++;
|
||||
NodeContext[DescriptorCount].Descriptor = CommonDescriptor;
|
||||
DescriptorCount++;
|
||||
|
||||
FilterDescriptor->NodeDescriptorsCount++;
|
||||
}
|
||||
else
|
||||
|
@ -353,6 +480,154 @@ BuildUSBAudioFilterTopology(
|
|||
}
|
||||
}
|
||||
|
||||
/* FIXME determine connections count*/
|
||||
FilterDescriptor->Connections = Connections = AllocFunction(sizeof(KSTOPOLOGY_CONNECTION) * FilterDescriptor->NodeDescriptorsCount * 2);
|
||||
if (!FilterDescriptor->Connections)
|
||||
{
|
||||
/* no memory */
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
FilterDescriptor->ConnectionsCount = 0;
|
||||
|
||||
/* now build connections array */
|
||||
DescriptorCount = 0;
|
||||
StreamingTerminalIndex = 0;
|
||||
NodeCount = 0;
|
||||
|
||||
CountTerminalUnits(DeviceExtension->ConfigurationDescriptor, &NonStreamingTerminalDescriptorCount, &TotalTerminalDescriptorCount);
|
||||
StreamingTerminalPinOffset = TotalTerminalDescriptorCount - NonStreamingTerminalDescriptorCount;
|
||||
|
||||
for (Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
|
||||
Descriptor != NULL;
|
||||
Descriptor = USBD_ParseConfigurationDescriptorEx(DeviceExtension->ConfigurationDescriptor, (PVOID)((ULONG_PTR)Descriptor + Descriptor->bLength), -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1))
|
||||
{
|
||||
if (Descriptor->bInterfaceSubClass == 0x01) /* AUDIO_CONTROL */
|
||||
{
|
||||
InterfaceHeaderDescriptor = (PUSB_AUDIO_CONTROL_INTERFACE_HEADER_DESCRIPTOR)USBD_ParseDescriptors(DeviceExtension->ConfigurationDescriptor, DeviceExtension->ConfigurationDescriptor->wTotalLength, Descriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
|
||||
if (InterfaceHeaderDescriptor != NULL)
|
||||
{
|
||||
CommonDescriptor = USBD_ParseDescriptors(InterfaceHeaderDescriptor, InterfaceHeaderDescriptor->wTotalLength, (PVOID)((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->bLength), USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
|
||||
while (CommonDescriptor)
|
||||
{
|
||||
InputTerminalDescriptor = (PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
|
||||
if (InputTerminalDescriptor->bDescriptorSubtype == 0x02 /* INPUT TERMINAL*/)
|
||||
{
|
||||
if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalIndex;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
StreamingTerminalIndex++;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = KSFILTER_NODE;
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = StreamingTerminalPinOffset;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
StreamingTerminalPinOffset++;
|
||||
}
|
||||
DescriptorCount++;
|
||||
}
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x03 /* OUTPUT_TERMINAL*/)
|
||||
{
|
||||
OutputTerminalDescriptor = (PUSB_AUDIO_CONTROL_OUTPUT_TERMINAL_DESCRIPTOR)CommonDescriptor;
|
||||
PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, OutputTerminalDescriptor->bSourceID);
|
||||
if (PreviousNodeContext)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
}
|
||||
|
||||
if (InputTerminalDescriptor->wTerminalType == USB_AUDIO_STREAMING_TERMINAL_TYPE)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalIndex;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
StreamingTerminalIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = StreamingTerminalPinOffset;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = KSFILTER_NODE;
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
|
||||
StreamingTerminalPinOffset++;
|
||||
}
|
||||
DescriptorCount++;
|
||||
}
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x06 /* FEATURE_UNIT*/)
|
||||
{
|
||||
FeatureUnitDescriptor = (PUSB_AUDIO_CONTROL_FEATURE_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, FeatureUnitDescriptor->bSourceID);
|
||||
if (PreviousNodeContext)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount-1];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[0];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
}
|
||||
for (Index = 1; Index < NodeContext[DescriptorCount].NodeCount; Index++)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index - 1];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
}
|
||||
|
||||
DescriptorCount++;
|
||||
}
|
||||
else if (InputTerminalDescriptor->bDescriptorSubtype == 0x04 /* MIXER_UNIT */)
|
||||
{
|
||||
MixerUnitDescriptor = (PUSB_AUDIO_CONTROL_MIXER_UNIT_DESCRIPTOR)InputTerminalDescriptor;
|
||||
for (Index = 0; Index < MixerUnitDescriptor->bNrInPins; Index++)
|
||||
{
|
||||
Value = MixerUnitDescriptor->baSourceID[Index];
|
||||
PreviousNodeContext = FindNodeContextWithId(NodeContext, ControlDescriptorCount, Value);
|
||||
if (PreviousNodeContext)
|
||||
{
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = PreviousNodeContext->Nodes[PreviousNodeContext->NodeCount - 1];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[Index];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
}
|
||||
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNode = NodeContext[DescriptorCount].Nodes[Index];
|
||||
Connections[FilterDescriptor->ConnectionsCount].FromNodePin = 0;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNodePin = 1 + Index;
|
||||
Connections[FilterDescriptor->ConnectionsCount].ToNode = NodeContext[DescriptorCount].Nodes[NodeContext[DescriptorCount].NodeCount-1];
|
||||
FilterDescriptor->ConnectionsCount++;
|
||||
}
|
||||
DescriptorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
|
||||
if ((ULONG_PTR)CommonDescriptor >= ((ULONG_PTR)InterfaceHeaderDescriptor + InterfaceHeaderDescriptor->wTotalLength))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -400,6 +675,7 @@ USBAudioFilterCreate(
|
|||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CountTerminalUnits(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||
OUT PULONG NonStreamingTerminalDescriptorCount,
|
||||
|
|
|
@ -155,12 +155,20 @@ typedef struct
|
|||
PUCHAR Buffer; /* iso buffer*/
|
||||
ULONG BufferSize; /* iso buffer size */
|
||||
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; /* interface descriptor */
|
||||
WORK_QUEUE_ITEM CaptureWorkItem; /* work item */
|
||||
PKSWORKER CaptureWorker; /* capture worker */
|
||||
WORK_QUEUE_ITEM StarvationWorkItem; /* work item */
|
||||
PKSWORKER StarvationWorker; /* capture worker */
|
||||
WORK_QUEUE_ITEM CaptureWorkItem; /* work item */
|
||||
PKSWORKER CaptureWorker; /* capture worker */
|
||||
WORK_QUEUE_ITEM StarvationWorkItem; /* work item */
|
||||
PKSWORKER StarvationWorker; /* capture worker */
|
||||
}PIN_CONTEXT, *PPIN_CONTEXT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PUSB_COMMON_DESCRIPTOR Descriptor;
|
||||
ULONG NodeCount;
|
||||
ULONG Nodes[20];
|
||||
}NODE_CONTEXT, *PNODE_CONTEXT;
|
||||
|
||||
|
||||
/* filter.c */
|
||||
|
||||
NTSTATUS
|
||||
|
@ -179,6 +187,13 @@ NTAPI
|
|||
FreeFunction(
|
||||
IN PVOID Item);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
CountTerminalUnits(
|
||||
IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor,
|
||||
OUT PULONG NonStreamingTerminalDescriptorCount,
|
||||
OUT PULONG TotalTerminalDescriptorCount);
|
||||
|
||||
/* usbaudio.c */
|
||||
|
||||
NTSTATUS
|
||||
|
|
Loading…
Reference in a new issue