mirror of
https://github.com/outbackdingo/UltraGrid.git
synced 2026-03-19 23:09:13 +00:00
displays: changed api for mainloop
- removed `needs_mainloop` attribute and deduce if mainloop is needed from the presence of _run callback (the information is now redundant only displays needing/running mainloop should announce _run callback) - run the custom mainloop (currently only Syphon!) only when display doesn't run its mainloop. This allows running Syphon and GL/SDL display because it connects to the display mainloop.
This commit is contained in:
@@ -89,7 +89,6 @@ static const struct video_display_info display_aja_info = {
|
||||
display_aja_get_property,
|
||||
display_aja_put_audio_frame,
|
||||
display_aja_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -827,6 +827,11 @@ void print_video_codecs(void) {
|
||||
cout << "\nLegend:\n" << " I - interframe codec\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers mainloop that will be run if display-owned mainloop isn't run.
|
||||
* Currently this is only used by Syphon, that either connects to display event
|
||||
* loop and if there isn't any, it runs its own.
|
||||
*/
|
||||
bool register_mainloop(mainloop_t m, void *u)
|
||||
{
|
||||
if (mainloop) {
|
||||
|
||||
@@ -102,6 +102,7 @@ extern unsigned int cuda_devices_count;
|
||||
#define MODE_RECEIVER (1U<<1U)
|
||||
|
||||
typedef void (*mainloop_t)(void *);
|
||||
/// mainloop to be run if display mainloop isn't run
|
||||
extern mainloop_t mainloop;
|
||||
extern void *mainloop_udata;
|
||||
|
||||
|
||||
12
src/main.cpp
12
src/main.cpp
@@ -1658,17 +1658,7 @@ int main(int argc, char *argv[])
|
||||
control_start(control);
|
||||
kc.start();
|
||||
|
||||
if(mainloop) {
|
||||
if (display_needs_mainloop(uv.display_device)) {
|
||||
throw string("Cannot run display when "
|
||||
"another mainloop registered!\n");
|
||||
}
|
||||
display_run_new_thread(uv.display_device);
|
||||
mainloop(mainloop_udata);
|
||||
display_join(uv.display_device);
|
||||
} else {
|
||||
display_run_this_thread(uv.display_device);
|
||||
}
|
||||
display_run_mainloop(uv.display_device);
|
||||
|
||||
} catch (ug_no_error const &e) {
|
||||
exit_uv(0);
|
||||
|
||||
@@ -195,13 +195,7 @@ void display_done(struct display *d)
|
||||
bool display_needs_mainloop(struct display *d)
|
||||
{
|
||||
assert(d->magic == DISPLAY_MAGIC);
|
||||
if (d->funcs->needs_mainloop == DISPLAY_NEEDS_MAINLOOP) {
|
||||
return true;
|
||||
}
|
||||
if (d->funcs->needs_mainloop == DISPLAY_DOESNT_NEED_MAINLOOP) {
|
||||
return false;
|
||||
}
|
||||
return d->funcs->needs_mainloop(d->state);
|
||||
return d->funcs->run != NULL;
|
||||
}
|
||||
|
||||
#define CHECK(cmd) do { \
|
||||
@@ -225,29 +219,25 @@ static void *display_run_helper(void *args)
|
||||
/**
|
||||
* @brief Display mainloop function.
|
||||
*
|
||||
* This function runs the display in the thread it is called from
|
||||
* and blocks until the display stops.
|
||||
* It is intended for GUI displays (GL/SDL), which run main event loop and need
|
||||
* to be run from main thread of the program (macOS).
|
||||
*
|
||||
* It is mainly intended for GUI displays (GL/SDL), which usually need
|
||||
* to be run from main thread of the * program (OS X).
|
||||
*
|
||||
* The function blocks while the display runs.
|
||||
* The display can be terminated by passing a poisoned pill (frame == NULL)
|
||||
* using the display_put_frame() call.
|
||||
*
|
||||
* @param d display to be run
|
||||
*/
|
||||
void display_run_this_thread(struct display *d)
|
||||
void display_run_mainloop(struct display *d)
|
||||
{
|
||||
assert(d->magic == DISPLAY_MAGIC);
|
||||
if (d->funcs->run) {
|
||||
d->funcs->run(d->state);
|
||||
} else if (mainloop) {
|
||||
mainloop(mainloop_udata);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Display mainloop function.
|
||||
*
|
||||
* This function runs the display in a new thread and does not block.
|
||||
*
|
||||
* It should not be used for GUI displays (GL/SDL), which usually need
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
* Thread #1 (main thread)
|
||||
* @code{.c}
|
||||
* d = ininitalize_video_display(...);
|
||||
* display_run_this_thread(d);
|
||||
* display_run_mainloop(d);
|
||||
* display_done(d);
|
||||
*
|
||||
* Thread #2
|
||||
@@ -142,18 +142,14 @@ enum display_prop_vid_mode {
|
||||
};
|
||||
/// @}
|
||||
|
||||
#define VIDEO_DISPLAY_ABI_VERSION 17
|
||||
|
||||
typedef bool (*display_needs_mainloop_t)(void *);
|
||||
#define DISPLAY_DOESNT_NEED_MAINLOOP ((display_needs_mainloop_t) 0x00)
|
||||
#define DISPLAY_NEEDS_MAINLOOP ((display_needs_mainloop_t) 0x01)
|
||||
#define VIDEO_DISPLAY_ABI_VERSION 18
|
||||
|
||||
#define DISPLAY_NO_GENERIC_FPS_INDICATOR ((const char *) 0x00)
|
||||
|
||||
struct video_display_info {
|
||||
device_probe_func probe;
|
||||
void *(*init) (struct module *parent, const char *fmt, unsigned int flags);
|
||||
void (*run) (void *state); ///< may be NULL
|
||||
void (*run) (void *state); ///< callback to display main event loop; may be NULL
|
||||
void (*done) (void *state);
|
||||
struct video_frame *(*getf) (void *state);
|
||||
/// @param timeout_ns display is supposed immplement the PUTF_* macros, numerical timeout is seldom used (but double-framerate postprocess can use that)
|
||||
@@ -163,7 +159,6 @@ struct video_display_info {
|
||||
void (*put_audio_frame) (void *state, const struct audio_frame *frame); ///< may be NULL
|
||||
int (*reconfigure_audio) (void *state, int quant_samples, int channels, ///< may be NULL
|
||||
int sample_rate);
|
||||
display_needs_mainloop_t needs_mainloop;
|
||||
const char *generic_fps_indicator_prefix; ///< NO_GENERIC_FPS_INDICATOR or pointer to preferred module name
|
||||
};
|
||||
|
||||
@@ -179,7 +174,7 @@ int initialize_video_display(struct module *parent,
|
||||
/* not_null */ const char *requested_display, /* not_null */ const char *fmt,
|
||||
unsigned int flags, const char *postprocess, /* not_null */ struct display **out);
|
||||
bool display_needs_mainloop(struct display *d);
|
||||
void display_run_this_thread(struct display *d);
|
||||
void display_run_mainloop(struct display *d);
|
||||
void display_run_new_thread(struct display *d);
|
||||
void display_join(struct display *d);
|
||||
void display_done(struct display *d);
|
||||
|
||||
@@ -390,7 +390,6 @@ static const struct video_display_info display_aggregate_info = {
|
||||
display_aggregate_get_property,
|
||||
display_aggregate_put_audio_frame,
|
||||
display_aggregate_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -1105,7 +1105,6 @@ static const struct video_display_info display_aja_info = {
|
||||
display_aja_get_property,
|
||||
display_aja_put_audio_frame,
|
||||
display_aja_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -424,7 +424,6 @@ static const struct video_display_info display_blend_info = {
|
||||
display_blend_get_property,
|
||||
display_blend_put_audio_frame,
|
||||
display_blend_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -1035,7 +1035,6 @@ static const struct video_display_info display_bluefish444_info = {
|
||||
display_bluefish444_get_property,
|
||||
display_bluefish444_put_audio_frame,
|
||||
display_bluefish444_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -314,7 +314,6 @@ static const void *display_caca_info_get() {
|
||||
display_caca_get_property,
|
||||
NULL,
|
||||
NULL,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
const char *display = getenv("DISPLAY");
|
||||
|
||||
@@ -635,7 +635,7 @@ static void display_conference_run(void *state)
|
||||
|
||||
std::thread worker = std::thread(display_conference_worker, s);
|
||||
|
||||
display_run_this_thread(s->real_display.get());
|
||||
display_run_mainloop(s->real_display.get());
|
||||
|
||||
worker.join();
|
||||
}
|
||||
@@ -731,12 +731,6 @@ static int display_conference_putf(void *state, struct video_frame *frame, long
|
||||
return 0;
|
||||
}
|
||||
|
||||
static auto display_conference_needs_mainloop(void *state)
|
||||
{
|
||||
auto s = static_cast<struct state_conference *>(state)->common;
|
||||
return display_needs_mainloop(s->real_display.get());
|
||||
}
|
||||
|
||||
static void display_conference_probe(struct device_info **available_cards, int *count, void (**deleter)(void *)) {
|
||||
UNUSED(deleter);
|
||||
*available_cards = nullptr;
|
||||
@@ -754,7 +748,6 @@ static const struct video_display_info display_conference_info = {
|
||||
display_conference_get_property,
|
||||
display_conference_put_audio_frame,
|
||||
display_conference_reconfigure_audio,
|
||||
display_conference_needs_mainloop,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -2029,7 +2029,6 @@ static const struct video_display_info display_decklink_info = {
|
||||
display_decklink_get_property,
|
||||
display_decklink_put_audio_frame,
|
||||
display_decklink_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -559,7 +559,6 @@ static const struct video_display_info display_deltacast_info = {
|
||||
display_deltacast_get_property,
|
||||
display_deltacast_put_audio_frame,
|
||||
display_deltacast_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -291,7 +291,6 @@ static const struct video_display_info display_dummy_info = {
|
||||
display_dummy_get_property,
|
||||
NULL, // _put_audio_frame
|
||||
NULL, // _reconfigure_audio
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -189,7 +189,6 @@ static const struct video_display_info display_dump_info = {
|
||||
display_dump_get_property,
|
||||
NULL, // _put_audio_frame
|
||||
NULL, // _reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -985,7 +985,6 @@ static const struct video_display_info display_dvs_info = {
|
||||
display_dvs_get_property,
|
||||
display_dvs_put_audio_frame,
|
||||
display_dvs_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -1944,7 +1944,6 @@ static const struct video_display_info display_gl_info = {
|
||||
display_gl_get_property,
|
||||
display_gl_put_audio_frame,
|
||||
display_gl_reconfigure_audio,
|
||||
DISPLAY_NEEDS_MAINLOOP, // many GLFW functions must be called from main thread (notably glfwPollEvents())
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ static void display_multiplier_run(void *state)
|
||||
|
||||
s->worker_thread = thread(display_multiplier_worker, state);
|
||||
|
||||
display_run_this_thread(s->displays[0].get());
|
||||
display_run_mainloop(s->displays[0].get());
|
||||
|
||||
s->worker_thread.join();
|
||||
for (size_t i = 1; i < s->displays.size(); i++) {
|
||||
@@ -300,12 +300,6 @@ static int display_multiplier_reconfigure_audio(void *state, int quant_samples,
|
||||
return display_reconfigure_audio(s->common->displays.at(0).get(), quant_samples, channels, sample_rate);
|
||||
}
|
||||
|
||||
static auto display_multiplier_needs_mainloop(void *state)
|
||||
{
|
||||
auto s = static_cast<struct state_multiplier *>(state)->common;
|
||||
return !s->displays.empty() && display_needs_mainloop(s->displays[0].get());
|
||||
}
|
||||
|
||||
static void display_multiplier_probe(struct device_info **available_cards, int *count, void (**deleter)(void *)) {
|
||||
UNUSED(deleter);
|
||||
*available_cards = nullptr;
|
||||
@@ -323,7 +317,6 @@ static const struct video_display_info display_multiplier_info = {
|
||||
display_multiplier_get_property,
|
||||
display_multiplier_put_audio_frame,
|
||||
display_multiplier_reconfigure_audio,
|
||||
display_multiplier_needs_mainloop,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -454,7 +454,6 @@ static const struct video_display_info display_ndi_info = {
|
||||
display_ndi_get_property,
|
||||
display_ndi_put_audio_frame,
|
||||
display_ndi_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -148,7 +148,6 @@ static const struct video_display_info display_null_info = {
|
||||
display_null_get_property,
|
||||
display_null_put_audio_frame,
|
||||
display_null_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -1160,7 +1160,6 @@ static const struct video_display_info openxr_gl_info = {
|
||||
display_xrgl_get_property,
|
||||
NULL,
|
||||
NULL,
|
||||
DISPLAY_NEEDS_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -377,7 +377,6 @@ static const struct video_display_info display_panogl_info = {
|
||||
display_panogl_get_property,
|
||||
NULL,
|
||||
NULL,
|
||||
DISPLAY_NEEDS_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -299,7 +299,6 @@ static const struct video_display_info display_pipe_info = {
|
||||
display_pipe_get_property,
|
||||
display_pipe_put_audio_frame,
|
||||
display_pipe_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -658,7 +658,6 @@ static const struct video_display_info display_rpi4_info = {
|
||||
display_rpi4_get_property,
|
||||
display_rpi4_put_audio_frame,
|
||||
display_rpi4_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
"[RPi display] ",
|
||||
};
|
||||
|
||||
|
||||
@@ -571,7 +571,6 @@ static const struct video_display_info display_sage_info = {
|
||||
display_sage_get_property,
|
||||
display_sage_put_audio_frame,
|
||||
display_sage_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -785,11 +785,6 @@ static const struct video_display_info display_sdl_info = {
|
||||
display_sdl_get_property,
|
||||
display_sdl_put_audio_frame,
|
||||
display_sdl_reconfigure_audio,
|
||||
#ifdef __APPLE__
|
||||
DISPLAY_NEEDS_MAINLOOP,
|
||||
#else
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
#endif
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -809,7 +809,6 @@ static const struct video_display_info display_sdl2_info = {
|
||||
display_sdl2_get_property,
|
||||
NULL,
|
||||
NULL,
|
||||
DISPLAY_NEEDS_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
|
||||
@@ -355,7 +355,6 @@ static const struct video_display_info display_unix_sock_info = {
|
||||
display_unix_sock_get_property,
|
||||
display_unix_sock_put_audio_frame,
|
||||
display_unix_sock_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
MOD_NAME,
|
||||
};
|
||||
|
||||
@@ -370,7 +369,6 @@ static const struct video_display_info display_preview_info = {
|
||||
display_unix_sock_get_property,
|
||||
display_unix_sock_put_audio_frame,
|
||||
display_unix_sock_reconfigure_audio,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
"[unix sock preview] ",
|
||||
};
|
||||
|
||||
|
||||
@@ -334,7 +334,6 @@ static const struct video_display_info display_v4l2_info = {
|
||||
display_v4l2_get_property,
|
||||
NULL,
|
||||
NULL,
|
||||
DISPLAY_DOESNT_NEED_MAINLOOP,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
|
||||
@@ -1001,8 +1001,7 @@ const video_display_info display_vulkan_info = {
|
||||
display_vulkan_get_property,
|
||||
display_vulkan_put_audio_frame,
|
||||
display_vulkan_reconfigure_audio,
|
||||
DISPLAY_NEEDS_MAINLOOP,
|
||||
nullptr,
|
||||
DISPLAY_NO_GENERIC_FPS_INDICATOR,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
Reference in New Issue
Block a user