[libcamera-devel,11/11] test: v4l2_videodevice: Test U8 array controls

Message ID 20200309162414.720306-12-jacopo@jmondi.org
State Accepted
Headers show
Series
  • Adda support for V4L2 array control and strings
Related show

Commit Message

Jacopo Mondi March 9, 2020, 4:24 p.m. UTC
Test V4L2 array control using vivid control VIVID_CID_U8_4D_ARRAY.

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---
 test/v4l2_videodevice/controls.cpp | 31 +++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

Comments

Laurent Pinchart March 20, 2020, 11:32 p.m. UTC | #1
Hi Jacopo,

Thank you for the patch.

On Mon, Mar 09, 2020 at 05:24:14PM +0100, Jacopo Mondi wrote:
> Test V4L2 array control using vivid control VIVID_CID_U8_4D_ARRAY.
> 
> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
> ---
>  test/v4l2_videodevice/controls.cpp | 31 +++++++++++++++++++++++++++++-
>  1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp
> index 478de3707a3c..e2601b7594bb 100644
> --- a/test/v4l2_videodevice/controls.cpp
> +++ b/test/v4l2_videodevice/controls.cpp
> @@ -5,6 +5,7 @@
>   * controls.cpp - V4L2 device controls handling test
>   */
>  
> +#include <array>
>  #include <iostream>
>  #include <limits.h>
>  
> @@ -12,6 +13,13 @@
>  
>  #include "v4l2_videodevice_test.h"
>  
> +/* These come from the vivid driver */

s/driver/driver./

> +#define VIVID_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
> +#define VIVID_CID_U8_4D_ARRAY		(VIVID_CID_CUSTOM_BASE + 10)
> +
> +/* Helper for VIVID_CID_U8_4D_ARRAY control array size: not from kernel. */
> +#define VIVID_CID_U8_ARRAY_SIZE		(2 * 3 * 4 * 5)
> +
>  using namespace std;
>  using namespace libcamera;
>  
> @@ -36,7 +44,8 @@ protected:
>  
>  		if (infoMap.find(V4L2_CID_BRIGHTNESS) == infoMap.end() ||
>  		    infoMap.find(V4L2_CID_CONTRAST) == infoMap.end() ||
> -		    infoMap.find(V4L2_CID_SATURATION) == infoMap.end()) {
> +		    infoMap.find(V4L2_CID_SATURATION) == infoMap.end() ||
> +		    infoMap.find(VIVID_CID_U8_4D_ARRAY) == infoMap.end()) {
>  			cerr << "Missing controls" << endl;
>  			return TestFail;
>  		}
> @@ -44,6 +53,7 @@ protected:
>  		const ControlInfo &brightness = infoMap.find(V4L2_CID_BRIGHTNESS)->second;
>  		const ControlInfo &contrast = infoMap.find(V4L2_CID_CONTRAST)->second;
>  		const ControlInfo &saturation = infoMap.find(V4L2_CID_SATURATION)->second;
> +		const ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;
>  
>  		/* Test getting controls. */
>  		ControlList ctrls(infoMap);
> @@ -51,6 +61,10 @@ protected:
>  		ctrls.set(V4L2_CID_CONTRAST, -1);
>  		ctrls.set(V4L2_CID_SATURATION, -1);
>  
> +		std::array<uint8_t, VIVID_CID_U8_ARRAY_SIZE> u8Values;
> +		Span<const uint8_t> u8Span(u8Values);
> +		ctrls.set(VIVID_CID_U8_4D_ARRAY, u8Span);

This potentially writes random values. The std::array constructor
documentation (https://en.cppreference.com/w/cpp/container/array)
mentions

"initializes the array following the rules of aggregate initialization
(note that default initialization may result in indeterminate values for
non-class T)"

You don't actually need to set VIVID_CID_U8_4D_ARRAY with an array here.
What matters for the getControls() call is that the ControlList has an
entry with the desired control ID. You can just set its value to 0, it
will be overwritten by getControls().

> +
>  		int ret = capture_->getControls(&ctrls);
>  		if (ret) {
>  			cerr << "Failed to get controls" << endl;
> @@ -64,11 +78,26 @@ protected:
>  			return TestFail;
>  		}
>  
> +		u8Span = ctrls.get(VIVID_CID_U8_4D_ARRAY).get<Span<const uint8_t>>();
> +		for (unsigned int i = 0; i < VIVID_CID_U8_ARRAY_SIZE; ++i) {
> +			if (u8Span[i] != 0)

How about checking for >= min and <= max to make this more generic ?

> +				continue;
> +
> +			cerr << "Incorrect value for retrieved array control"
> +			     << endl;
> +			return TestFail;
> +		}

		uint8_t u8Min = u8.min().get<uint8_t>();
		uint8_t u8Max = u8.max().get<uint8_t>();

		Span<const uint8_t> u8Span = ctrls.get(VIVID_CID_U8_4D_ARRAY).get<Span<const uint8_t>>();
		bool valid = std::all_of(u8Span.begin(), u8Span.end(),
					 [&](uint8_t v) { return v >= u8Min && v <= u8Max; });
		if (!valid) {
			cerr << "Incorrect value for retrieved array control"
			     << endl;
			return TestFail;
		}

> +
>  		/* Test setting controls. */
>  		ctrls.set(V4L2_CID_BRIGHTNESS, brightness.min());
>  		ctrls.set(V4L2_CID_CONTRAST, contrast.max());
>  		ctrls.set(V4L2_CID_SATURATION, saturation.min());
>  
> +		for (unsigned int i = 0; i < VIVID_CID_U8_ARRAY_SIZE; ++i)
> +			u8Values[i] = u8.min().get<uint8_t>();

		std::array<uint8_t, VIVID_CID_U8_ARRAY_SIZE> u8Values;
		std::fill(u8Values.begin(), u8Values.end(), u8Min);

(Don't forget to #include <algorithm>)

> +		u8Span = u8Values;
> +		ctrls.set(VIVID_CID_U8_4D_ARRAY, u8Span);

		ctrls.set(VIVID_CID_U8_4D_ARRAY, Span<const uint8_t>(u8Values));

> +
>  		ret = capture_->setControls(&ctrls);
>  		if (ret) {
>  			cerr << "Failed to set controls" << endl;

Patch

diff --git a/test/v4l2_videodevice/controls.cpp b/test/v4l2_videodevice/controls.cpp
index 478de3707a3c..e2601b7594bb 100644
--- a/test/v4l2_videodevice/controls.cpp
+++ b/test/v4l2_videodevice/controls.cpp
@@ -5,6 +5,7 @@ 
  * controls.cpp - V4L2 device controls handling test
  */
 
+#include <array>
 #include <iostream>
 #include <limits.h>
 
@@ -12,6 +13,13 @@ 
 
 #include "v4l2_videodevice_test.h"
 
+/* These come from the vivid driver */
+#define VIVID_CID_CUSTOM_BASE		(V4L2_CID_USER_BASE | 0xf000)
+#define VIVID_CID_U8_4D_ARRAY		(VIVID_CID_CUSTOM_BASE + 10)
+
+/* Helper for VIVID_CID_U8_4D_ARRAY control array size: not from kernel. */
+#define VIVID_CID_U8_ARRAY_SIZE		(2 * 3 * 4 * 5)
+
 using namespace std;
 using namespace libcamera;
 
@@ -36,7 +44,8 @@  protected:
 
 		if (infoMap.find(V4L2_CID_BRIGHTNESS) == infoMap.end() ||
 		    infoMap.find(V4L2_CID_CONTRAST) == infoMap.end() ||
-		    infoMap.find(V4L2_CID_SATURATION) == infoMap.end()) {
+		    infoMap.find(V4L2_CID_SATURATION) == infoMap.end() ||
+		    infoMap.find(VIVID_CID_U8_4D_ARRAY) == infoMap.end()) {
 			cerr << "Missing controls" << endl;
 			return TestFail;
 		}
@@ -44,6 +53,7 @@  protected:
 		const ControlInfo &brightness = infoMap.find(V4L2_CID_BRIGHTNESS)->second;
 		const ControlInfo &contrast = infoMap.find(V4L2_CID_CONTRAST)->second;
 		const ControlInfo &saturation = infoMap.find(V4L2_CID_SATURATION)->second;
+		const ControlInfo &u8 = infoMap.find(VIVID_CID_U8_4D_ARRAY)->second;
 
 		/* Test getting controls. */
 		ControlList ctrls(infoMap);
@@ -51,6 +61,10 @@  protected:
 		ctrls.set(V4L2_CID_CONTRAST, -1);
 		ctrls.set(V4L2_CID_SATURATION, -1);
 
+		std::array<uint8_t, VIVID_CID_U8_ARRAY_SIZE> u8Values;
+		Span<const uint8_t> u8Span(u8Values);
+		ctrls.set(VIVID_CID_U8_4D_ARRAY, u8Span);
+
 		int ret = capture_->getControls(&ctrls);
 		if (ret) {
 			cerr << "Failed to get controls" << endl;
@@ -64,11 +78,26 @@  protected:
 			return TestFail;
 		}
 
+		u8Span = ctrls.get(VIVID_CID_U8_4D_ARRAY).get<Span<const uint8_t>>();
+		for (unsigned int i = 0; i < VIVID_CID_U8_ARRAY_SIZE; ++i) {
+			if (u8Span[i] != 0)
+				continue;
+
+			cerr << "Incorrect value for retrieved array control"
+			     << endl;
+			return TestFail;
+		}
+
 		/* Test setting controls. */
 		ctrls.set(V4L2_CID_BRIGHTNESS, brightness.min());
 		ctrls.set(V4L2_CID_CONTRAST, contrast.max());
 		ctrls.set(V4L2_CID_SATURATION, saturation.min());
 
+		for (unsigned int i = 0; i < VIVID_CID_U8_ARRAY_SIZE; ++i)
+			u8Values[i] = u8.min().get<uint8_t>();
+		u8Span = u8Values;
+		ctrls.set(VIVID_CID_U8_4D_ARRAY, u8Span);
+
 		ret = capture_->setControls(&ctrls);
 		if (ret) {
 			cerr << "Failed to set controls" << endl;