Author: janderwald
Date: Fri Oct 14 10:35:19 2016
New Revision: 72969
URL:
http://svn.reactos.org/svn/reactos?rev=72969&view=rev
Log:
[USBAUDIO]
- specify processings flags in filter descriptor
- implement processing workers
- move code for initializing irp & urb into single function
- usbaudio now successfully captures audio in win2k3.
Modified:
trunk/reactos/drivers/usb/usbaudio/filter.c
trunk/reactos/drivers/usb/usbaudio/pin.c
trunk/reactos/drivers/usb/usbaudio/usbaudio.h
Modified: trunk/reactos/drivers/usb/usbaudio/filter.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/filte…
==============================================================================
--- trunk/reactos/drivers/usb/usbaudio/filter.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbaudio/filter.c [iso-8859-1] Fri Oct 14 10:35:19 2016
@@ -448,6 +448,9 @@
Pins[Index].PinDescriptor.DataFlow = KSPIN_DATAFLOW_IN;
}
+
+ Pins[Index].Flags = KSPIN_FLAG_PROCESS_IN_RUN_STATE_ONLY |
KSFILTER_FLAG_CRITICAL_PROCESSING;
+
/* irp sinks / sources can be instantiated */
Pins[Index].InstancesPossible = 1;
Pins[Index].InstancesNecessary = 1;
Modified: trunk/reactos/drivers/usb/usbaudio/pin.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/pin.c…
==============================================================================
--- trunk/reactos/drivers/usb/usbaudio/pin.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbaudio/pin.c [iso-8859-1] Fri Oct 14 10:35:19 2016
@@ -8,7 +8,9 @@
*/
#include "usbaudio.h"
-#include <math.h>
+
+#define PACKET_COUNT 10
+
NTSTATUS
GetMaxPacketSizeForInterface(
@@ -55,15 +57,11 @@
OUT PURB * OutUrb)
{
PURB Urb;
- ULONG PacketCount;
ULONG UrbSize;
ULONG Index;
- /* calculate packet count */
- PacketCount = BufferLength / MaxPacketSize;
-
/* calculate urb size*/
- UrbSize = GET_ISO_URB_SIZE(PacketCount);
+ UrbSize = GET_ISO_URB_SIZE(PACKET_COUNT);
/* allocate urb */
Urb = AllocFunction(UrbSize);
@@ -80,9 +78,9 @@
Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN |
USBD_START_ISO_TRANSFER_ASAP;
Urb->UrbIsochronousTransfer.TransferBufferLength = BufferLength;
Urb->UrbIsochronousTransfer.TransferBuffer = Buffer;
- Urb->UrbIsochronousTransfer.NumberOfPackets = PacketCount;
-
- for (Index = 0; Index < PacketCount; Index++)
+ Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
+
+ for (Index = 0; Index < PACKET_COUNT; Index++)
{
Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * MaxPacketSize;
}
@@ -92,7 +90,112 @@
}
-
+NTSTATUS
+UsbAudioSetMuteOff(
+ IN PKSPIN Pin)
+{
+ PURB Urb;
+ PVOID SampleRateBuffer;
+ PPIN_CONTEXT PinContext;
+ NTSTATUS Status;
+
+ /* allocate sample rate buffer */
+ SampleRateBuffer = AllocFunction(sizeof(ULONG));
+ if (!SampleRateBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* allocate urb */
+ Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ /* no memory */
+ FreeFunction(SampleRateBuffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* FIXME: determine controls and format urb */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ 0x01,
+ 0x100,
+ 0x300,
+ SampleRateBuffer,
+ NULL,
+ 1,
+ NULL);
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* submit urb */
+ Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
+
+ DPRINT1("UsbAudioSetMuteOff Pin %p Status %x\n", Pin, Status);
+ FreeFunction(Urb);
+ FreeFunction(SampleRateBuffer);
+ return Status;
+}
+
+NTSTATUS
+UsbAudioSetVolume(
+ IN PKSPIN Pin)
+{
+ PURB Urb;
+ PUCHAR SampleRateBuffer;
+ PPIN_CONTEXT PinContext;
+ NTSTATUS Status;
+
+ /* allocate sample rate buffer */
+ SampleRateBuffer = AllocFunction(sizeof(ULONG));
+ if (!SampleRateBuffer)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* allocate urb */
+ Urb = AllocFunction(sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST));
+ if (!Urb)
+ {
+ /* no memory */
+ FreeFunction(SampleRateBuffer);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* FIXME: determine controls and format urb */
+ UsbBuildVendorRequest(Urb,
+ URB_FUNCTION_CLASS_INTERFACE,
+ sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
+ USBD_TRANSFER_DIRECTION_OUT,
+ 0,
+ 0x01,
+ 0x200,
+ 0x300,
+ SampleRateBuffer,
+ NULL,
+ 2,
+ NULL);
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ SampleRateBuffer[0] = 0xC2;
+ SampleRateBuffer[1] = 0xFE;
+
+ /* submit urb */
+ Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
+
+ DPRINT1("UsbAudioSetVolume Pin %p Status %x\n", Pin, Status);
+ FreeFunction(Urb);
+ FreeFunction(SampleRateBuffer);
+ return Status;
+}
NTSTATUS
UsbAudioSetFormat(
@@ -140,13 +243,13 @@
return STATUS_INSUFFICIENT_RESOURCES;
}
- /* format urb */
+ /* FIXME: determine controls and format urb */
UsbBuildVendorRequest(Urb,
URB_FUNCTION_CLASS_ENDPOINT,
sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST),
USBD_TRANSFER_DIRECTION_OUT,
0,
- 0x01,
+ 0x01, // SET_CUR
0x100,
0x81, //FIXME bEndpointAddress
SampleRateBuffer,
@@ -244,6 +347,156 @@
return Status;
}
+VOID
+NTAPI
+CaptureGateOnWorkItem(
+ _In_ PVOID Context)
+{
+ PKSPIN Pin;
+ PPIN_CONTEXT PinContext;
+ PKSGATE Gate;
+ ULONG Count;
+
+ /* get pin */
+ Pin = Context;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ do
+ {
+ /* acquire processing mutex */
+ KsPinAcquireProcessingMutex(Pin);
+
+ /* get pin control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* turn input on */
+ KsGateTurnInputOn(Gate);
+
+ /* schedule processing */
+ KsPinAttemptProcessing(Pin, TRUE);
+
+ /* release processing mutex */
+ KsPinReleaseProcessingMutex(Pin);
+
+ /* decrement worker count */
+ Count = KsDecrementCountedWorker(PinContext->CaptureWorker);
+ } while (Count);
+}
+
+
+
+VOID
+CaptureInitializeUrbAndIrp(
+ IN PKSPIN Pin,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ PURB Urb;
+ PUCHAR TransferBuffer;
+ ULONG Index;
+ PPIN_CONTEXT PinContext;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* backup urb and transferbuffer */
+ Urb = Irp->Tail.Overlay.DriverContext[0];
+ TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
+
+ /* initialize irp */
+ IoInitializeIrp(Irp,
IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize),
PinContext->DeviceExtension->LowerDevice->StackSize);
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+ Irp->Flags = 0;
+ Irp->UserBuffer = NULL;
+ Irp->Tail.Overlay.DriverContext[0] = Urb;
+ Irp->Tail.Overlay.DriverContext[1] = NULL;
+
+ /* init stack location */
+ IoStack = IoGetNextIrpStackLocation(Irp);
+ IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
+ IoStack->Parameters.Others.Argument1 = Urb;
+ IoStack->Parameters.Others.Argument2 = NULL;
+ IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
+ IoStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
+
+ IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
+
+ RtlZeroMemory(Urb, GET_ISO_URB_SIZE(PACKET_COUNT));
+
+ /* init urb */
+ Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
+ Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(10);
+ Urb->UrbIsochronousTransfer.PipeHandle =
PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
+ Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN |
USBD_START_ISO_TRANSFER_ASAP;
+ Urb->UrbIsochronousTransfer.TransferBufferLength =
PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize * 10;
+ Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
+ Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
+ Urb->UrbIsochronousTransfer.StartFrame = 0;
+
+ for (Index = 0; Index < PACKET_COUNT; Index++)
+ {
+ Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index *
PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize;
+ }
+}
+
+
+VOID
+NTAPI
+CaptureAvoidPipeStarvationWorker(
+ _In_ PVOID Context)
+{
+ PKSPIN Pin;
+ PPIN_CONTEXT PinContext;
+ KIRQL OldLevel;
+ PLIST_ENTRY CurEntry;
+ PIRP Irp;
+
+ /* get pin */
+ Pin = Context;
+
+ /* get pin context */
+ PinContext = Pin->Context;
+
+ /* acquire spin lock */
+ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
+
+ if (!IsListEmpty(&PinContext->IrpListHead))
+ {
+ /* sanity check */
+ ASSERT(!IsListEmpty(&PinContext->IrpListHead));
+
+ /* remove entry from list */
+ CurEntry = RemoveHeadList(&PinContext->IrpListHead);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ /* get irp offset */
+ Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
+
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
+
+ KsDecrementCountedWorker(PinContext->StarvationWorker);
+
+ /* call driver */
+ IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
+ }
+ else
+ {
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ KsDecrementCountedWorker(PinContext->StarvationWorker);
+ }
+}
+
+
+
NTSTATUS
InitCapturePin(
IN PKSPIN Pin)
@@ -257,6 +510,8 @@
PPIN_CONTEXT PinContext;
PIO_STACK_LOCATION IoStack;
PKSALLOCATOR_FRAMING_EX Framing;
+ PKSGATE Gate;
+
/* set sample rate */
Status = UsbAudioSetFormat(Pin);
@@ -271,6 +526,28 @@
/* lets get maximum packet size */
MaximumPacketSize =
GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor,
PinContext->InterfaceDescriptor, Pin->DataFlow);
+
+ /* initialize work item for capture worker */
+ ExInitializeWorkItem(&PinContext->CaptureWorkItem, CaptureGateOnWorkItem,
(PVOID)Pin);
+
+ /* register worker */
+ Status = KsRegisterCountedWorker(CriticalWorkQueue,
&PinContext->CaptureWorkItem, &PinContext->CaptureWorker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ return Status;
+ }
+
+ /* initialize work item */
+ ExInitializeWorkItem(&PinContext->StarvationWorkItem,
CaptureAvoidPipeStarvationWorker, (PVOID)Pin);
+
+ /* register worker */
+ Status = KsRegisterCountedWorker(CriticalWorkQueue,
&PinContext->StarvationWorkItem, &PinContext->StarvationWorker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ KsUnregisterWorker(PinContext->CaptureWorker);
+ }
/* lets edit framing struct */
Framing = (PKSALLOCATOR_FRAMING_EX)Pin->Descriptor->AllocatorFraming;
@@ -281,7 +558,7 @@
MaximumPacketSize;
/* calculate buffer size 8 irps * 10 iso packets * max packet size */
- BufferSize = 8 * 10 * MaximumPacketSize;
+ BufferSize = 8 * PACKET_COUNT * MaximumPacketSize;
/* allocate pin capture buffer */
PinContext->BufferSize = BufferSize;
@@ -318,20 +595,22 @@
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
-
- DPRINT1("InitCapturePin Irp %p\n", Irp);
+ IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
+
/* insert into irp list */
InsertTailList(&PinContext->IrpListHead,
&Irp->Tail.Overlay.ListEntry);
/* add to object bag*/
- KsAddItemToObjectBag(Pin->Bag, Irp, IoFreeIrp);
+ KsAddItemToObjectBag(Pin->Bag, Irp, ExFreePool);
/* FIXME select correct pipe handle */
Status =
UsbAudioAllocCaptureUrbIso(PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle,
MaximumPacketSize,
- &PinContext->Buffer[MaximumPacketSize
* 10 * Index],
- MaximumPacketSize * 10,
+ &PinContext->Buffer[MaximumPacketSize
* PACKET_COUNT * Index],
+ MaximumPacketSize * PACKET_COUNT,
&Urb);
+
+ DPRINT1("InitCapturePin Irp %p Urb %p\n", Irp, Urb);
if (NT_SUCCESS(Status))
{
@@ -348,6 +627,13 @@
return Status;
}
}
+
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* turn input off */
+ KsGateTurnInputOff(Gate);
+
return Status;
}
@@ -358,6 +644,8 @@
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
+
+
NTSTATUS
@@ -400,13 +688,16 @@
Pin->Context = PinContext;
/* lets edit allocator framing struct */
- Status = _KsEdit(Pin->Bag, &Pin->Descriptor, sizeof(KSPIN_DESCRIPTOR_EX),
sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
+ Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor,
sizeof(KSPIN_DESCRIPTOR_EX), sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
if (NT_SUCCESS(Status))
{
- Status = _KsEdit(Pin->Bag, &Pin->Descriptor->AllocatorFraming,
sizeof(KSALLOCATOR_FRAMING_EX), sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
+ Status = _KsEdit(Pin->Bag,
(PVOID*)&Pin->Descriptor->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING_EX),
sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
ASSERT(Status == STATUS_SUCCESS);
}
+ /* FIXME move to build filter topology*/
+ UsbAudioSetMuteOff(Pin);
+ UsbAudioSetVolume(Pin);
/* select streaming interface */
Status = USBAudioSelectAudioStreamingInterface(PinContext,
PinContext->DeviceExtension,
PinContext->DeviceExtension->ConfigurationDescriptor);
@@ -451,29 +742,39 @@
PPIN_CONTEXT PinContext;
KIRQL OldLevel;
PURB Urb;
- PIO_STACK_LOCATION IoStack;
-
/* get pin context */
Pin = Context;
PinContext = Pin->Context;
- /* get stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
-
/* get urb */
Urb = Irp->Tail.Overlay.DriverContext[0];
- //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p\n", Irp, Urb);
-
/* acquire lock */
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
- /* insert entry into done list */
- InsertTailList(&PinContext->DoneIrpListHead,
&Irp->Tail.Overlay.ListEntry);
-
- /* release lock */
- KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+ if (!NT_SUCCESS(Urb->UrbIsochronousTransfer.Hdr.Status))
+ {
+ //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p Status %x Packet Status
%x\n", Irp, Urb, Urb->UrbIsochronousTransfer.Hdr.Status,
Urb->UrbIsochronousTransfer.IsoPacket[0].Status);
+
+ /* insert entry into ready list */
+ InsertTailList(&PinContext->IrpListHead,
&Irp->Tail.Overlay.ListEntry);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ KsIncrementCountedWorker(PinContext->StarvationWorker);
+ }
+ else
+ {
+ /* insert entry into done list */
+ InsertTailList(&PinContext->DoneIrpListHead,
&Irp->Tail.Overlay.ListEntry);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ KsIncrementCountedWorker(PinContext->CaptureWorker);
+ }
/* done */
return STATUS_MORE_PROCESSING_REQUIRED;
@@ -491,13 +792,22 @@
PIO_STACK_LOCATION IoStack;
PURB Urb;
PUCHAR TransferBuffer, OutBuffer;
- ULONG Index, Offset, MaximumPacketSize, Length;
+ ULONG Offset, Length;
NTSTATUS Status;
- //PUSHORT SoundBuffer;
-
+ PKSGATE Gate;
+
+ //DPRINT1("PinCaptureProcess\n");
LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin,
KSSTREAM_POINTER_STATE_LOCKED);
if (LeadingStreamPointer == NULL)
+ {
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* shutdown processing */
+ KsGateTurnInputOff(Gate);
+
return STATUS_SUCCESS;
+ }
/* get pin context */
PinContext = Pin->Context;
@@ -521,61 +831,65 @@
Urb = (PURB)Irp->Tail.Overlay.DriverContext[0];
ASSERT(Urb);
- Offset = 0;
- for (Index = 0; Index < Urb->UrbIsochronousTransfer.NumberOfPackets;
Index++)
+ Offset = PtrToUlong(Irp->Tail.Overlay.DriverContext[1]);
+
+ /* get transfer buffer */
+ TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
+
+ /* get target buffer */
+ OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data;
+
+ /* calculate length */
+ Length = min(LeadingStreamPointer->OffsetOut.Count -
LeadingStreamPointer->StreamHeader->DataUsed,
Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
+
+ /* FIXME copy each packet extra */
+ /* copy audio bytes */
+
RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed],
&TransferBuffer[Offset], Length);
+
+ //DPRINT1("Irp %p Urb %p OutBuffer %p TransferBuffer %p Offset %lu Remaining
%lu TransferBufferLength %lu Length %lu\n", Irp, Urb, OutBuffer, TransferBuffer,
Offset, LeadingStreamPointer->OffsetOut.Remaining,
Urb->UrbIsochronousTransfer.TransferBufferLength, Length);
+
+ /* adjust streampointer */
+ LeadingStreamPointer->StreamHeader->DataUsed += Length;
+
+ if (Length == LeadingStreamPointer->OffsetOut.Remaining)
{
- /* add offset */
- Offset += Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset;
-
- /* get transfer buffer */
- TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
-
- /* get target buffer */
- OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data;
-
- /* calculate length */
- Length = min(LeadingStreamPointer->OffsetOut.Count -
LeadingStreamPointer->StreamHeader->DataUsed,
Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
-
- //DPRINT1("DataUsed %lu Count %lu Remaining %lu Copying %lu Data
%p\n", LeadingStreamPointer->StreamHeader->DataUsed,
LeadingStreamPointer->OffsetOut.Count, LeadingStreamPointer->OffsetOut.Remaining,
Length, LeadingStreamPointer->OffsetOut.Data);
-
- /* copy buffer */
-
RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed],
&TransferBuffer[Offset], Length);
-
- LeadingStreamPointer->StreamHeader->DataUsed += Length;
-
- if (Length == LeadingStreamPointer->OffsetOut.Remaining) {
- KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length,
TRUE);
-
- LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin,
KSSTREAM_POINTER_STATE_LOCKED);
- if (LeadingStreamPointer == NULL)
- {
- /* FIXME handle half processed packets */
- //ASSERT(FALSE);
- //DPRINT1("Warning: ignoring %lu packets\n",
Urb->UrbIsochronousTransfer.NumberOfPackets - Index);
-
- /* acquire spin lock */
- KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
-
- InsertTailList(&PinContext->IrpListHead,
&Irp->Tail.Overlay.ListEntry);
-
- KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
- return STATUS_SUCCESS;
- }
+ KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length,
TRUE);
+
+ /* acquire spin lock */
+ KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
+
+ /* adjust offset */
+ Irp->Tail.Overlay.DriverContext[1] = UlongToPtr(Length);
+
+ /* reinsert into processed list */
+ InsertHeadList(&PinContext->DoneIrpListHead,
&Irp->Tail.Overlay.ListEntry);
+
+ /* release lock */
+ KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
+
+ LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin,
KSSTREAM_POINTER_STATE_LOCKED);
+ if (LeadingStreamPointer == NULL)
+ {
+ /* no more work to be done*/
+ return STATUS_PENDING;
}
else
{
- Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length,
FALSE);
+ /* resume work on this irp */
+ continue;
}
}
+ else
+ {
+ Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length,
FALSE);
+ ASSERT(Length == Urb->UrbIsochronousTransfer.TransferBufferLength -
Offset);
+ }
/* acquire spin lock */
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
InsertTailList(&PinContext->IrpListHead,
&Irp->Tail.Overlay.ListEntry);
-
- if (LeadingStreamPointer == NULL)
- break;
}
while (!IsListEmpty(&PinContext->IrpListHead))
@@ -589,44 +903,8 @@
/* get irp offset */
Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
- /* backup urb and transferbuffer */
- Urb = Irp->Tail.Overlay.DriverContext[0];
- TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
-
- /* initialize irp */
- IoInitializeIrp(Irp,
IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize),
PinContext->DeviceExtension->LowerDevice->StackSize);
-
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- Irp->Flags = 0;
- Irp->UserBuffer = NULL;
- Irp->Tail.Overlay.DriverContext[0] = Urb;
-
- /* init stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
- IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
- IoStack->Parameters.Others.Argument1 = Urb;
- IoStack->Parameters.Others.Argument2 = NULL;
- IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- IoStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
-
- IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
-
- RtlZeroMemory(Urb, GET_ISO_URB_SIZE(10));
-
- /* init urb */
- Urb->UrbIsochronousTransfer.Hdr.Function = URB_FUNCTION_ISOCH_TRANSFER;
- Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(10);
- Urb->UrbIsochronousTransfer.PipeHandle =
PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
- Urb->UrbIsochronousTransfer.TransferFlags = USBD_TRANSFER_DIRECTION_IN |
USBD_START_ISO_TRANSFER_ASAP;
- Urb->UrbIsochronousTransfer.TransferBufferLength =
PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize * 10;
- Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
- Urb->UrbIsochronousTransfer.NumberOfPackets = 10;
-
- for (Index = 0; Index < 10; Index++)
- {
- Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * 100;
- }
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
@@ -641,7 +919,13 @@
if (LeadingStreamPointer != NULL)
KsStreamPointerUnlock(LeadingStreamPointer, FALSE);
- return STATUS_SUCCESS;
+ /* get process control gate */
+ Gate = KsPinGetAndGate(Pin);
+
+ /* shutdown processing */
+ KsGateTurnInputOff(Gate);
+
+ return STATUS_PENDING;
}
@@ -700,9 +984,6 @@
PPIN_CONTEXT PinContext;
PLIST_ENTRY CurEntry;
PIRP Irp;
- PURB Urb;
- PIO_STACK_LOCATION IoStack;
- NTSTATUS Status;
KIRQL OldLevel;
/* get pin context */
@@ -719,24 +1000,14 @@
/* get irp offset */
Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
-
- /* get next stack location */
- IoStack = IoGetNextIrpStackLocation(Irp);
-
- /* init stack location */
- IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
- IoStack->Parameters.DeviceIoControl.IoControlCode =
IOCTL_INTERNAL_USB_SUBMIT_URB;
-
- /* backup urb */
- Urb = Irp->Tail.Overlay.DriverContext[0] =
IoStack->Parameters.Others.Argument1;
-
- IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
-
/* release lock */
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
- DPRINT("StartCaptureIsocTransfer Irp %p Urb %p TransferBuffer %p\n",
Irp, Urb, Urb->UrbIsochronousTransfer.TransferBuffer);
- Status = IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
+ /* reinitialize irp and urb */
+ CaptureInitializeUrbAndIrp(Pin, Irp);
+
+ DPRINT("StartCaptureIsocTransfer Irp %p\n", Irp);
+ IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
/* acquire spin lock */
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
Modified: trunk/reactos/drivers/usb/usbaudio/usbaudio.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbaudio/usbau…
==============================================================================
--- trunk/reactos/drivers/usb/usbaudio/usbaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbaudio/usbaudio.h [iso-8859-1] Fri Oct 14 10:35:19 2016
@@ -127,7 +127,10 @@
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 */
}PIN_CONTEXT, *PPIN_CONTEXT;
/* filter.c */
@@ -252,6 +255,13 @@
NTSTATUS
NTAPI
+UsbAudioCaptureComplete(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID Context);
+
+NTSTATUS
+NTAPI
USBAudioPinCreate(
_In_ PKSPIN Pin,
_In_ PIRP Irp);