Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/arvenums.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,16 @@ ARV_API ArvExposureMode arv_exposure_mode_from_string (const char *string);
* ArvUvUsbMode:
* @ARV_UV_USB_MODE_SYNC: utilize libusb synchronous device I/O API
* @ARV_UV_USB_MODE_ASYNC: utilize libusb asynchronous device I/O API
* @ARV_UV_USB_MODE_ASYNC_ROLLING: rolling fixed-size asynchronous transfers (frame-agnostic)
* @ARV_UV_USB_MODE_DEFAULT: default usb mode
*/

typedef enum
{
ARV_UV_USB_MODE_SYNC,
ARV_UV_USB_MODE_ASYNC,
ARV_UV_USB_MODE_DEFAULT = ARV_UV_USB_MODE_ASYNC
ARV_UV_USB_MODE_ASYNC_ROLLING,
ARV_UV_USB_MODE_DEFAULT = ARV_UV_USB_MODE_ASYNC_ROLLING
} ArvUvUsbMode;

/**
Expand Down
24 changes: 24 additions & 0 deletions src/arvmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,30 @@ ArvGstCapsInfos arv_gst_caps_infos[] = {
"video/x-bayer, format=(string)bggr14le",
"video/x-bayer", "bggr14le",
},
{
ARV_PIXEL_FORMAT_BAYER_GR_14P,
"video/x-bayer, format=(string)grbg14le",
"video/x-bayer", "grbg14le",
NULL, NULL, 0, 0, 0
},
{
ARV_PIXEL_FORMAT_BAYER_RG_14P,
"video/x-bayer, format=(string)rggb14le",
"video/x-bayer", "rggb14le",
NULL, NULL, 0, 0, 0
},
{
ARV_PIXEL_FORMAT_BAYER_GB_14P,
"video/x-bayer, format=(string)gbrg14le",
"video/x-bayer", "gbrg14le",
NULL, NULL, 0, 0, 0
},
{
ARV_PIXEL_FORMAT_BAYER_BG_14P,
"video/x-bayer, format=(string)bggr14le",
"video/x-bayer", "bggr14le",
NULL, NULL, 0, 0, 0
},
{
ARV_PIXEL_FORMAT_BAYER_GR_16,
"video/x-bayer, format=(string)grbg16le",
Expand Down
96 changes: 93 additions & 3 deletions src/arvuvdevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <arvuvstreamprivate.h>
#include <arvuvdeviceprivate.h>
#include <arvrealtime.h>
#include <arvuvinterfaceprivate.h>
#include <arvuvcpprivate.h>
#include <arvgc.h>
Expand Down Expand Up @@ -61,6 +62,9 @@ typedef struct {
libusb_context *usb;
libusb_device_handle *usb_device;

libusb_context *usb_ctrl;
libusb_device_handle *usb_ctrl_device;

libusb_hotplug_callback_handle hotplug_cb_handle;

ArvGc *genicam;
Expand Down Expand Up @@ -128,6 +132,52 @@ arv_uvcp_status_to_device_error (ArvUvcpStatus status)

/* ArvUvDevice implementation */

gboolean
arv_uv_device_stream_recover (ArvUvDevice *uv_device)
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);

if (priv->usb_device == NULL || priv->disconnected)
return FALSE;

arv_warning_device ("[UvDevice] stream recover: resetting data endpoint 0x%02x",
priv->data_endpoint);
return arv_uv_device_reset_stream_endpoint (uv_device);
}

gboolean
arv_uv_device_usb_reset (ArvUvDevice *uv_device)
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);
int rc;

if (priv->usb_device == NULL || priv->disconnected)
return FALSE;

rc = libusb_reset_device (priv->usb_device);
arv_warning_device ("[UvDevice] usb reset = %s", libusb_error_name (rc));
if (rc != 0) {
priv->disconnected = TRUE;
arv_device_emit_control_lost_signal (ARV_DEVICE (uv_device));
return FALSE;
}

rc = libusb_claim_interface (priv->usb_device, priv->data_interface);
if (rc != 0)
arv_warning_device ("[UvDevice] post-reset data re-claim failed: %s",
libusb_error_name (rc));
rc = libusb_claim_interface (priv->usb_ctrl_device != NULL ?
priv->usb_ctrl_device : priv->usb_device,
priv->control_interface);
if (rc != 0)
arv_warning_device ("[UvDevice] post-reset control re-claim failed: %s",
libusb_error_name (rc));

arv_uv_device_reset_stream_endpoint (uv_device);

return TRUE;
}

gboolean
arv_uv_device_is_connected (ArvUvDevice *uv_device)
{
Expand Down Expand Up @@ -162,6 +212,7 @@ arv_uv_device_bulk_transfer (ArvUvDevice *uv_device, ArvUvEndpointType endpoint_
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);
gboolean success;
libusb_device_handle *handle;
guint8 endpoint;
int transferred = 0;
int result;
Expand All @@ -181,7 +232,9 @@ arv_uv_device_bulk_transfer (ArvUvDevice *uv_device, ArvUvEndpointType endpoint_
} else {
endpoint = priv->data_endpoint;
}
result = libusb_bulk_transfer (priv->usb_device, endpoint, data, size, &transferred,
handle = (endpoint_type == ARV_UV_ENDPOINT_CONTROL && priv->usb_ctrl_device != NULL) ?
priv->usb_ctrl_device : priv->usb_device;
result = libusb_bulk_transfer (handle, endpoint, data, size, &transferred,
timeout_ms > 0 ? timeout_ms : priv->timeout_ms);

success = result >= 0;
Expand Down Expand Up @@ -944,6 +997,10 @@ event_thread_func(void *p)

struct timeval tv = { 0, 100000 };

if (!arv_make_thread_realtime (10) &&
!arv_make_thread_high_priority (-10))
arv_info_device ("USB event thread priority could not be elevated");

while (priv->event_thread_run)
{
libusb_handle_events_timeout(priv->usb, &tv);
Expand Down Expand Up @@ -1101,7 +1158,33 @@ arv_uv_device_constructed (GObject *object)
arv_info_device("[UvDevice::new] Using data endpoint 0x%02x, interface %d",
priv->data_endpoint, priv->data_interface);

result = libusb_claim_interface (priv->usb_device, priv->control_interface);
if (libusb_init (&priv->usb_ctrl) == 0) {
libusb_device *main_dev = libusb_get_device (priv->usb_device);
guint8 bus = libusb_get_bus_number (main_dev);
guint8 addr = libusb_get_device_address (main_dev);
libusb_device **ctrl_list;
ssize_t n_ctrl = libusb_get_device_list (priv->usb_ctrl, &ctrl_list);
ssize_t ci;

for (ci = 0; ci < n_ctrl; ci++) {
if (libusb_get_bus_number (ctrl_list[ci]) == bus &&
libusb_get_device_address (ctrl_list[ci]) == addr) {
if (libusb_open (ctrl_list[ci], &priv->usb_ctrl_device) != LIBUSB_SUCCESS)
priv->usb_ctrl_device = NULL;
break;
}
}
if (n_ctrl >= 0)
libusb_free_device_list (ctrl_list, 1);
}
if (priv->usb_ctrl_device != NULL)
arv_info_device ("[UvDevice::new] Dedicated control handle opened");
else
arv_warning_device ("[UvDevice::new] No dedicated control handle, using shared handle");

result = libusb_claim_interface (priv->usb_ctrl_device != NULL ?
priv->usb_ctrl_device : priv->usb_device,
priv->control_interface);
if (result != 0) {
arv_device_take_init_error (ARV_DEVICE (uv_device),
g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_PROTOCOL_ERROR,
Expand Down Expand Up @@ -1182,11 +1265,18 @@ arv_uv_device_finalize (GObject *object)
g_clear_pointer (&priv->serial_number, g_free);
g_clear_pointer (&priv->guid, g_free);
g_clear_pointer (&priv->genicam_xml, g_free);
if (priv->usb_ctrl_device != NULL) {
libusb_release_interface (priv->usb_ctrl_device, priv->control_interface);
libusb_close (priv->usb_ctrl_device);
}
if (priv->usb_device != NULL) {
libusb_release_interface (priv->usb_device, priv->control_interface);
if (priv->usb_ctrl_device == NULL)
libusb_release_interface (priv->usb_device, priv->control_interface);
libusb_release_interface (priv->usb_device, priv->data_interface);
libusb_close (priv->usb_device);
}
if (priv->usb_ctrl != NULL)
libusb_exit (priv->usb_ctrl);
if (priv->usb != NULL)
libusb_exit (priv->usb);
g_mutex_clear (&priv->transfer_mutex);
Expand Down
2 changes: 2 additions & 0 deletions src/arvuvdeviceprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ gboolean arv_uv_device_bulk_transfer (ArvUvDevice *uv_device,
void *data, size_t size, size_t *transferred_size,
guint32 timeout_ms, GError **error);

gboolean arv_uv_device_stream_recover (ArvUvDevice *uv_device);
gboolean arv_uv_device_usb_reset (ArvUvDevice *uv_device);
void arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice *uv_device,
ArvUvEndpointType endpoint_type, unsigned char endpoint_flags,
void *data, size_t size,
Expand Down
Loading
Loading