mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[USBAUDIO]
- edit allocator framing struct to match endpoint requirements - implement partly PinCaptureProcess, not yet working svn path=/trunk/; revision=72890
This commit is contained in:
parent
160d7c5b1e
commit
1cfbbff51a
|
@ -255,6 +255,7 @@ InitCapturePin(
|
||||||
PURB Urb;
|
PURB Urb;
|
||||||
PPIN_CONTEXT PinContext;
|
PPIN_CONTEXT PinContext;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PKSALLOCATOR_FRAMING_EX Framing;
|
||||||
|
|
||||||
/* set sample rate */
|
/* set sample rate */
|
||||||
Status = UsbAudioSetFormat(Pin);
|
Status = UsbAudioSetFormat(Pin);
|
||||||
|
@ -267,8 +268,17 @@ InitCapturePin(
|
||||||
/* get pin context */
|
/* get pin context */
|
||||||
PinContext = Pin->Context;
|
PinContext = Pin->Context;
|
||||||
|
|
||||||
|
/* lets get maximum packet size */
|
||||||
MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
|
MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
|
||||||
|
|
||||||
|
/* lets edit framing struct */
|
||||||
|
Framing = (PKSALLOCATOR_FRAMING_EX)Pin->Descriptor->AllocatorFraming;
|
||||||
|
Framing->FramingItem[0].PhysicalRange.MinFrameSize =
|
||||||
|
Framing->FramingItem[0].PhysicalRange.MaxFrameSize =
|
||||||
|
Framing->FramingItem[0].FramingRange.Range.MinFrameSize =
|
||||||
|
Framing->FramingItem[0].FramingRange.Range.MaxFrameSize =
|
||||||
|
MaximumPacketSize;
|
||||||
|
|
||||||
/* calculate buffer size 8 irps * 10 iso packets * max packet size */
|
/* calculate buffer size 8 irps * 10 iso packets * max packet size */
|
||||||
BufferSize = 8 * 10 * MaximumPacketSize;
|
BufferSize = 8 * 10 * MaximumPacketSize;
|
||||||
|
|
||||||
|
@ -292,6 +302,7 @@ InitCapturePin(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINT1("InitCapturePin Irp %p\n", Irp);
|
||||||
/* insert into irp list */
|
/* insert into irp list */
|
||||||
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
|
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
@ -312,6 +323,7 @@ InitCapturePin(
|
||||||
|
|
||||||
/* store urb */
|
/* store urb */
|
||||||
IoStack->Parameters.Others.Argument1 = Urb;
|
IoStack->Parameters.Others.Argument1 = Urb;
|
||||||
|
Irp->Tail.Overlay.DriverContext[0] = Urb;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -364,10 +376,21 @@ USBAudioPinCreate(
|
||||||
PinContext->DeviceExtension = FilterContext->DeviceExtension;
|
PinContext->DeviceExtension = FilterContext->DeviceExtension;
|
||||||
PinContext->LowerDevice = FilterContext->LowerDevice;
|
PinContext->LowerDevice = FilterContext->LowerDevice;
|
||||||
InitializeListHead(&PinContext->IrpListHead);
|
InitializeListHead(&PinContext->IrpListHead);
|
||||||
|
InitializeListHead(&PinContext->DoneIrpListHead);
|
||||||
|
KeInitializeSpinLock(&PinContext->IrpListLock);
|
||||||
|
|
||||||
/* store pin context*/
|
/* store pin context*/
|
||||||
Pin->Context = PinContext;
|
Pin->Context = PinContext;
|
||||||
|
|
||||||
|
/* lets edit allocator framing struct */
|
||||||
|
Status = _KsEdit(Pin->Bag, &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);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* select streaming interface */
|
/* select streaming interface */
|
||||||
Status = USBAudioSelectAudioStreamingInterface(PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor);
|
Status = USBAudioSelectAudioStreamingInterface(PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -400,13 +423,197 @@ USBAudioPinClose(
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
UsbAudioCaptureComplete(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PVOID Context)
|
||||||
|
{
|
||||||
|
PKSPIN Pin;
|
||||||
|
PPIN_CONTEXT PinContext;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* get pin context */
|
||||||
|
Pin = Context;
|
||||||
|
PinContext = Pin->Context;
|
||||||
|
|
||||||
|
/* acquire lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
/* insert entry into done list */
|
||||||
|
InsertTailList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
DPRINT1("UsbAudioCaptureComplete Irp %p\n", Irp);
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return STATUS_MORE_PROCESSING_REQUIRED;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
PinCaptureProcess(
|
||||||
|
IN PKSPIN Pin)
|
||||||
|
{
|
||||||
|
PKSSTREAM_POINTER LeadingStreamPointer;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
PPIN_CONTEXT PinContext;
|
||||||
|
PLIST_ENTRY CurEntry;
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
PURB Urb;
|
||||||
|
PUCHAR TransferBuffer;
|
||||||
|
ULONG Index, Offset;
|
||||||
|
|
||||||
|
LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
|
||||||
|
if (LeadingStreamPointer == NULL)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* get pin context */
|
||||||
|
PinContext = Pin->Context;
|
||||||
|
|
||||||
|
/* acquire spin lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
while (!IsListEmpty(&PinContext->DoneIrpListHead))
|
||||||
|
{
|
||||||
|
/* remove entry from list */
|
||||||
|
CurEntry = RemoveHeadList(&PinContext->DoneIrpListHead);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
/* get irp offset */
|
||||||
|
Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
/* get urb from irp */
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
Urb = (PURB)Irp->Tail.Overlay.DriverContext[0];
|
||||||
|
ASSERT(Urb);
|
||||||
|
|
||||||
|
Offset = 0;
|
||||||
|
for (Index = 0; Index < Urb->UrbIsochronousTransfer.NumberOfPackets; Index++)
|
||||||
|
{
|
||||||
|
/* add offset */
|
||||||
|
Offset += Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset;
|
||||||
|
|
||||||
|
/* get transfer buffer */
|
||||||
|
TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
|
||||||
|
|
||||||
|
/* copy data */
|
||||||
|
if (LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length)
|
||||||
|
{
|
||||||
|
/* copy buffer */
|
||||||
|
RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* advance to next frame */
|
||||||
|
KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, 0, TRUE);
|
||||||
|
LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
|
||||||
|
if (LeadingStreamPointer == NULL)
|
||||||
|
{
|
||||||
|
/* FIXME handle half processed packets */
|
||||||
|
//ASSERT(FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(LeadingStreamPointer->OffsetOut.Remaining >= Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
|
||||||
|
|
||||||
|
/* copy buffer */
|
||||||
|
RtlCopyMemory((PUCHAR)LeadingStreamPointer->OffsetOut.Data, &TransferBuffer[Offset], Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LeadingStreamPointer->OffsetOut.Remaining == Urb->UrbIsochronousTransfer.IsoPacket[Index].Length)
|
||||||
|
{
|
||||||
|
KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, TRUE);
|
||||||
|
LeadingStreamPointer = KsPinGetLeadingEdgeStreamPointer(Pin, KSSTREAM_POINTER_STATE_LOCKED);
|
||||||
|
if (LeadingStreamPointer == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* acquire spin lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
/* get next stack location */
|
||||||
|
IoStack = IoGetNextIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
/* init stack location */
|
||||||
|
IoStack->Parameters.Others.Argument1 = Urb;
|
||||||
|
IoStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
|
||||||
|
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
|
||||||
|
|
||||||
|
if (LeadingStreamPointer == NULL)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!IsListEmpty(&PinContext->IrpListHead))
|
||||||
|
{
|
||||||
|
/* remove entry from list */
|
||||||
|
CurEntry = RemoveHeadList(&PinContext->IrpListHead);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
DPRINT1("PinCaptureProcess Irp %p\n", Irp);
|
||||||
|
IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
|
||||||
|
|
||||||
|
/* acquire spin lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
if (LeadingStreamPointer != NULL)
|
||||||
|
KsStreamPointerUnlock(LeadingStreamPointer, FALSE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
USBAudioPinProcess(
|
USBAudioPinProcess(
|
||||||
_In_ PKSPIN Pin)
|
_In_ PKSPIN Pin)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
|
||||||
|
{
|
||||||
|
Status = PinCaptureProcess(Pin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -437,6 +644,90 @@ USBAudioPinSetDataFormat(
|
||||||
return UsbAudioSetFormat(Pin);
|
return UsbAudioSetFormat(Pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
StartCaptureIsocTransfer(
|
||||||
|
IN PKSPIN Pin)
|
||||||
|
{
|
||||||
|
PPIN_CONTEXT PinContext;
|
||||||
|
PLIST_ENTRY CurEntry;
|
||||||
|
PIRP Irp;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KIRQL OldLevel;
|
||||||
|
|
||||||
|
/* get pin context */
|
||||||
|
PinContext = Pin->Context;
|
||||||
|
|
||||||
|
/* acquire spin lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
while(!IsListEmpty(&PinContext->IrpListHead))
|
||||||
|
{
|
||||||
|
/* remove entry from list */
|
||||||
|
CurEntry = RemoveHeadList(&PinContext->IrpListHead);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
IoSetCompletionRoutine(Irp, UsbAudioCaptureComplete, Pin, TRUE, TRUE, TRUE);
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
DPRINT1("StartCaptureIsocTransfer Irp %p\n", Irp);
|
||||||
|
Status = IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
|
||||||
|
|
||||||
|
/* acquire spin lock */
|
||||||
|
KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* release lock */
|
||||||
|
KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
CapturePinStateChange(
|
||||||
|
_In_ PKSPIN Pin,
|
||||||
|
_In_ KSSTATE ToState,
|
||||||
|
_In_ KSSTATE FromState)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
if (FromState != ToState)
|
||||||
|
{
|
||||||
|
if (ToState)
|
||||||
|
{
|
||||||
|
if (ToState == KSSTATE_PAUSE)
|
||||||
|
{
|
||||||
|
if (FromState == KSSTATE_RUN)
|
||||||
|
{
|
||||||
|
/* wait until pin processing is finished*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ToState == KSSTATE_RUN)
|
||||||
|
{
|
||||||
|
Status = StartCaptureIsocTransfer(Pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
USBAudioPinSetDeviceState(
|
USBAudioPinSetDeviceState(
|
||||||
|
@ -444,6 +735,18 @@ USBAudioPinSetDeviceState(
|
||||||
_In_ KSSTATE ToState,
|
_In_ KSSTATE ToState,
|
||||||
_In_ KSSTATE FromState)
|
_In_ KSSTATE FromState)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED
|
NTSTATUS Status;
|
||||||
return STATUS_SUCCESS;
|
|
||||||
|
if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
|
||||||
|
{
|
||||||
|
/* handle capture state changes */
|
||||||
|
Status = CapturePinStateChange(Pin, ToState, FromState);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
Status = STATUS_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,8 @@ typedef struct
|
||||||
PDEVICE_EXTENSION DeviceExtension; /* device extension */
|
PDEVICE_EXTENSION DeviceExtension; /* device extension */
|
||||||
PDEVICE_OBJECT LowerDevice; /* lower device*/
|
PDEVICE_OBJECT LowerDevice; /* lower device*/
|
||||||
LIST_ENTRY IrpListHead; /* irp list*/
|
LIST_ENTRY IrpListHead; /* irp list*/
|
||||||
|
LIST_ENTRY DoneIrpListHead; /* irp done list head */
|
||||||
|
KSPIN_LOCK IrpListLock; /* irp list lock*/
|
||||||
PUCHAR Buffer; /* iso buffer*/
|
PUCHAR Buffer; /* iso buffer*/
|
||||||
ULONG BufferSize; /* iso buffer size */
|
ULONG BufferSize; /* iso buffer size */
|
||||||
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; /* interface descriptor */
|
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; /* interface descriptor */
|
||||||
|
|
Loading…
Reference in a new issue