libusb-win32 icon indicating copy to clipboard operation
libusb-win32 copied to clipboard

Feature request: isochronous buffer packets offset/length

Open mcuee opened this issue 7 years ago • 4 comments

https://sourceforge.net/p/libusb-win32/feature-requests/12/

Updated: 2012-07-06 Created: 2010-11-23 Creator: Tim Schuerewegen

I am using libusb-win32 to communicate with a OV550/OV5620 based webcam. I am using isochronous async reads to get the video data from the webcam. However, there is one problem. The data in the buffer (after a reap) is not contiguous, ie. there are holes in it. In order for me to know which parts in the buffer are data and which parts are garbage/empty, I need access to the URB's IsoPacket array. The Offset/Length value pairs of the IsoPacket array are the only way I can piece the video frames back together.

Example:

usb_reap_async returned 0x60

IsoPacket 0 - Offset = 0, Length = 0
IsoPacket 1 - Offset = 0xBF4, Length = 0
IsoPacket 2 - Offset = 0x17E8, Length = 0x54
...
IsoPacket 29 - Offset = 0x15AA4, Length = 0xC
..
IsoPacket 31 - Offset = 0x1728C, Length = 0

As you can see the 0x60 bytes of data are spread across 2 iso packets. Without the IsoPacket array Offset/Length information I can not locate the 0x60 bytes of data from the buffer.

Thank you in advance.

mcuee avatar Jun 23 '18 05:06 mcuee

libusb-win32 project is in a support only mode. Mailing list support is still provided, no changes to the codes and release.

mcuee avatar Jun 23 '18 06:06 mcuee

For isochronous transfer, please use libusbk.sys or WinUSB. So I will keep wontfix label here.

mcuee avatar Oct 29 '21 02:10 mcuee

Mailing list discussion in 2011. https://sourceforge.net/p/libusb-win32/mailman/libusb-win32-devel/thread/BANLkTimkAAVgX00nKDSBqc4FRQYt4onPAw%40mail.gmail.com/#msg27481705

mcuee avatar Nov 13 '21 14:11 mcuee

Patches submitted:

Index: src/driver/transfer.c
===================================================================
--- src/driver/transfer.c	(revision 398)
+++ src/driver/transfer.c	(working copy)
@@ -199,6 +199,13 @@
 	return IoCallDriver(dev->target_device, irp);
 }
 
+void FixBuffer( struct _URB_ISOCH_TRANSFER *UrbIsochronousTransfer)
+{
+	unsigned char *Buffer;
+	Buffer = MmGetSystemAddressForMdlSafe( UrbIsochronousTransfer->TransferBufferMDL, HighPagePriority);
+	RtlCopyMemory( Buffer + 0, &UrbIsochronousTransfer->NumberOfPackets, 4);
+	RtlCopyMemory( Buffer + 4, UrbIsochronousTransfer->IsoPacket, sizeof( USBD_ISO_PACKET_DESCRIPTOR) * UrbIsochronousTransfer->NumberOfPackets);
+}
 
 NTSTATUS DDKAPI transfer_complete(DEVICE_OBJECT *device_object, IRP *irp,
 								  void *context)
@@ -218,6 +225,7 @@
 		if (c->urb->UrbHeader.Function == URB_FUNCTION_ISOCH_TRANSFER)
 		{
 			transmitted = c->urb->UrbIsochronousTransfer.TransferBufferLength;
+			FixBuffer( &c->urb->UrbIsochronousTransfer);
 		}
 		if (c->urb->UrbHeader.Function == URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER)
 		{
@@ -275,7 +283,7 @@
 			return STATUS_INVALID_PARAMETER;
 		}
 
-		num_packets = size / packetSize;
+		num_packets = (size - 4) / (packetSize + sizeof( USBD_ISO_PACKET_DESCRIPTOR));
 
 		if (num_packets <= 0)
 		{
@@ -322,7 +330,7 @@
 
 		for (i = 0; i < num_packets; i++)
 		{
-			(*urb)->UrbIsochronousTransfer.IsoPacket[i].Offset = i * packetSize;
+			(*urb)->UrbIsochronousTransfer.IsoPacket[i].Offset = (4 + (num_packets * sizeof( USBD_ISO_PACKET_DESCRIPTOR))) + (i * packetSize);
 			(*urb)->UrbIsochronousTransfer.IsoPacket[i].Length = packetSize;
 		}
 	}

mcuee avatar Nov 13 '21 14:11 mcuee