mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
d/vf: Refactor code to add videotestsrc capability and break out gstreamer detection
This commit is contained in:
parent
5853103820
commit
35da4a51ea
|
@ -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 -----#####")
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in a new issue