linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] v4l2-tracer: expand to stateful decoding
@ 2023-11-13 20:06 Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 1/8] v4l2-info/v4l2-tracer: add macro to mark the trace Deborah Brouwer
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

Fixes and improvements aimed at expanding the scope of the v4l2-tracer
to stateful decoding without causing regressions for stateless decoding.

Deborah Brouwer (8):
  v4l2-info/v4l2-tracer: add macro to mark the trace
  v4l2-tracer: replace buftype2s with val2s
  v4l2-tracer: remove buffers by type and index
  v4l2-tracer: remove compress_frame_count
  v4l2-tracer: get decoded bytesused from DQBUF
  v4l2-tracer: create an option to trace userspace args
  v4l2-tracer: stop retracing failed ioctls
  v4l2-tracer: auto generate flags for DECODER_CMD

 utils/common/v4l2-info.h                 |   7 +
 utils/v4l2-tracer/libv4l2tracer.cpp      |  33 ++++-
 utils/v4l2-tracer/retrace-helper.cpp     |   4 +-
 utils/v4l2-tracer/retrace.cpp            | 168 +++++++++++------------
 utils/v4l2-tracer/retrace.h              |   2 +-
 utils/v4l2-tracer/trace-helper.cpp       |  62 +++++----
 utils/v4l2-tracer/trace.cpp              |  20 +--
 utils/v4l2-tracer/trace.h                |   2 +-
 utils/v4l2-tracer/v4l2-tracer-common.cpp |   1 +
 utils/v4l2-tracer/v4l2-tracer-gen.pl     |  21 +++
 utils/v4l2-tracer/v4l2-tracer.cpp        |   6 +
 11 files changed, 198 insertions(+), 128 deletions(-)

-- 
2.41.0


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

* [PATCH 1/8] v4l2-info/v4l2-tracer: add macro to mark the trace
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 2/8] v4l2-tracer: replace buftype2s with val2s Deborah Brouwer
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

Add a macro to write to /dev/null. A v4l-utils application that is being
traced can call this macro to inject a comment into the JSON trace file.
It is helpful for debugging.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/common/v4l2-info.h            |  7 +++++++
 utils/v4l2-tracer/libv4l2tracer.cpp | 22 ++++++++++++++++++++++
 utils/v4l2-tracer/retrace.cpp       |  3 +++
 3 files changed, 32 insertions(+)

diff --git a/utils/common/v4l2-info.h b/utils/common/v4l2-info.h
index 6de5654c..2142952a 100644
--- a/utils/common/v4l2-info.h
+++ b/utils/common/v4l2-info.h
@@ -11,6 +11,13 @@
 #include <linux/videodev2.h>
 #include <linux/v4l2-subdev.h>
 
+#define v4l2_tracer_info(fmt, args...)					\
+	do {								\
+		char msg[256];						\
+		snprintf(msg, sizeof(msg), "v4l2-tracer: " fmt, ##args);\
+		write(open("/dev/null", O_WRONLY), msg, strlen(msg));	\
+	} while (0)
+
 /*
  * The max value comes from a check in the kernel source code
  * drivers/media/v4l2-core/v4l2-ioctl.c check_array_args()
diff --git a/utils/v4l2-tracer/libv4l2tracer.cpp b/utils/v4l2-tracer/libv4l2tracer.cpp
index 7286f321..c6a74afb 100644
--- a/utils/v4l2-tracer/libv4l2tracer.cpp
+++ b/utils/v4l2-tracer/libv4l2tracer.cpp
@@ -88,6 +88,28 @@ int open(const char *path, int oflag, ...)
 	return fd;
 }
 
+ssize_t write(int fd, const void *buf, size_t count)
+{
+	ssize_t (*original_write)(int fd, const void *buf, size_t count) = nullptr;
+	original_write = (ssize_t (*)(int, const void *, size_t)) dlsym(RTLD_NEXT, "write");
+	ssize_t ret = (*original_write)(fd, buf, count);
+
+	/*
+	 * If the write message starts with "v4l2-tracer", then assume it came from the
+	 * v4l2_tracer_info macro and trace it.
+	 */
+	std::string buf_string(static_cast<const char*>(buf), count);
+	if (buf_string.find("v4l2-tracer") == 0) {
+
+		json_object *write_obj = json_object_new_object();
+		json_object_object_add(write_obj, "write", json_object_new_string((const char*)buf));
+		write_json_object_to_json_file(write_obj);
+		json_object_put(write_obj);
+	}
+
+	return ret;
+}
+
 #if defined(linux) && defined(__GLIBC__)
 int open64(const char *path, int oflag, ...)
 {
diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index 88e70ea9..14c42568 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -1507,6 +1507,9 @@ void retrace_object(json_object *jobj)
 	if (json_object_object_get_ex(jobj, "Trace", &temp_obj)) {
 		return;
 	}
+	if (json_object_object_get_ex(jobj, "write", &temp_obj)) {
+		return;
+	}
 	line_info("\n\tWarning: unexpected JSON object in trace file.");
 }
 
-- 
2.41.0


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

* [PATCH 2/8] v4l2-tracer: replace buftype2s with val2s
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 1/8] v4l2-info/v4l2-tracer: add macro to mark the trace Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 3/8] v4l2-tracer: remove buffers by type and index Deborah Brouwer
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

While buftype2s gives a written description of the buffer type, val2s will
reproduce the type exactly as it appears in videodev2.h which is easier to
follow for tracing.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/retrace.cpp      | 19 ++++++++++++-------
 utils/v4l2-tracer/trace-helper.cpp |  6 +++---
 utils/v4l2-tracer/trace.cpp        |  4 ++--
 3 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index 14c42568..1bec635d 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -336,7 +336,8 @@ void retrace_vidioc_querybuf(int fd_retrace, json_object *ioctl_args_user)
 
 	if (is_verbose() || (errno != 0)) {
 		fprintf(stderr, "%s, index: %d, fd: %d, ",
-		        buftype2s((int) buf->type).c_str(), buf->index, fd_retrace);
+			val2s(buf->type, v4l2_buf_type_val_def).c_str(),
+			buf->index, fd_retrace);
 		perror("VIDIOC_QUERYBUF");
 		debug_line_info();
 		print_context();
@@ -360,7 +361,8 @@ void retrace_vidioc_qbuf(int fd_retrace, json_object *ioctl_args_user)
 
 	if (is_verbose() || (errno != 0)) {
 		fprintf(stderr, "%s, index: %d, fd: %d, ",
-		        buftype2s((int) ptr->type).c_str(), ptr->index, fd_retrace);
+		        val2s(ptr->type, v4l2_buf_type_val_def).c_str(),
+		        ptr->index, fd_retrace);
 		perror("VIDIOC_QBUF");
 		debug_line_info();
 		print_context();
@@ -395,7 +397,8 @@ void retrace_vidioc_dqbuf(int fd_retrace, json_object *ioctl_args_user)
 
 	if (is_verbose() || (errno != 0)) {
 		fprintf(stderr, "%s, index: %d, fd: %d, ",
-		        buftype2s((int) buf->type).c_str(), buf->index, fd_retrace);
+		        val2s(buf->type, v4l2_buf_type_val_def).c_str(),
+		        buf->index, fd_retrace);
 		perror("VIDIOC_DQBUF");
 		debug_line_info();
 		print_context();
@@ -416,7 +419,8 @@ void retrace_vidioc_prepare_buf(int fd_retrace, json_object *ioctl_args_user)
 
 	if (is_verbose() || (errno != 0)) {
 		fprintf(stderr, "%s, index: %d, fd: %d, ",
-		        buftype2s((int) buf->type).c_str(), buf->index, fd_retrace);
+		        val2s(buf->type, v4l2_buf_type_val_def).c_str(),
+		        buf->index, fd_retrace);
 		perror("VIDIOC_PREPARE_BUF");
 		debug_line_info();
 		print_context();
@@ -482,7 +486,7 @@ void retrace_vidioc_streamon(int fd_retrace, json_object *ioctl_args)
 	ioctl(fd_retrace, VIDIOC_STREAMON, &buf_type);
 
 	if (is_verbose() || (errno != 0)) {
-		fprintf(stderr, "%s, ", buftype2s(buf_type).c_str());
+		fprintf(stderr, "%s, ", val2s(buf_type, v4l2_buf_type_val_def).c_str());
 		perror("VIDIOC_STREAMON");
 	}
 }
@@ -497,7 +501,7 @@ void retrace_vidioc_streamoff(int fd_retrace, json_object *ioctl_args)
 	ioctl(fd_retrace, VIDIOC_STREAMOFF, &buf_type);
 
 	if (is_verbose() || (errno != 0)) {
-		fprintf(stderr, "%s, ", buftype2s(buf_type).c_str());
+		fprintf(stderr, "%s, ", val2s(buf_type, v4l2_buf_type_val_def).c_str());
 		perror("VIDIOC_STREAMOFF");
 	}
 }
@@ -1451,7 +1455,8 @@ void retrace_mem(json_object *mem_obj)
 		write_to_output_buffer(buffer_pointer, bytesused, mem_obj);
 
 	debug_line_info("\n\t%s, bytesused: %d, offset: %d, addr: %ld",
-	                buftype2s(type).c_str(), bytesused, offset, buffer_address_retrace);
+			val2s(type, v4l2_buf_type_val_def).c_str(),
+			bytesused, offset, buffer_address_retrace);
 	print_context();
 }
 
diff --git a/utils/v4l2-tracer/trace-helper.cpp b/utils/v4l2-tracer/trace-helper.cpp
index e5094b67..a1e83a44 100644
--- a/utils/v4l2-tracer/trace-helper.cpp
+++ b/utils/v4l2-tracer/trace-helper.cpp
@@ -228,7 +228,7 @@ void print_buffers_trace(void)
 		return;
 	for (auto &b : ctx_trace.buffers) {
 		fprintf(stderr, "fd: %d, %s, index: %d, display_order: %ld, bytesused: %d, ",
-		        b.fd, buftype2s(b.type).c_str(), b.index, b.display_order, b.bytesused);
+		        b.fd, val2s(b.type, v4l2_buf_type_val_def).c_str(), b.index, b.display_order, b.bytesused);
 		fprintf(stderr, "address: %lu, offset: %u \n",  b.address, b.offset);
 	}
 }
@@ -320,7 +320,7 @@ void s_ext_ctrls_setup(struct v4l2_ext_controls *ext_controls)
 
 void qbuf_setup(struct v4l2_buffer *buf)
 {
-	debug_line_info("\n\t%s, index: %d", buftype2s((int) buf->type).c_str(), buf->index);
+	debug_line_info("\n\t%s, index: %d", val2s(buf->type, v4l2_buf_type_val_def).c_str(), buf->index);
 
 	int buf_fd = get_buffer_fd_trace(buf->type, buf->index);
 	__u32 buf_offset = get_buffer_offset_trace(buf->type, buf->index);
@@ -361,7 +361,7 @@ void streamoff_cleanup(v4l2_buf_type buf_type)
 {
 	debug_line_info();
 	if (is_verbose() || (getenv("V4L2_TRACER_OPTION_WRITE_DECODED_TO_YUV_FILE") != nullptr)) {
-		fprintf(stderr, "VIDIOC_STREAMOFF: %s\n", buftype2s(buf_type).c_str());
+		fprintf(stderr, "VIDIOC_STREAMOFF: %s\n", val2s(buf_type, v4l2_buf_type_val_def).c_str());
 		fprintf(stderr, "%s, %s %s, width: %d, height: %d\n",
 		        val2s(ctx_trace.compression_format, v4l2_pix_fmt_val_def).c_str(),
 		        val2s(ctx_trace.pixelformat, v4l2_pix_fmt_val_def).c_str(),
diff --git a/utils/v4l2-tracer/trace.cpp b/utils/v4l2-tracer/trace.cpp
index 0e8531ff..f81f68d1 100644
--- a/utils/v4l2-tracer/trace.cpp
+++ b/utils/v4l2-tracer/trace.cpp
@@ -181,8 +181,8 @@ void trace_mem_decoded(void)
 			 */
 			if (it->bytesused < expected_length)
 				break;
-			debug_line_info("\n\tDisplaying: %ld, %s, index: %d",
-			                it->display_order, buftype2s(it->type).c_str(), it->index);
+			debug_line_info("\n\tDisplaying: %ld, %s, index: %d", it->display_order,
+					val2s(it->type, v4l2_buf_type_val_def).c_str(), it->index);
 			displayed_count++;
 
 			if (getenv("V4L2_TRACER_OPTION_WRITE_DECODED_TO_YUV_FILE") != nullptr) {
-- 
2.41.0


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

* [PATCH 3/8] v4l2-tracer: remove buffers by type and index
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 1/8] v4l2-info/v4l2-tracer: add macro to mark the trace Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 2/8] v4l2-tracer: replace buftype2s with val2s Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 4/8] v4l2-tracer: remove compress_frame_count Deborah Brouwer
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

Currently duplicate buffers are identified for removal by file descriptor,
but if the buffers were added by QUERYBUF then they will all have the same
file descriptor and the wrong buffer might be removed. So, instead,
identify duplicate buffers for removal by type and index.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/retrace-helper.cpp | 4 ++--
 utils/v4l2-tracer/retrace.cpp        | 2 +-
 utils/v4l2-tracer/retrace.h          | 2 +-
 utils/v4l2-tracer/trace-helper.cpp   | 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/utils/v4l2-tracer/retrace-helper.cpp b/utils/v4l2-tracer/retrace-helper.cpp
index 3c68986f..db24c667 100644
--- a/utils/v4l2-tracer/retrace-helper.cpp
+++ b/utils/v4l2-tracer/retrace-helper.cpp
@@ -41,10 +41,10 @@ void add_buffer_retrace(int fd, __u32 type, __u32 index, __u32 offset)
 	ctx_retrace.buffers.push_front(buf);
 }
 
-void remove_buffer_retrace(int fd)
+void remove_buffer_retrace(__u32 type, __u32 index)
 {
 	for (auto it = ctx_retrace.buffers.begin(); it != ctx_retrace.buffers.end(); ++it) {
-		if (it->fd == fd) {
+		if ((it->type == type) && (it->index == index)) {
 			ctx_retrace.buffers.erase(it);
 			break;
 		}
diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index 1bec635d..b2b4afbf 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -460,7 +460,7 @@ void retrace_vidioc_expbuf(int fd_retrace, json_object *ioctl_args_user, json_ob
 	 */
 	int fd_found_in_retrace_context = get_buffer_fd_retrace(ptr->type, ptr->index);
 	if (fd_found_in_retrace_context != -1)
-		remove_buffer_retrace(fd_found_in_retrace_context);
+		remove_buffer_retrace(ptr->type, ptr->index);
 
 	add_buffer_retrace(buf_fd_retrace, ptr->type, ptr->index);
 
diff --git a/utils/v4l2-tracer/retrace.h b/utils/v4l2-tracer/retrace.h
index 01157336..87a0417e 100644
--- a/utils/v4l2-tracer/retrace.h
+++ b/utils/v4l2-tracer/retrace.h
@@ -30,7 +30,7 @@ int retrace(std::string trace_filename);
 bool buffer_in_retrace_context(int fd, __u32 offset = 0);
 int get_buffer_fd_retrace(__u32 type, __u32 index);
 void add_buffer_retrace(int fd, __u32 type, __u32 index, __u32 offset = 0);
-void remove_buffer_retrace(int fd);
+void remove_buffer_retrace(__u32 type, __u32 index);
 void set_buffer_address_retrace(int fd, __u32 offset, long address_trace, long address_retrace);
 long get_retrace_address_from_trace_address(long address_trace);
 void add_fd(int fd_trace, int fd_retrace);
diff --git a/utils/v4l2-tracer/trace-helper.cpp b/utils/v4l2-tracer/trace-helper.cpp
index a1e83a44..b6336313 100644
--- a/utils/v4l2-tracer/trace-helper.cpp
+++ b/utils/v4l2-tracer/trace-helper.cpp
@@ -85,10 +85,10 @@ void add_buffer_trace(int fd, __u32 type, __u32 index, __u32 offset = 0)
 	ctx_trace.buffers.push_front(buf);
 }
 
-void remove_buffer_trace(int fd)
+void remove_buffer_trace(__u32 type, __u32 index)
 {
 	for (auto it = ctx_trace.buffers.begin(); it != ctx_trace.buffers.end(); ++it) {
-		if (it->fd == fd) {
+		if ((it->type == type) && (it->index == index)) {
 			ctx_trace.buffers.erase(it);
 			break;
 		}
@@ -420,7 +420,7 @@ void expbuf_setup(struct v4l2_exportbuffer *export_buffer)
 	 * file descriptor, replace the video fd with the more specific buffer fd from EXPBUF.
 	 */
 	if (fd_found_in_trace_context != 0)
-		remove_buffer_trace(fd_found_in_trace_context);
+		remove_buffer_trace(type, index);
 
 	add_buffer_trace(export_buffer->fd, type, index);
 }
-- 
2.41.0


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

* [PATCH 4/8] v4l2-tracer: remove compress_frame_count
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
                   ` (2 preceding siblings ...)
  2023-11-13 20:06 ` [PATCH 3/8] v4l2-tracer: remove buffers by type and index Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 5/8] v4l2-tracer: get decoded bytesused from DQBUF Deborah Brouwer
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

The trace context attempts to keep track of the number of compressed
frames received to avoid tracing the same decoded frame more than once.
However, this shared context only works if both the OUTPUT and CAPTURE
queues are run in the same process. If they are run in different
processes, then they will each have their own separate context and no
decoded frames will be traced.

Remove the compressed_frame_count since it is not functioning as expected.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/trace-helper.cpp | 23 ++++++++++-------------
 utils/v4l2-tracer/trace.cpp        |  1 -
 utils/v4l2-tracer/trace.h          |  1 -
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/utils/v4l2-tracer/trace-helper.cpp b/utils/v4l2-tracer/trace-helper.cpp
index b6336313..f58671df 100644
--- a/utils/v4l2-tracer/trace-helper.cpp
+++ b/utils/v4l2-tracer/trace-helper.cpp
@@ -288,10 +288,8 @@ void s_ext_ctrls_setup(struct v4l2_ext_controls *ext_controls)
 			 * received to avoid losing frames although this will still sometimes result
 			 * in frames out of order.
 			 */
-			if ((ctrl.p_h264_decode_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) != 0U) {
-				if (ctx_trace.compressed_frame_count != 0)
-					trace_mem_decoded();
-			}
+			if ((ctrl.p_h264_decode_params->flags & V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC) != 0U)
+				trace_mem_decoded();
 
 			/*
 			 * When pic_order_cnt_lsb wraps around to zero, adjust the total count using
@@ -337,15 +335,16 @@ void qbuf_setup(struct v4l2_buffer *buf)
 	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
 	    buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
 		trace_mem_encoded(buf_fd, buf_offset);
-		ctx_trace.compressed_frame_count = ctx_trace.compressed_frame_count + 1;
 	}
 
 	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
 	    buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-
-		/* If the capture buffer is queued for reuse, trace it before it is reused. */
-		if (ctx_trace.compressed_frame_count != 0)
-			trace_mem_decoded();
+		/*
+		 * If the capture buffer is queued for reuse, trace it before it is reused.
+		 * Capture buffers can't be traced using dqbuf because the buffer is mmapped
+		 * after the call to dqbuf.
+		 */
+		trace_mem_decoded();
 
 		/* H264 sets display order in controls, otherwise display just in the order queued. */
 		if (ctx_trace.compression_format != V4L2_PIX_FMT_H264_SLICE)
@@ -373,10 +372,8 @@ void streamoff_cleanup(v4l2_buf_type buf_type)
 	 * because they were not queued for reuse.
 	 */
 	if (buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
-	    buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		if (ctx_trace.compressed_frame_count != 0)
-			trace_mem_decoded();
-	}
+	    buf_type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		trace_mem_decoded();
 }
 
 void g_fmt_setup_trace(struct v4l2_format *format)
diff --git a/utils/v4l2-tracer/trace.cpp b/utils/v4l2-tracer/trace.cpp
index f81f68d1..31447f24 100644
--- a/utils/v4l2-tracer/trace.cpp
+++ b/utils/v4l2-tracer/trace.cpp
@@ -204,7 +204,6 @@ void trace_mem_decoded(void)
 		if (!it->address || it == ctx_trace.buffers.end() || it->bytesused < expected_length)
 			break;
 	}
-	ctx_trace.compressed_frame_count = ctx_trace.compressed_frame_count - displayed_count;
 }
 
 json_object *trace_v4l2_plane(struct v4l2_plane *ptr, __u32 memory)
diff --git a/utils/v4l2-tracer/trace.h b/utils/v4l2-tracer/trace.h
index 1e8b17e7..272f6c3c 100644
--- a/utils/v4l2-tracer/trace.h
+++ b/utils/v4l2-tracer/trace.h
@@ -36,7 +36,6 @@ struct trace_context {
 		struct h264_info h264;
 	} fmt;
 	std::string trace_filename;
-	int compressed_frame_count;
 	std::list<long> decode_order;
 	std::list<struct buffer_trace> buffers;
 	std::unordered_map<int, std::string> devices; /* key:fd, value: path of the device */
-- 
2.41.0


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

* [PATCH 5/8] v4l2-tracer: get decoded bytesused from DQBUF
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
                   ` (3 preceding siblings ...)
  2023-11-13 20:06 ` [PATCH 4/8] v4l2-tracer: remove compress_frame_count Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 6/8] v4l2-tracer: create an option to trace userspace args Deborah Brouwer
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

To write the decoded video data to a file, the tracer gets the bytesused
from userspace arguments when the capture buffers are queued for reuse.
But this only works by accident because the values in the buffers
haven’t been cleared for reuse. Instead get the bytesused from the
driver arguments when the capture buffer is dequeued.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/libv4l2tracer.cpp |  2 ++
 utils/v4l2-tracer/trace-helper.cpp  | 27 +++++++++++++++++++++++----
 utils/v4l2-tracer/trace.h           |  1 +
 3 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/utils/v4l2-tracer/libv4l2tracer.cpp b/utils/v4l2-tracer/libv4l2tracer.cpp
index c6a74afb..7618f554 100644
--- a/utils/v4l2-tracer/libv4l2tracer.cpp
+++ b/utils/v4l2-tracer/libv4l2tracer.cpp
@@ -309,6 +309,8 @@ int ioctl(int fd, unsigned long cmd, ...)
 		expbuf_setup(static_cast<struct v4l2_exportbuffer*>(arg));
 	if (cmd == VIDIOC_QUERYBUF)
 		querybuf_setup(fd, static_cast<struct v4l2_buffer*>(arg));
+	if (cmd == VIDIOC_DQBUF)
+		dqbuf_setup(static_cast<struct v4l2_buffer*>(arg));
 
 	/* Get info needed for tracing dynamic arrays */
 	if (cmd == VIDIOC_QUERY_EXT_CTRL)
diff --git a/utils/v4l2-tracer/trace-helper.cpp b/utils/v4l2-tracer/trace-helper.cpp
index f58671df..3eee20c2 100644
--- a/utils/v4l2-tracer/trace-helper.cpp
+++ b/utils/v4l2-tracer/trace-helper.cpp
@@ -324,12 +324,13 @@ void qbuf_setup(struct v4l2_buffer *buf)
 	__u32 buf_offset = get_buffer_offset_trace(buf->type, buf->index);
 
 	__u32 bytesused = 0;
-	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
-	    buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
 		bytesused = buf->m.planes[0].bytesused;
-	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT || buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+	else if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
 		bytesused = buf->bytesused;
-	set_buffer_bytesused_trace(buf_fd, buf_offset, bytesused);
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
+	    buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
+		set_buffer_bytesused_trace(buf_fd, buf_offset, bytesused);
 
 	/* The output buffer should have compressed data just before it is queued, so trace it. */
 	if (buf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
@@ -356,6 +357,24 @@ void qbuf_setup(struct v4l2_buffer *buf)
 	}
 }
 
+void dqbuf_setup(struct v4l2_buffer *buf)
+{
+	debug_line_info("\n\t%s, index: %d", val2s(buf->type, v4l2_buf_type_val_def).c_str(), buf->index);
+
+	int buf_fd = get_buffer_fd_trace(buf->type, buf->index);
+	__u32 buf_offset = get_buffer_offset_trace(buf->type, buf->index);
+
+	__u32 bytesused = 0;
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
+		bytesused = buf->m.planes[0].bytesused;
+	else if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		bytesused = buf->bytesused;
+
+	if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
+	    buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+		set_buffer_bytesused_trace(buf_fd, buf_offset, bytesused);
+}
+
 void streamoff_cleanup(v4l2_buf_type buf_type)
 {
 	debug_line_info();
diff --git a/utils/v4l2-tracer/trace.h b/utils/v4l2-tracer/trace.h
index 272f6c3c..a74a5f3f 100644
--- a/utils/v4l2-tracer/trace.h
+++ b/utils/v4l2-tracer/trace.h
@@ -62,6 +62,7 @@ bool buffer_is_mapped(unsigned long buffer_address);
 unsigned get_expected_length_trace(void);
 void s_ext_ctrls_setup(struct v4l2_ext_controls *ext_controls);
 void qbuf_setup(struct v4l2_buffer *buf);
+void dqbuf_setup(struct v4l2_buffer *buf);
 void streamoff_cleanup(v4l2_buf_type buf_type);
 void g_fmt_setup_trace(struct v4l2_format *format);
 void s_fmt_setup(struct v4l2_format *format);
-- 
2.41.0


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

* [PATCH 6/8] v4l2-tracer: create an option to trace userspace args
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
                   ` (4 preceding siblings ...)
  2023-11-13 20:06 ` [PATCH 5/8] v4l2-tracer: get decoded bytesused from DQBUF Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 7/8] v4l2-tracer: stop retracing failed ioctls Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 8/8] v4l2-tracer: auto generate flags for DECODER_CMD Deborah Brouwer
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

Currently all userspace arguments are traced and used in retracing. But
this add unnecessary duplication to the trace file since the driver
arguments are also traced. Stop tracing userspace arguments unless they
are necessary for retracing, but add an option to include all userspace
arguments.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/libv4l2tracer.cpp      |   9 +-
 utils/v4l2-tracer/retrace.cpp            | 123 +++++++++++------------
 utils/v4l2-tracer/v4l2-tracer-common.cpp |   1 +
 utils/v4l2-tracer/v4l2-tracer.cpp        |   6 ++
 4 files changed, 75 insertions(+), 64 deletions(-)

diff --git a/utils/v4l2-tracer/libv4l2tracer.cpp b/utils/v4l2-tracer/libv4l2tracer.cpp
index 7618f554..7335ee6b 100644
--- a/utils/v4l2-tracer/libv4l2tracer.cpp
+++ b/utils/v4l2-tracer/libv4l2tracer.cpp
@@ -271,8 +271,13 @@ int ioctl(int fd, unsigned long cmd, ...)
 	if (cmd == VIDIOC_STREAMOFF)
 		streamoff_cleanup(*(static_cast<v4l2_buf_type*>(arg)));
 
-	/* Trace userspace arguments if driver will be reading them i.e. _IOW or _IOWR ioctls */
-	if ((cmd & IOC_IN) != 0U) {
+	/*
+	 * To avoid cluttering the trace file, only trace userspace arguments when necessary
+	 * or if the option to trace them is selected.
+	 */
+	if (((cmd & IOC_INOUT) == IOC_IN) ||
+		(getenv("V4L2_TRACER_OPTION_TRACE_USERSPACE_ARG") != nullptr) ||
+		(cmd == VIDIOC_QBUF)) {
 		json_object *ioctl_args_userspace = trace_ioctl_args(cmd, arg);
 		/* Some ioctls won't have arguments to trace e.g. MEDIA_REQUEST_IOC_QUEUE. */
 		if (json_object_object_length(ioctl_args_userspace))
diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index b2b4afbf..d2f6a6e7 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -309,9 +309,9 @@ struct v4l2_buffer *retrace_v4l2_buffer(json_object *ioctl_args)
 	return buf;
 }
 
-void retrace_vidioc_querybuf(int fd_retrace, json_object *ioctl_args_user)
+void retrace_vidioc_querybuf(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args_user);
+	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args);
 
 	ioctl(fd_retrace, VIDIOC_QUERYBUF, buf);
 
@@ -346,9 +346,9 @@ void retrace_vidioc_querybuf(int fd_retrace, json_object *ioctl_args_user)
 	free(buf);
 }
 
-void retrace_vidioc_qbuf(int fd_retrace, json_object *ioctl_args_user)
+void retrace_vidioc_qbuf(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_buffer *ptr = retrace_v4l2_buffer(ioctl_args_user);
+	struct v4l2_buffer *ptr = retrace_v4l2_buffer(ioctl_args);
 
 	ioctl(fd_retrace, VIDIOC_QBUF, ptr);
 
@@ -371,9 +371,9 @@ void retrace_vidioc_qbuf(int fd_retrace, json_object *ioctl_args_user)
 	free(ptr);
 }
 
-void retrace_vidioc_dqbuf(int fd_retrace, json_object *ioctl_args_user)
+void retrace_vidioc_dqbuf(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args_user);
+	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args);
 
 	const int poll_timeout_ms = 5000;
 	struct pollfd *pfds = (struct pollfd *) calloc(1, sizeof(struct pollfd));
@@ -411,9 +411,9 @@ void retrace_vidioc_dqbuf(int fd_retrace, json_object *ioctl_args_user)
 	free(buf);
 }
 
-void retrace_vidioc_prepare_buf(int fd_retrace, json_object *ioctl_args_user)
+void retrace_vidioc_prepare_buf(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args_user);
+	struct v4l2_buffer *buf = retrace_v4l2_buffer(ioctl_args);
 
 	ioctl(fd_retrace, VIDIOC_PREPARE_BUF, buf);
 
@@ -447,9 +447,9 @@ void retrace_vidioc_create_bufs(int fd_retrace, json_object *ioctl_args)
 	free(ptr);
 }
 
-void retrace_vidioc_expbuf(int fd_retrace, json_object *ioctl_args_user, json_object *ioctl_args_driver)
+void retrace_vidioc_expbuf(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_exportbuffer *ptr = retrace_v4l2_exportbuffer_gen(ioctl_args_user);
+	struct v4l2_exportbuffer *ptr = retrace_v4l2_exportbuffer_gen(ioctl_args);
 	ioctl(fd_retrace, VIDIOC_EXPBUF, ptr);
 
 	int buf_fd_retrace = ptr->fd;
@@ -466,7 +466,7 @@ void retrace_vidioc_expbuf(int fd_retrace, json_object *ioctl_args_user, json_ob
 
 	/* Retrace again to associate the original fd with the current buffer fd. */
 	memset(ptr, 0, sizeof(v4l2_exportbuffer));
-	ptr = retrace_v4l2_exportbuffer_gen(ioctl_args_driver);
+	ptr = retrace_v4l2_exportbuffer_gen(ioctl_args);
 	int buf_fd_trace = ptr->fd;
 	add_fd(buf_fd_trace, buf_fd_retrace);
 
@@ -528,9 +528,9 @@ void retrace_vidioc_g_fmt(int fd_retrace, json_object *ioctl_args)
 	free(ptr);
 }
 
-void retrace_vidioc_s_fmt(int fd_retrace, json_object *ioctl_args_user)
+void retrace_vidioc_s_fmt(int fd_retrace, json_object *ioctl_args)
 {
-	struct v4l2_format *ptr = retrace_v4l2_format_gen(ioctl_args_user);
+	struct v4l2_format *ptr = retrace_v4l2_format_gen(ioctl_args);
 
 	ioctl(fd_retrace, VIDIOC_S_FMT, ptr);
 
@@ -1265,129 +1265,128 @@ void retrace_ioctl(json_object *syscall_obj)
 		return;
 	}
 
-	json_object *ioctl_args_user;
-	json_object_object_get_ex(syscall_obj, "from_userspace", &ioctl_args_user);
-
-	json_object *ioctl_args_driver;
-	json_object_object_get_ex(syscall_obj, "from_driver", &ioctl_args_driver);
+	/* If available, use the ioctl arguments from userspace, otherwise use the driver arguments. */
+	json_object *ioctl_args;
+	if (json_object_object_get_ex(syscall_obj, "from_userspace", &ioctl_args) == false)
+		json_object_object_get_ex(syscall_obj, "from_driver", &ioctl_args);
 
 	switch (cmd) {
 	case VIDIOC_QUERYCAP:
-		retrace_vidioc_querycap(fd_retrace, ioctl_args_user);
+		retrace_vidioc_querycap(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENUM_FMT:
-		retrace_vidioc_enum_fmt(fd_retrace, ioctl_args_user);
+		retrace_vidioc_enum_fmt(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_TRY_FMT:
-		retrace_vidioc_try_fmt(fd_retrace, ioctl_args_user);
+		retrace_vidioc_try_fmt(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_FMT:
-		retrace_vidioc_g_fmt(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_fmt(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_FMT:
-		retrace_vidioc_s_fmt(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_fmt(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_REQBUFS:
-		retrace_vidioc_reqbufs(fd_retrace, ioctl_args_user);
+		retrace_vidioc_reqbufs(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_QUERYBUF:
-		retrace_vidioc_querybuf(fd_retrace, ioctl_args_user);
+		retrace_vidioc_querybuf(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_QBUF:
-		retrace_vidioc_qbuf(fd_retrace, ioctl_args_user);
+		retrace_vidioc_qbuf(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_EXPBUF:
-		retrace_vidioc_expbuf(fd_retrace, ioctl_args_user, ioctl_args_driver);
+		retrace_vidioc_expbuf(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_DQBUF:
-		retrace_vidioc_dqbuf(fd_retrace, ioctl_args_user);
+		retrace_vidioc_dqbuf(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_STREAMON:
-		retrace_vidioc_streamon(fd_retrace, ioctl_args_user);
+		retrace_vidioc_streamon(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_STREAMOFF:
-		retrace_vidioc_streamoff(fd_retrace, ioctl_args_user);
+		retrace_vidioc_streamoff(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_PARM:
-		retrace_vidioc_g_parm(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_parm(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_PARM:
-		retrace_vidioc_s_parm(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_parm(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENUMINPUT:
-		retrace_vidioc_enuminput(fd_retrace, ioctl_args_user);
+		retrace_vidioc_enuminput(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_CTRL:
-		retrace_vidioc_g_control(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_control(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_CTRL:
-		retrace_vidioc_s_control(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_control(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_TUNER:
-		retrace_vidioc_g_tuner(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_tuner(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_TUNER:
-		retrace_vidioc_s_tuner(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_tuner(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_QUERYCTRL:
-		retrace_vidioc_queryctrl(fd_retrace, ioctl_args_user);
+		retrace_vidioc_queryctrl(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_INPUT:
-		retrace_vidioc_g_input(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_input(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_INPUT:
-		retrace_vidioc_s_input(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_input(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_OUTPUT:
-		retrace_vidioc_g_output(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_output(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_OUTPUT:
-		retrace_vidioc_s_output(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_output(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENUMOUTPUT:
-		retrace_vidioc_enumoutput(fd_retrace, ioctl_args_user);
+		retrace_vidioc_enumoutput(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_CROP:
-		retrace_vidioc_g_crop(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_crop(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_CROP:
-		retrace_vidioc_s_crop(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_crop(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_EXT_CTRLS:
-		retrace_vidioc_g_ext_ctrls(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_ext_ctrls(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_TRY_EXT_CTRLS:
-		retrace_vidioc_try_ext_ctrls(fd_retrace, ioctl_args_user);
+		retrace_vidioc_try_ext_ctrls(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_EXT_CTRLS:
-		retrace_vidioc_s_ext_ctrls(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_ext_ctrls(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENUM_FRAMESIZES:
-		retrace_vidioc_enum_framesizes(fd_retrace, ioctl_args_user);
+		retrace_vidioc_enum_framesizes(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENUM_FRAMEINTERVALS:
-		retrace_vidioc_enum_frameintervals(fd_retrace, ioctl_args_user);
+		retrace_vidioc_enum_frameintervals(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_TRY_ENCODER_CMD:
-		retrace_vidioc_try_encoder_cmd(fd_retrace, ioctl_args_user);
+		retrace_vidioc_try_encoder_cmd(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_ENCODER_CMD:
-		retrace_vidioc_encoder_cmd(fd_retrace, ioctl_args_user);
+		retrace_vidioc_encoder_cmd(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_CREATE_BUFS:
-		retrace_vidioc_create_bufs(fd_retrace, ioctl_args_user);
+		retrace_vidioc_create_bufs(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_G_SELECTION:
-		retrace_vidioc_g_selection(fd_retrace, ioctl_args_user);
+		retrace_vidioc_g_selection(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_S_SELECTION:
-		retrace_vidioc_s_selection(fd_retrace, ioctl_args_user);
+		retrace_vidioc_s_selection(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_PREPARE_BUF:
-		retrace_vidioc_prepare_buf(fd_retrace, ioctl_args_user);
+		retrace_vidioc_prepare_buf(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_TRY_DECODER_CMD:
-		retrace_vidioc_try_decoder_cmd(fd_retrace, ioctl_args_user);
+		retrace_vidioc_try_decoder_cmd(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_DQEVENT:
 		/* Don't retrace a timed-out DQEVENT */
@@ -1396,19 +1395,19 @@ void retrace_ioctl(json_object *syscall_obj)
 		retrace_vidioc_dqevent(fd_retrace);
 		break;
 	case VIDIOC_SUBSCRIBE_EVENT:
-		retrace_vidioc_subscribe_event(fd_retrace, ioctl_args_user);
+		retrace_vidioc_subscribe_event(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_UNSUBSCRIBE_EVENT:
-		retrace_vidioc_unsubscribe(fd_retrace, ioctl_args_user);
+		retrace_vidioc_unsubscribe(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_DECODER_CMD:
-		retrace_vidioc_decoder_cmd(fd_retrace, ioctl_args_user);
+		retrace_vidioc_decoder_cmd(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_QUERY_EXT_CTRL:
-		retrace_vidioc_query_ext_ctrl(fd_retrace, ioctl_args_user);
+		retrace_vidioc_query_ext_ctrl(fd_retrace, ioctl_args);
 		break;
 	case MEDIA_IOC_REQUEST_ALLOC:
-		retrace_media_ioc_request_alloc(fd_retrace, ioctl_args_driver);
+		retrace_media_ioc_request_alloc(fd_retrace, ioctl_args);
 		break;
 	case MEDIA_REQUEST_IOC_QUEUE:
 		ioctl(fd_retrace, MEDIA_REQUEST_IOC_QUEUE);
diff --git a/utils/v4l2-tracer/v4l2-tracer-common.cpp b/utils/v4l2-tracer/v4l2-tracer-common.cpp
index 1b0ab2af..62f62ada 100644
--- a/utils/v4l2-tracer/v4l2-tracer-common.cpp
+++ b/utils/v4l2-tracer/v4l2-tracer-common.cpp
@@ -37,6 +37,7 @@ void print_usage(void)
 	        "\t\t-g, --debug       Turn on verbose reporting plus additional debug info.\n"
 	        "\t\t-h, --help        Display this message.\n"
 	        "\t\t-r  --raw         Write decoded video frame data to JSON file.\n"
+	        "\t\t-u  --userspace   Trace userspace arguments.\n"
 	        "\t\t-v, --verbose     Turn on verbose reporting.\n"
 	        "\t\t-y, --yuv         Write decoded video frame data to yuv file.\n\n"
 
diff --git a/utils/v4l2-tracer/v4l2-tracer.cpp b/utils/v4l2-tracer/v4l2-tracer.cpp
index 9fd5eae0..a039f528 100644
--- a/utils/v4l2-tracer/v4l2-tracer.cpp
+++ b/utils/v4l2-tracer/v4l2-tracer.cpp
@@ -28,6 +28,7 @@ enum Options {
 	V4l2TracerOptHelp = 'h',
 	V4l2TracerOptSetMediaDevice = 'm',
 	V4l2TracerOptWriteDecodedToJson = 'r',
+	V4l2TracerOptTraceUserspaceArg = 'u',
 	V4l2TracerOptVerbose = 'v',
 	V4l2TracerOptWriteDecodedToYUVFile = 'y',
 };
@@ -39,6 +40,7 @@ const static struct option long_options[] = {
 	{ "help", no_argument, nullptr, V4l2TracerOptHelp },
 	{ "media_device", required_argument, nullptr, V4l2TracerOptSetMediaDevice },
 	{ "raw", no_argument, nullptr, V4l2TracerOptWriteDecodedToJson },
+	{ "userspace", no_argument, nullptr, V4l2TracerOptTraceUserspaceArg},
 	{ "verbose", no_argument, nullptr, V4l2TracerOptVerbose },
 	{ "yuv", no_argument, nullptr, V4l2TracerOptWriteDecodedToYUVFile },
 	{ nullptr, 0, nullptr, 0 }
@@ -51,6 +53,7 @@ const char short_options[] = {
 	V4l2TracerOptHelp,
 	V4l2TracerOptSetMediaDevice, ':',
 	V4l2TracerOptWriteDecodedToJson,
+	V4l2TracerOptTraceUserspaceArg,
 	V4l2TracerOptVerbose,
 	V4l2TracerOptWriteDecodedToYUVFile
 };
@@ -122,6 +125,9 @@ int get_options(int argc, char *argv[])
 		case V4l2TracerOptWriteDecodedToJson:
 			setenv("V4L2_TRACER_OPTION_WRITE_DECODED_TO_JSON_FILE", "true", 0);
 			break;
+		case V4l2TracerOptTraceUserspaceArg:
+			setenv("V4L2_TRACER_OPTION_TRACE_USERSPACE_ARG", "true", 0);
+			break;
 		case V4l2TracerOptVerbose:
 			setenv("V4L2_TRACER_OPTION_VERBOSE", "true", 0);
 			break;
-- 
2.41.0


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

* [PATCH 7/8] v4l2-tracer: stop retracing failed ioctls
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
                   ` (5 preceding siblings ...)
  2023-11-13 20:06 ` [PATCH 6/8] v4l2-tracer: create an option to trace userspace args Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  2023-11-13 20:06 ` [PATCH 8/8] v4l2-tracer: auto generate flags for DECODER_CMD Deborah Brouwer
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

Stop retracing ioctls that failed during the original trace. These ioctls
won’t affect the retrace and reporting their (expected) failure adds
noise to the retracer’s debug information.

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

diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index d2f6a6e7..d251180e 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -1246,7 +1246,6 @@ void retrace_ioctl(json_object *syscall_obj)
 {
 	__s64 cmd = 0;
 	int fd_retrace = 0;
-	bool ioctl_error = false;
 
 	json_object *fd_trace_obj;
 	json_object_object_get_ex(syscall_obj, "fd", &fd_trace_obj);
@@ -1258,7 +1257,7 @@ void retrace_ioctl(json_object *syscall_obj)
 
 	json_object *errno_obj;
 	if (json_object_object_get_ex(syscall_obj, "errno", &errno_obj))
-		ioctl_error = true;
+		return;
 
 	if (fd_retrace < 0) {
 		line_info("\n\tBad file descriptor on %s\n", json_object_get_string(cmd_obj));
@@ -1389,9 +1388,6 @@ void retrace_ioctl(json_object *syscall_obj)
 		retrace_vidioc_try_decoder_cmd(fd_retrace, ioctl_args);
 		break;
 	case VIDIOC_DQEVENT:
-		/* Don't retrace a timed-out DQEVENT */
-		if (ioctl_error)
-			break;
 		retrace_vidioc_dqevent(fd_retrace);
 		break;
 	case VIDIOC_SUBSCRIBE_EVENT:
-- 
2.41.0


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

* [PATCH 8/8] v4l2-tracer: auto generate flags for DECODER_CMD
  2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
                   ` (6 preceding siblings ...)
  2023-11-13 20:06 ` [PATCH 7/8] v4l2-tracer: stop retracing failed ioctls Deborah Brouwer
@ 2023-11-13 20:06 ` Deborah Brouwer
  7 siblings, 0 replies; 9+ messages in thread
From: Deborah Brouwer @ 2023-11-13 20:06 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil-cisco, Deborah Brouwer

The flags for V4L2_DEC_CMD_START STOP, and PAUSE aren’t being traced
correctly because unknown flags aren’t traced as hex values and only one
flag is traced per command. Auto generate the possible flags and use the
standard helper functions to trace and retrace them.

Signed-off-by: Deborah Brouwer <deborah.brouwer@collabora.com>
---
 utils/v4l2-tracer/retrace.cpp        | 15 ++++++---------
 utils/v4l2-tracer/trace.cpp          | 15 +++------------
 utils/v4l2-tracer/v4l2-tracer-gen.pl | 21 +++++++++++++++++++++
 3 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/utils/v4l2-tracer/retrace.cpp b/utils/v4l2-tracer/retrace.cpp
index d251180e..03fe13f8 100644
--- a/utils/v4l2-tracer/retrace.cpp
+++ b/utils/v4l2-tracer/retrace.cpp
@@ -1064,8 +1064,7 @@ struct v4l2_decoder_cmd *retrace_v4l2_decoder_cmd(json_object *parent_obj)
 
 	switch (ptr->cmd) {
 	case V4L2_DEC_CMD_START: {
-		if (flags == "V4L2_DEC_CMD_START_MUTE_AUDIO")
-			ptr->flags = V4L2_DEC_CMD_START_MUTE_AUDIO;
+		ptr->flags = s2flags(flags.c_str(), v4l2_decoder_cmd_start_flag_def);
 
 		json_object *start_obj;
 		json_object_object_get_ex(v4l2_decoder_cmd_obj, "start", &start_obj);
@@ -1087,10 +1086,7 @@ struct v4l2_decoder_cmd *retrace_v4l2_decoder_cmd(json_object *parent_obj)
 		break;
 	}
 	case V4L2_DEC_CMD_STOP: {
-		if (flags == "V4L2_DEC_CMD_STOP_TO_BLACK")
-			ptr->flags = V4L2_DEC_CMD_STOP_TO_BLACK;
-		else if (flags == "V4L2_DEC_CMD_STOP_IMMEDIATELY")
-			ptr->flags = V4L2_DEC_CMD_STOP_IMMEDIATELY;
+		ptr->flags = s2flags(flags.c_str(), v4l2_decoder_cmd_stop_flag_def);
 
 		json_object *stop_obj;
 		json_object_object_get_ex(v4l2_decoder_cmd_obj, "stop", &stop_obj);
@@ -1101,8 +1097,7 @@ struct v4l2_decoder_cmd *retrace_v4l2_decoder_cmd(json_object *parent_obj)
 		break;
 	}
 	case V4L2_DEC_CMD_PAUSE: {
-		if (flags == "V4L2_DEC_CMD_PAUSE_TO_BLACK")
-			ptr->flags = V4L2_DEC_CMD_PAUSE_TO_BLACK;
+		ptr->flags = s2flags(flags.c_str(), v4l2_decoder_cmd_pause_flag_def);
 		break;
 	}
 	default:
@@ -1542,7 +1537,9 @@ int retrace(std::string trace_filename)
 	json_object *root_array_obj = json_object_from_file(trace_filename.c_str());
 
 	if (root_array_obj == nullptr) {
-		line_info("\n\tCan't get JSON-object from file: %s", trace_filename.c_str());
+		line_info("\n\t%s\tCan't get JSON-object from file: %s",
+			  json_util_get_last_err(),
+			  trace_filename.c_str());
 		return 1;
 	}
 
diff --git a/utils/v4l2-tracer/trace.cpp b/utils/v4l2-tracer/trace.cpp
index 31447f24..c4fc1584 100644
--- a/utils/v4l2-tracer/trace.cpp
+++ b/utils/v4l2-tracer/trace.cpp
@@ -466,10 +466,7 @@ void trace_v4l2_decoder_cmd(void *arg, json_object *ioctl_args)
 
 	switch (ptr->cmd) {
 	case V4L2_DEC_CMD_START: {
-		/*  This command has one flag: V4L2_DEC_CMD_START_MUTE_AUDIO. */
-		if (ptr->flags == V4L2_DEC_CMD_START_MUTE_AUDIO)
-			flags = "V4L2_DEC_CMD_START_MUTE_AUDIO";
-
+		flags = fl2s(ptr->flags, v4l2_decoder_cmd_start_flag_def);
 		/* struct start */
 		json_object *start_obj = json_object_new_object();
 		json_object_object_add(start_obj, "speed", json_object_new_int(ptr->start.speed));
@@ -486,12 +483,7 @@ void trace_v4l2_decoder_cmd(void *arg, json_object *ioctl_args)
 		break;
 	}
 	case V4L2_DEC_CMD_STOP: {
-		/*  This command has two flags */
-		if (ptr->flags == V4L2_DEC_CMD_STOP_TO_BLACK)
-			flags = "V4L2_DEC_CMD_STOP_TO_BLACK";
-		else if (ptr->flags == V4L2_DEC_CMD_STOP_IMMEDIATELY)
-			flags = "V4L2_DEC_CMD_STOP_IMMEDIATELY";
-
+		flags = fl2s(ptr->flags, v4l2_decoder_cmd_stop_flag_def);
 		json_object *stop_obj = json_object_new_object();
 		json_object_object_add(stop_obj, "pts", json_object_new_uint64(ptr->stop.pts));
 
@@ -500,8 +492,7 @@ void trace_v4l2_decoder_cmd(void *arg, json_object *ioctl_args)
 	}
 
 	case V4L2_DEC_CMD_PAUSE: {
-		if (ptr->flags == V4L2_DEC_CMD_PAUSE_TO_BLACK)
-			flags = "V4L2_DEC_CMD_PAUSE_TO_BLACK";
+		flags = fl2s(ptr->flags, v4l2_decoder_cmd_pause_flag_def);
 		break;
 	}
 	case V4L2_DEC_CMD_RESUME:
diff --git a/utils/v4l2-tracer/v4l2-tracer-gen.pl b/utils/v4l2-tracer/v4l2-tracer-gen.pl
index e8f9d71e..cb9c3ab5 100755
--- a/utils/v4l2-tracer/v4l2-tracer-gen.pl
+++ b/utils/v4l2-tracer/v4l2-tracer-gen.pl
@@ -123,6 +123,12 @@ sub val_def_gen {
 	}
 	($val) = ($_) =~ /^#define\s*(\w+)\s*/;
 	printf $fh_common_info_h "\t{ %s,\t\"%s\" },\n", $val, $val;
+
+	# in case there is only one value e.g. flags for V4L2_DEC_CMD_START
+	if ($val eq $last_val) {
+		printf $fh_common_info_h "\t{ $sentinel, \"\" }\n};\n\n";
+		return;
+	}
 	while (<>) {
 		next if ($_ =~ /^\s*\/?\s?\*.*/); # skip comments
 		next if ($_ =~ /^\s*$/);  # skip blank lines
@@ -1000,6 +1006,21 @@ while (<>) {
 		val_def_gen("V4L2_DEC_CMD_FLUSH");
 		next;
 	}
+	if (grep {/^#define V4L2_DEC_CMD_START_MUTE_AUDIO\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_start_flag_def[] = {\n";
+		flag_def_gen("V4L2_DEC_CMD_START_MUTE_AUDIO");
+		next;
+	}
+	if (grep {/^#define V4L2_DEC_CMD_PAUSE_TO_BLACK\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_pause_flag_def[] = {\n";
+		flag_def_gen("V4L2_DEC_CMD_PAUSE_TO_BLACK");
+		next;
+	}
+	if (grep {/^#define V4L2_DEC_CMD_STOP_TO_BLACK\s+/} $_) {
+		printf $fh_common_info_h "constexpr flag_def v4l2_decoder_cmd_stop_flag_def[] = {\n";
+		flag_def_gen("V4L2_DEC_CMD_STOP_IMMEDIATELY");
+		next;
+	}
 	if (grep {/^#define V4L2_EVENT_ALL\s+/} $_) {
 		printf $fh_common_info_h "constexpr val_def event_val_def[] = {\n";
 		val_def_gen("V4L2_EVENT_PRIVATE_START");
-- 
2.41.0


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

end of thread, other threads:[~2023-11-13 20:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-13 20:06 [PATCH 0/8] v4l2-tracer: expand to stateful decoding Deborah Brouwer
2023-11-13 20:06 ` [PATCH 1/8] v4l2-info/v4l2-tracer: add macro to mark the trace Deborah Brouwer
2023-11-13 20:06 ` [PATCH 2/8] v4l2-tracer: replace buftype2s with val2s Deborah Brouwer
2023-11-13 20:06 ` [PATCH 3/8] v4l2-tracer: remove buffers by type and index Deborah Brouwer
2023-11-13 20:06 ` [PATCH 4/8] v4l2-tracer: remove compress_frame_count Deborah Brouwer
2023-11-13 20:06 ` [PATCH 5/8] v4l2-tracer: get decoded bytesused from DQBUF Deborah Brouwer
2023-11-13 20:06 ` [PATCH 6/8] v4l2-tracer: create an option to trace userspace args Deborah Brouwer
2023-11-13 20:06 ` [PATCH 7/8] v4l2-tracer: stop retracing failed ioctls Deborah Brouwer
2023-11-13 20:06 ` [PATCH 8/8] v4l2-tracer: auto generate flags for DECODER_CMD 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).