public class UsbIso
extends java.lang.Object
This class is used to read and write from an isochronous endpoint of an USB device. It uses JNA to access the USBFS API via IOCTL calls. USBFS is available in the Linux kernel and can be accessed from an Android application.
This class is independent of Android and could also be used under other Linux based operating systems.
The following program logic may be used e.g. for reading the video data stream from an UVC compliant camera:
... set streaming parameters via control channel (SET_CUR VS_COMMIT_CONTROL, etc.) ... usbIso.preallocateRequests(n); usbIso.setInterface(interfaceId, altSetting); // enable streaming for (int i = 0; i < n; i++) { // submit initial transfer requests Request req = usbIso.getRequest(); req.initialize(endpointAddr); req.submit(); } while (...) { // streaming loop Request req = usbIso.reapRequest(true); // wait for next request completion .. process received data ... req.initialize(endpointAddr); // re-use the request req.submit(); } // re-submit the request usbIso.setInterface(interfaceId, 0); // disable streaming usbIso.flushRequests(); // remove pending requests
Note that for e.g. an USB2 UVC camera, data packets arrive at a rate of 125 microseconds per packet. This corresponds to 8000 packets per second. Each packet may contain up to 3072 bytes.
Modifier and Type | Class and Description |
---|---|
class |
UsbIso.Request
This class represents an isochronous data transfer request that can be queued with the USB device driver.
|
Constructor and Description |
---|
UsbIso(int fileDescriptor,
int maxPacketsPerRequest,
int maxPacketSize)
Creates an isochronous transfer controller instance.
|
Modifier and Type | Method and Description |
---|---|
void |
dispose()
Releases all resources associated with this class.
|
void |
flushRequests()
Cancels all pending requests and removes all requests from the queue of the USB device driver.
|
UsbIso.Request |
getRequest()
Returns an inactive
Request object that can be submitted to the device driver. |
void |
preallocateRequests(int n)
Pre-allocates
n UsbIso.Request objects with their associated buffer space. |
UsbIso.Request |
reapRequest(boolean wait)
Returns a completed request.
|
void |
setInterface(int interfaceId,
int altSetting)
Sends a SET_INTERFACE command to the USB device.
|
public UsbIso(int fileDescriptor, int maxPacketsPerRequest, int maxPacketSize)
The size of the data buffer allocated for each Request
object is
maxPacketsPerRequest * maxPacketSize
.
fileDescriptor
- For Android, this is the value returned by UsbDeviceConnection.getFileDescriptor().maxPacketsPerRequest
- The maximum number of packets per request.maxPacketSize
- The maximum packet size.public void preallocateRequests(int n)
n
UsbIso.Request
objects with their associated buffer space.
The UsbIso
class maintains an internal pool of Request
objects.
Each Request
object has native buffer space associated with it.
The purpose of this method is to save some execution time between the instant when
setInterface(int, int)
is called to enable streaming, and the instant when reapRequest(boolean)
is called to receive the first data packet.
n
- The minimum number of internal Request
objects to be pre-allocated.public void dispose() throws java.io.IOException
flushRequests()
to cancel all pending requests.java.io.IOException
public void flushRequests() throws java.io.IOException
java.io.IOException
public void setInterface(int interfaceId, int altSetting) throws java.io.IOException
Starting with Android 5.0, UsbDeviceConnection.setInterface() could be used instead.
interfaceId
- The interface ID.
For Android, this is the value returned by UsbInterface.getId()
.altSetting
- The alternate setting number. The value 0 is used to stop streaming.
For Android, this is the value returned by UsbInterface.getAlternateSetting()
(only available since Android 5.0).
You may use lsusb -v -d xxxx:xxxx
to find the alternate settings available for your USB device.java.io.IOException
public UsbIso.Request getRequest()
Request
object that can be submitted to the device driver.
The UsbIso
class maintains an internal pool of all it's Request
objects.
If the pool contains a Request
object which is not in the request queue of the
USB device driver, that Request
object is returned.
Otherwise a new Request
object is created and returned.
The returned Request
object must be initialized by calling UsbIso.Request.initialize(int)
and
can then be submitted by calling UsbIso.Request.submit()
.
public UsbIso.Request reapRequest(boolean wait) throws java.io.IOException
A Request
object returned by this method has been removed from the queue and can be re-used by calling UsbIso.Request.initialize(int)
and UsbIso.Request.submit()
.
wait
- true
to wait until a completed request is available. false
to return immediately when no
completed request is available.Request
object representing a completed request, or null
if
wait
is false
and no completed request is available at the time.java.io.IOException