New Upstream Release - aravis

Ready changes

Summary

Merged new upstream version: 0.8.27 (was: 0.8.26).

Diff

diff --git a/.github/workflows/aravis-msvc.yml b/.github/workflows/aravis-msvc.yml
index ab0f993..abb4721 100644
--- a/.github/workflows/aravis-msvc.yml
+++ b/.github/workflows/aravis-msvc.yml
@@ -21,7 +21,7 @@ jobs:
     steps:
     - name: pip
       run: |
-        pip install conan
+        pip install "conan<2.0.0"
     - name: disable-perl
       run: |
         rm -r C:\Strawberry\perl
@@ -32,7 +32,7 @@ jobs:
         INPUT_CONANFILE: |
           [requires]
           libiconv/1.17
-          glib/2.74.1
+          glib/2.76.2
           #gobject-introspection/1.69.0
           gstreamer/1.19.2
           gst-plugins-base/1.19.2
diff --git a/NEWS.md b/NEWS.md
index 1ab1102..1367d3c 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,3 +1,16 @@
+Stable release 0.8.27
+=====================
+
+  * camera: add vendor specific quirks to frame rate (durnezj)
+  * camera: multiple tap helpers #745 (Brian)
+  * gv: start packet timeout after the first non leader packet #746 (Brian)
+  * gv: auto packet size fix (Emmanuel)
+  * gv: add more camera to the legacy endianness mechanism exception list (Emmanuel)
+  * u3v: fix u3vcp_cpability register size (Emmanuel)
+  * chore: compilation warning fixes (Marco, Emmanuel)
+  * ci: pipeline babysitting (Emmanuel)
+  * doc: link fix (Henrique)
+
 Stable release 0.8.26
 =====================
 
diff --git a/RELEASING.md b/RELEASING.md
index e3c6dc5..090012e 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -12,10 +12,10 @@ Here are the steps to follow to create a new aravis release:
   easily done with a command such as:
 
   ```
-git log --stat X.Y.Z..
+git log --stat x.y.z..
   ```
 
-  where X.Y.Z is the previous release version.
+  where x.y.z is the previous release version.
 
   Summarize major changes briefly in a style similar to other
   entries in NEWS. Take special care to note any additions in
@@ -40,13 +40,13 @@ Distribution package /home/pacaud/Sources/aravis/build/meson-dist/aravis-0.7.2.t
   the release directory.
 
   ```
-$ git tag -a ARAVIS_X_Y_Z (from whatever branch you're releasing)
-$ git push origin ARAVIS_X_Y_Z
+$ git tag -a x.y.z (from whatever branch you're releasing)
+$ git push origin x.y.z
   ```
 
   If that fails because someone has pushed since you last updated, then you'll
   need to repeat the entire process. Well, update, add a new NEWS entry, and
-  make distcheck again.
+  ninja dist again.
 
 * Upload the tarball to github.
 
diff --git a/debian/changelog b/debian/changelog
index 517ddb0..fcbcbd0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+aravis (0.8.27-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 11 Jun 2023 21:13:45 -0000
+
 aravis (0.8.26-1) unstable; urgency=low
 
   * New upstream release.
diff --git a/debian/patches/build_doc.diff b/debian/patches/build_doc.diff
index bd3abbb..3074747 100644
--- a/debian/patches/build_doc.diff
+++ b/debian/patches/build_doc.diff
@@ -1,6 +1,8 @@
---- a/meson_options.txt
-+++ b/meson_options.txt
-@@ -15,4 +15,4 @@
+Index: aravis.git/meson_options.txt
+===================================================================
+--- aravis.git.orig/meson_options.txt
++++ aravis.git/meson_options.txt
+@@ -15,4 +15,4 @@ option('gv-n-buffers', type: 'integer',
  # Documentation and introspection
  
  option('introspection', type: 'feature', value: 'auto', description: 'Build introspection data (requires gobject-introspection)')
diff --git a/docs/reference/aravis/ethernet.md b/docs/reference/aravis/ethernet.md
index 8722fe6..909e898 100644
--- a/docs/reference/aravis/ethernet.md
+++ b/docs/reference/aravis/ethernet.md
@@ -101,3 +101,28 @@ example, the following command gives this capability to the Aravis viewer:
 ```
 sudo setcap cap_net_raw+ep arv-viewer
 ```
+
+# Legacy endianess mechanism
+
+Some GigEVision devices incorrectly report a Genicam schema version greater or
+equal to 1.1, while implementing the legacy behavior for register access. We
+maintain a list in
+[arvgcport.c](https://github.com/AravisProject/aravis/blob/6f1d65608dcecef2326ae2b3a542f5f59771ea32/src/arvgcport.c#L44)
+which allows to force the use of the legacy endianness mechanism.
+
+The documentation about the legacy endianness mechanism is in the 3.1 appendix
+('Endianess of GigE Vision Cameras') of the GenICam Standard.
+
+There is a chance this part of Aravis is due to a misunderstanding of how a
+GigEVision device is supposed to behave (Remember we can not use the GigEVision
+specification documentation).  But until now, there was no evidence in the issue
+reports it is the case. If you think this should be implemented differently,
+don't hesitate to explain your thoughts on Aravis issue report system, or even
+better, to open a pull request. The related Aravis issues are available here:
+[https://github.com/AravisProject/aravis/labels/5. Genicam 1.0 legacy
+mode](https://github.com/AravisProject/aravis/labels/5.%20Genicam%201.0%20legacy%20mode).
+
+Meanwhile, if you want to add a device to the exception list, please open an
+issue on github, giving the vendor name and model name as found in the Genicam
+data of your device, using the `genicam` command of `arv-tool`. They are stored
+in the ModelName and VendorName attributes of the RegisterDescription element.
diff --git a/docs/reference/aravis/porting-0.8.md b/docs/reference/aravis/porting-0.8.md
index b722151..4002358 100644
--- a/docs/reference/aravis/porting-0.8.md
+++ b/docs/reference/aravis/porting-0.8.md
@@ -13,7 +13,7 @@ NULL parameter to most of the modified functions. But you are advised to take
 this opportunity to correctly handle errors.
 
 There is a page explaining Glib errors and how to manage them in the [Glib
-documentation](https://developer.gnome.org/glib/stable/glib-Error-Reporting.html).
+documentation](https://docs.gtk.org/glib/error-reporting.html).
 
 During the camera configuration, in C language it can be somehow cumbersome to
 check for errors at each function call. A convenient way to deal with this issue
diff --git a/meson.build b/meson.build
index c0598c9..0672ed9 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project ('aravis', 'c', 'cpp', version: '0.8.26', meson_version: '>=0.57.0')
+project ('aravis', 'c', 'cpp', version: '0.8.27', meson_version: '>=0.57.0')
 
 gnome = import('gnome')
 pkg = import ('pkgconfig')
diff --git a/src/arv.h b/src/arv.h
index 3742748..47443c7 100644
--- a/src/arv.h
+++ b/src/arv.h
@@ -85,6 +85,7 @@
 #include <arvgcregisternode.h>
 #include <arvgcselector.h>
 #include <arvgcstring.h>
+#include <arvgcstringnode.h>
 #include <arvgcstringregnode.h>
 #include <arvgcstructregnode.h>
 #include <arvgcstructentrynode.h>
diff --git a/src/arvcamera.c b/src/arvcamera.c
index adacd22..82c4ab7 100644
--- a/src/arvcamera.c
+++ b/src/arvcamera.c
@@ -1035,17 +1035,16 @@ arv_camera_set_frame_rate (ArvCamera *camera, double frame_rate, GError **error)
 	g_return_if_fail (ARV_IS_CAMERA (camera));
 
 	if (frame_rate <= 0.0) {
-		if (arv_camera_is_feature_available (camera, "AcquisitionFrameRateEnable", &local_error)) {
-			if (local_error == NULL)
-				arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", FALSE, error);
-			else
-				g_propagate_error (error, local_error);
+		arv_camera_set_frame_rate_enable(camera, FALSE, &local_error);
+		if (local_error != NULL)
+		{
+			g_propagate_error (error, local_error);
 		}
 		return;
 	}
 
-        /* Ignore the error in order to be able to change the frame rate during the acquisition, as some devices don't
-         * allow to change TriggerMode if the acquisition is already started. */
+	/* Ignore the error in order to be able to change the frame rate during the acquisition, as some devices don't
+	* allow to change TriggerMode if the acquisition is already started. */
 	arv_camera_clear_triggers (camera, NULL);
 
 	arv_camera_get_frame_rate_bounds (camera, &minimum, &maximum, &local_error);
@@ -1062,11 +1061,7 @@ arv_camera_set_frame_rate (ArvCamera *camera, double frame_rate, GError **error)
 	switch (priv->vendor) {
 		case ARV_CAMERA_VENDOR_BASLER:
 			if (local_error == NULL){
-				if (arv_camera_is_feature_available (camera, "AcquisitionFrameRateEnable", &local_error)){
-					/* enable is optional on some devices */
-					if (local_error == NULL)
-						arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", TRUE, &local_error);
-				}
+				arv_camera_set_frame_rate_enable(camera, TRUE, &local_error);
 			}
 			if (local_error == NULL)
 				arv_camera_set_float (camera,
@@ -1104,17 +1099,15 @@ arv_camera_set_frame_rate (ArvCamera *camera, double frame_rate, GError **error)
 			}
 			break;
 		case ARV_CAMERA_VENDOR_POINT_GREY_FLIR:
-			if (local_error == NULL) {
-				if (priv->has_acquisition_frame_rate_enabled)
-					arv_camera_set_boolean (camera, "AcquisitionFrameRateEnabled", TRUE, &local_error);
-				else
-					arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", TRUE, &local_error);
+			arv_camera_set_frame_rate_enable(camera, TRUE, &local_error);
+			if (local_error == NULL && priv->has_acquisition_frame_rate_auto) {
+				arv_camera_set_string (camera, "AcquisitionFrameRateAuto", "Off", &local_error);
 			}
-			if (local_error == NULL)
-				if (priv->has_acquisition_frame_rate_auto)
-					arv_camera_set_string (camera, "AcquisitionFrameRateAuto", "Off", &local_error);
-			if (local_error == NULL)
+
+			if (local_error == NULL) {
 				arv_camera_set_float (camera, "AcquisitionFrameRate", frame_rate, &local_error);
+			}
+
 			break;
 		case ARV_CAMERA_VENDOR_DALSA:
 		case ARV_CAMERA_VENDOR_RICOH:
@@ -1122,19 +1115,14 @@ arv_camera_set_frame_rate (ArvCamera *camera, double frame_rate, GError **error)
 		case ARV_CAMERA_VENDOR_MATRIX_VISION:
 		case ARV_CAMERA_VENDOR_IMPERX:
 		case ARV_CAMERA_VENDOR_UNKNOWN:
-                        if (local_error == NULL) {
-                                if (arv_camera_is_feature_available (camera, "AcquisitionFrameRateEnable", &local_error)) {
-                                        if (local_error == NULL)
-                                                arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", TRUE, &local_error);
-                                }
-                        }
-                        if (local_error == NULL)
-                                arv_camera_set_float (camera,
-                                                      priv->has_acquisition_frame_rate ?
-                                                      "AcquisitionFrameRate":
-                                                      "AcquisitionFrameRateAbs", frame_rate, &local_error);
-                        break;
-        }
+			arv_camera_set_frame_rate_enable(camera, TRUE, &local_error);
+			if (local_error == NULL)
+				arv_camera_set_float (camera,
+															priv->has_acquisition_frame_rate ?
+															"AcquisitionFrameRate":
+															"AcquisitionFrameRateAbs", frame_rate, &local_error);
+			break;
+	}
 
 	if (local_error != NULL)
 		g_propagate_error (error, local_error);
@@ -1271,6 +1259,66 @@ arv_camera_get_frame_rate_bounds (ArvCamera *camera, double *min, double *max, G
 	}
 }
 
+/*
+* arv_camera_set_frame_rate_enable:
+* @camera: an #ArvCamera
+* @enable: true to enable, false to disable
+* @error: a #GError placeholer, %NULL to ignore
+*
+* Configures whether to enable the upper frame rate limit set by #arv_camera_set_frame_rate.
+* Implements vendor specific quirks if needed.
+* Since: 0.8.26
+*/
+void
+arv_camera_set_frame_rate_enable(ArvCamera *camera, gboolean enable, GError **error)
+{
+	ArvCameraPrivate *priv = arv_camera_get_instance_private (camera);
+	GError *local_error = NULL;
+
+	g_return_if_fail (ARV_IS_CAMERA (camera));
+
+  switch (priv->vendor) {
+		case ARV_CAMERA_VENDOR_BASLER:
+			if (local_error == NULL){
+				if (arv_camera_is_feature_available (camera, "AcquisitionFrameRateEnable", &local_error)){
+					/* enable is optional on some devices */
+					if (local_error == NULL)
+						arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", enable, &local_error);
+				}
+			}
+			break;
+		case ARV_CAMERA_VENDOR_POINT_GREY_FLIR:
+			if (local_error == NULL) {
+				if (priv->has_acquisition_frame_rate_enabled)				
+					arv_camera_set_boolean (camera, "AcquisitionFrameRateEnabled", enable, &local_error);
+				else
+					arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", enable, &local_error);
+			}
+			break;
+		case ARV_CAMERA_VENDOR_DALSA:
+		case ARV_CAMERA_VENDOR_RICOH:
+		case ARV_CAMERA_VENDOR_XIMEA:
+		case ARV_CAMERA_VENDOR_MATRIX_VISION:
+		case ARV_CAMERA_VENDOR_IMPERX:	
+		case ARV_CAMERA_VENDOR_UNKNOWN:
+			if (local_error == NULL) {
+				if (arv_camera_is_feature_available (camera, "AcquisitionFrameRateEnable", &local_error)) {
+					if (local_error == NULL)
+						arv_camera_set_boolean (camera, "AcquisitionFrameRateEnable", TRUE, &local_error);
+					}
+			}
+			break;
+		case ARV_CAMERA_VENDOR_PROSILICA:
+		case ARV_CAMERA_VENDOR_TIS:
+		default:
+			break; /* No specific frame rate enable code */
+	}
+
+	if (local_error != NULL) {
+		g_propagate_error (error, local_error);
+	}
+}
+
 /**
  * arv_camera_set_trigger:
  * @camera: a #ArvCamera
@@ -1821,6 +1869,45 @@ arv_camera_get_gain_auto (ArvCamera *camera, GError **error)
 	return arv_auto_from_string (arv_camera_get_string (camera, "GainAuto", error));
 }
 
+/**
+ * arv_camera_select_gain:
+ * @camera: a #ArvCamera
+ * @selector: gain selector
+ * @error: a #GError placeholder, %NULL to ignore
+ *
+ * Configures Gain Selector feature.
+ *
+ * Since: 0.8.27
+ **/
+
+void
+arv_camera_select_gain (ArvCamera *camera, const char *selector, GError **error)
+{
+	arv_camera_set_string (camera, "GainSelector", selector, error);
+}
+
+/**
+ * arv_camera_dup_available_gains:
+ * @camera: a #ArvCamera
+ * @n_selectors: (out): number of different gain selectors
+ * @error: a #GError placeholder, %NULL to ignore
+ *
+ * Retrieves the list of all available gain selectors as strings.
+ *
+ * Returns: (array length=n_selectors) (transfer container): a newly allocated array of strings, to be freed after use with
+ * g_free().
+ *
+ * Since: 0.8.27
+ */
+
+const char **
+arv_camera_dup_available_gains (ArvCamera *camera, guint *n_selectors, GError **error)
+{
+	g_return_val_if_fail (ARV_IS_CAMERA (camera), NULL);
+
+	return arv_camera_dup_available_enumerations_as_strings (camera, "GainSelector", n_selectors, error);
+}
+
 /**
  * arv_camera_is_black_level_available:
  * @camera: a #ArvCamera
@@ -1896,6 +1983,45 @@ arv_camera_get_black_level (ArvCamera *camera, GError **error)
 		return arv_camera_get_float (camera, "BlackLevel", error);
 }
 
+/**
+ * arv_camera_select_black_level:
+ * @camera: a #ArvCamera
+ * @selector: black level selection
+ * @error: a #GError placeholder, %NULL to ignore
+ *
+ * Configures Black Level Selector feature.
+ *
+ * Since: 0.8.27
+ **/
+
+void
+arv_camera_select_black_level (ArvCamera *camera, const char *selector, GError **error)
+{
+	arv_camera_set_string (camera, "BlackLevelSelector", selector, error);
+}
+
+/**
+ * arv_camera_dup_available_black_levels:
+ * @camera: a #ArvCamera
+ * @n_selectors: (out): number of different black level selectors
+ * @error: a #GError placeholder, %NULL to ignore
+ *
+ * Retrieves the list of all available black level selectors as strings.
+ *
+ * Returns: (array length=n_selectors) (transfer container): a newly allocated array of strings, to be freed after use with
+ * g_free().
+ *
+ * Since: 0.8.27
+ */
+
+const char **
+arv_camera_dup_available_black_levels (ArvCamera *camera, guint *n_selectors, GError **error)
+{
+	g_return_val_if_fail (ARV_IS_CAMERA (camera), NULL);
+
+	return arv_camera_dup_available_enumerations_as_strings (camera, "BlackLevelSelector", n_selectors, error);
+}
+
 /**
  * arv_camera_get_black_level_bounds:
  * @camera: a #ArvCamera
diff --git a/src/arvcamera.h b/src/arvcamera.h
index 6a0499f..bc5f28e 100644
--- a/src/arvcamera.h
+++ b/src/arvcamera.h
@@ -110,6 +110,7 @@ ARV_API ArvAcquisitionMode	arv_camera_get_acquisition_mode (ArvCamera *camera, G
 ARV_API void		arv_camera_set_frame_count		(ArvCamera *camera, gint64 frame_count, GError **error);
 ARV_API gint64		arv_camera_get_frame_count		(ArvCamera *camera, GError **error);
 ARV_API void		arv_camera_get_frame_count_bounds	(ArvCamera *camera, gint64 *min, gint64 *max, GError **error);
+ARV_API void            arv_camera_set_frame_rate_enable       (ArvCamera *camera, gboolean enable, GError **error);
 
 ARV_API gboolean	arv_camera_is_frame_rate_available	(ArvCamera *camera, GError **error);
 
@@ -140,6 +141,8 @@ ARV_API void		arv_camera_set_exposure_mode		(ArvCamera *camera, ArvExposureMode
 
 ARV_API gboolean	arv_camera_is_gain_available		(ArvCamera *camera, GError **error);
 ARV_API gboolean	arv_camera_is_gain_auto_available	(ArvCamera *camera, GError **error);
+ARV_API void		arv_camera_select_gain			(ArvCamera *camera, const char *selector, GError **error);
+ARV_API const char **	arv_camera_dup_available_gains	        (ArvCamera *camera, guint *n_selectors, GError **error);
 
 ARV_API void		arv_camera_set_gain			(ArvCamera *camera, double gain, GError **error);
 ARV_API double		arv_camera_get_gain			(ArvCamera *camera, GError **error);
@@ -149,6 +152,8 @@ ARV_API ArvAuto		arv_camera_get_gain_auto		(ArvCamera *camera, GError **error);
 
 ARV_API gboolean	arv_camera_is_black_level_available	(ArvCamera *camera, GError **error);
 ARV_API gboolean	arv_camera_is_black_level_auto_available(ArvCamera *camera, GError **error);
+ARV_API void		arv_camera_select_black_level		(ArvCamera *camera, const char *selector, GError **error);
+ARV_API const char **	arv_camera_dup_available_black_levels   (ArvCamera *camera, guint *n_selectors, GError **error);
 
 ARV_API void		arv_camera_set_black_level		(ArvCamera *camera, double blacklevel, GError **error);
 ARV_API double		arv_camera_get_black_level		(ArvCamera *camera, GError **error);
diff --git a/src/arvdebug.c b/src/arvdebug.c
index 6d8e550..4f151df 100644
--- a/src/arvdebug.c
+++ b/src/arvdebug.c
@@ -264,7 +264,6 @@ arv_debug_dup_infos_as_string (void)
 	GEnumClass *debug_level_class = g_type_class_ref (ARV_TYPE_DEBUG_LEVEL);
 	GString *string = g_string_new ("");
 	unsigned int i;
-	char *str;
 
 	g_string_append (string, "Debug categories:\n");
 	for (i = 0; i < ARV_DEBUG_CATEGORY_N_ELEMENTS; i++) {
@@ -285,10 +284,7 @@ arv_debug_dup_infos_as_string (void)
 
 	g_type_class_unref (debug_level_class);
 
-	str = string->str;
-	g_string_free (string, FALSE);
-
-	return str;
+        return arv_g_string_free_and_steal(string);
 }
 
 void
diff --git a/src/arvenums.h b/src/arvenums.h
index 33a8aa3..3bdf32b 100644
--- a/src/arvenums.h
+++ b/src/arvenums.h
@@ -1,6 +1,6 @@
 /* Aravis - Digital camera library
  *
- * Copyright © 2009-2022 Emmanuel Pacaud
+ * Copyright © 2009-2023 Emmanuel Pacaud
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
diff --git a/src/arvgc.c b/src/arvgc.c
index 6655bd6..3772175 100644
--- a/src/arvgc.c
+++ b/src/arvgc.c
@@ -256,6 +256,12 @@ arv_gc_create_element (ArvDomDocument *document, const char *tag_name)
 		node = arv_gc_invalidator_node_new ();
 	else if (strcmp (tag_name, "Streamable") == 0)
 		node = arv_gc_property_node_new_streamable ();
+	else if (strcmp (tag_name, "IsDeprecated") == 0)
+		node = arv_gc_property_node_new_is_deprecated ();
+	else if (strcmp (tag_name, "pAlias") == 0)
+		node = arv_gc_property_node_new_p_alias ();
+	else if (strcmp (tag_name, "pCastAlias") == 0)
+		node = arv_gc_property_node_new_p_cast_alias ();
 
 	else if (strcmp (tag_name, "CommandValue") == 0)
 		node = arv_gc_property_node_new_command_value ();
diff --git a/src/arvgcfeaturenode.c b/src/arvgcfeaturenode.c
index c706d57..9bb3c7e 100644
--- a/src/arvgcfeaturenode.c
+++ b/src/arvgcfeaturenode.c
@@ -56,6 +56,9 @@ typedef struct {
 	ArvGcPropertyNode *is_locked;
 	ArvGcPropertyNode *imposed_access_mode;
 	ArvGcPropertyNode *streamable;
+        ArvGcPropertyNode *is_deprecated;
+        ArvGcPropertyNode *alias;
+        ArvGcPropertyNode *cast_alias;
 
 	guint64 change_count;
 
@@ -106,7 +109,16 @@ arv_gc_feature_node_post_new_child (ArvDomNode *self, ArvDomNode *child)
 				priv->imposed_access_mode = property_node;
 				break;
 			case ARV_GC_PROPERTY_NODE_TYPE_STREAMABLE:
-				priv->streamable = property_node;		/* TODO */
+				priv->streamable = property_node;       	/* TODO */
+				break;
+			case ARV_GC_PROPERTY_NODE_TYPE_IS_DEPRECATED:
+				priv->is_deprecated = property_node;       	/* TODO */
+				break;
+			case ARV_GC_PROPERTY_NODE_TYPE_P_ALIAS:
+				priv->alias = property_node;		        /* TODO */
+				break;
+			case ARV_GC_PROPERTY_NODE_TYPE_P_CAST_ALIAS:
+				priv->alias = property_node;		        /* TODO */
 				break;
 			default:
 				break;
diff --git a/src/arvgcport.c b/src/arvgcport.c
index 056828c..6b26a38 100644
--- a/src/arvgcport.c
+++ b/src/arvgcport.c
@@ -41,11 +41,31 @@ typedef struct {
 	const char *model_selection;
 } ArvGvLegacyInfos;
 
+/*
+ * Some GigEVision devices incorrectly report a Genicam schema version greater or equal to 1.1, while implementing the
+ * legacy behavior for register access. This list allows to force the use of the legacy endianness mechanism. Vendor and
+ * model listed below are those found in the Genicam XML data, which can be obtained using the `genicam` command of
+ * `arv-tool`.  They are stored in the ModelName and VendorName attributes of the RegisterDescription element.
+ *
+ * The documentation about the legacy endianness mechanism is in the 3.1 appendix ('Endianess of GigE Vision Cameras')
+ * of the GenICam Standard.
+ *
+ * There is a chance this part of Aravis is due to a misunderstanding of how a GigEVision device is supposed to behave
+ * (Remember we can not use the GigEVision specification documentation).  But until now, there was no evidence in the
+ * issue reports it is the case. If you think this should be implemented differently, don't hesitate to explain your
+ * thoughts on Aravis issue report system, or even better, to open a pull request. The related Aravis issues are
+ * available here:
+ *
+ * https://github.com/AravisProject/aravis/labels/5.%20Genicam%201.0%20legacy%20mode
+ */
+
 static ArvGvLegacyInfos arv_gc_port_legacy_infos[] = {
    { .vendor_selection = "Imperx",                      .model_selection = "IpxGEVCamera"},
    { .vendor_selection = "KowaOptronics",               .model_selection = "SC130ET3"},
+   { .vendor_selection = "NIT",                         .model_selection = "Tachyon16k"},
    { .vendor_selection = "PleoraTechnologiesInc",       .model_selection = "iPORTCLGigE"},
    { .vendor_selection = "PleoraTechnologiesInc",       .model_selection = "NTxGigE"},
+   { .vendor_selection = "TeledyneDALSA",               .model_selection = "ICE"},
    { .vendor_selection = "Sony",                        .model_selection = "XCG_CGSeries"},
 };
 
diff --git a/src/arvgcpropertynode.c b/src/arvgcpropertynode.c
index 5f7099a..684ba7c 100644
--- a/src/arvgcpropertynode.c
+++ b/src/arvgcpropertynode.c
@@ -36,7 +36,7 @@
 #include <arvgcstring.h>
 #include <arvgc.h>
 #include <arvdomtext.h>
-#include <arvmisc.h>
+#include <arvmiscprivate.h>
 #include <arvdebugprivate.h>
 #include <arvenumtypes.h>
 #include <string.h>
@@ -242,8 +242,7 @@ _get_value_data (ArvGcPropertyNode *property_node)
 		     iter = arv_dom_node_get_next_sibling (iter))
 			g_string_append (string, arv_dom_character_data_get_data (ARV_DOM_CHARACTER_DATA (iter)));
 		g_free (priv->value_data);
-		priv->value_data = string->str;
-		g_string_free (string, FALSE);
+		priv->value_data = arv_g_string_free_and_steal(string);
 		priv->value_data_up_to_date = TRUE;
 	}
 
@@ -1054,6 +1053,24 @@ arv_gc_property_node_new_streamable (void)
 	return arv_gc_property_node_new (ARV_GC_PROPERTY_NODE_TYPE_STREAMABLE);
 }
 
+ArvGcNode *
+arv_gc_property_node_new_is_deprecated (void)
+{
+	return arv_gc_property_node_new (ARV_GC_PROPERTY_NODE_TYPE_IS_DEPRECATED);
+}
+
+ArvGcNode *
+arv_gc_property_node_new_p_alias (void)
+{
+	return arv_gc_property_node_new (ARV_GC_PROPERTY_NODE_TYPE_P_ALIAS);
+}
+
+ArvGcNode *
+arv_gc_property_node_new_p_cast_alias (void)
+{
+	return arv_gc_property_node_new (ARV_GC_PROPERTY_NODE_TYPE_P_CAST_ALIAS);
+}
+
 static void
 _set_property (GObject * object, guint prop_id,
 	       const GValue * value, GParamSpec * pspec)
diff --git a/src/arvgcpropertynode.h b/src/arvgcpropertynode.h
index 752812d..08ed0ff 100644
--- a/src/arvgcpropertynode.h
+++ b/src/arvgcpropertynode.h
@@ -74,6 +74,7 @@ typedef enum {
 	ARV_GC_PROPERTY_NODE_TYPE_VALUE_INDEXED,
 	ARV_GC_PROPERTY_NODE_TYPE_VALUE_DEFAULT,
 	ARV_GC_PROPERTY_NODE_TYPE_STREAMABLE,
+        ARV_GC_PROPERTY_NODE_TYPE_IS_DEPRECATED,
 
 	ARV_GC_PROPERTY_NODE_TYPE_P_UNKNONW	= 1000,
 	ARV_GC_PROPERTY_NODE_TYPE_P_FEATURE,
@@ -93,7 +94,9 @@ typedef enum {
 	ARV_GC_PROPERTY_NODE_TYPE_P_INVALIDATOR,
 	ARV_GC_PROPERTY_NODE_TYPE_P_COMMAND_VALUE,
 	ARV_GC_PROPERTY_NODE_TYPE_P_VALUE_INDEXED,
-	ARV_GC_PROPERTY_NODE_TYPE_P_VALUE_DEFAULT
+	ARV_GC_PROPERTY_NODE_TYPE_P_VALUE_DEFAULT,
+        ARV_GC_PROPERTY_NODE_TYPE_P_ALIAS,
+        ARV_GC_PROPERTY_NODE_TYPE_P_CAST_ALIAS
 } ArvGcPropertyNodeType;
 
 #define ARV_TYPE_GC_PROPERTY_NODE             (arv_gc_property_node_get_type ())
@@ -155,6 +158,9 @@ ARV_API ArvGcNode *		arv_gc_property_node_new_event_id		(void);
 ARV_API ArvGcNode *		arv_gc_property_node_new_value_default		(void);
 ARV_API ArvGcNode *		arv_gc_property_node_new_p_value_default	(void);
 ARV_API ArvGcNode *		arv_gc_property_node_new_streamable		(void);
+ARV_API ArvGcNode *		arv_gc_property_node_new_is_deprecated		(void);
+ARV_API ArvGcNode *		arv_gc_property_node_new_p_alias		(void);
+ARV_API ArvGcNode *		arv_gc_property_node_new_p_cast_alias		(void);
 
 ARV_API const char *		arv_gc_property_node_get_name			(ArvGcPropertyNode *node);
 
diff --git a/src/arvgvcp.c b/src/arvgvcp.c
index 4b2a9c1..d3e5e1c 100644
--- a/src/arvgvcp.c
+++ b/src/arvgvcp.c
@@ -27,6 +27,7 @@
 
 #include <arvgvcpprivate.h>
 #include <arvgvspprivate.h>
+#include <arvmiscprivate.h>
 #include <arvenumtypes.h>
 #include <arvenumtypesprivate.h>
 #include <string.h>
@@ -487,7 +488,6 @@ char *
 arv_gvcp_packet_flags_to_string_new (ArvGvcpCommand command, guint8 flags)
 {
 	GString *string = g_string_new ("");
-	char *buffer = NULL;
 	unsigned i;
 
 	for (i = 0; i < 8; i++) {
@@ -518,11 +518,7 @@ arv_gvcp_packet_flags_to_string_new (ArvGvcpCommand command, guint8 flags)
 	if (string->len == 0)
 		g_string_append (string, "none");
 
-	buffer = string->str;
-
-	g_string_free (string, FALSE);
-
-	return buffer;
+        return arv_g_string_free_and_steal(string);
 }
 
 /**
@@ -572,7 +568,6 @@ char *
 arv_gvcp_packet_to_string (const ArvGvcpPacket *packet)
 {
 	GString *string;
-	char *c_string;
 	char *data;
 	int packet_size;
 	guint32 value;
@@ -663,11 +658,7 @@ arv_gvcp_packet_to_string (const ArvGvcpPacket *packet)
 
 	arv_g_string_append_hex_dump (string, packet, packet_size);
 
-	c_string = string->str;
-
-	g_string_free (string, FALSE);
-
-	return c_string;
+        return arv_g_string_free_and_steal(string);
 }
 
 /**
diff --git a/src/arvgvdevice.c b/src/arvgvdevice.c
index ebca38b..4d94bcc 100644
--- a/src/arvgvdevice.c
+++ b/src/arvgvdevice.c
@@ -728,19 +728,20 @@ auto_packet_size (ArvGvDevice *gv_device, gboolean exit_early, GError **error)
 
 		do {
 			if (current_size == last_size ||
-                            min_size + inc >= max_size)
+                            min_size + inc > max_size)
 				break;
 
 			last_size = current_size;
 
-			arv_info_device ("[GvDevice::auto_packet_size] Try packet size = %d (min: %d - max: %d - inc: %d)",
-                                         current_size, min_size, max_size, inc);
 			arv_device_set_integer_feature_value (device, "ArvGevSCPSPacketSize", current_size, NULL);
 
 			current_size = arv_device_get_integer_feature_value (device, "ArvGevSCPSPacketSize", &local_error);
                         if (local_error != NULL)
                                 break;
 
+			arv_info_device ("[GvDevice::auto_packet_size] Try packet size = %d (%d - min: %d - max: %d - inc: %d)",
+                                         current_size, last_size, min_size, max_size, inc);
+
 			success = test_packet_check (device, &poll_fd, socket, buffer, max_size, current_size);
 
 			if (success) {
@@ -753,7 +754,7 @@ auto_packet_size (ArvGvDevice *gv_device, gboolean exit_early, GError **error)
 				max_size = current_size;
 			}
 
-                        current_size = min_size + (((max_size - min_size) / 2 + 1) / inc) * inc;
+                        current_size = min_size + (((max_size - min_size) / 2) / inc) * inc;
 		} while (TRUE);
 
                 if (local_error == NULL) {
diff --git a/src/arvgvsp.c b/src/arvgvsp.c
index eca05bc..a572c8a 100644
--- a/src/arvgvsp.c
+++ b/src/arvgvsp.c
@@ -26,7 +26,7 @@
  */
 
 #include <arvdebug.h>
-#include <arvmisc.h>
+#include <arvmiscprivate.h>
 #include <arvenumtypes.h>
 #include <arvgvspprivate.h>
 #include <arvenumtypesprivate.h>
@@ -173,7 +173,6 @@ arv_gvsp_packet_to_string (const ArvGvspPacket *packet, size_t packet_size)
         guint part_id;
         ptrdiff_t offset;
 	GString *string;
-	char *c_string;
 
 	string = g_string_new ("");
 
@@ -275,11 +274,7 @@ arv_gvsp_packet_to_string (const ArvGvspPacket *packet, size_t packet_size)
                         break;
         }
 
-	c_string = string->str;
-
-	g_string_free (string, FALSE);
-
-	return c_string;
+        return arv_g_string_free_and_steal(string);
 }
 
 void
diff --git a/src/arvgvspprivate.h b/src/arvgvspprivate.h
index cefb9d1..10f1798 100644
--- a/src/arvgvspprivate.h
+++ b/src/arvgvspprivate.h
@@ -270,12 +270,12 @@ static inline ArvGvspContentType
 arv_gvsp_packet_get_content_type (const ArvGvspPacket *packet)
 {
 	if (arv_gvsp_packet_has_extended_ids (packet)) {
-		ArvGvspExtendedHeader *header = (void *) &packet->header;
+		ArvGvspExtendedHeader *header = (ArvGvspExtendedHeader *) &packet->header;
 
 		return (ArvGvspContentType) ((g_ntohl (header->packet_infos) & ARV_GVSP_PACKET_INFOS_CONTENT_TYPE_MASK) >>
 					     ARV_GVSP_PACKET_INFOS_CONTENT_TYPE_POS);
 	} else {
-		ArvGvspHeader *header = (void *) &packet->header;
+		ArvGvspHeader *header = (ArvGvspHeader *) &packet->header;
 
 		return (ArvGvspContentType) ((g_ntohl (header->packet_infos) & ARV_GVSP_PACKET_INFOS_CONTENT_TYPE_MASK) >>
 					     ARV_GVSP_PACKET_INFOS_CONTENT_TYPE_POS);
@@ -327,11 +327,11 @@ static inline guint32
 arv_gvsp_packet_get_packet_id (const ArvGvspPacket *packet)
 {
 	if (arv_gvsp_packet_has_extended_ids (packet)) {
-		ArvGvspExtendedHeader *header = (void *) &packet->header;
+		ArvGvspExtendedHeader *header = (ArvGvspExtendedHeader *) &packet->header;
 
 		return g_ntohl (header->packet_id);
 	} else {
-		ArvGvspHeader *header = (void *) &packet->header;
+		ArvGvspHeader *header = (ArvGvspHeader *) &packet->header;
 
 		return g_ntohl (header->packet_infos) & ARV_GVSP_PACKET_ID_MASK;
 	}
@@ -341,11 +341,11 @@ static inline guint64
 arv_gvsp_packet_get_frame_id (const ArvGvspPacket *packet)
 {
 	if (arv_gvsp_packet_has_extended_ids (packet)) {
-		ArvGvspExtendedHeader *header = (void *) &packet->header;
+		ArvGvspExtendedHeader *header = (ArvGvspExtendedHeader *) &packet->header;
 
 		return GUINT64_FROM_BE(header->frame_id);
 	} else {
-		ArvGvspHeader *header = (void *) &packet->header;
+		ArvGvspHeader *header = (ArvGvspHeader *) &packet->header;
 
 		return g_ntohs (header->frame_id);
 	}
@@ -355,11 +355,11 @@ static inline void *
 arv_gvsp_packet_get_data (const ArvGvspPacket *packet)
 {
 	if (arv_gvsp_packet_has_extended_ids (packet)) {
-		ArvGvspExtendedHeader *header = (void *) &packet->header;
+		ArvGvspExtendedHeader *header = (ArvGvspExtendedHeader *) &packet->header;
 
 		return &header->data;
 	} else {
-		ArvGvspHeader *header = (void *) &packet->header;
+		ArvGvspHeader *header = (ArvGvspHeader *) &packet->header;
 
 		return &header->data;
 	}
@@ -372,14 +372,14 @@ arv_gvsp_leader_packet_get_buffer_payload_type (const ArvGvspPacket *packet, gbo
                 ArvGvspLeader *leader;
                 guint16 payload_type;
 
-                leader = arv_gvsp_packet_get_data (packet);
+                leader = (ArvGvspLeader *) arv_gvsp_packet_get_data (packet);
                 payload_type = g_ntohs (leader->payload_type);
 
                 if (has_chunks != NULL)
                         *has_chunks = ((payload_type & 0x4000) != 0 ||
                                        (payload_type == 0x0004));
 
-                return payload_type & 0x3fff;
+                return (ArvBufferPayloadType) (payload_type & 0x3fff);
         }
 
         return ARV_BUFFER_PAYLOAD_TYPE_UNKNOWN;
@@ -391,7 +391,7 @@ arv_gvsp_leader_packet_get_timestamp (const ArvGvspPacket *packet)
         if (G_LIKELY (arv_gvsp_packet_get_content_type (packet) == ARV_GVSP_CONTENT_TYPE_LEADER)) {
                 ArvGvspLeader *leader;
 
-                leader = arv_gvsp_packet_get_data (packet);
+                leader = (ArvGvspLeader *) arv_gvsp_packet_get_data (packet);
 
                 return ((guint64) g_ntohl (leader->timestamp_high) << 32) | g_ntohl (leader->timestamp_low);
         }
@@ -404,10 +404,10 @@ arv_gvsp_leader_packet_get_multipart_n_parts (const ArvGvspPacket *packet)
 {
         if (arv_gvsp_leader_packet_get_buffer_payload_type (packet, NULL) == ARV_BUFFER_PAYLOAD_TYPE_MULTIPART) {
                 if (arv_gvsp_packet_has_extended_ids (packet)) {
-                        ArvGvspExtendedHeader *header = (void *) &packet->header;
+                        ArvGvspExtendedHeader *header = (ArvGvspExtendedHeader *) &packet->header;
                         return (g_ntohl (header->packet_infos) & ARV_GVSP_PACKET_INFOS_N_PARTS_MASK);
                 } else {
-                        ArvGvspHeader *header = (void *) &packet->header;
+                        ArvGvspHeader *header = (ArvGvspHeader *) &packet->header;
                         return (g_ntohl (header->packet_infos) & ARV_GVSP_PACKET_INFOS_N_PARTS_MASK);
                 }
         }
@@ -437,11 +437,11 @@ arv_gvsp_leader_packet_get_multipart_infos (const ArvGvspPacket *packet,
         if (part_id >= n_parts)
                 return FALSE;
 
-        leader = arv_gvsp_packet_get_data (packet);
+        leader = (ArvGvspMultipartLeader *) arv_gvsp_packet_get_data (packet);
         infos = &leader->parts[part_id];
 
         *purpose_id = g_ntohs(infos->data_purpose_id);
-        *data_type = g_ntohs (infos->data_type);
+        *data_type = (ArvBufferPartDataType) g_ntohs (infos->data_type);
         *size = g_ntohl (infos->part_length_low) + (((guint64) g_ntohs (infos->part_length_high)) << 32);
         *pixel_format = g_ntohl (infos->pixel_format);
         *width = g_ntohl (infos->width);
@@ -466,7 +466,7 @@ arv_gvsp_leader_packet_get_multipart_size (const ArvGvspPacket *packet,
         if (part_id >= n_parts)
                 return 0;
 
-        leader = arv_gvsp_packet_get_data (packet);
+        leader = (ArvGvspMultipartLeader *) arv_gvsp_packet_get_data (packet);
         infos = &leader->parts[part_id];
 
         return g_ntohl (infos->part_length_low) + (((guint64) g_ntohs (infos->part_length_high)) << 32);
@@ -487,7 +487,7 @@ arv_gvsp_leader_packet_get_image_infos (const ArvGvspPacket *packet,
             payload_type == ARV_BUFFER_PAYLOAD_TYPE_EXTENDED_CHUNK_DATA) {
                 ArvGvspImageLeader *leader;
 
-                leader = arv_gvsp_packet_get_data (packet);
+                leader = (ArvGvspImageLeader *) arv_gvsp_packet_get_data (packet);
 
                 *pixel_format = g_ntohl (leader->infos.pixel_format);
                 *width = g_ntohl (leader->infos.width);
@@ -526,7 +526,7 @@ arv_gvsp_multipart_packet_get_infos (const ArvGvspPacket *packet, guint *part_id
                 return FALSE;
         }
 
-        multipart = arv_gvsp_packet_get_data(packet);
+        multipart = (ArvGvspMultipart *) arv_gvsp_packet_get_data(packet);
 
         *part_id = multipart->part_id;
         *offset = ( (guint64) g_ntohs(multipart->offset_high) << 32) + g_ntohl(multipart->offset_low);
diff --git a/src/arvgvstream.c b/src/arvgvstream.c
index 04499ab..3e6f807 100644
--- a/src/arvgvstream.c
+++ b/src/arvgvstream.c
@@ -814,6 +814,10 @@ _check_frame_completion (ArvGvStreamThreadData *thread_data,
 		}
 
 		if (can_close_frame &&
+                    /* Do not timeout on the most recent frame if the LEADER packet is so far the ONLY
+                     * valid packet received. This is needed by some devices sending the leader packet early, at
+                     * acquisition start. */
+                    (frame->frame_id != thread_data->last_frame_id || frame->last_valid_packet != 0) &&
 		    time_us - frame->last_packet_time_us >= thread_data->frame_retention_us) {
 			frame->buffer->priv->status = ARV_BUFFER_STATUS_TIMEOUT;
 			arv_warning_stream_thread ("[GvStream::check_frame_completion] Timeout for frame %"
diff --git a/src/arvmisc.c b/src/arvmisc.c
index 9ca9ae3..c9a1c57 100644
--- a/src/arvmisc.c
+++ b/src/arvmisc.c
@@ -279,7 +279,6 @@ arv_histogram_to_string (const ArvHistogram *histogram)
 	int i, j, bin_max;
 	gboolean max_found = FALSE;
 	GString *string;
-	char *str;
 
 	g_return_val_if_fail (histogram != NULL, NULL);
 
@@ -369,10 +368,7 @@ arv_histogram_to_string (const ArvHistogram *histogram)
 		g_string_append_printf (string, ":%12llu", (unsigned long long) histogram->variables[j].counter);
 	}
 
-	str = string->str;
-	g_string_free (string, FALSE);
-
-	return str;
+        return arv_g_string_free_and_steal(string);
 }
 
 ArvValue *
@@ -1158,3 +1154,17 @@ arv_regex_new_from_glob_pattern (const char *glob, gboolean caseless)
 
 	return regex;
 }
+
+char *
+arv_g_string_free_and_steal (GString *string)
+{
+#if GLIB_CHECK_VERSION(2,75,4)
+        return g_string_free_and_steal(string);
+#else
+        char *buffer = string->str;
+
+        g_string_free (string, FALSE);
+
+        return buffer;
+#endif
+}
diff --git a/src/arvmiscprivate.h b/src/arvmiscprivate.h
index 3a0caf1..40539f1 100644
--- a/src/arvmiscprivate.h
+++ b/src/arvmiscprivate.h
@@ -66,6 +66,10 @@ double 		arv_value_get_double 		(ArvValue *value);
 gboolean 	arv_value_holds_int64 		(ArvValue *value);
 double 		arv_value_holds_double 		(ArvValue *value);
 
+/* Compatibility functions */
+
+char *          arv_g_string_free_and_steal     (GString *string) G_GNUC_WARN_UNUSED_RESULT;
+
 /* private, but used by tests */
 ARV_API gboolean	arv_parse_genicam_url	(const char *url, gssize url_length,
 						 char **scheme, char **authority, char **path,
diff --git a/src/arvuvcp.c b/src/arvuvcp.c
index cbbea71..80b5666 100644
--- a/src/arvuvcp.c
+++ b/src/arvuvcp.c
@@ -25,6 +25,7 @@
  * @short_description: USB3Vision control packet handling
  */
 
+#include <arvmiscprivate.h>
 #include <arvuvcpprivate.h>
 #include <arvenumtypesprivate.h>
 #include <arvdebug.h>
@@ -148,7 +149,6 @@ arv_uvcp_packet_to_string (const ArvUvcpPacket *packet)
 {
 	ArvUvcpCommand command;
 	GString *string;
-	char *c_string;
 	int packet_size;
 	guint64 value;
 
@@ -206,11 +206,7 @@ arv_uvcp_packet_to_string (const ArvUvcpPacket *packet)
 
 	arv_g_string_append_hex_dump (string, packet, packet_size);
 
-	c_string = string->str;
-
-	g_string_free (string, FALSE);
-
-	return c_string;
+        return arv_g_string_free_and_steal(string);
 }
 
 /**
diff --git a/src/arvuvcpprivate.h b/src/arvuvcpprivate.h
index 7bd5192..dec06f7 100644
--- a/src/arvuvcpprivate.h
+++ b/src/arvuvcpprivate.h
@@ -314,7 +314,7 @@ static inline ArvUvcpFlags
 arv_uvcp_packet_get_flags (const ArvUvcpPacket *packet)
 {
 	if (packet == NULL)
-		return 0;
+		return (ArvUvcpFlags) 0;
 
 	return (ArvUvcpFlags) GUINT16_FROM_LE (packet->header.flags);
 }
diff --git a/src/arvuvdevice.c b/src/arvuvdevice.c
index 0cabc4e..8c5fc7c 100644
--- a/src/arvuvdevice.c
+++ b/src/arvuvdevice.c
@@ -462,7 +462,7 @@ _bootstrap (ArvUvDevice *uv_device)
 	guint64 device_capability;
 	guint32 max_cmd_transfer;
 	guint32 max_ack_transfer;
-	guint32 u3vcp_capability;
+	guint64 u3vcp_capability;
 	guint64 sirm_offset;
 	guint32 si_info;
 	guint32 si_control;
@@ -493,10 +493,14 @@ _bootstrap (ArvUvDevice *uv_device)
 	manufacturer[63] = 0;
 	arv_info_device ("MANUFACTURER_NAME =        '%s'", manufacturer);
 
-	success = success && arv_device_read_memory (device, ARV_ABRM_SBRM_ADDRESS, sizeof (guint64), &offset, NULL);
-	success = success && arv_device_read_memory (device, ARV_ABRM_MAX_DEVICE_RESPONSE_TIME, sizeof (guint32), &response_time, NULL);
-	success = success && arv_device_read_memory (device, ARV_ABRM_DEVICE_CAPABILITY, sizeof (guint64), &device_capability, NULL);
-	success = success && arv_device_read_memory (device, ARV_ABRM_MANIFEST_TABLE_ADDRESS, sizeof (guint64), &manifest_table_address, NULL);
+	success = success && arv_device_read_memory (device, ARV_ABRM_SBRM_ADDRESS,
+                                                     sizeof (offset), &offset, NULL);
+	success = success && arv_device_read_memory (device, ARV_ABRM_MAX_DEVICE_RESPONSE_TIME,
+                                                     sizeof (response_time), &response_time, NULL);
+	success = success && arv_device_read_memory (device, ARV_ABRM_DEVICE_CAPABILITY,
+                                                     sizeof (device_capability), &device_capability, NULL);
+	success = success && arv_device_read_memory (device, ARV_ABRM_MANIFEST_TABLE_ADDRESS,
+                                                     sizeof (manifest_table_address), &manifest_table_address, NULL);
 	if (!success) {
 		arv_warning_device ("[UvDevice::_bootstrap] Error during memory read");
 		return FALSE;
@@ -509,16 +513,20 @@ _bootstrap (ArvUvDevice *uv_device)
 
 	priv->timeout_ms = MAX (ARV_UVCP_DEFAULT_RESPONSE_TIME_MS, response_time);
 
-	success = success && arv_device_read_memory (device, offset + ARV_SBRM_U3VCP_CAPABILITY, sizeof (guint32), &u3vcp_capability, NULL);
-	success = success && arv_device_read_memory (device, offset + ARV_SBRM_MAX_CMD_TRANSFER, sizeof (guint32), &max_cmd_transfer, NULL);
-	success = success && arv_device_read_memory (device, offset + ARV_SBRM_MAX_ACK_TRANSFER, sizeof (guint32), &max_ack_transfer, NULL);
-	success = success && arv_device_read_memory (device, offset + ARV_SBRM_SIRM_ADDRESS, sizeof (guint64), &sirm_offset, NULL);
+	success = success && arv_device_read_memory (device, offset + ARV_SBRM_U3VCP_CAPABILITY,
+                                                     sizeof (u3vcp_capability), &u3vcp_capability, NULL);
+	success = success && arv_device_read_memory (device, offset + ARV_SBRM_MAX_CMD_TRANSFER,
+                                                     sizeof (max_cmd_transfer), &max_cmd_transfer, NULL);
+	success = success && arv_device_read_memory (device, offset + ARV_SBRM_MAX_ACK_TRANSFER,
+                                                     sizeof (max_ack_transfer), &max_ack_transfer, NULL);
+	success = success && arv_device_read_memory (device, offset + ARV_SBRM_SIRM_ADDRESS,
+                                                     sizeof (sirm_offset), &sirm_offset, NULL);
 	if (!success) {
 		arv_warning_device ("[UvDevice::_bootstrap] Error during memory read");
 		return FALSE;
 	}
 
-	arv_info_device ("U3VCP_CAPABILITY =         0x%08x", u3vcp_capability);
+	arv_info_device ("U3VCP_CAPABILITY =         0x%016" G_GINT64_MODIFIER "x", u3vcp_capability);
 	arv_info_device ("MAX_CMD_TRANSFER =         0x%08x", max_cmd_transfer);
 	arv_info_device ("MAX_ACK_TRANSFER =         0x%08x", max_ack_transfer);
 	arv_info_device ("SIRM_OFFSET =              0x%016" G_GINT64_MODIFIER "x", sirm_offset);
@@ -526,36 +534,49 @@ _bootstrap (ArvUvDevice *uv_device)
 	priv->cmd_packet_size_max = MIN (priv->cmd_packet_size_max, max_cmd_transfer);
 	priv->ack_packet_size_max = MIN (priv->ack_packet_size_max, max_ack_transfer);
 
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_INFO, sizeof (si_info), &si_info, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_CONTROL, sizeof (si_control), &si_control, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_PAYLOAD_SIZE, sizeof (si_req_payload_size), &si_req_payload_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_LEADER_SIZE, sizeof (si_req_leader_size), &si_req_leader_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_TRAILER_SIZE, sizeof (si_req_trailer_size), &si_req_trailer_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_MAX_LEADER_SIZE, sizeof (si_max_leader_size), &si_max_leader_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_PAYLOAD_SIZE, sizeof (si_payload_size), &si_payload_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_PAYLOAD_COUNT, sizeof (si_payload_count), &si_payload_count, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_TRANSFER1_SIZE, sizeof (si_transfer1_size), &si_transfer1_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_TRANSFER2_SIZE, sizeof (si_transfer2_size), &si_transfer2_size, NULL);
-	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_MAX_TRAILER_SIZE, sizeof (si_max_trailer_size), &si_max_trailer_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_INFO,
+                                                     sizeof (si_info), &si_info, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_CONTROL,
+                                                     sizeof (si_control), &si_control, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_PAYLOAD_SIZE,
+                                                     sizeof (si_req_payload_size), &si_req_payload_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_LEADER_SIZE,
+                                                     sizeof (si_req_leader_size), &si_req_leader_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_REQ_TRAILER_SIZE,
+                                                     sizeof (si_req_trailer_size), &si_req_trailer_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_MAX_LEADER_SIZE,
+                                                     sizeof (si_max_leader_size), &si_max_leader_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_PAYLOAD_SIZE,
+                                                     sizeof (si_payload_size), &si_payload_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_PAYLOAD_COUNT,
+                                                     sizeof (si_payload_count), &si_payload_count, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_TRANSFER1_SIZE,
+                                                     sizeof (si_transfer1_size), &si_transfer1_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_TRANSFER2_SIZE,
+                                                     sizeof (si_transfer2_size), &si_transfer2_size, NULL);
+	success = success && arv_device_read_memory (device, sirm_offset + ARV_SIRM_MAX_TRAILER_SIZE,
+                                                     sizeof (si_max_trailer_size), &si_max_trailer_size, NULL);
 	if (!success) {
 		arv_warning_device ("[UvDevice::_bootstrap] Error during memory read");
 		return FALSE;
 	}
 
-	arv_info_device ("SIRM_INFO =                  0x%08x", si_info);
-	arv_info_device ("SIRM_CONTROL =               0x%08x", si_control);
-	arv_info_device ("SIRM_REQ_PAYLOAD_SIZE =      0x%016" G_GINT64_MODIFIER "x", si_req_payload_size);
-	arv_info_device ("SIRM_REQ_LEADER_SIZE =       0x%08x", si_req_leader_size);
-	arv_info_device ("SIRM_REQ_TRAILER_SIZE =      0x%08x", si_req_trailer_size);
-	arv_info_device ("SIRM_MAX_LEADER_SIZE =       0x%08x", si_max_leader_size);
-	arv_info_device ("SIRM_PAYLOAD_SIZE =          0x%08x", si_payload_size);
-	arv_info_device ("SIRM_PAYLOAD_COUNT =         0x%08x", si_payload_count);
-	arv_info_device ("SIRM_TRANSFER1_SIZE =        0x%08x", si_transfer1_size);
-	arv_info_device ("SIRM_TRANSFER2_SIZE =        0x%08x", si_transfer2_size);
-	arv_info_device ("SIRM_MAX_TRAILER_SIZE =      0x%08x", si_max_trailer_size);
-
-	success = success && arv_device_read_memory (device, manifest_table_address, sizeof (guint64), &manifest_n_entries, NULL);
-	success = success && arv_device_read_memory (device, manifest_table_address + 0x08, sizeof (entry), &entry, NULL);
+	arv_info_device ("SIRM_INFO =                0x%08x", si_info);
+	arv_info_device ("SIRM_CONTROL =             0x%08x", si_control);
+	arv_info_device ("SIRM_REQ_PAYLOAD_SIZE =    0x%016" G_GINT64_MODIFIER "x", si_req_payload_size);
+	arv_info_device ("SIRM_REQ_LEADER_SIZE =     0x%08x", si_req_leader_size);
+	arv_info_device ("SIRM_REQ_TRAILER_SIZE =    0x%08x", si_req_trailer_size);
+	arv_info_device ("SIRM_MAX_LEADER_SIZE =     0x%08x", si_max_leader_size);
+	arv_info_device ("SIRM_PAYLOAD_SIZE =        0x%08x", si_payload_size);
+	arv_info_device ("SIRM_PAYLOAD_COUNT =       0x%08x", si_payload_count);
+	arv_info_device ("SIRM_TRANSFER1_SIZE =      0x%08x", si_transfer1_size);
+	arv_info_device ("SIRM_TRANSFER2_SIZE =      0x%08x", si_transfer2_size);
+	arv_info_device ("SIRM_MAX_TRAILER_SIZE =    0x%08x", si_max_trailer_size);
+
+	success = success && arv_device_read_memory (device, manifest_table_address,
+                                                     sizeof (manifest_n_entries), &manifest_n_entries, NULL);
+	success = success && arv_device_read_memory (device, manifest_table_address + 0x08,
+                                                     sizeof (entry), &entry, NULL);
 	if (!success) {
 		arv_warning_device ("[UvDevice::_bootstrap] Error during memory read");
 		return FALSE;
@@ -972,7 +993,7 @@ arv_uv_device_constructed (GObject *object)
         if (result != 0) {
                 arv_device_take_init_error (ARV_DEVICE (uv_device),
                                             g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_PROTOCOL_ERROR,
-                                                         "Failed to claim USB interface to '%s-%s-%s-%s': %s",
+                                                         "Failed to claim USB control interface to '%s-%s-%s-%s': %s",
                                                          priv->vendor, priv->product, priv->serial_number, priv->guid,
                                                          libusb_error_name (result)));
                 return;
@@ -982,7 +1003,7 @@ arv_uv_device_constructed (GObject *object)
         if (result != 0) {
                 arv_device_take_init_error (ARV_DEVICE (uv_device),
                                             g_error_new (ARV_DEVICE_ERROR, ARV_DEVICE_ERROR_PROTOCOL_ERROR,
-                                                         "Failed to claim USB interface to '%s-%s-%s-%s': %s",
+                                                         "Failed to claim USB data interface to '%s-%s-%s-%s': %s",
                                                          priv->vendor, priv->product, priv->serial_number, priv->guid,
                                                          libusb_error_name (result)));
                 return;
@@ -1040,7 +1061,8 @@ arv_uv_device_finalize (GObject *object)
         libusb_hotplug_deregister_callback (priv->usb, priv->hotplug_cb_handle);
 
 	priv->event_thread_run = 0;
-	g_thread_join (priv->event_thread);
+        if (priv->event_thread)
+                g_thread_join (priv->event_thread);
 
 	g_clear_object (&priv->genicam);
 
diff --git a/src/arvuvsp.c b/src/arvuvsp.c
index fa5502b..0facea0 100644
--- a/src/arvuvsp.c
+++ b/src/arvuvsp.c
@@ -22,7 +22,7 @@
 
 #include <arvuvspprivate.h>
 #include <arvstr.h>
-#include <arvmisc.h>
+#include <arvmiscprivate.h>
 
 /*
  * SECTION: arvuvsp
@@ -44,7 +44,6 @@ arv_uvsp_packet_to_string (const ArvUvspPacket *packet)
 	ArvUvspLeader *leader = (ArvUvspLeader *) packet;
 	ArvUvspTrailer *trailer = (ArvUvspTrailer *) packet;
 	GString *string;
-	char *c_string;
 
 	g_return_val_if_fail (packet != NULL, NULL);
 
@@ -101,11 +100,7 @@ arv_uvsp_packet_to_string (const ArvUvspPacket *packet)
 	}
 #endif
 
-	c_string = string->str;
-
-	g_string_free (string, FALSE);
-
-	return c_string;
+        return arv_g_string_free_and_steal(string);
 }
 
 /**
diff --git a/src/arvuvspprivate.h b/src/arvuvspprivate.h
index 6d88135..b9fbe3e 100644
--- a/src/arvuvspprivate.h
+++ b/src/arvuvspprivate.h
@@ -123,7 +123,7 @@ arv_uvsp_packet_get_buffer_payload_type (ArvUvspPacket *packet, gboolean *has_ch
         if (has_chunks != NULL)
                 *has_chunks = (payload_type & 0x4000) != 0;
 
-        return payload_type & 0x3fff;
+        return (ArvBufferPayloadType) (payload_type & 0x3fff);
 }
 
 static inline guint64

More details

Full run details

Historical runs