ReactOS 0.4.15-dev-7958-gcd0bb1a
pin.c File Reference
#include "usbaudio.h"
Include dependency graph for pin.c:

Go to the source code of this file.

Macros

#define PACKET_COUNT   10
 

Functions

NTSTATUS GetMaxPacketSizeForInterface (IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, KSPIN_DATAFLOW DataFlow)
 
NTSTATUS UsbAudioAllocCaptureUrbIso (IN USBD_PIPE_HANDLE PipeHandle, IN ULONG MaxPacketSize, IN PVOID Buffer, IN ULONG BufferLength, OUT PURB *OutUrb)
 
NTSTATUS UsbAudioSetFormat (IN PKSPIN Pin)
 
NTSTATUS USBAudioSelectAudioStreamingInterface (IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN PDEVICE_EXTENSION DeviceExtension, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG FormatDescriptorIndex)
 
VOID NTAPI CaptureGateOnWorkItem (_In_ PVOID Context)
 
NTSTATUS RenderInitializeUrbAndIrp (IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN OUT PIRP Irp, IN PVOID TransferBuffer, IN ULONG TransferBufferSize, IN ULONG PacketSize)
 
VOID CaptureInitializeUrbAndIrp (IN PKSPIN Pin, IN PIRP Irp)
 
VOID NTAPI CaptureAvoidPipeStarvationWorker (_In_ PVOID Context)
 
NTSTATUS InitCapturePin (IN PKSPIN Pin)
 
NTSTATUS InitStreamPin (IN PKSPIN Pin)
 
ULONG GetDataRangeIndexForFormat (IN PKSDATARANGE ConnectionFormat, IN const PKSDATARANGE *DataRanges, IN ULONG DataRangesCount)
 
NTSTATUS NTAPI USBAudioPinCreate (_In_ PKSPIN Pin, _In_ PIRP Irp)
 
NTSTATUS NTAPI USBAudioPinClose (_In_ PKSPIN Pin, _In_ PIRP Irp)
 
NTSTATUS NTAPI UsbAudioRenderComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS NTAPI UsbAudioCaptureComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
PIRP PinGetIrpFromReadyList (IN PKSPIN Pin)
 
NTSTATUS PinRenderProcess (IN PKSPIN Pin)
 
NTSTATUS PinCaptureProcess (IN PKSPIN Pin)
 
NTSTATUS NTAPI USBAudioPinProcess (_In_ PKSPIN Pin)
 
VOID NTAPI USBAudioPinReset (_In_ PKSPIN Pin)
 
NTSTATUS NTAPI USBAudioPinSetDataFormat (_In_ PKSPIN Pin, _In_opt_ PKSDATAFORMAT OldFormat, _In_opt_ PKSMULTIPLE_ITEM OldAttributeList, _In_ const KSDATARANGE *DataRange, _In_opt_ const KSATTRIBUTE_LIST *AttributeRange)
 
NTSTATUS StartCaptureIsocTransfer (IN PKSPIN Pin)
 
NTSTATUS CapturePinStateChange (_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
 
NTSTATUS NTAPI USBAudioPinSetDeviceState (_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
 
NTSTATUS NTAPI UsbAudioPinDataIntersect (_In_ PVOID Context, _In_ PIRP Irp, _In_ PKSP_PIN Pin, _In_ PKSDATARANGE DataRange, _In_ PKSDATARANGE MatchingDataRange, _In_ ULONG DataBufferSize, _Out_ PVOID Data, _Out_ PULONG DataSize)
 

Macro Definition Documentation

◆ PACKET_COUNT

#define PACKET_COUNT   10

Definition at line 12 of file pin.c.

Function Documentation

◆ CaptureAvoidPipeStarvationWorker()

VOID NTAPI CaptureAvoidPipeStarvationWorker ( _In_ PVOID  Context)

Definition at line 438 of file pin.c.

440{
441 PKSPIN Pin;
442 PPIN_CONTEXT PinContext;
443 KIRQL OldLevel;
444 PLIST_ENTRY CurEntry;
445 PIRP Irp;
446
447 /* get pin */
448 Pin = Context;
449
450 /* get pin context */
451 PinContext = Pin->Context;
452
453 /* acquire spin lock */
454 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
455
456 if (!IsListEmpty(&PinContext->IrpListHead))
457 {
458 /* sanity check */
459 ASSERT(!IsListEmpty(&PinContext->IrpListHead));
460
461 /* remove entry from list */
462 CurEntry = RemoveHeadList(&PinContext->IrpListHead);
463
464 /* release lock */
465 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
466
467 /* get irp offset */
468 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
469
470 /* reinitialize irp and urb */
472
474
475 /* call driver */
476 IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
477 }
478 else
479 {
480 /* release lock */
481 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
482
484 }
485}
struct _IRP * PIRP
_In_ PIRP Irp
Definition: csq.h:116
VOID CaptureInitializeUrbAndIrp(IN PKSPIN Pin, IN PIRP Irp)
Definition: pin.c:380
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
#define ASSERT(a)
Definition: mode.c:44
#define IoCallDriver
Definition: irp.c:1225
LIST_ENTRY IrpListHead
Definition: usbaudio.h:198
PKSWORKER StarvationWorker
Definition: usbaudio.h:209
PDEVICE_EXTENSION DeviceExtension
Definition: usbaudio.h:196
KSPIN_LOCK IrpListLock
Definition: usbaudio.h:200
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
KSDDKAPI ULONG NTAPI KsDecrementCountedWorker(IN PKSWORKER Worker)
Definition: worker.c:198

Referenced by InitCapturePin().

◆ CaptureGateOnWorkItem()

VOID NTAPI CaptureGateOnWorkItem ( _In_ PVOID  Context)

Definition at line 275 of file pin.c.

277{
278 PKSPIN Pin;
279 PPIN_CONTEXT PinContext;
280 PKSGATE Gate;
281 ULONG Count;
282
283 /* get pin */
284 Pin = Context;
285
286 /* get pin context */
287 PinContext = Pin->Context;
288
289 do
290 {
291 /* acquire processing mutex */
293
294 /* get pin control gate */
295 Gate = KsPinGetAndGate(Pin);
296
297 /* turn input on */
298 KsGateTurnInputOn(Gate);
299
300 /* schedule processing */
302
303 /* release processing mutex */
305
306 /* decrement worker count */
308 } while (Count);
309}
#define TRUE
Definition: types.h:120
VOID NTAPI KsPinAttemptProcessing(IN PKSPIN Pin, IN BOOLEAN Asynchronous)
Definition: pin.c:993
PKSGATE NTAPI KsPinGetAndGate(IN PKSPIN Pin)
Definition: pin.c:980
VOID NTAPI KsPinReleaseProcessingMutex(IN PKSPIN Pin)
Definition: pin.c:1196
VOID NTAPI KsPinAcquireProcessingMutex(IN PKSPIN Pin)
Definition: pin.c:933
int Count
Definition: noreturn.cpp:7
PKSWORKER CaptureWorker
Definition: usbaudio.h:207
uint32_t ULONG
Definition: typedefs.h:59

Referenced by InitCapturePin().

◆ CaptureInitializeUrbAndIrp()

VOID CaptureInitializeUrbAndIrp ( IN PKSPIN  Pin,
IN PIRP  Irp 
)

Definition at line 380 of file pin.c.

383{
384 PIO_STACK_LOCATION IoStack;
385 PURB Urb;
386 PUCHAR TransferBuffer;
387 ULONG Index;
388 PPIN_CONTEXT PinContext;
389
390 /* get pin context */
391 PinContext = Pin->Context;
392
393 /* backup urb and transferbuffer */
394 Urb = Irp->Tail.Overlay.DriverContext[0];
395 TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
396
397 /* initialize irp */
398 IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
399
400 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
401 Irp->IoStatus.Information = 0;
402 Irp->Flags = 0;
403 Irp->UserBuffer = NULL;
404 Irp->Tail.Overlay.DriverContext[0] = Urb;
405 Irp->Tail.Overlay.DriverContext[1] = NULL;
406
407 /* init stack location */
409 IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
410 IoStack->Parameters.Others.Argument1 = Urb;
411 IoStack->Parameters.Others.Argument2 = NULL;
414
416
418
419 /* init urb */
421 Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(10);
422 Urb->UrbIsochronousTransfer.PipeHandle = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
424 Urb->UrbIsochronousTransfer.TransferBufferLength = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize * 10;
425 Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
426 Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
427 Urb->UrbIsochronousTransfer.StartFrame = 0;
428
429 for (Index = 0; Index < PACKET_COUNT; Index++)
430 {
431 Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * PinContext->DeviceExtension->InterfaceInfo->Pipes[0].MaximumPacketSize;
432 }
433}
#define NULL
Definition: types.h:112
#define PACKET_COUNT
Definition: pin.c:12
NTSTATUS NTAPI UsbAudioCaptureComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: pin.c:909
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
struct _IO_STACK_LOCATION::@1564::@1565 DeviceIoControl
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3978::@4017 Others
union _IO_STACK_LOCATION::@1564 Parameters
Definition: usb.h:529
struct _URB_ISOCH_TRANSFER UrbIsochronousTransfer
Definition: usb.h:544
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
#define USBD_TRANSFER_DIRECTION_IN
Definition: usb.h:160
#define USBD_START_ISO_TRANSFER_ASAP
Definition: usb.h:155
#define URB_FUNCTION_ISOCH_TRANSFER
Definition: usb.h:96
#define GET_ISO_URB_SIZE(n)
Definition: usbdlib.h:125
#define IOCTL_INTERNAL_USB_SUBMIT_URB
Definition: usbioctl.h:32
_In_ WDFCOLLECTION _In_ ULONG Index
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IoSizeOfIrp(_StackSize)
#define IRP_MJ_INTERNAL_DEVICE_CONTROL

Referenced by CaptureAvoidPipeStarvationWorker(), PinCaptureProcess(), and StartCaptureIsocTransfer().

◆ CapturePinStateChange()

NTSTATUS CapturePinStateChange ( _In_ PKSPIN  Pin,
_In_ KSSTATE  ToState,
_In_ KSSTATE  FromState 
)

Definition at line 1359 of file pin.c.

1363{
1365
1366 if (FromState != ToState)
1367 {
1368 if (ToState)
1369 {
1370 if (ToState == KSSTATE_PAUSE)
1371 {
1372 if (FromState == KSSTATE_RUN)
1373 {
1374 /* wait until pin processing is finished*/
1375 }
1376 }
1377 else
1378 {
1379 if (ToState == KSSTATE_RUN)
1380 {
1382 }
1383 }
1384 }
1385 }
1386 return Status;
1387}
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS StartCaptureIsocTransfer(IN PKSPIN Pin)
Definition: pin.c:1316
Status
Definition: gdiplustypes.h:25
@ KSSTATE_PAUSE
Definition: ks.h:1217
@ KSSTATE_RUN
Definition: ks.h:1218
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by USBAudioPinSetDeviceState().

◆ GetDataRangeIndexForFormat()

ULONG GetDataRangeIndexForFormat ( IN PKSDATARANGE  ConnectionFormat,
IN const PKSDATARANGE DataRanges,
IN ULONG  DataRangesCount 
)

Definition at line 698 of file pin.c.

702{
703 ULONG Index;
704 PKSDATARANGE CurrentDataRange;
705 PKSDATARANGE_AUDIO CurrentAudioDataRange;
706 PKSDATAFORMAT_WAVEFORMATEX ConnectionDataFormat;
707
708 if (ConnectionFormat->FormatSize != sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX))
709 {
710 /* unsupported connection format */
711 DPRINT1("GetDataRangeIndexForFormat expected KSDATARANGE_AUDIO\n");
712 return MAXULONG;
713 }
714
715 /* cast to right type */
716 ConnectionDataFormat = (PKSDATAFORMAT_WAVEFORMATEX)ConnectionFormat;
717
718 for (Index = 0; Index < DataRangesCount; Index++)
719 {
720 /* get current data range */
721 CurrentDataRange = DataRanges[Index];
722
723 /* compare guids */
724 if (!IsEqualGUIDAligned(&CurrentDataRange->MajorFormat, &ConnectionFormat->MajorFormat) ||
725 !IsEqualGUIDAligned(&CurrentDataRange->SubFormat, &ConnectionFormat->SubFormat) ||
726 !IsEqualGUIDAligned(&CurrentDataRange->Specifier, &ConnectionFormat->Specifier))
727 {
728 /* no match */
729 continue;
730 }
731
732 /* all pin data ranges are KSDATARANGE_AUDIO */
733 CurrentAudioDataRange = (PKSDATARANGE_AUDIO)CurrentDataRange;
734
735 /* check if number of channel match */
736 if (CurrentAudioDataRange->MaximumChannels != ConnectionDataFormat->WaveFormatEx.nChannels)
737 {
738 /* number of channels mismatch */
739 continue;
740 }
741
742 if (CurrentAudioDataRange->MinimumSampleFrequency > ConnectionDataFormat->WaveFormatEx.nSamplesPerSec)
743 {
744 /* channel frequency too low */
745 continue;
746 }
747
748 if (CurrentAudioDataRange->MaximumSampleFrequency < ConnectionDataFormat->WaveFormatEx.nSamplesPerSec)
749 {
750 /* channel frequency too high */
751 continue;
752 }
753
754 /* FIXME add checks for bitrate / sample size etc */
755 return Index;
756 }
757
758 /* no datarange found */
759 return MAXULONG;
760}
#define DPRINT1
Definition: precomp.h:8
struct KSDATAFORMAT_WAVEFORMATEX * PKSDATAFORMAT_WAVEFORMATEX
struct KSDATARANGE_AUDIO * PKSDATARANGE_AUDIO
WAVEFORMATEX WaveFormatEx
Definition: ksmedia.h:632
ULONG MaximumChannels
Definition: ksmedia.h:680
ULONG MaximumSampleFrequency
Definition: ksmedia.h:684
ULONG MinimumSampleFrequency
Definition: ksmedia.h:683
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define MAXULONG
Definition: typedefs.h:251
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235

Referenced by USBAudioPinCreate().

◆ GetMaxPacketSizeForInterface()

NTSTATUS GetMaxPacketSizeForInterface ( IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
IN PUSB_INTERFACE_DESCRIPTOR  InterfaceDescriptor,
KSPIN_DATAFLOW  DataFlow 
)

Definition at line 16 of file pin.c.

20{
21 PUSB_COMMON_DESCRIPTOR CommonDescriptor;
22 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
23
24 /* loop descriptors */
26 ASSERT(InterfaceDescriptor->bNumEndpoints > 0);
27 while (CommonDescriptor)
28 {
29 if (CommonDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE)
30 {
31 EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)CommonDescriptor;
32 return EndpointDescriptor->wMaxPacketSize;
33 }
34
35 if (CommonDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
36 {
37 /* reached next interface descriptor */
38 break;
39 }
40
41 if ((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength))
42 break;
43
44 CommonDescriptor = (PUSB_COMMON_DESCRIPTOR)((ULONG_PTR)CommonDescriptor + CommonDescriptor->bLength);
45 }
46
47 /* default to 100 */
48 return 100;
49}
#define ULONG_PTR
Definition: config.h:101
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define USB_ENDPOINT_DESCRIPTOR_TYPE
Definition: usb100.h:53
struct _USB_COMMON_DESCRIPTOR * PUSB_COMMON_DESCRIPTOR
struct _USB_ENDPOINT_DESCRIPTOR * PUSB_ENDPOINT_DESCRIPTOR
#define USB_INTERFACE_DESCRIPTOR_TYPE
Definition: usb100.h:52
_In_ WDFUSBINTERFACE _In_ UCHAR _Out_ PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: wdfusb.h:2334

Referenced by InitCapturePin().

◆ InitCapturePin()

NTSTATUS InitCapturePin ( IN PKSPIN  Pin)

Definition at line 490 of file pin.c.

492{
494 ULONG Index;
496 ULONG MaximumPacketSize;
497 PIRP Irp;
498 PURB Urb;
499 PPIN_CONTEXT PinContext;
500 PIO_STACK_LOCATION IoStack;
502 PKSGATE Gate;
503
504
505 /* set sample rate */
507 if (!NT_SUCCESS(Status))
508 {
509 /* failed */
510 return Status;
511 }
512
513 /* get pin context */
514 PinContext = Pin->Context;
515
516 /* lets get maximum packet size */
517 MaximumPacketSize = GetMaxPacketSizeForInterface(PinContext->DeviceExtension->ConfigurationDescriptor, PinContext->InterfaceDescriptor, Pin->DataFlow);
518
519 /* initialize work item for capture worker */
521
522 /* register worker */
524 if (!NT_SUCCESS(Status))
525 {
526 /* failed */
527 return Status;
528 }
529
530 /* initialize work item */
532
533 /* register worker */
535 if (!NT_SUCCESS(Status))
536 {
537 /* failed */
539 }
540
541 /* lets edit framing struct */
542 Framing = (PKSALLOCATOR_FRAMING_EX)Pin->Descriptor->AllocatorFraming;
547 MaximumPacketSize;
548
549 /* calculate buffer size 8 irps * 10 iso packets * max packet size */
550 BufferSize = 8 * PACKET_COUNT * MaximumPacketSize;
551
552 /* allocate pin capture buffer */
553 PinContext->BufferSize = BufferSize;
554 PinContext->Buffer = AllocFunction(BufferSize);
555 if (!PinContext->Buffer)
556 {
557 /* no memory */
559 }
560 KsAddItemToObjectBag(Pin->Bag, PinContext->Buffer, ExFreePool);
561
562 /* init irps */
563 for (Index = 0; Index < 8; Index++)
564 {
565 /* allocate irp */
566 Irp = AllocFunction(IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize));
567 if (!Irp)
568 {
569 /* no memory */
571 }
572
573 /* initialize irp */
574 IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
575
576 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
577 Irp->IoStatus.Information = 0;
578 Irp->Flags = 0;
579 Irp->UserBuffer = NULL;
580
582 IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
583 IoStack->Parameters.Others.Argument2 = NULL;
586
588
589 /* insert into irp list */
590 InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
591
592 /* add to object bag*/
594
595 /* FIXME select correct pipe handle */
596 Status = UsbAudioAllocCaptureUrbIso(PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle,
597 MaximumPacketSize,
598 &PinContext->Buffer[MaximumPacketSize * PACKET_COUNT * Index],
599 MaximumPacketSize * PACKET_COUNT,
600 &Urb);
601
602 DPRINT1("InitCapturePin Irp %p Urb %p\n", Irp, Urb);
603
604 if (NT_SUCCESS(Status))
605 {
606 /* get next stack location */
608
609 /* store urb */
610 IoStack->Parameters.Others.Argument1 = Urb;
611 Irp->Tail.Overlay.DriverContext[0] = Urb;
612 }
613 else
614 {
615 /* failed */
616 return Status;
617 }
618 }
619
620 /* get process control gate */
621 Gate = KsPinGetAndGate(Pin);
622
623 /* turn input off */
624 KsGateTurnInputOff(Gate);
625
626 return Status;
627}
NTSTATUS NTAPI KsAddItemToObjectBag(IN KSOBJECT_BAG ObjectBag, IN PVOID Item, IN PFNKSFREE Free OPTIONAL)
Definition: bag.c:86
#define BufferSize
Definition: mmc.h:75
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID NTAPI CaptureGateOnWorkItem(_In_ PVOID Context)
Definition: pin.c:275
NTSTATUS UsbAudioAllocCaptureUrbIso(IN USBD_PIPE_HANDLE PipeHandle, IN ULONG MaxPacketSize, IN PVOID Buffer, IN ULONG BufferLength, OUT PURB *OutUrb)
Definition: pin.c:52
NTSTATUS GetMaxPacketSizeForInterface(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, KSPIN_DATAFLOW DataFlow)
Definition: pin.c:16
VOID NTAPI CaptureAvoidPipeStarvationWorker(_In_ PVOID Context)
Definition: pin.c:438
NTSTATUS UsbAudioSetFormat(IN PKSPIN Pin)
Definition: pin.c:94
#define InsertTailList(ListHead, Entry)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
PVOID NTAPI AllocFunction(IN ULONG ItemSize)
Definition: hid.c:45
struct KSALLOCATOR_FRAMING_EX * PKSALLOCATOR_FRAMING_EX
KS_FRAMING_ITEM FramingItem[1]
Definition: ks.h:1681
KS_FRAMING_RANGE PhysicalRange
Definition: ks.h:1371
KS_FRAMING_RANGE_WEIGHTED FramingRange
Definition: ks.h:1372
KS_FRAMING_RANGE Range
Definition: ks.h:1357
ULONG MaxFrameSize
Definition: ks.h:1352
ULONG MinFrameSize
Definition: ks.h:1351
WORK_QUEUE_ITEM StarvationWorkItem
Definition: usbaudio.h:208
WORK_QUEUE_ITEM CaptureWorkItem
Definition: usbaudio.h:206
PUCHAR Buffer
Definition: usbaudio.h:201
ULONG BufferSize
Definition: usbaudio.h:202
PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor
Definition: usbaudio.h:205
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
KSDDKAPI VOID NTAPI KsUnregisterWorker(IN PKSWORKER Worker)
Definition: worker.c:128
KSDDKAPI NTSTATUS NTAPI KsRegisterCountedWorker(IN WORK_QUEUE_TYPE WorkQueueType, IN PWORK_QUEUE_ITEM CountedWorkItem, OUT PKSWORKER *Worker)
Definition: worker.c:166
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by USBAudioPinCreate().

◆ InitStreamPin()

NTSTATUS InitStreamPin ( IN PKSPIN  Pin)

Definition at line 630 of file pin.c.

632{
633 ULONG Index;
634 PIRP Irp;
635 PPIN_CONTEXT PinContext;
636 PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
637 PIO_STACK_LOCATION IoStack;
638
639 DPRINT1("InitStreamPin\n");
640
641 /* get pin context */
642 PinContext = Pin->Context;
643
644 /* allocate 1 sec buffer */
645 WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
646 PinContext->Buffer = AllocFunction(WaveFormatEx->WaveFormatEx.nAvgBytesPerSec);
647 if (!PinContext->Buffer)
648 {
649 /* no memory */
651 }
652
653 /* init buffer size*/
654 PinContext->BufferSize = WaveFormatEx->WaveFormatEx.nAvgBytesPerSec;
655 PinContext->BufferOffset = 0;
656 PinContext->BufferLength = 0;
657
658 /* init irps */
659 for (Index = 0; Index < 12; Index++)
660 {
661 /* allocate irp */
662 Irp = AllocFunction(IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize));
663 if (!Irp)
664 {
665 /* no memory */
667 }
668
669 DPRINT1("InitStreamPin Irp %p\n", Irp);
670
671 /* initialize irp */
672 IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
673
674 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
675 Irp->IoStatus.Information = 0;
676 Irp->Flags = 0;
677 Irp->UserBuffer = NULL;
678
680 IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
681 IoStack->Parameters.Others.Argument2 = NULL;
684
686
687 /* insert into irp list */
688 InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
689
690 /* add to object bag*/
692 }
693
694 return STATUS_SUCCESS;
695}
NTSTATUS NTAPI UsbAudioRenderComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: pin.c:853
ULONG BufferOffset
Definition: usbaudio.h:203
ULONG BufferLength
Definition: usbaudio.h:204
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43

Referenced by USBAudioPinCreate().

◆ PinCaptureProcess()

NTSTATUS PinCaptureProcess ( IN PKSPIN  Pin)

Definition at line 1121 of file pin.c.

1123{
1124 PKSSTREAM_POINTER LeadingStreamPointer;
1125 KIRQL OldLevel;
1126 PPIN_CONTEXT PinContext;
1127 PLIST_ENTRY CurEntry;
1128 PIRP Irp;
1129 PURB Urb;
1130 PUCHAR TransferBuffer, OutBuffer;
1133 PKSGATE Gate;
1134
1135 //DPRINT1("PinCaptureProcess\n");
1137 if (LeadingStreamPointer == NULL)
1138 {
1139 /* get process control gate */
1140 Gate = KsPinGetAndGate(Pin);
1141
1142 /* shutdown processing */
1143 KsGateTurnInputOff(Gate);
1144
1145 return STATUS_SUCCESS;
1146 }
1147
1148 /* get pin context */
1149 PinContext = Pin->Context;
1150
1151 /* acquire spin lock */
1152 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1153
1154 while (!IsListEmpty(&PinContext->DoneIrpListHead))
1155 {
1156 /* remove entry from list */
1157 CurEntry = RemoveHeadList(&PinContext->DoneIrpListHead);
1158
1159 /* release lock */
1160 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1161
1162 /* get irp offset */
1163 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1164
1165 /* get urb from irp */
1166 Urb = (PURB)Irp->Tail.Overlay.DriverContext[0];
1167 ASSERT(Urb);
1168
1169 Offset = PtrToUlong(Irp->Tail.Overlay.DriverContext[1]);
1170
1171 /* get transfer buffer */
1172 TransferBuffer = Urb->UrbIsochronousTransfer.TransferBuffer;
1173
1174 /* get target buffer */
1175 OutBuffer = (PUCHAR)LeadingStreamPointer->StreamHeader->Data;
1176
1177 /* calculate length */
1178 Length = min(LeadingStreamPointer->OffsetOut.Count - LeadingStreamPointer->StreamHeader->DataUsed, Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
1179
1180 /* FIXME copy each packet extra */
1181 /* copy audio bytes */
1182 RtlCopyMemory((PUCHAR)&OutBuffer[LeadingStreamPointer->StreamHeader->DataUsed], &TransferBuffer[Offset], Length);
1183
1184 //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);
1185
1186 /* adjust streampointer */
1187 LeadingStreamPointer->StreamHeader->DataUsed += Length;
1188
1189 if (Length == LeadingStreamPointer->OffsetOut.Remaining)
1190 {
1191 KsStreamPointerAdvanceOffsetsAndUnlock(LeadingStreamPointer, 0, Length, TRUE);
1192
1193 /* acquire spin lock */
1194 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1195
1196 /* adjust offset */
1197 Irp->Tail.Overlay.DriverContext[1] = UlongToPtr(Length);
1198
1199 /* reinsert into processed list */
1200 InsertHeadList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
1201
1202 /* release lock */
1203 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1204
1206 if (LeadingStreamPointer == NULL)
1207 {
1208 /* no more work to be done*/
1209 return STATUS_PENDING;
1210 }
1211 else
1212 {
1213 /* resume work on this irp */
1214 continue;
1215 }
1216 }
1217 else
1218 {
1219 Status = KsStreamPointerAdvanceOffsets(LeadingStreamPointer, 0, Length, FALSE);
1221 ASSERT(Length == Urb->UrbIsochronousTransfer.TransferBufferLength - Offset);
1222 }
1223
1224
1225 /* acquire spin lock */
1226 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1227
1228 InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
1229 }
1230
1231 while (!IsListEmpty(&PinContext->IrpListHead))
1232 {
1233 /* remove entry from list */
1234 CurEntry = RemoveHeadList(&PinContext->IrpListHead);
1235
1236 /* release lock */
1237 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1238
1239 /* get irp offset */
1240 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1241
1242 /* reinitialize irp and urb */
1244
1245 IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
1246
1247 /* acquire spin lock */
1248 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1249
1250 }
1251
1252 /* release lock */
1253 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1254
1255 if (LeadingStreamPointer != NULL)
1256 KsStreamPointerUnlock(LeadingStreamPointer, FALSE);
1257
1258 /* get process control gate */
1259 Gate = KsPinGetAndGate(Pin);
1260
1261 /* shutdown processing */
1262 KsGateTurnInputOff(Gate);
1263
1264 return STATUS_PENDING;
1265}
#define FALSE
Definition: types.h:117
KSDDKAPI VOID NTAPI KsStreamPointerAdvanceOffsetsAndUnlock(IN PKSSTREAM_POINTER StreamPointer, IN ULONG InUsed, IN ULONG OutUsed, IN BOOLEAN Eject)
Definition: pin.c:1480
KSDDKAPI PKSSTREAM_POINTER NTAPI KsPinGetLeadingEdgeStreamPointer(IN PKSPIN Pin, IN KSSTREAM_POINTER_STATE State)
Definition: pin.c:1385
KSDDKAPI VOID NTAPI KsStreamPointerUnlock(IN PKSSTREAM_POINTER StreamPointer, IN BOOLEAN Eject)
Definition: pin.c:1463
KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvanceOffsets(IN PKSSTREAM_POINTER StreamPointer, IN ULONG InUsed, IN ULONG OutUsed, IN BOOLEAN Eject)
Definition: pin.c:1628
#define UlongToPtr(u)
Definition: config.h:106
#define PtrToUlong(u)
Definition: config.h:107
#define InsertHeadList(ListHead, Entry)
@ KSSTREAM_POINTER_STATE_LOCKED
Definition: ks.h:3025
#define min(a, b)
Definition: monoChain.cc:55
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_PENDING
Definition: ntstatus.h:82
_In_ UCHAR _In_ ULONG _Out_ PUCHAR _Outptr_result_bytebuffer_ OutBufferLength PVOID * OutBuffer
Definition: scsi.h:4071
LIST_ENTRY DoneIrpListHead
Definition: usbaudio.h:199
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
struct _URB * PURB
#define NT_ASSERT
Definition: rtlfuncs.h:3310

Referenced by USBAudioPinProcess().

◆ PinGetIrpFromReadyList()

PIRP PinGetIrpFromReadyList ( IN PKSPIN  Pin)

Definition at line 957 of file pin.c.

959{
960 PPIN_CONTEXT PinContext;
961 PLIST_ENTRY CurEntry;
962 KIRQL OldLevel;
963 PIRP Irp = NULL;
964
965 /* get pin context */
966 PinContext = Pin->Context;
967
968 /* acquire spin lock */
969 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
970
971 if (!IsListEmpty(&PinContext->IrpListHead))
972 {
973 /* remove entry from list */
974 CurEntry = RemoveHeadList(&PinContext->IrpListHead);
975
976 /* get irp offset */
977 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
978 }
979
980 /* release lock */
981 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
982
983 return Irp;
984}

Referenced by PinRenderProcess().

◆ PinRenderProcess()

NTSTATUS PinRenderProcess ( IN PKSPIN  Pin)

Definition at line 987 of file pin.c.

989{
990 PKSSTREAM_POINTER LeadingStreamPointer;
991 PKSSTREAM_POINTER CloneStreamPointer;
993 PPIN_CONTEXT PinContext;
994 ULONG PacketCount, TotalPacketSize, Offset;
995 PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
996 PUCHAR TransferBuffer;
997 PIRP Irp = NULL;
998
999 //DPRINT1("PinRenderProcess\n");
1000
1002 if (LeadingStreamPointer == NULL)
1003 {
1004 return STATUS_SUCCESS;
1005 }
1006
1007 if (NULL == LeadingStreamPointer->StreamHeader->Data)
1008 {
1009 Status = KsStreamPointerAdvance(LeadingStreamPointer);
1010 DPRINT1("Advancing Streampointer\n");
1011 }
1012
1013
1014 /* get pin context */
1015 PinContext = Pin->Context;
1016
1017 /* get irp from ready list */
1019
1020 if (!Irp)
1021 {
1022 /* no irps available */
1023 DPRINT1("No irps available");
1024 KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1025 return STATUS_SUCCESS;
1026 }
1027
1028 /* clone stream pointer */
1029 Status = KsStreamPointerClone(LeadingStreamPointer, NULL, 0, &CloneStreamPointer);
1030 if (!NT_SUCCESS(Status))
1031 {
1032 /* failed */
1033 KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1034 DPRINT1("Leaking Irp %p\n", Irp);
1035 return STATUS_SUCCESS;
1036 }
1037
1038 /* calculate packet count */
1039 /* FIXME support various sample rates */
1040 WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
1041 TotalPacketSize = WaveFormatEx->WaveFormatEx.nAvgBytesPerSec / 1000;
1042
1043 /* init transfer buffer*/
1044 TransferBuffer = CloneStreamPointer->StreamHeader->Data;
1045
1046 Offset = 0;
1047
1048 /* are there bytes from previous request*/
1049 if (PinContext->BufferLength)
1050 {
1051 ASSERT(PinContext->BufferLength < TotalPacketSize);
1052
1053 /* calculate offset*/
1054 Offset = TotalPacketSize - PinContext->BufferLength;
1055
1056 if (PinContext->BufferOffset + TotalPacketSize >= PinContext->BufferSize)
1057 {
1058 RtlMoveMemory(PinContext->Buffer, &PinContext->Buffer[PinContext->BufferOffset - PinContext->BufferLength], PinContext->BufferLength);
1059 PinContext->BufferOffset = PinContext->BufferLength;
1060 }
1061
1062 /* copy audio bytes */
1063 RtlCopyMemory(&PinContext->Buffer[PinContext->BufferOffset], TransferBuffer, Offset);
1064
1065 /* init irp*/
1066 Status = RenderInitializeUrbAndIrp(Pin, PinContext, Irp, &PinContext->Buffer[PinContext->BufferOffset-PinContext->BufferLength], TotalPacketSize, TotalPacketSize);
1067 if (NT_SUCCESS(Status))
1068 {
1069 /* render audio bytes */
1070 Status = IoCallDriver(PinContext->LowerDevice, Irp);
1071 }
1072 else
1073 {
1074 ASSERT(FALSE);
1075 }
1076
1077 PinContext->BufferLength = 0;
1078 PinContext->BufferOffset += Offset;
1079
1080 /* get new irp from ready list */
1082 ASSERT(Irp);
1083
1084 }
1085
1086 /* FIXME correct MaximumPacketSize ? */
1087 PacketCount = (CloneStreamPointer->OffsetIn.Remaining - Offset) / TotalPacketSize;
1088
1089 Status = RenderInitializeUrbAndIrp(Pin, PinContext, Irp, &TransferBuffer[Offset], PacketCount * TotalPacketSize, TotalPacketSize);
1090 if (NT_SUCCESS(Status))
1091 {
1092 /* store in irp context */
1093 Irp->Tail.Overlay.DriverContext[1] = CloneStreamPointer;
1094
1095 if ((PacketCount * TotalPacketSize) + Offset < CloneStreamPointer->OffsetIn.Remaining)
1096 {
1097 /* calculate remaining buffer bytes */
1098 PinContext->BufferLength = CloneStreamPointer->OffsetIn.Remaining - ((PacketCount * TotalPacketSize) + Offset);
1099
1100 /* check for overflow */
1101 if (PinContext->BufferOffset + TotalPacketSize >= PinContext->BufferSize)
1102 {
1103 /* reset buffer offset*/
1104 PinContext->BufferOffset = 0;
1105 }
1106 RtlCopyMemory(&PinContext->Buffer[PinContext->BufferOffset], &TransferBuffer[(PacketCount * TotalPacketSize) + Offset], PinContext->BufferLength);
1107 PinContext->BufferOffset += PinContext->BufferLength;
1108 }
1109
1110 /* render audio bytes */
1111 Status = IoCallDriver(PinContext->LowerDevice, Irp);
1112 }
1113
1114
1115 /* unlock stream pointer and finish*/
1116 KsStreamPointerUnlock(LeadingStreamPointer, TRUE);
1117 return STATUS_PENDING;
1118}
KSDDKAPI NTSTATUS NTAPI KsStreamPointerAdvance(IN PKSSTREAM_POINTER StreamPointer)
Definition: pin.c:1688
KSDDKAPI NTSTATUS NTAPI KsStreamPointerClone(IN PKSSTREAM_POINTER StreamPointer, IN PFNKSSTREAMPOINTER CancelCallback OPTIONAL, IN ULONG ContextSize, OUT PKSSTREAM_POINTER *CloneStreamPointer)
Definition: pin.c:1545
NTSTATUS RenderInitializeUrbAndIrp(IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN OUT PIRP Irp, IN PVOID TransferBuffer, IN ULONG TransferBufferSize, IN ULONG PacketSize)
Definition: pin.c:312
PIRP PinGetIrpFromReadyList(IN PKSPIN Pin)
Definition: pin.c:957
if(dx< 0)
Definition: linetemp.h:194
PDEVICE_OBJECT LowerDevice
Definition: usbaudio.h:197
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by USBAudioPinProcess().

◆ RenderInitializeUrbAndIrp()

NTSTATUS RenderInitializeUrbAndIrp ( IN PKSPIN  Pin,
IN PPIN_CONTEXT  PinContext,
IN OUT PIRP  Irp,
IN PVOID  TransferBuffer,
IN ULONG  TransferBufferSize,
IN ULONG  PacketSize 
)

Definition at line 312 of file pin.c.

319{
320 ULONG Index, PacketCount;
321 PURB Urb;
322 PIO_STACK_LOCATION IoStack;
323
324 /* initialize irp */
325 IoInitializeIrp(Irp, IoSizeOfIrp(PinContext->DeviceExtension->LowerDevice->StackSize), PinContext->DeviceExtension->LowerDevice->StackSize);
326
327 /* set irp members */
328 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
329 Irp->IoStatus.Information = 0;
330 Irp->Flags = 0;
331 Irp->UserBuffer = NULL;
332
333 /* init stack location */
335 IoStack->DeviceObject = PinContext->DeviceExtension->LowerDevice;
336 IoStack->Parameters.Others.Argument2 = NULL;
339
340 /* set completion routine */
342
343 /* calculate packet count */
344 PacketCount = TransferBufferSize / PacketSize;
345 ASSERT(TransferBufferSize % PacketSize == 0);
346
347 /* lets allocate urb */
348 Urb = (PURB)AllocFunction(GET_ISO_URB_SIZE(PacketCount));
349 if (!Urb)
350 {
351 /* no memory */
353 }
354
355 /* init urb */
357 Urb->UrbIsochronousTransfer.Hdr.Length = GET_ISO_URB_SIZE(PacketCount);
358 Urb->UrbIsochronousTransfer.PipeHandle = PinContext->DeviceExtension->InterfaceInfo->Pipes[0].PipeHandle;
360 Urb->UrbIsochronousTransfer.TransferBufferLength = TransferBufferSize;
361 Urb->UrbIsochronousTransfer.TransferBuffer = TransferBuffer;
362 Urb->UrbIsochronousTransfer.NumberOfPackets = PacketCount;
363 Urb->UrbIsochronousTransfer.StartFrame = 0;
364
365 for (Index = 0; Index < PacketCount; Index++)
366 {
367 Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * PacketSize;
368 }
369
370 /* store urb */
371 IoStack->Parameters.Others.Argument1 = Urb;
372 Irp->Tail.Overlay.DriverContext[0] = Urb;
373
374
375 /* done */
376 return STATUS_SUCCESS;
377}
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define USBD_TRANSFER_DIRECTION_OUT
Definition: usb.h:159
_In_ USHORT PacketSize
Definition: iofuncs.h:1058

Referenced by PinRenderProcess().

◆ StartCaptureIsocTransfer()

NTSTATUS StartCaptureIsocTransfer ( IN PKSPIN  Pin)

Definition at line 1316 of file pin.c.

1318{
1319 PPIN_CONTEXT PinContext;
1320 PLIST_ENTRY CurEntry;
1321 PIRP Irp;
1322 KIRQL OldLevel;
1323
1324 /* get pin context */
1325 PinContext = Pin->Context;
1326
1327 /* acquire spin lock */
1328 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1329
1330 while(!IsListEmpty(&PinContext->IrpListHead))
1331 {
1332 /* remove entry from list */
1333 CurEntry = RemoveHeadList(&PinContext->IrpListHead);
1334
1335 /* get irp offset */
1336 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
1337
1338 /* release lock */
1339 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1340
1341 /* reinitialize irp and urb */
1343
1344 DPRINT("StartCaptureIsocTransfer Irp %p\n", Irp);
1345 IoCallDriver(PinContext->DeviceExtension->LowerDevice, Irp);
1346
1347 /* acquire spin lock */
1348 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
1349
1350 }
1351
1352 /* release lock */
1353 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
1354
1355 return STATUS_SUCCESS;
1356}
#define DPRINT
Definition: sndvol32.h:71

Referenced by CapturePinStateChange().

◆ UsbAudioAllocCaptureUrbIso()

NTSTATUS UsbAudioAllocCaptureUrbIso ( IN USBD_PIPE_HANDLE  PipeHandle,
IN ULONG  MaxPacketSize,
IN PVOID  Buffer,
IN ULONG  BufferLength,
OUT PURB OutUrb 
)

Definition at line 52 of file pin.c.

58{
59 PURB Urb;
60 ULONG UrbSize;
62
63 /* calculate urb size*/
65
66 /* allocate urb */
67 Urb = AllocFunction(UrbSize);
68 if (!Urb)
69 {
70 /* no memory */
72 }
73
74 /* init urb */
76 Urb->UrbIsochronousTransfer.Hdr.Length = UrbSize;
77 Urb->UrbIsochronousTransfer.PipeHandle = PipeHandle;
79 Urb->UrbIsochronousTransfer.TransferBufferLength = BufferLength;
80 Urb->UrbIsochronousTransfer.TransferBuffer = Buffer;
81 Urb->UrbIsochronousTransfer.NumberOfPackets = PACKET_COUNT;
82
83 for (Index = 0; Index < PACKET_COUNT; Index++)
84 {
85 Urb->UrbIsochronousTransfer.IsoPacket[Index].Offset = Index * MaxPacketSize;
86 }
87
88 *OutUrb = Urb;
89 return STATUS_SUCCESS;
90
91}
Definition: bufpool.h:45
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771

Referenced by InitCapturePin().

◆ UsbAudioCaptureComplete()

NTSTATUS NTAPI UsbAudioCaptureComplete ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 909 of file pin.c.

913{
914 PKSPIN Pin;
915 PPIN_CONTEXT PinContext;
916 KIRQL OldLevel;
917 PURB Urb;
918
919 /* get pin context */
920 Pin = Context;
921 PinContext = Pin->Context;
922
923 /* get urb */
924 Urb = Irp->Tail.Overlay.DriverContext[0];
925
926 /* acquire lock */
927 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
928
929 if (!NT_SUCCESS(Urb->UrbIsochronousTransfer.Hdr.Status))
930 {
931 //DPRINT("UsbAudioCaptureComplete Irp %p Urb %p Status %x Packet Status %x\n", Irp, Urb, Urb->UrbIsochronousTransfer.Hdr.Status, Urb->UrbIsochronousTransfer.IsoPacket[0].Status);
932
933 /* insert entry into ready list */
934 InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
935
936 /* release lock */
937 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
938
940 }
941 else
942 {
943 /* insert entry into done list */
944 InsertTailList(&PinContext->DoneIrpListHead, &Irp->Tail.Overlay.ListEntry);
945
946 /* release lock */
947 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
948
950 }
951
952 /* done */
954}
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
KSDDKAPI ULONG NTAPI KsIncrementCountedWorker(IN PKSWORKER Worker)
Definition: worker.c:222

Referenced by CaptureInitializeUrbAndIrp(), and InitCapturePin().

◆ USBAudioPinClose()

NTSTATUS NTAPI USBAudioPinClose ( _In_ PKSPIN  Pin,
_In_ PIRP  Irp 
)

Definition at line 843 of file pin.c.

846{
849}
#define UNIMPLEMENTED
Definition: debug.h:115
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ USBAudioPinCreate()

NTSTATUS NTAPI USBAudioPinCreate ( _In_ PKSPIN  Pin,
_In_ PIRP  Irp 
)

Definition at line 764 of file pin.c.

767{
768 PKSFILTER Filter;
770 PPIN_CONTEXT PinContext;
772 ULONG FormatIndex;
773
775 if (Filter == NULL)
776 {
777 /* invalid parameter */
779 }
780
781 /* get filter context */
782 FilterContext = Filter->Context;
783
784 /* allocate pin context */
785 PinContext = AllocFunction(sizeof(PIN_CONTEXT));
786 if (!PinContext)
787 {
788 /* no memory*/
790 }
791
792 /* init pin context */
793 PinContext->DeviceExtension = FilterContext->DeviceExtension;
794 PinContext->LowerDevice = FilterContext->LowerDevice;
795 InitializeListHead(&PinContext->IrpListHead);
797 KeInitializeSpinLock(&PinContext->IrpListLock);
798
799 /* store pin context*/
800 Pin->Context = PinContext;
801
802 /* lets edit allocator framing struct */
803 Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor, sizeof(KSPIN_DESCRIPTOR_EX), sizeof(KSPIN_DESCRIPTOR_EX), USBAUDIO_TAG);
804 if (NT_SUCCESS(Status))
805 {
806 Status = _KsEdit(Pin->Bag, (PVOID*)&Pin->Descriptor->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING_EX), sizeof(KSALLOCATOR_FRAMING_EX), USBAUDIO_TAG);
808 }
809
810 /* choose correct dataformat */
811 FormatIndex = GetDataRangeIndexForFormat(Pin->ConnectionFormat, Pin->Descriptor->PinDescriptor.DataRanges, Pin->Descriptor->PinDescriptor.DataRangesCount);
812 if (FormatIndex == MAXULONG)
813 {
814 /* no format match */
815 return STATUS_NO_MATCH;
816 }
817
818 /* select streaming interface */
819 Status = USBAudioSelectAudioStreamingInterface(Pin, PinContext, PinContext->DeviceExtension, PinContext->DeviceExtension->ConfigurationDescriptor, FormatIndex);
820 if (!NT_SUCCESS(Status))
821 {
822 /* failed */
823 DPRINT1("USBAudioSelectAudioStreamingInterface failed with %x\n", Status);
824 return Status;
825 }
826
827 if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
828 {
829 /* init capture pin */
831 }
832 else
833 {
834 /* audio streaming pin*/
836 }
837
838 return Status;
839}
KSDDKAPI NTSTATUS NTAPI _KsEdit(IN KSOBJECT_BAG ObjectBag, IN OUT PVOID *PointerToPointerToItem, IN ULONG NewSize, IN ULONG OldSize, IN ULONG Tag)
Definition: bag.c:358
PKSFILTER NTAPI KsPinGetParentFilter(IN PKSPIN Pin)
Definition: pin.c:1097
NTSTATUS InitCapturePin(IN PKSPIN Pin)
Definition: pin.c:490
NTSTATUS InitStreamPin(IN PKSPIN Pin)
Definition: pin.c:630
ULONG GetDataRangeIndexForFormat(IN PKSDATARANGE ConnectionFormat, IN const PKSDATARANGE *DataRanges, IN ULONG DataRangesCount)
Definition: pin.c:698
NTSTATUS USBAudioSelectAudioStreamingInterface(IN PKSPIN Pin, IN PPIN_CONTEXT PinContext, IN PDEVICE_EXTENSION DeviceExtension, IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG FormatDescriptorIndex)
Definition: pin.c:168
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG _In_opt_ PVOID _In_opt_ PVOID FilterContext
Definition: fsrtlfuncs.h:746
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
#define STATUS_NO_MATCH
Definition: ntstatus.h:751
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define USBAUDIO_TAG
Definition: usbaudio.h:13

◆ UsbAudioPinDataIntersect()

NTSTATUS NTAPI UsbAudioPinDataIntersect ( _In_ PVOID  Context,
_In_ PIRP  Irp,
_In_ PKSP_PIN  Pin,
_In_ PKSDATARANGE  DataRange,
_In_ PKSDATARANGE  MatchingDataRange,
_In_ ULONG  DataBufferSize,
_Out_ PVOID  Data,
_Out_ PULONG  DataSize 
)

Definition at line 1416 of file pin.c.

1425{
1426 PKSFILTER Filter;
1427 PKSPIN_DESCRIPTOR_EX PinDescriptor;
1429 PKSDATARANGE_AUDIO DataRangeAudio;
1430
1431 /* get filter from irp*/
1433 if (!Filter)
1434 {
1435 /* no match*/
1436 return STATUS_NO_MATCH;
1437 }
1438
1439 /* get pin descriptor */
1440 PinDescriptor = (PKSPIN_DESCRIPTOR_EX)&Filter->Descriptor->PinDescriptors[Pin->PinId];
1441
1443 if (DataBufferSize == 0)
1444 {
1445 /* buffer too small */
1447 }
1448
1449 /* sanity checks*/
1450 ASSERT(PinDescriptor->PinDescriptor.DataRangesCount >= 0);
1451 ASSERT(PinDescriptor->PinDescriptor.DataRanges[0]->FormatSize == sizeof(KSDATARANGE_AUDIO));
1452
1453 DataRangeAudio = (PKSDATARANGE_AUDIO)PinDescriptor->PinDescriptor.DataRanges[0];
1454
1455 DataFormat = Data;
1456 DataFormat->WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
1457 DataFormat->WaveFormatEx.nChannels = DataRangeAudio->MaximumChannels;
1458 DataFormat->WaveFormatEx.nSamplesPerSec = DataRangeAudio->MaximumSampleFrequency;
1459 DataFormat->WaveFormatEx.nAvgBytesPerSec = DataRangeAudio->MaximumSampleFrequency * (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1460 DataFormat->WaveFormatEx.nBlockAlign = (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1461 DataFormat->WaveFormatEx.wBitsPerSample = DataRangeAudio->MaximumBitsPerSample;
1462 DataFormat->WaveFormatEx.cbSize = 0;
1463
1464 DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
1465 DataFormat->DataFormat.Flags = 0;
1466 DataFormat->DataFormat.Reserved = 0;
1467 DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
1468 DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
1469 DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
1470 DataFormat->DataFormat.SampleSize = (DataRangeAudio->MaximumBitsPerSample / 8) * DataRangeAudio->MaximumChannels;
1471
1472 return STATUS_SUCCESS;
1473}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
KSDDKAPI PKSFILTER NTAPI KsGetFilterFromIrp(IN PIRP Irp)
Definition: filter.c:2106
#define KSDATAFORMAT_SUBTYPE_PCM
Definition: ksmedia.h:1021
#define KSDATAFORMAT_TYPE_AUDIO
Definition: ksmedia.h:983
#define KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
Definition: ksmedia.h:1031
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
ULONG MaximumBitsPerSample
Definition: ksmedia.h:682

Referenced by USBAudioPinBuildDescriptors().

◆ USBAudioPinProcess()

NTSTATUS NTAPI USBAudioPinProcess ( _In_ PKSPIN  Pin)

Definition at line 1270 of file pin.c.

1272{
1274
1275 if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
1276 {
1278 }
1279 else
1280 {
1282 }
1283
1284 return Status;
1285}
NTSTATUS PinRenderProcess(IN PKSPIN Pin)
Definition: pin.c:987
NTSTATUS PinCaptureProcess(IN PKSPIN Pin)
Definition: pin.c:1121

◆ USBAudioPinReset()

VOID NTAPI USBAudioPinReset ( _In_ PKSPIN  Pin)

Definition at line 1290 of file pin.c.

1292{
1294}

◆ USBAudioPinSetDataFormat()

NTSTATUS NTAPI USBAudioPinSetDataFormat ( _In_ PKSPIN  Pin,
_In_opt_ PKSDATAFORMAT  OldFormat,
_In_opt_ PKSMULTIPLE_ITEM  OldAttributeList,
_In_ const KSDATARANGE DataRange,
_In_opt_ const KSATTRIBUTE_LIST *  AttributeRange 
)

Definition at line 1298 of file pin.c.

1304{
1305 if (OldFormat == NULL)
1306 {
1307 /* TODO: verify connection format */
1309 return STATUS_SUCCESS;
1310 }
1311
1312 return UsbAudioSetFormat(Pin);
1313}

◆ USBAudioPinSetDeviceState()

NTSTATUS NTAPI USBAudioPinSetDeviceState ( _In_ PKSPIN  Pin,
_In_ KSSTATE  ToState,
_In_ KSSTATE  FromState 
)

Definition at line 1392 of file pin.c.

1396{
1398
1399 if (Pin->DataFlow == KSPIN_DATAFLOW_OUT)
1400 {
1401 /* handle capture state changes */
1402 Status = CapturePinStateChange(Pin, ToState, FromState);
1403 }
1404 else
1405 {
1408 }
1409
1410 return Status;
1411}
NTSTATUS CapturePinStateChange(_In_ PKSPIN Pin, _In_ KSSTATE ToState, _In_ KSSTATE FromState)
Definition: pin.c:1359

◆ UsbAudioRenderComplete()

NTSTATUS NTAPI UsbAudioRenderComplete ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 853 of file pin.c.

857{
858 PKSPIN Pin;
859 PPIN_CONTEXT PinContext;
860 KIRQL OldLevel;
861 PKSSTREAM_POINTER StreamPointerClone;
863 PURB Urb;
864
865 /* get pin context */
866 Pin = Context;
867 PinContext = Pin->Context;
868
869 /* get status */
870 Status = Irp->IoStatus.Status;
871
872 /* get streampointer */
873 StreamPointerClone = Irp->Tail.Overlay.DriverContext[1];
874
875 /* get urb */
876 Urb = Irp->Tail.Overlay.DriverContext[0];
877
878 /* and free it */
879 FreeFunction(Urb);
880
881 /* acquire lock */
882 KeAcquireSpinLock(&PinContext->IrpListLock, &OldLevel);
883
884 /* insert entry into ready list */
885 InsertTailList(&PinContext->IrpListHead, &Irp->Tail.Overlay.ListEntry);
886
887 /* release lock */
888 KeReleaseSpinLock(&PinContext->IrpListLock, OldLevel);
889
890 if (!NT_SUCCESS(Status) && StreamPointerClone)
891 {
892 /* set status code because it failed */
894 DPRINT1("UsbAudioRenderComplete failed with %x\n", Status);
895 }
896
897 if (StreamPointerClone)
898 {
899 /* lets delete the stream pointer clone */
900 KsStreamPointerDelete(StreamPointerClone);
901 }
902
903 /* done */
905}
KSDDKAPI NTSTATUS NTAPI KsStreamPointerSetStatusCode(IN PKSSTREAM_POINTER StreamPointer, IN NTSTATUS Status)
Definition: pin.c:1436
KSDDKAPI VOID NTAPI KsStreamPointerDelete(IN PKSSTREAM_POINTER StreamPointer)
Definition: pin.c:1497
VOID NTAPI FreeFunction(IN PVOID Item)
Definition: hid.c:53
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159

Referenced by InitStreamPin(), and RenderInitializeUrbAndIrp().

◆ USBAudioSelectAudioStreamingInterface()

NTSTATUS USBAudioSelectAudioStreamingInterface ( IN PKSPIN  Pin,
IN PPIN_CONTEXT  PinContext,
IN PDEVICE_EXTENSION  DeviceExtension,
IN PUSB_CONFIGURATION_DESCRIPTOR  ConfigurationDescriptor,
IN ULONG  FormatDescriptorIndex 
)

Definition at line 168 of file pin.c.

174{
175 PURB Urb;
179
180 PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR StreamingInterfaceDescriptor;
182
183 /* search for terminal descriptor of that irp sink / irp source */
184 TerminalDescriptor = UsbAudioGetStreamingTerminalDescriptorByIndex(DeviceExtension->ConfigurationDescriptor, Pin->Id);
185 ASSERT(TerminalDescriptor != NULL);
186
187 /* grab interface descriptor */
188 InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, -1, -1, USB_DEVICE_CLASS_AUDIO, -1, -1);
190 {
191 /* no such interface */
193 }
194
195 Found = FALSE;
196 Index = 0;
197
198 /* selects the interface which has an audio streaming interface descriptor associated to the input / output terminal at the given format index */
199 while (InterfaceDescriptor != NULL)
200 {
201 if (InterfaceDescriptor->bInterfaceSubClass == 0x02 /* AUDIO_STREAMING */ && InterfaceDescriptor->bNumEndpoints > 0)
202 {
203 StreamingInterfaceDescriptor = (PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR)USBD_ParseDescriptors(ConfigurationDescriptor, ConfigurationDescriptor->wTotalLength, InterfaceDescriptor, USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE);
204 if (StreamingInterfaceDescriptor != NULL)
205 {
206 ASSERT(StreamingInterfaceDescriptor->bDescriptorSubtype == 0x01);
207 ASSERT(StreamingInterfaceDescriptor->wFormatTag == WAVE_FORMAT_PCM);
208 if (StreamingInterfaceDescriptor->bTerminalLink == TerminalDescriptor->bTerminalID)
209 {
210 if (FormatDescriptorIndex == Index)
211 {
212 Found = TRUE;
213 break;
214 }
215 Index++;
216 }
217 }
218 }
220 }
221
222 if (!Found)
223 {
224 /* no such interface */
225 DPRINT1("No Interface found\n");
227 }
228
230 if (!Urb)
231 {
232 /* no memory */
234 }
235
236 /* now prepare interface urb */
237 UsbBuildSelectInterfaceRequest(Urb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceDescriptor->bNumEndpoints), DeviceExtension->ConfigurationHandle, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
238
239 /* now select the interface */
240 Status = SubmitUrbSync(DeviceExtension->LowerDevice, Urb);
241
242 DPRINT1("USBAudioSelectAudioStreamingInterface Status %x UrbStatus %x InterfaceNumber %x AlternateSetting %x\n", Status, Urb->UrbSelectInterface.Hdr.Status, InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting);
243
244 /* did it succeeed */
245 if (NT_SUCCESS(Status))
246 {
247 /* free old interface info */
248 if (DeviceExtension->InterfaceInfo)
249 {
250 /* free old info */
251 FreeFunction(DeviceExtension->InterfaceInfo);
252 }
253
254 /* alloc interface info */
255 DeviceExtension->InterfaceInfo = AllocFunction(Urb->UrbSelectInterface.Interface.Length);
256 if (DeviceExtension->InterfaceInfo == NULL)
257 {
258 /* no memory */
259 FreeFunction(Urb);
261 }
262
263 /* copy interface info */
264 RtlCopyMemory(DeviceExtension->InterfaceInfo, &Urb->UrbSelectInterface.Interface, Urb->UrbSelectInterface.Interface.Length);
265 PinContext->InterfaceDescriptor = InterfaceDescriptor;
266 }
267
268 /* free urb */
269 FreeFunction(Urb);
270 return Status;
271}
return Found
Definition: dirsup.c:1270
PUSB_AUDIO_CONTROL_INPUT_TERMINAL_DESCRIPTOR UsbAudioGetStreamingTerminalDescriptorByIndex(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN ULONG Index)
Definition: filter.c:1063
struct _URB_SELECT_INTERFACE UrbSelectInterface
Definition: usb.h:532
#define USB_DEVICE_CLASS_AUDIO
Definition: usb100.h:91
NTSTATUS SubmitUrbSync(IN PDEVICE_OBJECT DeviceObject, IN PURB Urb)
Definition: usbaudio.c:37
#define USB_AUDIO_CONTROL_TERMINAL_DESCRIPTOR_TYPE
Definition: usbaudio.h:14
struct USB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR * PUSB_AUDIO_STREAMING_INTERFACE_DESCRIPTOR
PUSB_COMMON_DESCRIPTOR NTAPI USBD_ParseDescriptors(PVOID DescriptorBuffer, ULONG TotalLength, PVOID StartPosition, LONG DescriptorType)
Definition: usbd.c:445
PUSB_INTERFACE_DESCRIPTOR NTAPI USBD_ParseConfigurationDescriptorEx(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, PVOID StartPosition, LONG InterfaceNumber, LONG AlternateSetting, LONG InterfaceClass, LONG InterfaceSubClass, LONG InterfaceProtocol)
Definition: usbd.c:496
#define UsbBuildSelectInterfaceRequest(urb, length, configurationHandle, interfaceNumber, alternateSetting)
Definition: usbdlib.h:59
#define GET_SELECT_INTERFACE_REQUEST_SIZE(totalPipes)
Definition: usbdlib.h:117

Referenced by USBAudioPinCreate().

◆ UsbAudioSetFormat()

NTSTATUS UsbAudioSetFormat ( IN PKSPIN  Pin)

Definition at line 94 of file pin.c.

96{
97 PURB Urb;
98 PUCHAR SampleRateBuffer;
99 PPIN_CONTEXT PinContext;
101 PKSDATAFORMAT_WAVEFORMATEX WaveFormatEx;
102
103 /* allocate sample rate buffer */
104 SampleRateBuffer = AllocFunction(sizeof(ULONG));
105 if (!SampleRateBuffer)
106 {
107 /* no memory */
109 }
110
111 if (IsEqualGUIDAligned(&Pin->ConnectionFormat->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO) &&
112 IsEqualGUIDAligned(&Pin->ConnectionFormat->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM) &&
113 IsEqualGUIDAligned(&Pin->ConnectionFormat->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX))
114 {
115 WaveFormatEx = (PKSDATAFORMAT_WAVEFORMATEX)Pin->ConnectionFormat;
116 SampleRateBuffer[2] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 16) & 0xFF;
117 SampleRateBuffer[1] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 8) & 0xFF;
118 SampleRateBuffer[0] = (WaveFormatEx->WaveFormatEx.nSamplesPerSec >> 0) & 0xFF;
119
120 /* TODO: verify connection format */
121 }
122 else
123 {
124 /* not supported yet*/
126 FreeFunction(SampleRateBuffer);
128 }
129
130 /* allocate urb */
132 if (!Urb)
133 {
134 /* no memory */
135 FreeFunction(SampleRateBuffer);
137 }
138
139 /* get pin context */
140 PinContext = Pin->Context;
141
142 /* FIXME: determine controls and format urb */
147 0,
148 0x01, // SET_CUR
149 0x100,
150 PinContext->DeviceExtension->InterfaceInfo->Pipes[0].EndpointAddress,
151 SampleRateBuffer,
152 NULL,
153 3,
154 NULL);
155
156
157
158 /* submit urb */
159 Status = SubmitUrbSync(PinContext->LowerDevice, Urb);
160
161 DPRINT1("USBAudioPinSetDataFormat Pin %p Status %x\n", Pin, Status);
162 FreeFunction(Urb);
163 FreeFunction(SampleRateBuffer);
164 return Status;
165}
#define URB_FUNCTION_CLASS_ENDPOINT
Definition: usb.h:114
#define UsbBuildVendorRequest(urb, cmd, length, transferFlags, reservedbits, request, value, index, transferBuffer, transferBufferMDL, transferBufferLength, link)
Definition: usbdlib.h:68

Referenced by InitCapturePin(), and USBAudioPinSetDataFormat().