linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5] v4l2-tracer: misc fixes
@ 2023-02-09  6:06 Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 1/5] v4l2-tracer: add signal handling Deborah Brouwer
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

Hi,
This is a series of small fixes for errors that I noticed
while adding tracing for INPUT and OUTPUT ioctls.

Deborah Brouwer (5):
  v4l2-tracer: add signal handling
  v4l2-tracer: remove trailing comma from JSON trace
  v4l2-tracer: refactor autogeneration script
  v4l2-tracer: add exact matching for 'type' and 'field'
  v4l2-tracer: add INPUT and OUTPUT ioctls

 utils/v4l2-tracer/libv4l2tracer.cpp  |   6 +
 utils/v4l2-tracer/retrace.cpp        |  84 +++++++++
 utils/v4l2-tracer/trace.cpp          |  18 ++
 utils/v4l2-tracer/v4l2-tracer-gen.pl | 273 +++++++++++++++------------
 utils/v4l2-tracer/v4l2-tracer.cpp    |  34 ++--
 5 files changed, 287 insertions(+), 128 deletions(-)

-- 
2.39.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] v4l2-tracer: add signal handling
  2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
@ 2023-02-09  6:06 ` Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace Deborah Brouwer
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

Make sure that any SIGINT or SIGTERM received by the v4l2-tracer gets
passed onto the traced process. This allows the tracee to exit gracefully
before v4l2-tracer exits.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/v4l2-tracer.cpp | 32 ++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/utils/v4l2-tracer/v4l2-tracer.cpp b/utils/v4l2-tracer/v4l2-tracer.cpp
index 3afcd34f..ae6f68e4 100644
--- a/utils/v4l2-tracer/v4l2-tracer.cpp
+++ b/utils/v4l2-tracer/v4l2-tracer.cpp
@@ -10,6 +10,16 @@
 
 int tracer(int argc, char *argv[], bool retrace = false);
 
+pid_t tracee_pid = 0;
+
+void v4l2_tracer_sig_handler(int signum)
+{
+	fprintf(stderr, "%s:%s:%d: received: %d\n", __FILE__, __func__, __LINE__, signum);
+	kill(tracee_pid, signum);
+	/* Wait for tracee to handle the signal first before v4l2-tracer exits. */
+	wait(nullptr);
+}
+
 enum Options {
 	V4l2TracerOptCompactPrint = 'c',
 	V4l2TracerOptSetVideoDevice = 'd',
@@ -307,7 +317,8 @@ int tracer(int argc, char *argv[], bool retrace)
 		fprintf(stderr, "Loading libv4l2tracer: %s\n", libv4l2tracer_path.c_str());
 	setenv("LD_PRELOAD", libv4l2tracer_path.c_str(), 0);
 
-	if (fork() == 0) {
+	tracee_pid = fork();
+	if (tracee_pid == 0) {
 
 		if (is_debug()) {
 			fprintf(stderr, "%s:%s:%d: ", __FILE__, __func__, __LINE__);
@@ -328,16 +339,10 @@ int tracer(int argc, char *argv[], bool retrace)
 	int exec_result = 0;
 	wait(&exec_result);
 
-	if (WEXITSTATUS(exec_result)) {
-		fprintf(stderr, "Trace error: %s\n", trace_filename.c_str());
+	if (WIFEXITED(exec_result))
+		WEXITSTATUS(exec_result);
 
-		trace_file = fopen(trace_filename.c_str(), "a");
-		fseek(trace_file, 0L, SEEK_END);
-		fputs("\n]\n", trace_file);
-		fclose(trace_file);
-
-		exit(EXIT_FAILURE);
-	}
+	fprintf(stderr, "Tracee exited with status: %d\n", exec_result);
 
 	/* Close the json-array and the trace file. */
 	trace_file = fopen(trace_filename.c_str(), "a");
@@ -352,7 +357,7 @@ int tracer(int argc, char *argv[], bool retrace)
 	fprintf(stderr, "%s", trace_filename.c_str());
 	fprintf(stderr, "\n");
 
-	return 0;
+	return exec_result;
 }
 
 int main(int argc, char *argv[])
@@ -388,6 +393,11 @@ int main(int argc, char *argv[])
 		return ret;
 	}
 
+	struct sigaction act = {};
+	act.sa_handler = v4l2_tracer_sig_handler;
+	sigaction(SIGINT, &act, nullptr);
+	sigaction(SIGTERM, &act, nullptr);
+
 	if (command == "trace") {
 		ret = tracer(argc, argv);
 	} else if (command == "retrace") {
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace
  2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 1/5] v4l2-tracer: add signal handling Deborah Brouwer
@ 2023-02-09  6:06 ` Deborah Brouwer
  2023-02-22 19:26   ` Hans Verkuil
  2023-02-09  6:06 ` [PATCH 3/5] v4l2-tracer: refactor autogeneration script Deborah Brouwer
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

Put the trace file into valid JSON format by removing the trailing comma
from the trace file array.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/v4l2-tracer.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/utils/v4l2-tracer/v4l2-tracer.cpp b/utils/v4l2-tracer/v4l2-tracer.cpp
index ae6f68e4..7adbe04e 100644
--- a/utils/v4l2-tracer/v4l2-tracer.cpp
+++ b/utils/v4l2-tracer/v4l2-tracer.cpp
@@ -346,7 +346,7 @@ int tracer(int argc, char *argv[], bool retrace)
 
 	/* Close the json-array and the trace file. */
 	trace_file = fopen(trace_filename.c_str(), "a");
-	fseek(trace_file, 0L, SEEK_END);
+	ftruncate(fileno(trace_file), lseek(fileno(trace_file), 0, SEEK_END) - 2);
 	fputs("\n]\n", trace_file);
 	fclose(trace_file);
 
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] v4l2-tracer: refactor autogeneration script
  2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 1/5] v4l2-tracer: add signal handling Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace Deborah Brouwer
@ 2023-02-09  6:06 ` Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 4/5] v4l2-tracer: add exact matching for 'type' and 'field' Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 5/5] v4l2-tracer: add INPUT and OUTPUT ioctls Deborah Brouwer
  4 siblings, 0 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

Use a function to generate value and flag arrays which gets rid of some
duplicate code and makes it easier to specify when the array generation
should stop. Also optimize the code to return or continue as soon as
possible within a function or loop.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/v4l2-tracer-gen.pl | 190 ++++++++++++---------------
 1 file changed, 83 insertions(+), 107 deletions(-)

diff --git a/utils/v4l2-tracer/v4l2-tracer-gen.pl b/utils/v4l2-tracer/v4l2-tracer-gen.pl
index fe648182..86e6d9d7 100755
--- a/utils/v4l2-tracer/v4l2-tracer-gen.pl
+++ b/utils/v4l2-tracer/v4l2-tracer-gen.pl
@@ -85,6 +85,30 @@ sub enum_gen {
 	printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
 }
 
+sub val_def_gen {
+	my $last_val = shift;
+	my $sentinel = shift;
+	if (length $sentinel == 0) {
+		$sentinel = "-1"; # _flag_def arrays end with 0, _val_def arrays end in -1
+	}
+	($val) = ($_) =~ /^#define\s*(\w+)\s*/;
+	printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $val, $val;
+	while (<>) {
+		next if ($_ =~ /^\s*\/?\s?\*.*/); # skip comments
+		next if ($_ =~ /^\s*$/);  # skip blank lines
+		($val) = ($_) =~ /^#define\s*(\w+)\s*/;
+		next if ($val eq ""); # skip lines that don't start with define e.g. V4L2_STD_ATSC_16_VSB
+		printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $val, $val;
+		last if ($val eq $last_val);
+	}
+	printf $fh_common_info_h "\t{ $sentinel, \"\" }\n};\n\n";
+}
+
+sub flag_def_gen {
+	my $last_flag = shift;
+	val_def_gen($last_flag, 0);
+}
+
 sub clean_up_line {
 	my $line = shift;
 	chomp($line);
@@ -104,103 +128,97 @@ sub clean_up_line {
 }
 
 sub get_val_def_name {
-	my @params = @_;
-	my $member = @params[0];
-	my $struct_name = @params[1];
-
-	$val_def_name = "";
+	my $member = shift;
+	my $struct_name = shift;
 	if ($member =~ /type/) {
 		if ($struct_name =~ /.*fmt|format|buf|parm|crop|selection|vbi.*/) {
-			$val_def_name = "v4l2_buf_type_val_def";
+			return "v4l2_buf_type_val_def";
 		} elsif ($struct_name =~ /ctrl$/) {
-			$val_def_name = "v4l2_ctrl_type_val_def";
+			return "v4l2_ctrl_type_val_def";
 		} else {
-			$val_def_name = "nullptr"; # will print as hex string
+			return "nullptr"; # will print as hex string
 		}
 	}
 	if ($member =~ /pixelformat/) {
-		$val_def_name = "v4l2_pix_fmt_val_def";
+		return "v4l2_pix_fmt_val_def";
 	}
 	if ($member =~ /cmd/) {
 		if ($struct_name =~ /v4l2_decoder_cmd/) {
-			$val_def_name = "decoder_cmd_val_def";
+			return "decoder_cmd_val_def";
 		}
 		if ($struct_name =~ /v4l2_encoder_cmd/) {
-			$val_def_name = "encoder_cmd_val_def";
+			return "encoder_cmd_val_def";
 		}
 	}
 	if ($member =~ /memory/) {
-		$val_def_name = "v4l2_memory_val_def";
+		return "v4l2_memory_val_def";
 	}
 	if ($member =~ /field/) {
 		if ($struct_name =~ /.*pix|buffer.*/) {
-			$val_def_name = "v4l2_field_val_def";
+			return "v4l2_field_val_def";
 		} else {
-			$val_def_name = "nullptr"; # will print as hex string
+			return "nullptr"; # will print as hex string
 		}
 	}
 	if ($member =~ /^id$/) {
 		if ($struct_name =~ /.*control|query.*/) {
-			$val_def_name = "control_val_def";
-		} else {
-			$val_def_name = "nullptr"; # will print as hex string
+			return "control_val_def";
 		}
+		return "nullptr"; # will print as hex string
 	}
 	if ($member =~ /capability|outputmode|capturemode/) {
 		if ($struct_name =~ /.*v4l2_captureparm|v4l2_outputparm.*/) {
-		$val_def_name = "streamparm_val_def";
+		return "streamparm_val_def";
 		}
 	}
 	if ($member =~ /colorspace/) {
-		$val_def_name = "v4l2_colorspace_val_def";
+		return "v4l2_colorspace_val_def";
 	}
 	if ($member =~ /ycbcr_enc/) {
-		$val_def_name = "v4l2_ycbcr_encoding_val_def";
+		return "v4l2_ycbcr_encoding_val_def";
 	}
 	if ($member =~ /quantization/) {
-		$val_def_name = "v4l2_quantization_val_def";
+		return "v4l2_quantization_val_def";
 	}
 	if ($member =~ /xfer_func/) {
-		$val_def_name = "v4l2_xfer_func_val_def";
+		return "v4l2_xfer_func_val_def";
 	}
-
-	return $val_def_name;
+	return "";
 }
 
 sub get_flag_def_name {
-	my @params = @_;
-	my $member = @params[0];
-	my $struct_name = @params[1];
-
-	$flag_def_name = "";
+	my $member = shift;
+	my $struct_name = shift;
 	if ($member =~ /flags/) {
 		if ($struct_name =~ /buffers$/) {
-			$flag_def_name = "v4l2_memory_flag_def";
-		} elsif ($struct_name =~ /.*pix_format.*/) {
-			$flag_def_name = "v4l2_pix_fmt_flag_def";
-		} elsif ($struct_name =~ /.*ctrl$/) {
-			$flag_def_name = "v4l2_ctrl_flag_def";
-		} elsif ($struct_name =~ /.*fmtdesc$/) {
-			$flag_def_name = "v4l2_fmt_flag_def";
-		} elsif ($struct_name =~ /.*selection$/) {
-			$flag_def_name = "v4l2_sel_flag_def";
-		} else {
-			$flag_def_name = "nullptr"
+			return "v4l2_memory_flag_def";
+		}
+		if ($struct_name =~ /.*pix_format.*/) {
+			return "v4l2_pix_fmt_flag_def";
+		}
+		if ($struct_name =~ /.*ctrl$/) {
+			return "v4l2_ctrl_flag_def";
 		}
+		if ($struct_name =~ /.*fmtdesc$/) {
+			return "v4l2_fmt_flag_def";
+		}
+		if ($struct_name =~ /.*selection$/) {
+			return "v4l2_sel_flag_def";
+		}
+			return "nullptr";
 	}
 
 	if ($member =~ /.*cap.*/) {
 		# v4l2_requestbuffers, v4l2_create_buffers
 		if ($struct_name =~ /buffers$/) {
-			$flag_def_name = "v4l2_buf_cap_flag_def";
+			return "v4l2_buf_cap_flag_def";
 		}
 		# v4l2_capability
 		if ($struct_name =~ /capability$/) {
-			$flag_def_name = "v4l2_cap_flag_def";
+			return "v4l2_cap_flag_def";
 		}
 	}
-
-	return $flag_def_name;
+	return "";
 }
 
 # trace a struct nested in another struct in videodev2.h
@@ -760,82 +778,40 @@ while (<>) {
 		push (@controls, $_);
 	}
 
-	if (grep {/^\/\* Control classes \*\//} $_) {
+	if (grep {/^#define V4L2_CTRL_CLASS_USER\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def ctrlclass_val_def[] = {\n";
-		while (<>) {
-			last if $_ =~ /^\s*$/; # last if blank line
-			($ctrl_class) = ($_) =~ /#define\s*(\w+)\s+.*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $ctrl_class, $ctrl_class;
-		}
-		printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
+		val_def_gen("V4L2_CTRL_CLASS_COLORIMETRY");
+		next;
 	}
-
-	if (grep {/\/\* Values for 'capabilities' field \*\//} $_) {
+	if (grep {/^#define V4L2_CAP_VIDEO_CAPTURE/} $_) {
 		printf $fh_common_info_h "constexpr flag_def v4l2_cap_flag_def[] = {\n";
-		while (<>) {
-			last if $_ =~ /.*V I D E O   I M A G E   F O R M A T.*/;
-			next if ($_ =~ /^\/?\s?\*.*/); # skip comments
-			next if $_ =~ /^\s*$/; # skip blank lines
-			($cap) = ($_) =~ /#define\s+(\w+)\s+.+/;
-			printf $fh_common_info_h "\t{ $cap, \"$cap\" },\n"
-		}
-		printf $fh_common_info_h "\t{ 0, \"\" }\n};\n\n";
+		flag_def_gen("V4L2_CAP_DEVICE_CAPS");
+		next;
 	}
-
-	if (grep {/\*      Pixel format         FOURCC                          depth  Description  \*\//} $_) {
+	if (grep {/^#define V4L2_PIX_FMT_RGB332\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def v4l2_pix_fmt_val_def[] = {\n";
-		while (<>) {
-			last if $_ =~ /.*SDR formats - used only for Software Defined Radio devices.*/;
-			next if ($_ =~ /^\s*\/\*.*/); # skip comments
-			next if $_ =~ /^\s*$/; # skip blank lines
-			($pixfmt) = ($_) =~ /#define (\w+)\s+.*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $pixfmt, $pixfmt;
-		}
-		printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
+		val_def_gen("V4L2_PIX_FMT_IPU3_SRGGB10");
+		next;
 	}
-
-	if (grep {/^#define V4L2_BUF_CAP_SUPPORTS_MMAP.*/} $_) {
+	if (grep {/^#define V4L2_BUF_CAP_SUPPORTS_MMAP\s+/} $_) {
 		printf $fh_common_info_h "constexpr flag_def v4l2_buf_cap_flag_def[] = {\n";
-		($buf_cap) = ($_) =~ /#define (\w+)\s+.*/;
-		printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $buf_cap, $buf_cap;
-		while (<>) {
-			last if $_ =~ /^\s*$/; # blank line
-			($buf_cap) = ($_) =~ /#define (\w+)\s+.*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $buf_cap, $buf_cap;
-		}
-		printf $fh_common_info_h "\t{ 0, \"\" }\n};\n\n";
+		flag_def_gen("V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS");
+		next;
 	}
-
-	if (grep {/.*Flags for 'capability' and 'capturemode' fields.*/} $_) {
+	if (grep {/^#define V4L2_MODE_HIGHQUALITY\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def streamparm_val_def[] = {\n";
-		while (<>) {
-			last if $_ =~ /^\s*$/; # blank line
-			($streamparm) = ($_) =~ /^#define\s*(\w+)\s*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $streamparm, $streamparm;
-		}
-		printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
+		val_def_gen("V4L2_CAP_TIMEPERFRAME");
+		next;
 	}
-
-	if (grep {/.*V4L2_ENC_CMD_START.*/} $_) {
+	if (grep {/^#define V4L2_ENC_CMD_START\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def encoder_cmd_val_def[] = {\n";
-		($enc_cmd) = ($_) =~ /^#define\s*(\w+)\s*/;
-		printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $enc_cmd, $enc_cmd;
-		while (<>) {
-			last if $_ =~ /^\s*$/; # blank line
-			($enc_cmd) = ($_) =~ /^#define\s*(\w+)\s*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $enc_cmd, $enc_cmd;
-		}
-		printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
+		val_def_gen("V4L2_ENC_CMD_RESUME");
+		next;
 	}
-
-	if (grep {/.*Decoder commands.*/} $_) {
+	if (grep {/^#define V4L2_DEC_CMD_START\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def decoder_cmd_val_def[] = {\n";
-		while (<>) {
-			last if $_ =~ /^\s*$/; # blank line
-			($dec_cmd) = ($_) =~ /^#define\s*(\w+)\s*/;
-			printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $dec_cmd, $dec_cmd;
-		}
-		printf $fh_common_info_h "\t{ -1, \"\" }\n};\n\n";
+		val_def_gen("V4L2_DEC_CMD_FLUSH");
+		next;
 	}
 
 	if (grep {/^#define\s+(VIDIOC_\w*)\s*.*/} $_) {
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] v4l2-tracer: add exact matching for 'type' and 'field'
  2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
                   ` (2 preceding siblings ...)
  2023-02-09  6:06 ` [PATCH 3/5] v4l2-tracer: refactor autogeneration script Deborah Brouwer
@ 2023-02-09  6:06 ` Deborah Brouwer
  2023-02-09  6:06 ` [PATCH 5/5] v4l2-tracer: add INPUT and OUTPUT ioctls Deborah Brouwer
  4 siblings, 0 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

The autogeneration script was overly broad in converting to strings any
struct member whose name included the words 'type' or 'field.' Stop
converting members to strings when the name only partially matches e.g.
pic_order_cnt_type. Convert a member to a string only if the name matches
exactly 'type' or 'field.'

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/v4l2-tracer-gen.pl | 50 +++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 12 deletions(-)

diff --git a/utils/v4l2-tracer/v4l2-tracer-gen.pl b/utils/v4l2-tracer/v4l2-tracer-gen.pl
index 86e6d9d7..66d46f0c 100755
--- a/utils/v4l2-tracer/v4l2-tracer-gen.pl
+++ b/utils/v4l2-tracer/v4l2-tracer-gen.pl
@@ -130,14 +130,37 @@ sub clean_up_line {
 sub get_val_def_name {
 	my $member = shift;
 	my $struct_name = shift;
-	if ($member =~ /type/) {
-		if ($struct_name =~ /.*fmt|format|buf|parm|crop|selection|vbi.*/) {
-			return "v4l2_buf_type_val_def";
-		} elsif ($struct_name =~ /ctrl$/) {
-			return "v4l2_ctrl_type_val_def";
-		} else {
-			return "nullptr"; # will print as hex string
+	@structs_that_use_v4l2_buf_type = qw(v4l2_fmtdesc v4l2_requestbuffers v4l2_buffer v4l2_crop
+	                                     v4l2_exportbuffer v4l2_cropcap v4l2_selection
+	                                     v4l2_sliced_vbi_cap v4l2_format v4l2_streamparm);
+	@structs_that_use_v4l2_ctrl_type = qw(v4l2_queryctrl v4l2_query_ext_ctrl);
+	if ($member eq "type") {
+		foreach (@structs_that_use_v4l2_buf_type) {
+			if ($struct_name eq $_) {
+				return "v4l2_buf_type_val_def";
+			}
+		}
+		foreach (@structs_that_use_v4l2_tuner_type) {
+			if ($struct_name eq $_) {
+				return "v4l2_tuner_type_val_def";
+			}
+		}
+		foreach (@structs_that_use_v4l2_ctrl_type) {
+			if ($struct_name eq $_) {
+				return "v4l2_ctrl_type_val_def";
+			}
+		}
+		if ($struct_name eq "v4l2_frmsizeenum") {
+			return "v4l2_frmsizetypes_val_def";
 		}
+		if ($struct_name eq "v4l2_frmivalenum") {
+			return "v4l2_frmivaltypes_val_def";
+		}
+		return "nullptr"; # will print as hex string
+	}
+	# special treatment for struct v4l2_input which has members named both "tuner" and "type"
+	if (($member eq "tuner") && ($struct_name eq "v4l2_input")) {
+		return "v4l2_tuner_type_val_def";
 	}
 	if ($member =~ /pixelformat/) {
 		return "v4l2_pix_fmt_val_def";
@@ -153,12 +176,15 @@ sub get_val_def_name {
 	if ($member =~ /memory/) {
 		return "v4l2_memory_val_def";
 	}
-	if ($member =~ /field/) {
-		if ($struct_name =~ /.*pix|buffer.*/) {
-			return "v4l2_field_val_def";
-		} else {
-			return "nullptr"; # will print as hex string
+	@structs_that_use_v4l2_field = qw(v4l2_pix_format v4l2_buffer v4l2_framebuffer v4l2_window
+	                                  v4l2_pix_format_mplane v4l2_event_vsync);
+	if ($member eq "field") {
+		foreach (@structs_that_use_v4l2_field) {
+			if ($struct_name eq $_) {
+				return "v4l2_field_val_def";
+			}
 		}
+		return "nullptr"; # will print as hex string
 	}
 	if ($member =~ /^id$/) {
 		if ($struct_name =~ /.*control|query.*/) {
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] v4l2-tracer: add INPUT and OUTPUT ioctls
  2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
                   ` (3 preceding siblings ...)
  2023-02-09  6:06 ` [PATCH 4/5] v4l2-tracer: add exact matching for 'type' and 'field' Deborah Brouwer
@ 2023-02-09  6:06 ` Deborah Brouwer
  4 siblings, 0 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-09  6:06 UTC (permalink / raw)
  To: linux-media; +Cc: Deborah Brouwer

Add tracing and retracing for: VIDIOC_ENUMINPUT, VIDIOC_ENUMOUTPUT,
VIDIOC_G_INPUT, VIDIOC_S_INPUT, VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/libv4l2tracer.cpp  |  6 ++
 utils/v4l2-tracer/retrace.cpp        | 84 ++++++++++++++++++++++++++++
 utils/v4l2-tracer/trace.cpp          | 18 ++++++
 utils/v4l2-tracer/v4l2-tracer-gen.pl | 39 +++++++++++++
 4 files changed, 147 insertions(+)

diff --git a/utils/v4l2-tracer/libv4l2tracer.cpp b/utils/v4l2-tracer/libv4l2tracer.cpp
index 6b438628..5d0817b2 100644
--- a/utils/v4l2-tracer/libv4l2tracer.cpp
+++ b/utils/v4l2-tracer/libv4l2tracer.cpp
@@ -24,9 +24,15 @@ const std::list<unsigned long> ioctls = {
 	VIDIOC_DQBUF,
 	VIDIOC_G_PARM,
 	VIDIOC_S_PARM,
+	VIDIOC_ENUMINPUT,
 	VIDIOC_G_CTRL,
 	VIDIOC_S_CTRL,
 	VIDIOC_QUERYCTRL,
+	VIDIOC_G_INPUT,
+	VIDIOC_S_INPUT,
+	VIDIOC_G_OUTPUT,
+	VIDIOC_S_OUTPUT,
+	VIDIOC_ENUMOUTPUT,
 	VIDIOC_G_CROP,
 	VIDIOC_S_CROP,
 	VIDIOC_TRY_FMT,
diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index 36a218d3..29ac4a38 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -614,6 +614,17 @@ void retrace_vidioc_queryctrl(int fd_retrace, json_object *ioctl_args)
 	free(ptr);
 }
 
+void retrace_vidioc_enuminput(int fd_retrace, json_object *ioctl_args)
+{
+	struct v4l2_input *ptr = retrace_v4l2_input_gen(ioctl_args);
+	ioctl(fd_retrace, VIDIOC_ENUMINPUT, ptr);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_ENUMINPUT");
+
+	free(ptr);
+}
+
 void retrace_vidioc_g_control(int fd_retrace, json_object *ioctl_args)
 {
 	struct v4l2_control *ptr = retrace_v4l2_control_gen(ioctl_args);
@@ -636,6 +647,61 @@ void retrace_vidioc_s_control(int fd_retrace, json_object *ioctl_args)
 	free(ptr);
 }
 
+void retrace_vidioc_g_input(int fd_retrace, json_object *ioctl_args)
+{
+	int input = 0;
+	ioctl(fd_retrace, VIDIOC_G_INPUT, &input);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_G_INPUT");
+}
+
+void retrace_vidioc_s_input(int fd_retrace, json_object *ioctl_args)
+{
+	int input = 0;
+	json_object *input_obj;
+	if (json_object_object_get_ex(ioctl_args, "input", &input_obj))
+		input = json_object_get_int(input_obj);
+
+	ioctl(fd_retrace, VIDIOC_S_INPUT, &input);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_S_INPUT");
+}
+
+void retrace_vidioc_g_output(int fd_retrace, json_object *ioctl_args)
+{
+	int output = 0;
+	ioctl(fd_retrace, VIDIOC_G_OUTPUT, &output);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_G_OUTPUT");
+}
+
+void retrace_vidioc_s_output(int fd_retrace, json_object *ioctl_args)
+{
+	int output = 0;
+	json_object *output_obj;
+	if (json_object_object_get_ex(ioctl_args, "output", &output_obj))
+		output = json_object_get_int(output_obj);
+
+	ioctl(fd_retrace, VIDIOC_S_OUTPUT, &output);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_S_OUTPUT");
+}
+
+void retrace_vidioc_enumoutput(int fd_retrace, json_object *ioctl_args)
+{
+	struct v4l2_output *ptr = retrace_v4l2_output_gen(ioctl_args);
+	ioctl(fd_retrace, VIDIOC_ENUMOUTPUT, ptr);
+
+	if (is_verbose() || (errno != 0))
+		perror("VIDIOC_ENUMOUTPUT");
+
+	free(ptr);
+}
+
 void retrace_vidioc_g_crop(int fd_retrace, json_object *ioctl_args)
 {
 	struct v4l2_crop *ptr = retrace_v4l2_crop_gen(ioctl_args);
@@ -1165,6 +1231,9 @@ void retrace_ioctl(json_object *syscall_obj)
 	case VIDIOC_S_PARM:
 		retrace_vidioc_s_parm(fd_retrace, ioctl_args_user);
 		break;
+	case VIDIOC_ENUMINPUT:
+		retrace_vidioc_enuminput(fd_retrace, ioctl_args_user);
+		break;
 	case VIDIOC_G_CTRL:
 		retrace_vidioc_g_control(fd_retrace, ioctl_args_user);
 		break;
@@ -1174,6 +1243,21 @@ void retrace_ioctl(json_object *syscall_obj)
 	case VIDIOC_QUERYCTRL:
 		retrace_vidioc_queryctrl(fd_retrace, ioctl_args_user);
 		break;
+	case VIDIOC_G_INPUT:
+		retrace_vidioc_g_input(fd_retrace, ioctl_args_user);
+		break;
+	case VIDIOC_S_INPUT:
+		retrace_vidioc_s_input(fd_retrace, ioctl_args_user);
+		break;
+	case VIDIOC_G_OUTPUT:
+		retrace_vidioc_g_output(fd_retrace, ioctl_args_user);
+		break;
+	case VIDIOC_S_OUTPUT:
+		retrace_vidioc_s_output(fd_retrace, ioctl_args_user);
+		break;
+	case VIDIOC_ENUMOUTPUT:
+		retrace_vidioc_enumoutput(fd_retrace, ioctl_args_user);
+		break;
 	case VIDIOC_G_CROP:
 		retrace_vidioc_g_crop(fd_retrace, ioctl_args_user);
 		break;
diff --git a/utils/v4l2-tracer/trace.cpp b/utils/v4l2-tracer/trace.cpp
index 4896751b..a393d0d4 100644
--- a/utils/v4l2-tracer/trace.cpp
+++ b/utils/v4l2-tracer/trace.cpp
@@ -556,6 +556,9 @@ json_object *trace_ioctl_args(unsigned long cmd, void *arg)
 	case VIDIOC_S_PARM:
 		trace_v4l2_streamparm(arg, ioctl_args);
 		break;
+	case VIDIOC_ENUMINPUT:
+		trace_v4l2_input_gen(arg, ioctl_args);
+		break;
 	case VIDIOC_G_CTRL:
 	case VIDIOC_S_CTRL:
 		trace_v4l2_control_gen(arg, ioctl_args);
@@ -563,6 +566,21 @@ json_object *trace_ioctl_args(unsigned long cmd, void *arg)
 	case VIDIOC_QUERYCTRL:
 		trace_v4l2_queryctrl_gen(arg, ioctl_args);
 		break;
+	case VIDIOC_G_INPUT:
+	case VIDIOC_S_INPUT: {
+		int *input = static_cast<int*>(arg);
+		json_object_object_add(ioctl_args, "input", json_object_new_int(*input));
+		break;
+	}
+	case VIDIOC_G_OUTPUT:
+	case VIDIOC_S_OUTPUT: {
+		int *output = static_cast<int*>(arg);
+		json_object_object_add(ioctl_args, "output", json_object_new_int(*output));
+		break;
+	}
+	case VIDIOC_ENUMOUTPUT:
+		trace_v4l2_output_gen(arg, ioctl_args);
+		break;
 	case VIDIOC_G_CROP:
 	case VIDIOC_S_CROP:
 		trace_v4l2_crop_gen(arg, ioctl_args);
diff --git a/utils/v4l2-tracer/v4l2-tracer-gen.pl b/utils/v4l2-tracer/v4l2-tracer-gen.pl
index 66d46f0c..7a47f116 100755
--- a/utils/v4l2-tracer/v4l2-tracer-gen.pl
+++ b/utils/v4l2-tracer/v4l2-tracer-gen.pl
@@ -156,6 +156,12 @@ sub get_val_def_name {
 		if ($struct_name eq "v4l2_frmivalenum") {
 			return "v4l2_frmivaltypes_val_def";
 		}
+		if ($struct_name eq "v4l2_input") {
+			return $val_def_name = "input_type_val_def";
+		}
+		if ($struct_name eq "v4l2_output") {
+			return $val_def_name = "output_type_val_def";
+		}
 		return "nullptr"; # will print as hex string
 	}
 	# special treatment for struct v4l2_input which has members named both "tuner" and "type"
@@ -209,6 +215,9 @@ sub get_val_def_name {
 	if ($member =~ /xfer_func/) {
 		return "v4l2_xfer_func_val_def";
 	}
+	if (($member eq "status") && ($struct_name eq "v4l2_input")) {
+		$val_def_name = "input_field_val_def";
+	}
 	return "";
 }
 
@@ -824,11 +833,41 @@ while (<>) {
 		flag_def_gen("V4L2_BUF_CAP_SUPPORTS_MMAP_CACHE_HINTS");
 		next;
 	}
+	if (grep {/^#define V4L2_STD_PAL_B\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def std_flag_def[] = {\n";
+		flag_def_gen("V4L2_STD_ALL");
+		next
+	}
 	if (grep {/^#define V4L2_MODE_HIGHQUALITY\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def streamparm_val_def[] = {\n";
 		val_def_gen("V4L2_CAP_TIMEPERFRAME");
 		next;
 	}
+	if (grep {/^#define V4L2_INPUT_TYPE_TUNER\s+/} $_) {
+		printf $fh_common_info_h "constexpr val_def input_type_val_def[] = {\n";
+		val_def_gen("V4L2_INPUT_TYPE_TOUCH");
+		next
+	}
+	if (grep {/^#define V4L2_IN_ST_NO_POWER\s+/} $_) {
+		printf $fh_common_info_h "constexpr val_def input_field_val_def[] = {\n";
+		val_def_gen("V4L2_IN_ST_VTR");
+		next
+	}
+	if (grep {/^#define V4L2_IN_CAP_DV_TIMINGS\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def input_cap_flag_def[] = {\n";
+		flag_def_gen("V4L2_IN_CAP_NATIVE_SIZE");
+		next
+	}
+	if (grep {/^#define V4L2_OUTPUT_TYPE_MODULATOR\s+/} $_) {
+		printf $fh_common_info_h "constexpr val_def output_type_val_def[] = {\n";
+		val_def_gen("V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY");
+		next
+	}
+	if (grep {/^#define V4L2_OUT_CAP_DV_TIMINGS\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def output_cap_flag_def[] = {\n";
+		flag_def_gen("V4L2_OUT_CAP_NATIVE_SIZE");
+		next
+	}
 	if (grep {/^#define V4L2_ENC_CMD_START\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def encoder_cmd_val_def[] = {\n";
 		val_def_gen("V4L2_ENC_CMD_RESUME");
-- 
2.39.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace
  2023-02-09  6:06 ` [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace Deborah Brouwer
@ 2023-02-22 19:26   ` Hans Verkuil
  2023-02-22 20:43     ` Deborah Brouwer
  0 siblings, 1 reply; 8+ messages in thread
From: Hans Verkuil @ 2023-02-22 19:26 UTC (permalink / raw)
  To: Deborah Brouwer, linux-media

On 09/02/2023 07:06, Deborah Brouwer wrote:
> Put the trace file into valid JSON format by removing the trailing comma
> from the trace file array.
> 
> Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
> ---
>  utils/v4l2-tracer/v4l2-tracer.cpp | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/utils/v4l2-tracer/v4l2-tracer.cpp b/utils/v4l2-tracer/v4l2-tracer.cpp
> index ae6f68e4..7adbe04e 100644
> --- a/utils/v4l2-tracer/v4l2-tracer.cpp
> +++ b/utils/v4l2-tracer/v4l2-tracer.cpp
> @@ -346,7 +346,7 @@ int tracer(int argc, char *argv[], bool retrace)
>  
>  	/* Close the json-array and the trace file. */
>  	trace_file = fopen(trace_filename.c_str(), "a");
> -	fseek(trace_file, 0L, SEEK_END);
> +	ftruncate(fileno(trace_file), lseek(fileno(trace_file), 0, SEEK_END) - 2);
>  	fputs("\n]\n", trace_file);

ftruncate seems overkill to me. Wouldn't it be enough to just do

fseek(trace_file, -2, SEEK_END);

since the fputs afterwards will overwrite those last two characters anyway?

(I think it is -2 for SEEK_END, I'm not 100% certain though, it could be 2)

Regards,

	Hans

>  	fclose(trace_file);
>  


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace
  2023-02-22 19:26   ` Hans Verkuil
@ 2023-02-22 20:43     ` Deborah Brouwer
  0 siblings, 0 replies; 8+ messages in thread
From: Deborah Brouwer @ 2023-02-22 20:43 UTC (permalink / raw)
  To: Hans Verkuil; +Cc: linux-media

On Wed, Feb 22, 2023 at 08:26:33PM +0100, Hans Verkuil wrote:
> On 09/02/2023 07:06, Deborah Brouwer wrote:
> > Put the trace file into valid JSON format by removing the trailing comma
> > from the trace file array.
> > 
> > Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
> > ---
> >  utils/v4l2-tracer/v4l2-tracer.cpp | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/utils/v4l2-tracer/v4l2-tracer.cpp b/utils/v4l2-tracer/v4l2-tracer.cpp
> > index ae6f68e4..7adbe04e 100644
> > --- a/utils/v4l2-tracer/v4l2-tracer.cpp
> > +++ b/utils/v4l2-tracer/v4l2-tracer.cpp
> > @@ -346,7 +346,7 @@ int tracer(int argc, char *argv[], bool retrace)
> >  
> >  	/* Close the json-array and the trace file. */
> >  	trace_file = fopen(trace_filename.c_str(), "a");
> > -	fseek(trace_file, 0L, SEEK_END);
> > +	ftruncate(fileno(trace_file), lseek(fileno(trace_file), 0, SEEK_END) - 2);
> >  	fputs("\n]\n", trace_file);
> 
> ftruncate seems overkill to me. Wouldn't it be enough to just do
> 
> fseek(trace_file, -2, SEEK_END);
> 
> since the fputs afterwards will overwrite those last two characters anyway?
> 
> (I think it is -2 for SEEK_END, I'm not 100% certain though, it could be 2)

It took me a while to remember why I didn't use this simpler method,
but it's because the trace file is opened in append mode "a" in
write_json_object_to_json_file() and so fputs() stubbornly ignores the
file position indicator set by fseek.

> 
> Regards,
> 
> 	Hans
> 
> >  	fclose(trace_file);
> >  
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2023-02-22 20:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-09  6:06 [PATCH 0/5] v4l2-tracer: misc fixes Deborah Brouwer
2023-02-09  6:06 ` [PATCH 1/5] v4l2-tracer: add signal handling Deborah Brouwer
2023-02-09  6:06 ` [PATCH 2/5] v4l2-tracer: remove trailing comma from JSON trace Deborah Brouwer
2023-02-22 19:26   ` Hans Verkuil
2023-02-22 20:43     ` Deborah Brouwer
2023-02-09  6:06 ` [PATCH 3/5] v4l2-tracer: refactor autogeneration script Deborah Brouwer
2023-02-09  6:06 ` [PATCH 4/5] v4l2-tracer: add exact matching for 'type' and 'field' Deborah Brouwer
2023-02-09  6:06 ` [PATCH 5/5] v4l2-tracer: add INPUT and OUTPUT ioctls Deborah Brouwer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).