1
Discussion - Software / Re: USB HOST UVC Camera FTDI Vinculum-II not reading video stream
« on: April 13, 2021, 04:52:50 PM »
Hello,
We plugged your code into a VNC2 and a Logitech web cam. The code worked straight away with a transfer size of 192 bytes using the simple GET_CUR (probe) and SET_CUR (commit). We used a USB Analyser to observe the output. This particular webcam defaulted to a resolution 320x240 at 15 fps in MJPEG. There were 12 bytes of header per packet leaving up-to 180 bytes of data.
However the program printed out zero bytes per read. The cause is the USB Host read and writes work slightly differently from other read and writes. When a USB host read or write is used the actual length of data transfer is held in the usbhost_xfer_iso_t structure and not in the parameters passed to vos_dev_read/write.
See the page “USB Host Read and Write Operations” in the help file.
“In vos_dev_write() the num_to_write and num_written parameters are ignored and in vos_dev_read() the num_to_read and num_read parameters are ignored as this information is provided and returned in the transfer block.”
Specifically for isochronous transfers the maximum transfer length is specified in the len structure member of the usbhost_xfer_iso_t structure. In the “USB Host Isochronous Transfer Block” page the note for this member says “When the operation completes, the value of len is not updated. However, the transfer length for each frame transaction is updated.” So, the total count of bytes transferred is obtained by reading and checking the condition code of all the deployed len_psw members and summing the sizes there. This is done to ensure that any missed isochronous transfers are accounted for properly in code.
We’ve modified the code as follows and can see 192 bytes reported in the while loop correctly.
xfer.frame = frame + 1;
*num_read = 0; // LAZ, Added /*Note this is a pointer and needs dereferenced. */
// now start the read from the ISO endpoint (line 511)
status = vos_dev_read(ctx->hc, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), num_read); /*(2)*/
// Sum the total data transferred in each of the isochronous packets for the actual transfer size.
while (i > 0)
{
*num_read += xfer.len_psw[i - 1].size;
i--;
}
if (status != USBHOST_OK)
{
return UVC_ERROR;
}
If we set the number of transfers in the usbhost_xfer_iso_t structure to 8 via the ISO_TRANSFER_COUNT macro and disable the printf then we can get meaningful measurements of data transfer from the web cam. In this default resolution the bus utilisation was between 10% and 25%. Maximum throughput can be achieved with the USBHOST_XFER_FLAG_NONBLOCKING set and semaphores used to signal completion as in the original app note code.
Best Regards,
FTDI Community
We plugged your code into a VNC2 and a Logitech web cam. The code worked straight away with a transfer size of 192 bytes using the simple GET_CUR (probe) and SET_CUR (commit). We used a USB Analyser to observe the output. This particular webcam defaulted to a resolution 320x240 at 15 fps in MJPEG. There were 12 bytes of header per packet leaving up-to 180 bytes of data.
However the program printed out zero bytes per read. The cause is the USB Host read and writes work slightly differently from other read and writes. When a USB host read or write is used the actual length of data transfer is held in the usbhost_xfer_iso_t structure and not in the parameters passed to vos_dev_read/write.
See the page “USB Host Read and Write Operations” in the help file.
“In vos_dev_write() the num_to_write and num_written parameters are ignored and in vos_dev_read() the num_to_read and num_read parameters are ignored as this information is provided and returned in the transfer block.”
Specifically for isochronous transfers the maximum transfer length is specified in the len structure member of the usbhost_xfer_iso_t structure. In the “USB Host Isochronous Transfer Block” page the note for this member says “When the operation completes, the value of len is not updated. However, the transfer length for each frame transaction is updated.” So, the total count of bytes transferred is obtained by reading and checking the condition code of all the deployed len_psw members and summing the sizes there. This is done to ensure that any missed isochronous transfers are accounted for properly in code.
We’ve modified the code as follows and can see 192 bytes reported in the while loop correctly.
xfer.frame = frame + 1;
*num_read = 0; // LAZ, Added /*Note this is a pointer and needs dereferenced. */
// now start the read from the ISO endpoint (line 511)
status = vos_dev_read(ctx->hc, (unsigned char *) &xfer, sizeof(usbhost_xfer_t), num_read); /*(2)*/
// Sum the total data transferred in each of the isochronous packets for the actual transfer size.
while (i > 0)
{
*num_read += xfer.len_psw[i - 1].size;
i--;
}
if (status != USBHOST_OK)
{
return UVC_ERROR;
}
If we set the number of transfers in the usbhost_xfer_iso_t structure to 8 via the ISO_TRANSFER_COUNT macro and disable the printf then we can get meaningful measurements of data transfer from the web cam. In this default resolution the bus utilisation was between 10% and 25%. Maximum throughput can be achieved with the USBHOST_XFER_FLAG_NONBLOCKING set and semaphores used to signal completion as in the original app note code.
Best Regards,
FTDI Community