mcuee / libusb-win32

libusb-win32 project official github repo
179 stars 49 forks source link

Feature request: isochronous buffer packets offset/length #2

Open mcuee opened 6 years ago

mcuee commented 6 years ago

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 commented 6 years ago

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

mcuee commented 3 years ago

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

mcuee commented 2 years ago

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

mcuee commented 2 years ago

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;
        }
    }