diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt index c3a36f316be93026a44bf3e6dc77817e17a7da7b..5d7882fec3b2dddbc08481ca3567421f0530ef1f 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 0000000000000000000000000000000000000000..d945629c01f21f742512b1e5d235501ca567cb5b --- /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 1960057c35a7e1c5b1e8e2fcc289dc2705b0ad3b..2790b99f4d77b93ccc98926baf716bc453b3674f 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, ¶ms, 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; }