All of lore.kernel.org
 help / color / mirror / Atom feed
* [v4l-utils PATCH v3 0/8] add support to stateless decoder
@ 2019-02-24  8:41 Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 1/8] v4l2-ctl: rename variable 'vic_fmt' to 'info' Dafna Hirschfeld
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Changes from v2:
patches 1,2,3,6 are new

Dafna Hirschfeld (8):
  v4l2-ctl: rename variable 'vic_fmt' to 'info'
  v4l2-ctl: bugfix: correctly read/write V4L2_PIX_FMT_NV24 padded buffer
  v4l2-ctl: test if do_setup_out_buffers returns -1 instead of non zero
  v4l2-ctl: move stateful m2m decode code to a separate function
  (c)v4l-helpers.h: Add support for the request api
  v4l-utils: copy fwht-ctrls.h from kernel dir
  v4l2-ctl: Add functions and variables to support fwht stateless
    decoder
  v4l2-ctl: Add implementation for the stateless fwht decoder.

 Makefile.am                           |   1 +
 utils/common/codec-fwht.patch         |   7 +-
 utils/common/cv4l-helpers.h           |   5 +
 utils/common/v4l-helpers.h            |  22 ++
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 482 ++++++++++++++++++++++----
 5 files changed, 455 insertions(+), 62 deletions(-)

-- 
2.17.1


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

* [v4l-utils PATCH v3 1/8] v4l2-ctl: rename variable 'vic_fmt' to 'info'
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 2/8] v4l2-ctl: bugfix: correctly read/write V4L2_PIX_FMT_NV24 padded buffer Dafna Hirschfeld
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

This is a better name for
'v4l2_fwht_pixfmt_info' type and it is not
confused with 'cv4l_fmt' type.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 766872b5..352b946d 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -753,7 +753,7 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 				    FILE *fpointer, unsigned &sz,
 				    unsigned &len, bool is_read)
 {
-	const struct v4l2_fwht_pixfmt_info *vic_fmt =
+	const struct v4l2_fwht_pixfmt_info *info =
 			v4l2_fwht_find_pixfmt(fmt.g_pixelformat());
 	unsigned coded_height = fmt.g_height();
 	unsigned real_width;
@@ -770,14 +770,14 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 	}
 
 	sz = 0;
-	len = real_width * real_height * vic_fmt->sizeimage_mult / vic_fmt->sizeimage_div;
+	len = real_width * real_height * info->sizeimage_mult / info->sizeimage_div;
 
-	for (unsigned plane_idx = 0; plane_idx < vic_fmt->planes_num; plane_idx++) {
+	for (unsigned plane_idx = 0; plane_idx < info->planes_num; plane_idx++) {
 		bool is_chroma_plane = plane_idx == 1 || plane_idx == 2;
-		unsigned h_div = is_chroma_plane ? vic_fmt->height_div : 1;
-		unsigned w_div = is_chroma_plane ? vic_fmt->width_div : 1;
-		unsigned step = is_chroma_plane ? vic_fmt->chroma_step : vic_fmt->luma_alpha_step;
-		unsigned stride_div = (vic_fmt->planes_num == 3 && plane_idx > 0) ? 2 : 1;
+		unsigned h_div = is_chroma_plane ? info->height_div : 1;
+		unsigned w_div = is_chroma_plane ? info->width_div : 1;
+		unsigned step = is_chroma_plane ? info->chroma_step : info->luma_alpha_step;
+		unsigned stride_div = (info->planes_num == 3 && plane_idx > 0) ? 2 : 1;
 
 		row_p = plane_p;
 		for (unsigned i = 0; i < real_height / h_div; i++) {
-- 
2.17.1


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

* [v4l-utils PATCH v3 2/8] v4l2-ctl: bugfix: correctly read/write V4L2_PIX_FMT_NV24 padded buffer
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 1/8] v4l2-ctl: rename variable 'vic_fmt' to 'info' Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 3/8] v4l2-ctl: test if do_setup_out_buffers returns -1 instead of non zero Dafna Hirschfeld
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

For V4L2_PIX_FMT_NV24/42 types the chroma stride is twice the
luma stride. Add support for it in 'read_write_padded_frame'

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 352b946d..6f4317bf 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -760,6 +760,7 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 	unsigned real_height;
 	unsigned char *plane_p = buf;
 	unsigned char *row_p;
+	unsigned stride = fmt.g_bytesperline();
 
 	if (is_read) {
 		real_width  = cropped_width;
@@ -776,13 +777,20 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 		bool is_chroma_plane = plane_idx == 1 || plane_idx == 2;
 		unsigned h_div = is_chroma_plane ? info->height_div : 1;
 		unsigned w_div = is_chroma_plane ? info->width_div : 1;
-		unsigned step = is_chroma_plane ? info->chroma_step : info->luma_alpha_step;
-		unsigned stride_div = (info->planes_num == 3 && plane_idx > 0) ? 2 : 1;
+		unsigned step = is_chroma_plane ? info->chroma_step :
+			info->luma_alpha_step;
+		unsigned int consume_sz = step * real_width / w_div;
+
+		if (info->planes_num == 3 && plane_idx == 1)
+			stride /= 2;
+
+		if (plane_idx == 1 &&
+		    (info->id == V4L2_PIX_FMT_NV24 || info->id == V4L2_PIX_FMT_NV42))
+			stride *= 2;
 
 		row_p = plane_p;
 		for (unsigned i = 0; i < real_height / h_div; i++) {
 			unsigned int wsz = 0;
-			unsigned int consume_sz = step * real_width / w_div;
 
 			if (is_read)
 				wsz = fread(row_p, 1, consume_sz, fpointer);
@@ -795,9 +803,9 @@ static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 				return;
 			}
 			sz += wsz;
-			row_p += fmt.g_bytesperline() / stride_div;
+			row_p += stride;
 		}
-		plane_p += (fmt.g_bytesperline() / stride_div) * (coded_height / h_div);
+		plane_p += stride * (coded_height / h_div);
 		if (sz == 0)
 			break;
 	}
-- 
2.17.1


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

* [v4l-utils PATCH v3 3/8] v4l2-ctl: test if do_setup_out_buffers returns -1 instead of non zero
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 1/8] v4l2-ctl: rename variable 'vic_fmt' to 'info' Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 2/8] v4l2-ctl: bugfix: correctly read/write V4L2_PIX_FMT_NV24 padded buffer Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 4/8] v4l2-ctl: move stateful m2m decode code to a separate function Dafna Hirschfeld
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

If 'do_setup_out_buffers' returns -2 it means that
it finished queuing all output stream buffers and
the program should not terminate in that case.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 6f4317bf..d023aa12 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -1823,7 +1823,7 @@ static void streaming_set_out(cv4l_fd &fd, cv4l_fd &exp_fd)
 	if (q.obtain_bufs(&fd))
 		goto done;
 
-	if (do_setup_out_buffers(fd, q, fin, true))
+	if (do_setup_out_buffers(fd, q, fin, true) == -1)
 		goto done;
 
 	fps_ts.determine_field(fd.g_fd(), type);
@@ -2013,7 +2013,7 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 			goto done;
 	}
 
-	if (do_setup_out_buffers(fd, out, file[OUT], true))
+	if (do_setup_out_buffers(fd, out, file[OUT], true) == -1)
 		goto done;
 
 	if (fd.streamon(out.g_type()))
@@ -2250,7 +2250,7 @@ static void streaming_set_cap2out(cv4l_fd &fd, cv4l_fd &out_fd)
 
 	if (in.obtain_bufs(&fd) ||
 	    in.queue_all(&fd) ||
-	    do_setup_out_buffers(out_fd, out, file[OUT], false))
+	    do_setup_out_buffers(out_fd, out, file[OUT], false) == -1)
 		goto done;
 
 	fps_ts[CAP].determine_field(fd.g_fd(), in.g_type());
-- 
2.17.1


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

* [v4l-utils PATCH v3 4/8] v4l2-ctl: move stateful m2m decode code to a separate function
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
                   ` (2 preceding siblings ...)
  2019-02-24  8:41 ` [v4l-utils PATCH v3 3/8] v4l2-ctl: test if do_setup_out_buffers returns -1 instead of non zero Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api Dafna Hirschfeld
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add the function stateful_m2m that implements the stateful
codec api.
This is a preparation for having both stateful and stateless
implementations

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 95 ++++++++++++++-------------
 1 file changed, 50 insertions(+), 45 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index d023aa12..adfa6796 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -1941,16 +1941,12 @@ static int capture_setup(cv4l_fd &fd, cv4l_queue &in, cv4l_fd *exp_fd)
 	return 0;
 }
 
-static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
+static void stateful_m2m(cv4l_fd &fd, cv4l_queue &in, cv4l_queue &out,
+			 FILE *fin, FILE *fout, cv4l_fd *exp_fd_p)
 {
 	int fd_flags = fcntl(fd.g_fd(), F_GETFL);
-	cv4l_queue in(fd.g_type(), memory);
-	cv4l_queue out(v4l_type_invert(fd.g_type()), out_memory);
-	cv4l_queue exp_q(exp_fd.g_type(), V4L2_MEMORY_MMAP);
-	cv4l_fd *exp_fd_p = NULL;
 	fps_timestamps fps_ts[2];
 	unsigned count[2] = { 0, 0 };
-	FILE *file[2] = {NULL, NULL};
 	fd_set fds[3];
 	fd_set *rd_fds = &fds[0]; /* for capture */
 	fd_set *ex_fds = &fds[1]; /* for capture */
@@ -1961,19 +1957,6 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 	fd.g_fmt(fmt[OUT], out.g_type());
 	fd.g_fmt(fmt[CAP], in.g_type());
 
-	if (!fd.has_vid_m2m()) {
-		fprintf(stderr, "unsupported m2m stream type\n");
-		return;
-	}
-	if (options[OptStreamDmaBuf] && options[OptStreamOutDmaBuf]) {
-		fprintf(stderr, "--stream-dmabuf and --stream-out-dmabuf not supported for m2m devices\n");
-		return;
-	}
-	if ((options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf]) && exp_fd.g_fd() < 0) {
-		fprintf(stderr, "--stream-dmabuf or --stream-out-dmabuf can only work in combination with --export-device\n");
-		return;
-	}
-
 	struct v4l2_event_subscription sub;
 
 	memset(&sub, 0, sizeof(sub));
@@ -1994,34 +1977,18 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 	sub.type = V4L2_EVENT_SOURCE_CHANGE;
 	bool have_source_change = !fd.subscribe_event(sub);
 
-	file[CAP] = open_output_file(fd);
-	file[OUT] = open_input_file(fd, out.g_type());
-
 	if (out.reqbufs(&fd, reqbufs_count_out))
-		goto done;
-
-	if (options[OptStreamDmaBuf]) {
-		if (exp_q.reqbufs(&exp_fd, reqbufs_count_cap))
-			goto done;
-		exp_fd_p = &exp_fd;
-	}
-
-	if (options[OptStreamOutDmaBuf]) {
-		if (exp_q.reqbufs(&exp_fd, reqbufs_count_out))
-			goto done;
-		if (out.export_bufs(&exp_fd, exp_fd.g_type()))
-			goto done;
-	}
+		return;
 
-	if (do_setup_out_buffers(fd, out, file[OUT], true) == -1)
-		goto done;
+	if (do_setup_out_buffers(fd, out, fout, true) == -1)
+		return;
 
 	if (fd.streamon(out.g_type()))
-		goto done;
+		return;
 
 	if (codec_type != DECODER || !have_source_change)
 		if (capture_setup(fd, in, exp_fd_p))
-			goto done;
+			return;
 
 	fps_ts[CAP].determine_field(fd.g_fd(), in.g_type());
 	fps_ts[OUT].determine_field(fd.g_fd(), out.g_type());
@@ -2057,15 +2024,15 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 				continue;
 			fprintf(stderr, "select error: %s\n",
 					strerror(errno));
-			goto done;
+			return;
 		}
 		if (r == 0) {
 			fprintf(stderr, "select timeout\n");
-			goto done;
+			return;
 		}
 
 		if (rd_fds && FD_ISSET(fd.g_fd(), rd_fds)) {
-			r = do_handle_cap(fd, in, file[CAP], NULL,
+			r = do_handle_cap(fd, in, fin, NULL,
 					  count[CAP], fps_ts[CAP], fmt[CAP]);
 			if (r < 0) {
 				rd_fds = NULL;
@@ -2077,7 +2044,7 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 		}
 
 		if (wr_fds && FD_ISSET(fd.g_fd(), wr_fds)) {
-			r = do_handle_out(fd, out, file[OUT], NULL,
+			r = do_handle_out(fd, out, fout, NULL,
 					  count[OUT], fps_ts[OUT], fmt[OUT]);
 			if (r < 0)  {
 				wr_fds = NULL;
@@ -2128,7 +2095,7 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 				in_source_change_event = false;
 				last_buffer = false;
 				if (capture_setup(fd, in, exp_fd_p))
-					goto done;
+					return;
 				fd.g_fmt(fmt[OUT], out.g_type());
 				fd.g_fmt(fmt[CAP], in.g_type());
 				cap_streaming = true;
@@ -2146,7 +2113,45 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 	in.free(&fd);
 	out.free(&fd);
 	tpg_free(&tpg);
+}
+
+static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
+{
+	cv4l_queue in(fd.g_type(), memory);
+	cv4l_queue out(v4l_type_invert(fd.g_type()), out_memory);
+	cv4l_queue exp_q(exp_fd.g_type(), V4L2_MEMORY_MMAP);
+	cv4l_fd *exp_fd_p = NULL;
+	FILE *file[2] = {NULL, NULL};
+
+	if (!fd.has_vid_m2m()) {
+		fprintf(stderr, "unsupported m2m stream type\n");
+		return;
+	}
+	if (options[OptStreamDmaBuf] && options[OptStreamOutDmaBuf]) {
+		fprintf(stderr, "--stream-dmabuf and --stream-out-dmabuf not supported for m2m devices\n");
+		return;
+	}
+	if ((options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf]) && exp_fd.g_fd() < 0) {
+		fprintf(stderr, "--stream-dmabuf or --stream-out-dmabuf can only work in combination with --export-device\n");
+		return;
+	}
 
+	file[CAP] = open_output_file(fd);
+	file[OUT] = open_input_file(fd, out.g_type());
+
+	if (options[OptStreamDmaBuf]) {
+		if (exp_q.reqbufs(&exp_fd, reqbufs_count_cap))
+			return;
+		exp_fd_p = &exp_fd;
+	}
+
+	if (options[OptStreamOutDmaBuf]) {
+		if (exp_q.reqbufs(&exp_fd, reqbufs_count_out))
+			return;
+		if (out.export_bufs(&exp_fd, exp_fd.g_type()))
+			return;
+	}
+	stateful_m2m(fd, in, out, file[CAP], file[OUT], exp_fd_p);
 done:
 	if (options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf])
 		exp_q.close_exported_fds();
-- 
2.17.1


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

* [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
                   ` (3 preceding siblings ...)
  2019-02-24  8:41 ` [v4l-utils PATCH v3 4/8] v4l2-ctl: move stateful m2m decode code to a separate function Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-25 10:38   ` Hans Verkuil
  2019-02-24  8:41 ` [v4l-utils PATCH v3 6/8] v4l-utils: copy fwht-ctrls.h from kernel dir Dafna Hirschfeld
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add an array of request file descriptors to v4l_queue
and add methods to allocate and get them.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/common/cv4l-helpers.h |  5 +++++
 utils/common/v4l-helpers.h  | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/utils/common/cv4l-helpers.h b/utils/common/cv4l-helpers.h
index 1cd2b6b2..551d4673 100644
--- a/utils/common/cv4l-helpers.h
+++ b/utils/common/cv4l-helpers.h
@@ -745,6 +745,7 @@ public:
 	unsigned g_capabilities() const { return v4l_queue_g_capabilities(this); }
 	unsigned g_length(unsigned plane) const { return v4l_queue_g_length(this, plane); }
 	unsigned g_mem_offset(unsigned index, unsigned plane) const { return v4l_queue_g_mem_offset(this, index, plane); }
+	unsigned g_req_fd(unsigned index) const { return v4l_queue_g_req_fd(this, index); }
 	void *g_mmapping(unsigned index, unsigned plane) const { return v4l_queue_g_mmapping(this, index, plane); }
 	void s_mmapping(unsigned index, unsigned plane, void *m) { v4l_queue_s_mmapping(this, index, plane, m); }
 	void *g_userptr(unsigned index, unsigned plane) const { return v4l_queue_g_userptr(this, index, plane); }
@@ -797,6 +798,10 @@ public:
 	{
 		return v4l_queue_export_bufs(fd->g_v4l_fd(), this, exp_type);
 	}
+	int alloc_req(int media_fd, unsigned index)
+	{
+		return v4l_queue_alloc_req(this, media_fd, index);
+	}
 	void close_exported_fds()
 	{
 		v4l_queue_close_exported_fds(this);
diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h
index 59d8566a..daa49a1f 100644
--- a/utils/common/v4l-helpers.h
+++ b/utils/common/v4l-helpers.h
@@ -10,6 +10,7 @@
 #define _V4L_HELPERS_H_
 
 #include <linux/videodev2.h>
+#include <linux/media.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -1414,6 +1415,7 @@ struct v4l_queue {
 	void *mmappings[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
 	unsigned long userptrs[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
 	int fds[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
+	int req_fds[VIDEO_MAX_FRAME];
 };
 
 static inline void v4l_queue_init(struct v4l_queue *q,
@@ -1445,6 +1447,11 @@ static inline __u32 v4l_queue_g_mem_offset(const struct v4l_queue *q, unsigned i
 	return q->mem_offsets[index][plane];
 }
 
+static inline unsigned v4l_queue_g_req_fd(const struct v4l_queue *q, unsigned index)
+{
+	return q->req_fds[index];
+}
+
 static inline void v4l_queue_s_mmapping(struct v4l_queue *q, unsigned index, unsigned plane, void *m)
 {
 	q->mmappings[index][plane] = m;
@@ -1701,6 +1708,21 @@ static inline int v4l_queue_export_bufs(struct v4l_fd *f, struct v4l_queue *q,
 	return 0;
 }
 
+static inline int v4l_queue_alloc_req(struct v4l_queue *q, int media_fd, unsigned index)
+{
+	int rc = 0;
+
+	rc = ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &q->req_fds[index]);
+	if (rc < 0) {
+		fprintf(stderr, "Unable to allocate media request: %s\n",
+			strerror(errno));
+		return rc;
+	}
+
+	return 0;
+}
+
+
 static inline void v4l_queue_close_exported_fds(struct v4l_queue *q)
 {
 	unsigned b, p;
-- 
2.17.1


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

* [v4l-utils PATCH v3 6/8] v4l-utils: copy fwht-ctrls.h from kernel dir
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
                   ` (4 preceding siblings ...)
  2019-02-24  8:41 ` [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 7/8] v4l2-ctl: Add functions and variables to support fwht stateless decoder Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 8/8] v4l2-ctl: Add implementation for the stateless fwht decoder Dafna Hirschfeld
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

copy fwht-ctrls.h from the kernel dir when
running 'sync' and add typedef for u64
in codec-fwht.h

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 Makefile.am                   | 1 +
 utils/common/codec-fwht.patch | 7 ++++---
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index b0b8a098..8abe4f94 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -52,6 +52,7 @@ sync-with-kernel:
 	cp -a $(KERNEL_DIR)/drivers/media/common/v4l2-tpg/v4l2-tpg-core.c $(top_srcdir)/utils/common
 	cp -a $(KERNEL_DIR)/drivers/media/common/v4l2-tpg/v4l2-tpg-colors.c $(top_srcdir)/utils/common
 	cp -a $(KERNEL_DIR)/include/media/tpg/v4l2-tpg* $(top_srcdir)/utils/common
+	cp -a $(KERNEL_DIR)/include/media/fwht-ctrls.h $(top_srcdir)/utils/common
 	patch -d $(top_srcdir) --no-backup-if-mismatch -p0 <$(top_srcdir)/utils/common/v4l2-tpg.patch
 	cp -a $(KERNEL_DIR)/drivers/media/platform/vicodec/codec-fwht.[ch] $(top_srcdir)/utils/common/
 	cp -a $(KERNEL_DIR)/drivers/media/platform/vicodec/codec-v4l2-fwht.[ch] $(top_srcdir)/utils/common/
diff --git a/utils/common/codec-fwht.patch b/utils/common/codec-fwht.patch
index 37ac4672..ad27b37a 100644
--- a/utils/common/codec-fwht.patch
+++ b/utils/common/codec-fwht.patch
@@ -1,6 +1,6 @@
---- a/utils/common/codec-fwht.h.old	2018-12-29 11:23:58.128328613 -0800
-+++ b/utils/common/codec-fwht.h	2018-12-29 11:24:16.099127560 -0800
-@@ -8,8 +8,26 @@
+--- a/utils/common/codec-fwht.h.old	2019-02-23 09:38:59.454065366 -0800
++++ b/utils/common/codec-fwht.h	2019-02-23 09:40:44.007803414 -0800
+@@ -8,8 +8,27 @@
  #define CODEC_FWHT_H
  
  #include <linux/types.h>
@@ -21,6 +21,7 @@
 +#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
 +
 +
++typedef __u64 u64;
 +typedef __u32 u32;
 +typedef __u16 u16;
 +typedef __s16 s16;
-- 
2.17.1


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

* [v4l-utils PATCH v3 7/8] v4l2-ctl: Add functions and variables to support fwht stateless decoder
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
                   ` (5 preceding siblings ...)
  2019-02-24  8:41 ` [v4l-utils PATCH v3 6/8] v4l-utils: copy fwht-ctrls.h from kernel dir Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  2019-02-24  8:41 ` [v4l-utils PATCH v3 8/8] v4l2-ctl: Add implementation for the stateless fwht decoder Dafna Hirschfeld
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add the variable 'last_fwht_bf_ts' and the array 'fwht_reqs' to
allow the fwht stateless decoder to maintain the requests.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 121 ++++++++++++++++++++++++++
 1 file changed, 121 insertions(+)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index adfa6796..82a93d4b 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -20,11 +20,18 @@
 
 #include "v4l2-ctl.h"
 #include "v4l-stream.h"
+#include <media-info.h>
+#include <fwht-ctrls.h>
 
 extern "C" {
 #include "v4l2-tpg.h"
 }
 
+#define VICODEC_CID_CUSTOM_BASE        (V4L2_CID_MPEG_BASE | 0xf000)
+#define VICODEC_CID_I_FRAME_QP         (VICODEC_CID_CUSTOM_BASE + 0)
+#define VICODEC_CID_P_FRAME_QP         (VICODEC_CID_CUSTOM_BASE + 1)
+#define VICODEC_CID_STATELESS_FWHT     (VICODEC_CID_CUSTOM_BASE + 2)
+
 static unsigned stream_count;
 static unsigned stream_skip;
 static __u32 memory = V4L2_MEMORY_MMAP;
@@ -80,6 +87,16 @@ static bool support_cap_compose;
 static bool support_out_crop;
 static bool in_source_change_event;
 
+static __u64 last_fwht_bf_ts;
+
+struct request_fwht {
+	int fd;
+	__u64 ts;
+	struct v4l2_ctrl_fwht_params params;
+};
+
+static request_fwht fwht_reqs[VIDEO_MAX_FRAME];
+
 #define TS_WINDOW 241
 #define FILE_HDR_ID			v4l2_fourcc('V', 'h', 'd', 'r')
 
@@ -420,6 +437,12 @@ static int get_out_crop_rect(cv4l_fd &fd)
 	return 0;
 }
 
+static __u64 get_ns_timestamp(cv4l_buffer &buf)
+{
+	const struct timeval tv = buf.g_timestamp();
+	return v4l2_timeval_to_ns(&tv);
+}
+
 static void set_time_stamp(cv4l_buffer &buf)
 {
 	if ((buf.g_flags() & V4L2_BUF_FLAG_TIMESTAMP_MASK) != V4L2_BUF_FLAG_TIMESTAMP_COPY)
@@ -749,6 +772,104 @@ void streaming_cmd(int ch, char *optarg)
 	}
 }
 
+/*
+ * Assume that the fwht stream is valid and that each
+ * frame starts right after the previous one.
+ */
+static void read_fwht_frame(cv4l_fmt &fmt, unsigned char *buf,
+			    FILE *fpointer, unsigned &sz,
+			    unsigned &len)
+{
+	struct fwht_cframe_hdr *h = (struct fwht_cframe_hdr *)buf;
+
+	len = sizeof(struct fwht_cframe_hdr);
+	sz = fread(buf, 1, sizeof(struct fwht_cframe_hdr), fpointer);
+	if (sz < sizeof(struct fwht_cframe_hdr))
+		return;
+
+	len += ntohl(h->size);
+	sz += fread(buf + sz, 1, ntohl(h->size), fpointer);
+}
+
+static void set_fwht_stateless_params(struct v4l2_ctrl_fwht_params &fwht_params,
+				      const struct fwht_cframe_hdr *hdr,
+				      __u64 last_bf_ts)
+{
+	fwht_params.backward_ref_ts = last_bf_ts;
+	fwht_params.version = ntohl(hdr->version);
+	fwht_params.width = ntohl(hdr->width);
+	fwht_params.height = ntohl(hdr->height);
+	fwht_params.flags = ntohl(hdr->flags);
+	fwht_params.colorspace = ntohl(hdr->colorspace);
+	fwht_params.xfer_func = ntohl(hdr->xfer_func);
+	fwht_params.ycbcr_enc = ntohl(hdr->ycbcr_enc);
+	fwht_params.quantization = ntohl(hdr->quantization);
+	fwht_params.comp_frame_size = ntohl(hdr->size);
+
+	if (!last_bf_ts)
+		fwht_params.flags |= FWHT_FL_I_FRAME;
+}
+
+static void set_fwht_req_by_idx(unsigned idx, struct fwht_cframe_hdr *hdr,
+				int req_fd, __u64 last_bf_ts, __u64 ts)
+{
+	struct v4l2_ctrl_fwht_params fwht_params;
+
+	set_fwht_stateless_params(fwht_params, hdr, last_bf_ts);
+
+	fwht_reqs[idx].fd = req_fd;
+	fwht_reqs[idx].ts = ts;
+	fwht_reqs[idx].params = fwht_params;
+}
+
+static int get_fwht_req_by_ts(__u64 ts)
+{
+	for (int idx = 0; idx < VIDEO_MAX_FRAME; idx++) {
+		if (fwht_reqs[idx].ts == ts)
+			return idx;
+	}
+	return -1;
+}
+
+static bool set_fwht_req_by_fd(struct fwht_cframe_hdr *hdr,
+			       int req_fd, __u64 last_bf_ts, __u64 ts)
+{
+	struct v4l2_ctrl_fwht_params fwht_params;
+
+	set_fwht_stateless_params(fwht_params, hdr, last_bf_ts);
+
+	for (int idx = 0; idx < VIDEO_MAX_FRAME; idx++) {
+		if (fwht_reqs[idx].fd == req_fd) {
+			fwht_reqs[idx].ts = ts;
+			fwht_reqs[idx].params = fwht_params;
+			return true;
+		}
+	}
+	return false;
+}
+
+static int set_fwht_ext_ctrl(cv4l_fd &fd, struct fwht_cframe_hdr *hdr,
+			     __u64 last_bf_ts, int req_fd)
+{
+	v4l2_ext_controls controls;
+	struct v4l2_ext_control control;
+	struct v4l2_ctrl_fwht_params fwht_params;
+
+	memset(&control, 0, sizeof(control));
+	memset(&controls, 0, sizeof(controls));
+
+	set_fwht_stateless_params(fwht_params, hdr, last_bf_ts);
+
+	control.id = VICODEC_CID_STATELESS_FWHT;
+	control.ptr = &fwht_params;
+	control.size = sizeof(fwht_params);
+	controls.which = V4L2_CTRL_WHICH_REQUEST_VAL;
+	controls.request_fd = req_fd;
+	controls.controls = &control;
+	controls.count = 1;
+	return fd.s_ext_ctrls(controls);
+}
+
 static void read_write_padded_frame(cv4l_fmt &fmt, unsigned char *buf,
 				    FILE *fpointer, unsigned &sz,
 				    unsigned &len, bool is_read)
-- 
2.17.1


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

* [v4l-utils PATCH v3 8/8] v4l2-ctl: Add implementation for the stateless fwht decoder.
  2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
                   ` (6 preceding siblings ...)
  2019-02-24  8:41 ` [v4l-utils PATCH v3 7/8] v4l2-ctl: Add functions and variables to support fwht stateless decoder Dafna Hirschfeld
@ 2019-02-24  8:41 ` Dafna Hirschfeld
  7 siblings, 0 replies; 10+ messages in thread
From: Dafna Hirschfeld @ 2019-02-24  8:41 UTC (permalink / raw)
  To: linux-media; +Cc: hverkuil, helen.koike, Dafna Hirschfeld

Add code to support the stateless decoder
and the function 'stateless_m2m' that implements it.

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
---
 utils/v4l2-ctl/v4l2-ctl-streaming.cpp | 236 +++++++++++++++++++++++++-
 1 file changed, 233 insertions(+), 3 deletions(-)

diff --git a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
index 82a93d4b..db6734e9 100644
--- a/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl-streaming.cpp
@@ -1063,8 +1063,9 @@ restart:
 				return false;
 			}
 		}
-
-		if (support_out_crop && v4l2_fwht_find_pixfmt(fmt.g_pixelformat()))
+		if (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS)
+			read_fwht_frame(fmt, (unsigned char *)buf, fin, sz, len);
+		else if (support_out_crop && v4l2_fwht_find_pixfmt(fmt.g_pixelformat()))
 			read_write_padded_frame(fmt, (unsigned char *)buf, fin, sz, len, true);
 		else
 			sz = fread(buf, 1, len, fin);
@@ -1091,6 +1092,21 @@ restart:
 	return true;
 }
 
+static bool split_fwht_frame(u8 *frame, struct fwht_cframe_hdr *hdr, unsigned max_len)
+{
+	unsigned int len;
+	bool ret = true;
+
+	memcpy(hdr, frame, sizeof(struct fwht_cframe_hdr));
+	len = ntohl(hdr->size);
+	if (len > max_len) {
+		len = max_len;
+		ret = false;
+	}
+	memmove(frame, frame + sizeof(struct fwht_cframe_hdr), len);
+	return ret;
+}
+
 static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf)
 {
 	tpg_pixel_aspect aspect = TPG_PIXEL_ASPECT_SQUARE;
@@ -1195,6 +1211,35 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf
 		if (fin && !fill_buffer_from_file(fd, q, buf, fmt, fin))
 			return -2;
 
+		struct fwht_cframe_hdr hdr;
+
+		if (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
+			int media_fd = mi_get_media_fd(fd.g_fd());
+
+			if (!split_fwht_frame((u8 *)q.g_dataptr(buf.g_index(), 0),
+					      &hdr, buf.g_length(0)))
+				fprintf(stderr, "%s: warning: size field in fwht header is larger than buf size\n",
+					__func__);
+
+			if (media_fd < 0) {
+				fprintf(stderr, "%s: mi_get_media_fd failed\n", __func__);
+				return media_fd;
+			}
+
+			if (q.alloc_req(media_fd, i)) {
+				fprintf(stderr, "%s: q.alloc_req failed\n", __func__);
+				return -1;
+			}
+			buf.s_request_fd(q.g_req_fd(i));
+			buf.or_flags(V4L2_BUF_FLAG_REQUEST_FD);
+
+			if (set_fwht_ext_ctrl(fd, &hdr, last_fwht_bf_ts,
+					      buf.g_request_fd())) {
+				fprintf(stderr, "%s: set_fwht_ext_ctrls failed on %dth buf: %s\n",
+					__func__, i, strerror(errno));
+				return -1;
+			}
+		}
 		if (qbuf) {
 			set_time_stamp(buf);
 			if (fd.qbuf(buf))
@@ -1204,6 +1249,16 @@ static int do_setup_out_buffers(cv4l_fd &fd, cv4l_queue &q, FILE *fin, bool qbuf
 				fprintf(stderr, ">");
 			fflush(stderr);
 		}
+		if (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
+			set_fwht_req_by_idx(i, &hdr, q.g_req_fd(i),
+					    last_fwht_bf_ts, get_ns_timestamp(buf));
+			last_fwht_bf_ts = get_ns_timestamp(buf);
+			if (ioctl(q.g_req_fd(i), MEDIA_REQUEST_IOC_QUEUE) < 0) {
+				fprintf(stderr, "Unable to queue media request: %s\n",
+					strerror(errno));
+				return -1;
+			}
+		}
 	}
 	if (qbuf)
 		output_field = field;
@@ -1442,12 +1497,48 @@ static int do_handle_out(cv4l_fd &fd, cv4l_queue &q, FILE *fin, cv4l_buffer *cap
 				       (u8 *)q.g_dataptr(buf.g_index(), j));
 	}
 
+	struct fwht_cframe_hdr hdr;
+
+	if (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
+		if (ioctl(buf.g_request_fd(), MEDIA_REQUEST_IOC_REINIT, NULL)) {
+			fprintf(stderr, "Unable to reinit media request: %s\n",
+				strerror(errno));
+			return -1;
+		}
+		if (!split_fwht_frame((u8 *)q.g_dataptr(buf.g_index(), 0), &hdr, buf.g_length(0)))
+			fprintf(stderr, "%s: warning: size field in fwht header is larger than buf size\n",
+					__func__);
+
+		if (set_fwht_ext_ctrl(fd, &hdr, last_fwht_bf_ts,
+				      buf.g_request_fd())) {
+			fprintf(stderr, "%s: set_fwht_ext_ctrls failed: %s\n",
+				__func__, strerror(errno));
+			return -1;
+		}
+	}
+
 	set_time_stamp(buf);
 
 	if (fd.qbuf(buf)) {
 		fprintf(stderr, "%s: failed: %s\n", "VIDIOC_QBUF", strerror(errno));
 		return -1;
 	}
+	if (q.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS) {
+		if (!set_fwht_req_by_fd(&hdr, buf.g_request_fd(), last_fwht_bf_ts,
+					get_ns_timestamp(buf))) {
+			fprintf(stderr, "%s: request for fd %d does not exist\n",
+				__func__, buf.g_request_fd());
+			return -1;
+		}
+
+		last_fwht_bf_ts = get_ns_timestamp(buf);
+		if (ioctl(buf.g_request_fd(), MEDIA_REQUEST_IOC_QUEUE) < 0) {
+			fprintf(stderr, "Unable to queue media request: %s\n",
+				strerror(errno));
+			return -1;
+		}
+	}
+
 	tpg_update_mv_count(&tpg, V4L2_FIELD_HAS_T_OR_B(output_field));
 
 	if (!verbose)
@@ -2236,6 +2327,140 @@ static void stateful_m2m(cv4l_fd &fd, cv4l_queue &in, cv4l_queue &out,
 	tpg_free(&tpg);
 }
 
+static void stateless_m2m(cv4l_fd &fd, cv4l_queue &in, cv4l_queue &out,
+			  FILE *fin, FILE *fout, cv4l_fd *exp_fd_p)
+{
+	fps_timestamps fps_ts[2];
+	unsigned count[2] = { 0, 0 };
+	cv4l_fmt fmt[2];
+	int fd_flags = fcntl(fd.g_fd(), F_GETFL);
+
+	fd.g_fmt(fmt[OUT], out.g_type());
+	fd.g_fmt(fmt[CAP], in.g_type());
+
+	if (out.reqbufs(&fd, reqbufs_count_out)) {
+		fprintf(stderr, "%s: out.reqbufs failed\n", __func__);
+		return;
+	}
+
+	if (in.reqbufs(&fd, reqbufs_count_cap)) {
+		fprintf(stderr, "%s: in.reqbufs failed\n", __func__);
+		return;
+	}
+
+	if (exp_fd_p && in.export_bufs(exp_fd_p, exp_fd_p->g_type()))
+		return;
+
+	if (in.obtain_bufs(&fd)) {
+		fprintf(stderr, "%s: in.obtain_bufs error\n", __func__);
+		return;
+	}
+
+	if (do_setup_out_buffers(fd, out, fout, true) == -1) {
+		fprintf(stderr, "%s: do_setup_out_buffers failed\n", __func__);
+		return;
+	}
+
+	if (in.queue_all(&fd)) {
+		fprintf(stderr, "%s: in.queue_all failed\n", __func__);
+		return;
+	}
+
+	if (fd.streamon(out.g_type())) {
+		fprintf(stderr, "%s: streamon for out failed\n", __func__);
+		return;
+	}
+
+	if (fd.streamon(in.g_type())) {
+		fprintf(stderr, "%s: streamon for in failed\n", __func__);
+		return;
+	}
+	int index = 0;
+	bool queue_lst_buf = false;
+	cv4l_buffer last_in_buf;
+
+	fcntl(fd.g_fd(), F_SETFL, fd_flags | O_NONBLOCK);
+
+	while (true) {
+		fd_set except_fds;
+		int req_fd = out.g_req_fd(index);
+		struct timeval tv = { 2, 0 };
+
+		FD_ZERO(&except_fds);
+		FD_SET(req_fd, &except_fds);
+
+		int rc = select(req_fd + 1, NULL, NULL, &except_fds, &tv);
+
+		if (rc == 0) {
+			fprintf(stderr, "Timeout when waiting for media request\n");
+			return;
+		} else if (rc < 0) {
+			fprintf(stderr, "Unable to select media request: %s\n",
+				strerror(errno));
+			return;
+		}
+		/*
+		 * it is safe to queue back last cap buffer only after
+		 * the following request is done so that the buffer
+		 * is not needed anymore as a reference frame
+		 */
+		if (queue_lst_buf) {
+			if (fd.qbuf(last_in_buf) < 0) {
+				fprintf(stderr, "%s: qbuf failed\n", __func__);
+				return;
+			}
+		}
+		int buf_idx = -1;
+		  /*
+		   * fin is not sent to do_handle_cap since the capture buf is
+		   * written to the file in current function
+		   */
+		rc = do_handle_cap(fd, in, NULL, &buf_idx, count[CAP],
+				   fps_ts[CAP], fmt[CAP]);
+		if (rc) {
+			fprintf(stderr, "%s: do_handle_cap err\n", __func__);
+			return;
+		}
+		/*
+		 * in case of an error in the frame, set last ts to 0 as a mean
+		 * to recover so that next request will not use a
+		 * reference buffer. Otherwise the error flag will be set to
+		 * all the future capture buffers.
+		 */
+		if (buf_idx == -1) {
+			fprintf(stderr, "%s: frame returned with error\n", __func__);
+			last_fwht_bf_ts	= 0;
+		} else {
+			cv4l_buffer cap_buf(in, index);
+			if (fd.querybuf(cap_buf))
+				return;
+			last_in_buf = cap_buf;
+			queue_lst_buf = true;
+			if (fin && cap_buf.g_bytesused(0) &&
+			    !(cap_buf.g_flags() & V4L2_BUF_FLAG_ERROR)) {
+				int idx = get_fwht_req_by_ts(get_ns_timestamp(cap_buf));
+
+				if (idx < 0) {
+					fprintf(stderr, "%s: could not find request from buffer\n", __func__);
+					fprintf(stderr, "%s: ts = %llu\n", __func__, get_ns_timestamp(cap_buf));
+					return;
+				}
+				composed_width = fwht_reqs[idx].params.width;
+				composed_height = fwht_reqs[idx].params.height;
+				write_buffer_to_file(fd, in, cap_buf,
+						     fmt[CAP], fin);
+			}
+		}
+		rc = do_handle_out(fd, out, fout, NULL, count[OUT],
+				   fps_ts[OUT], fmt[OUT]);
+		if (rc) {
+			fprintf(stderr, "%s: output stream ended\n", __func__);
+			close(req_fd);
+		}
+		index = (index + 1) % out.g_buffers();
+	}
+}
+
 static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 {
 	cv4l_queue in(fd.g_type(), memory);
@@ -2272,7 +2497,12 @@ static void streaming_set_m2m(cv4l_fd &fd, cv4l_fd &exp_fd)
 		if (out.export_bufs(&exp_fd, exp_fd.g_type()))
 			return;
 	}
-	stateful_m2m(fd, in, out, file[CAP], file[OUT], exp_fd_p);
+	if (out.reqbufs(&fd, 0))
+		goto done;
+	if (out.g_capabilities() & V4L2_BUF_CAP_SUPPORTS_REQUESTS)
+		stateless_m2m(fd, in, out, file[CAP], file[OUT], exp_fd_p);
+	else
+		stateful_m2m(fd, in, out, file[CAP], file[OUT], exp_fd_p);
 done:
 	if (options[OptStreamDmaBuf] || options[OptStreamOutDmaBuf])
 		exp_q.close_exported_fds();
-- 
2.17.1


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

* Re: [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api
  2019-02-24  8:41 ` [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api Dafna Hirschfeld
@ 2019-02-25 10:38   ` Hans Verkuil
  0 siblings, 0 replies; 10+ messages in thread
From: Hans Verkuil @ 2019-02-25 10:38 UTC (permalink / raw)
  To: Dafna Hirschfeld, linux-media; +Cc: helen.koike

On 2/24/19 9:41 AM, Dafna Hirschfeld wrote:
> Add an array of request file descriptors to v4l_queue
> and add methods to allocate and get them.
> 
> Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>

This patch isn't right, just drop it altogether. These helpers are for v4l2 devices,
not for a media device.

Just use the media ioctls directly in v4l2-ctl and make the req_fds array a local
array in a function or perhaps a global in v4l2-ctl-streaming.cpp.

Regards,

	Hans

> ---
>  utils/common/cv4l-helpers.h |  5 +++++
>  utils/common/v4l-helpers.h  | 22 ++++++++++++++++++++++
>  2 files changed, 27 insertions(+)
> 
> diff --git a/utils/common/cv4l-helpers.h b/utils/common/cv4l-helpers.h
> index 1cd2b6b2..551d4673 100644
> --- a/utils/common/cv4l-helpers.h
> +++ b/utils/common/cv4l-helpers.h
> @@ -745,6 +745,7 @@ public:
>  	unsigned g_capabilities() const { return v4l_queue_g_capabilities(this); }
>  	unsigned g_length(unsigned plane) const { return v4l_queue_g_length(this, plane); }
>  	unsigned g_mem_offset(unsigned index, unsigned plane) const { return v4l_queue_g_mem_offset(this, index, plane); }
> +	unsigned g_req_fd(unsigned index) const { return v4l_queue_g_req_fd(this, index); }
>  	void *g_mmapping(unsigned index, unsigned plane) const { return v4l_queue_g_mmapping(this, index, plane); }
>  	void s_mmapping(unsigned index, unsigned plane, void *m) { v4l_queue_s_mmapping(this, index, plane, m); }
>  	void *g_userptr(unsigned index, unsigned plane) const { return v4l_queue_g_userptr(this, index, plane); }
> @@ -797,6 +798,10 @@ public:
>  	{
>  		return v4l_queue_export_bufs(fd->g_v4l_fd(), this, exp_type);
>  	}
> +	int alloc_req(int media_fd, unsigned index)
> +	{
> +		return v4l_queue_alloc_req(this, media_fd, index);
> +	}
>  	void close_exported_fds()
>  	{
>  		v4l_queue_close_exported_fds(this);
> diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h
> index 59d8566a..daa49a1f 100644
> --- a/utils/common/v4l-helpers.h
> +++ b/utils/common/v4l-helpers.h
> @@ -10,6 +10,7 @@
>  #define _V4L_HELPERS_H_
>  
>  #include <linux/videodev2.h>
> +#include <linux/media.h>
>  #include <string.h>
>  #include <stdlib.h>
>  #include <stdio.h>
> @@ -1414,6 +1415,7 @@ struct v4l_queue {
>  	void *mmappings[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
>  	unsigned long userptrs[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
>  	int fds[VIDEO_MAX_FRAME][VIDEO_MAX_PLANES];
> +	int req_fds[VIDEO_MAX_FRAME];
>  };
>  
>  static inline void v4l_queue_init(struct v4l_queue *q,
> @@ -1445,6 +1447,11 @@ static inline __u32 v4l_queue_g_mem_offset(const struct v4l_queue *q, unsigned i
>  	return q->mem_offsets[index][plane];
>  }
>  
> +static inline unsigned v4l_queue_g_req_fd(const struct v4l_queue *q, unsigned index)
> +{
> +	return q->req_fds[index];
> +}
> +
>  static inline void v4l_queue_s_mmapping(struct v4l_queue *q, unsigned index, unsigned plane, void *m)
>  {
>  	q->mmappings[index][plane] = m;
> @@ -1701,6 +1708,21 @@ static inline int v4l_queue_export_bufs(struct v4l_fd *f, struct v4l_queue *q,
>  	return 0;
>  }
>  
> +static inline int v4l_queue_alloc_req(struct v4l_queue *q, int media_fd, unsigned index)
> +{
> +	int rc = 0;
> +
> +	rc = ioctl(media_fd, MEDIA_IOC_REQUEST_ALLOC, &q->req_fds[index]);
> +	if (rc < 0) {
> +		fprintf(stderr, "Unable to allocate media request: %s\n",
> +			strerror(errno));
> +		return rc;
> +	}
> +
> +	return 0;
> +}
> +
> +
>  static inline void v4l_queue_close_exported_fds(struct v4l_queue *q)
>  {
>  	unsigned b, p;
> 


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

end of thread, other threads:[~2019-02-25 10:38 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-24  8:41 [v4l-utils PATCH v3 0/8] add support to stateless decoder Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 1/8] v4l2-ctl: rename variable 'vic_fmt' to 'info' Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 2/8] v4l2-ctl: bugfix: correctly read/write V4L2_PIX_FMT_NV24 padded buffer Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 3/8] v4l2-ctl: test if do_setup_out_buffers returns -1 instead of non zero Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 4/8] v4l2-ctl: move stateful m2m decode code to a separate function Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 5/8] (c)v4l-helpers.h: Add support for the request api Dafna Hirschfeld
2019-02-25 10:38   ` Hans Verkuil
2019-02-24  8:41 ` [v4l-utils PATCH v3 6/8] v4l-utils: copy fwht-ctrls.h from kernel dir Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 7/8] v4l2-ctl: Add functions and variables to support fwht stateless decoder Dafna Hirschfeld
2019-02-24  8:41 ` [v4l-utils PATCH v3 8/8] v4l2-ctl: Add implementation for the stateless fwht decoder Dafna Hirschfeld

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.