d/vf: Refactor code to add videotestsrc capability and break out gstreamer detection

This commit is contained in:
Jakob Bornecrantz 2021-02-01 19:04:39 +00:00
parent 5853103820
commit 35da4a51ea
8 changed files with 113 additions and 64 deletions

View file

@ -128,7 +128,6 @@ cmake_dependent_option(XRT_HAVE_OPENGL "Enable OpenGL Graphics API support" ON "
cmake_dependent_option(XRT_HAVE_OPENGLES "Enable OpenGL-ES Graphics API support" ON "OpenGLES_FOUND" OFF)
cmake_dependent_option(XRT_HAVE_EGL "Enable OpenGL on EGL Graphics API support" ON "EGL_FOUND; XRT_HAVE_OPENGL OR XRT_HAVE_OPENGLES" OFF)
cmake_dependent_option(XRT_HAVE_DBUS "Enable dbus support (for BLE support)" ON "DBUS_FOUND" OFF)
cmake_dependent_option(XRT_HAVE_VF "Enable gstreamer support (for video file support)" ON "GST_FOUND" OFF)
cmake_dependent_option(XRT_FEATURE_COMPOSITOR_MAIN "Build main compositor host functionality" ON "XRT_HAVE_VULKAN; XRT_HAVE_WAYLAND OR XRT_HAVE_XCB OR ANDROID OR WIN32" OFF)
cmake_dependent_option(XRT_FEATURE_OPENXR "Build OpenXR runtime target" ON "XRT_FEATURE_COMPOSITOR_MAIN" OFF)
cmake_dependent_option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" ON "NOT WIN32" OFF)
@ -172,6 +171,7 @@ cmake_dependent_option(XRT_HAVE_LIBUVC "Enable libuvc video driver" ON "LIBUVC_F
cmake_dependent_option(XRT_HAVE_FFMPEG "Enable ffmpeg testing video driver" ON "FFMPEG_FOUND" OFF)
cmake_dependent_option(XRT_HAVE_SDL2 "Enable use of SDL2" ON "SDL2_FOUND AND XRT_HAVE_OPENGL" OFF)
cmake_dependent_option(XRT_HAVE_SYSTEM_CJSON "Enable cJSON from system, instead of bundled source" ON "CJSON_FOUND" OFF)
cmake_dependent_option(XRT_HAVE_GST "Enable gstreamer" ON "GST_FOUND" OFF)
cmake_dependent_option(XRT_BUILD_DRIVER_PSVR "Enable PSVR HMD driver" ON "HIDAPI_FOUND" OFF)
@ -191,6 +191,7 @@ cmake_dependent_option(XRT_BUILD_DRIVER_HDK "Enable HDK driver" ON "XRT_HAVE_INT
cmake_dependent_option(XRT_BUILD_DRIVER_PSMV "Enable Playstation Move driver" ON "XRT_HAVE_INTERNAL_HID" OFF)
cmake_dependent_option(XRT_BUILD_DRIVER_HYDRA "Enable Hydra driver" ON "XRT_HAVE_INTERNAL_HID" OFF)
cmake_dependent_option(XRT_BUILD_DRIVER_NS "Enable North Star driver" ON "XRT_HAVE_INTERNAL_HID" OFF)
cmake_dependent_option(XRT_BUILD_DRIVER_VF "Build video frame driver (for video file support, uses gstreamer)" ON "XRT_HAVE_GST" OFF)
# This one defaults to off, even if we find the deps.
cmake_dependent_option(XRT_BUILD_DRIVER_SURVIVE "Enable libsurvive driver" ON "SURVIVE_FOUND" OFF)
@ -216,6 +217,7 @@ list(APPEND AVAILABLE_DRIVERS
"REMOTE"
"SURVIVE"
"V4L2"
"VF"
"VIVE"
)
@ -348,5 +350,6 @@ message(STATUS "# DRIVER_PSVR: ${XRT_BUILD_DRIVER_PSVR}")
message(STATUS "# DRIVER_RS: ${XRT_BUILD_DRIVER_RS}")
message(STATUS "# DRIVER_REMOTE: ${XRT_BUILD_DRIVER_REMOTE}")
message(STATUS "# DRIVER_SURVIVE: ${XRT_BUILD_DRIVER_SURVIVE}")
message(STATUS "# DRIVER_VF: ${XRT_BUILD_DRIVER_VF}")
message(STATUS "# DRIVER_VIVE: ${XRT_BUILD_DRIVER_VIVE}")
message(STATUS "#####----- Config -----#####")

View file

@ -192,7 +192,7 @@ if(XRT_HAVE_V4L2)
list(APPEND ENABLED_DRIVERS v4l2)
endif()
if(XRT_HAVE_VF)
if(XRT_BUILD_DRIVER_VF)
set(VF_SOURCE_FILES
vf/vf_driver.c
)

View file

@ -61,7 +61,6 @@ struct vf_fs
struct os_thread_helper play_thread;
const char *path;
GMainLoop *loop;
GstElement *source;
GstElement *testsink;
@ -280,7 +279,7 @@ on_new_sample_from_sink(GstElement *elt, struct vf_fs *vid)
gst_structure_get_int(structure, "width", &width);
gst_structure_get_int(structure, "height", &height);
VF_DEBUG(vid, "video size is %dx%d\n", width, height);
VF_DEBUG(vid, "video size is %dx%d", width, height);
vid->got_sample = true;
vid->width = width;
vid->height = height;
@ -303,8 +302,8 @@ print_gst_error(GstMessage *message)
gchar *dbg_info = NULL;
gst_message_parse_error(message, &err, &dbg_info);
U_LOG_E("ERROR from element %s: %s\n", GST_OBJECT_NAME(message->src), err->message);
U_LOG_E("Debugging info: %s\n", (dbg_info) ? dbg_info : "none");
U_LOG_E("ERROR from element %s: %s", GST_OBJECT_NAME(message->src), err->message);
U_LOG_E("Debugging info: %s", (dbg_info) ? dbg_info : "none");
g_error_free(err);
g_free(dbg_info);
}
@ -315,11 +314,11 @@ on_source_message(GstBus *bus, GstMessage *message, struct vf_fs *vid)
/* nil */
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_EOS:
VF_DEBUG(vid, "Finished playback\n");
VF_DEBUG(vid, "Finished playback.");
g_main_loop_quit(vid->loop);
break;
case GST_MESSAGE_ERROR:
VF_ERROR(vid, "Received error\n");
VF_ERROR(vid, "Received error.");
print_gst_error(message);
g_main_loop_quit(vid->loop);
break;
@ -333,9 +332,9 @@ run_play_thread(void *ptr)
{
struct vf_fs *vid = (struct vf_fs *)ptr;
VF_DEBUG(vid, "Let's run!\n");
VF_DEBUG(vid, "Let's run!");
g_main_loop_run(vid->loop);
VF_DEBUG(vid, "Going out\n");
VF_DEBUG(vid, "Going out!");
gst_object_unref(vid->testsink);
gst_element_set_state(vid->source, GST_STATE_NULL);
@ -347,56 +346,35 @@ run_play_thread(void *ptr)
return NULL;
}
struct xrt_fs *
vf_fs_create(struct xrt_frame_context *xfctx, const char *path)
static struct xrt_fs *
alloc_and_init_common(struct xrt_frame_context *xfctx, //
enum xrt_format format, //
enum xrt_stereo_format stereo_format, //
gchar *pipeline_string) //
{
if (path == NULL) {
U_LOG_E("No path given");
return NULL;
}
struct vf_fs *vid = U_TYPED_CALLOC(struct vf_fs);
vid->path = path;
vid->got_sample = false;
vid->format = format;
vid->stereo_format = stereo_format;
gchar *loop = "false";
gchar *string = NULL;
GstBus *bus = NULL;
gst_init(0, NULL);
if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
VF_ERROR(vid, "File %s does not exist\n", path);
int ret = os_thread_helper_init(&vid->play_thread);
if (ret < 0) {
VF_ERROR(vid, "Failed to init thread");
g_free(pipeline_string);
free(vid);
return NULL;
}
vid->loop = g_main_loop_new(NULL, FALSE);
VF_DEBUG(vid, "Pipeline: %s", pipeline_string);
#if 0
const gchar *caps = "video/x-raw,format=RGB";
vid->format = XRT_FORMAT_R8G8B8;
vid->stereo_format = XRT_STEREO_FORMAT_SBS;
#endif
#if 1
const gchar *caps = "video/x-raw,format=YUY2";
vid->format = XRT_FORMAT_YUYV422;
vid->stereo_format = XRT_STEREO_FORMAT_SBS;
#endif
string = g_strdup_printf(
"multifilesrc location=\"%s\" loop=%s ! decodebin ! videoconvert ! "
"appsink caps=\"%s\" name=testsink",
path, loop, caps);
VF_DEBUG(vid, "Pipeline: %s\n", string);
vid->source = gst_parse_launch(string, NULL);
g_free(string);
vid->source = gst_parse_launch(pipeline_string, NULL);
g_free(pipeline_string);
if (vid->source == NULL) {
VF_ERROR(vid, "Bad source\n");
VF_ERROR(vid, "Bad source");
g_main_loop_unref(vid->loop);
free(vid);
return NULL;
@ -410,16 +388,21 @@ vf_fs_create(struct xrt_frame_context *xfctx, const char *path)
gst_bus_add_watch(bus, (GstBusFunc)on_source_message, vid);
gst_object_unref(bus);
int ret = os_thread_helper_start(&vid->play_thread, run_play_thread, vid);
if (!ret) {
VF_ERROR(vid, "Failed to start thread");
ret = os_thread_helper_start(&vid->play_thread, run_play_thread, vid);
if (ret != 0) {
VF_ERROR(vid, "Failed to start thread '%i'", ret);
g_main_loop_unref(vid->loop);
free(vid);
return NULL;
}
// we need one sample to determine frame size
// We need one sample to determine frame size.
VF_DEBUG(vid, "Waiting for frame");
gst_element_set_state(vid->source, GST_STATE_PLAYING);
while (!vid->got_sample) {
os_nanosleep(100 * 1000 * 1000);
}
VF_DEBUG(vid, "Got first sample");
gst_element_set_state(vid->source, GST_STATE_PAUSED);
vid->base.enumerate_modes = vf_fs_enumerate_modes;
@ -443,3 +426,61 @@ vf_fs_create(struct xrt_frame_context *xfctx, const char *path)
return &(vid->base);
}
struct xrt_fs *
vf_fs_videotestsource(struct xrt_frame_context *xfctx, uint32_t width, uint32_t height)
{
gst_init(0, NULL);
enum xrt_format format = XRT_FORMAT_R8G8B8;
enum xrt_stereo_format stereo_format = XRT_STEREO_FORMAT_NONE;
gchar *pipeline_string = g_strdup_printf(
"videotestsrc name=source ! "
"videoconvert ! "
"videoscale ! "
"video/x-raw,format=RGB,width=%u,height=%u ! "
"appsink name=testsink",
width, height);
return alloc_and_init_common(xfctx, format, stereo_format, pipeline_string);
}
struct xrt_fs *
vf_fs_open_file(struct xrt_frame_context *xfctx, const char *path)
{
if (path == NULL) {
U_LOG_E("No path given");
return NULL;
}
gst_init(0, NULL);
if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
U_LOG_E("File %s does not exist", path);
return NULL;
}
#if 0
const gchar *caps = "video/x-raw,format=RGB";
enum xrt_format format = XRT_FORMAT_R8G8B8;
enum xrt_stereo_format stereo_format = XRT_STEREO_FORMAT_NONE;
#endif
#if 1
const gchar *caps = "video/x-raw,format=YUY2";
enum xrt_format format = XRT_FORMAT_YUYV422;
enum xrt_stereo_format stereo_format = XRT_STEREO_FORMAT_SBS;
#endif
gchar *loop = "false";
gchar *pipeline_string = g_strdup_printf(
"multifilesrc location=\"%s\" loop=%s ! "
"decodebin ! "
"videoconvert ! "
"appsink caps=\"%s\" name=testsink",
path, loop, caps);
return alloc_and_init_common(xfctx, format, stereo_format, pipeline_string);
}

View file

@ -1,4 +1,4 @@
// Copyright 2029, Collabora, Ltd.
// Copyright 2020-2021, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
@ -11,6 +11,7 @@
#include "xrt/xrt_frameserver.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -23,14 +24,22 @@ extern "C" {
*/
/*!
* Create a vf frameserver
* Create a vf frameserver by opening a video file.
*
* @ingroup drv_vf
*/
struct xrt_fs *
vf_fs_create(struct xrt_frame_context *xfctx, const char *path);
vf_fs_open_file(struct xrt_frame_context *xfctx, const char *path);
/*!
* Create a vf frameserver that uses the videotestsource.
*
* @ingroup drv_vf
*/
struct xrt_fs *
vf_fs_videotestsource(struct xrt_frame_context *xfctx, uint32_t width, uint32_t height);
#ifdef __cplusplus
}
#endif

View file

@ -68,10 +68,6 @@ if has_v4l2_header and 'v4l2' in drivers
have_conf.set('XRT_HAVE_V4L2', true)
endif
if 'vf' in drivers
have_conf.set('XRT_HAVE_VF', true)
endif
if true
have_conf.set('XRT_HAVE_VULKAN', true)
endif

View file

@ -10,9 +10,9 @@
#pragma once
#cmakedefine XRT_HAVE_DBUS
#cmakedefine XRT_HAVE_VF
#cmakedefine XRT_HAVE_EGL
#cmakedefine XRT_HAVE_FFMPEG
#cmakedefine XRT_HAVE_GST
#cmakedefine XRT_HAVE_JPEG
#cmakedefine XRT_HAVE_LIBUDEV
#cmakedefine XRT_HAVE_LIBUSB

View file

@ -20,7 +20,7 @@
#include "v4l2/v4l2_interface.h"
#endif
#ifdef XRT_HAVE_VF
#ifdef XRT_BUILD_DRIVER_VF
#include "vf/vf_interface.h"
#endif
@ -742,10 +742,10 @@ open_video_device(struct xrt_prober *xp,
{
XRT_MAYBE_UNUSED struct prober_device *pdev = (struct prober_device *)xpdev;
#if defined(XRT_HAVE_VF)
#if defined(XRT_BUILD_DRIVER_VF)
const char *path = debug_get_option_vf_path();
if (path != NULL) {
struct xrt_fs *xfs = vf_fs_create(xfctx, path);
struct xrt_fs *xfs = vf_fs_open_file(xfctx, path);
if (xfs) {
*out_xfs = xfs;
return 0;

View file

@ -72,7 +72,7 @@ if(XRT_HAVE_V4L2)
target_link_libraries(target_lists PRIVATE drv_v4l2)
endif()
if(XRT_HAVE_VF)
if(XRT_BUILD_DRIVER_VF)
target_link_libraries(target_lists PRIVATE drv_vf)
endif()