From d313a049482766d3372486c9e17a19c0ff9f04a6 Mon Sep 17 00:00:00 2001
From: Jakob Bornecrantz <jakob@collabora.com>
Date: Sat, 31 Aug 2019 15:05:08 +0100
Subject: [PATCH] WORK

---
 src/xrt/auxiliary/CMakeLists.txt     |  1 +
 src/xrt/auxiliary/util/u_sink_pool.c | 62 ++++++++++++++++++++
 src/xrt/targets/cli/cli_main.c       | 86 +++++++++++++++++++++++++++-
 3 files changed, 147 insertions(+), 2 deletions(-)
 create mode 100644 src/xrt/auxiliary/util/u_sink_pool.c

diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt
index c3a36f316..5d7882fec 100644
--- a/src/xrt/auxiliary/CMakeLists.txt
+++ b/src/xrt/auxiliary/CMakeLists.txt
@@ -47,6 +47,7 @@ set(UTIL_SOURCE_FILES
 	util/u_hashset.h
 	util/u_sink.h
 	util/u_sink_converter.c
+	util/u_sink_pool.c
 	util/u_sink_queue.c
 	util/u_sink_split.c
 	util/u_time.cpp
diff --git a/src/xrt/auxiliary/util/u_sink_pool.c b/src/xrt/auxiliary/util/u_sink_pool.c
new file mode 100644
index 000000000..d945629c0
--- /dev/null
+++ b/src/xrt/auxiliary/util/u_sink_pool.c
@@ -0,0 +1,62 @@
+// Copyright 2019, Collabora, Ltd.
+// SPDX-License-Identifier: BSL-1.0
+/*!
+ * @file
+ * @brief  Pool for @ref xrt_frame.
+ * @author Jakob Bornecrantz <jakob@collabora.com>
+ * @ingroup aux_util
+ */
+
+#include "util/u_sink.h"
+
+#include <assert.h>
+#include <pthread.h>
+
+
+struct xrt_frame_pool
+{
+	pthread_mutex_t mutex;
+
+	struct xrt_frame **frames;
+	uint32_t num_frames;
+	uint32_t num_pool_pop;
+};
+
+
+static void
+free_frame(struct xrt_frame *xf, void *owner)
+{
+	struct xrt_frame_pool *p = (struct xrt_frame_pool *)owner;
+	// Have to lock it again.
+	pthread_mutex_lock(&p->mutex);
+
+	assert(xf->reference.count == 0);
+	assert(p->num_pool_pop < p->num_frames);
+
+	p->frames[p->num_pool_pop++] = xf;
+
+	pthread_mutex_unlock(&p->mutex);
+}
+
+bool
+xrt_frame_pool_get(struct xrt_frame_pool *p, struct xrt_frame **out_frame)
+{
+	struct xrt_frame *xf = NULL;
+
+	pthread_mutex_lock(&p->mutex);
+
+	if (p->num_pool_pop == 0) {
+		pthread_mutex_unlock(&p->mutex);
+		return false;
+	}
+
+	xf = p->frames[--p->num_pool_pop];
+	p->frames[p->num_pool_pop] = NULL;
+
+	pthread_mutex_unlock(&p->mutex);
+
+	// Make sure to reference without the lock being held.
+	xrt_frame_reference(out_frame, xf);
+
+	return true;
+}
diff --git a/src/xrt/targets/cli/cli_main.c b/src/xrt/targets/cli/cli_main.c
index 1960057c3..2790b99f4 100644
--- a/src/xrt/targets/cli/cli_main.c
+++ b/src/xrt/targets/cli/cli_main.c
@@ -6,14 +6,21 @@
  * @author Jakob Bornecrantz <jakob@collabora.com>
  */
 
-#include <string.h>
-#include <stdio.h>
+#include "util/u_sink.h"
+#include "util/u_format.h"
+
+#include "tracking/t_tracking.h"
 
 #include "cli_common.h"
 
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
 
 #define P(...) fprintf(stderr, __VA_ARGS__)
 
+#if 0
 static int
 cli_print_help(int argc, const char **argv)
 {
@@ -30,10 +37,39 @@ cli_print_help(int argc, const char **argv)
 
 	return 1;
 }
+#endif
+
+#include "v4l2/v4l2_interface.h"
+
+static void
+print_modes(struct xrt_fs *xfs)
+{
+	struct xrt_fs_mode *modes = NULL;
+	uint32_t count = 0;
+
+	xrt_fs_enumerate_modes(xfs, &modes, &count);
+
+	P("Got %u mode%s\n", count, count == 1 ? "" : "s");
+
+	for (uint32_t i = 0; i < count; i++) {
+		P("%6i - %dx%d %s\n", i, modes[i].width, modes[i].height,
+		  u_format_str(modes[i].format));
+	}
+
+	free(modes);
+}
+
+static void
+push_frame(struct xrt_frame_sink *sink, struct xrt_frame *f)
+{
+	P("%s - Got frame #%u %ux%u\n", __func__, (uint32_t)f->source_sequence,
+	  f->width, f->height);
+}
 
 int
 main(int argc, const char **argv)
 {
+#if 0
 	if (argc <= 1) {
 		return cli_print_help(argc, argv);
 	}
@@ -44,5 +80,51 @@ main(int argc, const char **argv)
 	if (strcmp(argv[1], "calibrate") == 0) {
 		return cli_cmd_calibrate(argc, argv);
 	}
+
 	return cli_print_help(argc, argv);
+#endif
+
+	if (argc != 3) {
+		fprintf(stderr, "Must supply exactly two arguments!\n");
+		fprintf(stderr, "\tdevice file\n");
+		fprintf(stderr, "\tmode number\n");
+	}
+
+	struct xrt_frame_context xfctx = {0};
+	struct xrt_frame_sink cli_sink = {0};
+	cli_sink.push_frame = push_frame;
+
+	struct xrt_frame_sink *xsink = &cli_sink;
+
+	struct xrt_frame_sink *xsinks[4] = {&cli_sink, NULL, NULL, NULL};
+	struct t_hsv_filter_params params = T_HSV_DEFAULT_PARAMS();
+	t_hsv_filter_create(&xfctx, &params, xsinks, &xsink);
+
+	// u_sink_queue_create(&xfctx, xsink, &xsink);
+	// u_sink_create_format_converter(&xfctx, XRT_FORMAT_R8G8B8, xsink,
+	//                                &xsink);
+	u_sink_queue_create(&xfctx, xsink, &xsink);
+
+	struct xrt_fs *xfs = v4l2_fs_create(&xfctx, argv[1]);
+	if (xfs == NULL) {
+		fprintf(stderr, "Failed to create frameserver!\n");
+		return -1;
+	}
+
+	// Just to be helpful
+	print_modes(xfs);
+
+	// Start it up!
+	xrt_fs_stream_start(xfs, xsink, atoi(argv[2]));
+
+	// Sleep five seconds.
+	usleep(3 * 1000 * 1000);
+
+	// Stop it and destroy it.
+	xrt_fs_stream_stop(xfs);
+
+	// Tear everything down.
+	xrt_frame_context_destroy_nodes(&xfctx);
+
+	return 0;
 }
-- 
GitLab