1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-02-13 11:01:58 +00:00

miracle-wfdctl: integrate sd_event with GMainLoop for running gstreamer

in process instead of fork n exec gst-launch
This commit is contained in:
Derek Dai 2017-03-03 15:40:43 +08:00
parent 0e1f3243bc
commit c458b273b1
No known key found for this signature in database
GPG key ID: E109CC97553EF009
2 changed files with 125 additions and 24 deletions

View file

@ -2,9 +2,9 @@ find_package(Readline)
########### next target ###############
set(miracle-wifictl_SRCS ctl.h
ctl-cli.c
ctl-wifi.c
wifictl.c)
ctl-cli.c
ctl-wifi.c
wifictl.c)
add_executable(miracle-wifictl ${miracle-wifictl_SRCS})
@ -22,12 +22,12 @@ target_link_libraries(miracle-wifictl miracle-shared)
########### next target ###############
set(miracle-sinkctl_SRCS ctl.h
ctl-cli.c
ctl-sink.h
ctl-sink.c
ctl-wifi.c
sinkctl.c
wfd.c)
ctl-cli.c
ctl-sink.h
ctl-sink.c
ctl-wifi.c
sinkctl.c
wfd.c)
add_executable(miracle-sinkctl ${miracle-sinkctl_SRCS})
@ -57,7 +57,8 @@ set(miracle-wfdctl_SRCS ctl-cli.c
wfd-arg.c)
include_directories(${CMAKE_BINARY_DIR}
${CMAKE_SOURCE_DIR}/src
${GLIB2_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/shared)
add_executable(miracle-wfdctl ${miracle-wfdctl_SRCS})
@ -72,7 +73,7 @@ if(READLINE_FOUND)
target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY})
endif(READLINE_FOUND)
target_link_libraries(miracle-wfdctl miracle-shared)
target_link_libraries(miracle-wfdctl miracle-shared ${GLIB2_LIBRARIES})
########### install files ###############

View file

@ -24,6 +24,7 @@
#include <string.h>
#include <time.h>
#include <systemd/sd-event.h>
#include <glib.h>
#include "ctl.h"
#include "wfd.h"
#include "wfd-dbus.h"
@ -416,11 +417,91 @@ void cli_fn_help()
{
}
/*
* see: https://lists.freedesktop.org/archives/systemd-devel/2014-August/022329.html
**/
#define SD_SOURCE(p) ((SDSource *) (p))
typedef struct _SDSource SDSource;
struct _SDSource
{
GSource source;
sd_event *event;
GPollFD pollfd;
};
static gboolean sd_source_prepare(GSource *source, gint *timeout)
{
return sd_event_prepare(SD_SOURCE(source)->event) > 0 ? TRUE : FALSE;
}
static gboolean sd_source_check(GSource *source)
{
return sd_event_wait(SD_SOURCE(source)->event, 0) > 0 ? TRUE : FALSE;
}
static gboolean sd_source_dispatch(GSource *source,
GSourceFunc callback,
gpointer userdata)
{
return sd_event_dispatch(SD_SOURCE(source)->event) >= 0
? G_SOURCE_CONTINUE
: G_SOURCE_REMOVE;
}
static void sd_source_finalize(GSource *source)
{
sd_event_unref(SD_SOURCE(source)->event);
}
static int sd_source_on_exit(sd_event_source *source, void *userdata)
{
g_main_loop_quit(userdata);
sd_event_source_set_enabled(source, false);
sd_event_source_unref(source);
return 0;
}
static int sd_source_attach(GSource *source, GMainLoop *loop)
{
g_source_set_name(source, "sd-event");
g_source_add_poll(source, &SD_SOURCE(source)->pollfd);
g_source_attach(source, g_main_loop_get_context(loop));
return sd_event_add_exit(SD_SOURCE(source)->event,
NULL,
sd_source_on_exit,
loop);
}
GSource * sd_source_new(sd_event *event)
{
static GSourceFuncs funcs = {
sd_source_prepare,
sd_source_check,
sd_source_dispatch,
sd_source_finalize,
};
GSource *s = g_source_new(&funcs, sizeof(SDSource));
if(s) {
SD_SOURCE(s)->event = sd_event_ref(event);
SD_SOURCE(s)->pollfd.fd = sd_event_get_fd(event);
SD_SOURCE(s)->pollfd.events = G_IO_IN | G_IO_HUP;
}
return s;
}
int main(int argc, char **argv)
{
int r;
sd_event *loop;
GMainLoop *loop;
GSource *source;
sd_event *event;
sd_bus *bus;
setlocale(LC_ALL, "");
@ -429,30 +510,47 @@ int main(int argc, char **argv)
log_max_sev = log_parse_arg(getenv("LOG_LEVEL"));
}
r = sd_event_default(&loop);
if(0 > r) {
loop = g_main_loop_new(NULL, FALSE);
if(!loop) {
r = -ENOMEM;
goto end;
}
r = sd_event_default(&event);
if(0 > r) {
goto unref_loop;
}
source = sd_source_new(event);
if(!source) {
r = -ENOMEM;
goto unref_event;
}
r = sd_source_attach(source, loop);
if(0 > r) {
goto unref_source;
}
r = sd_bus_default_system(&bus);
if(0 > r) {
log_warning("unabled to connect to system DBus: %s", strerror(errno));
goto unref_loop;
goto unref_source;
}
r = sd_bus_attach_event(bus, loop, 0);
r = sd_bus_attach_event(bus, event, 0);
if(0 > r) {
log_warning("unabled to attache DBus event source to loop: %s",
strerror(errno));
goto unref_bus;
}
r = ctl_wfd_new(&wfd, loop, bus);
r = ctl_wfd_new(&wfd, event, bus);
if(0 > r) {
goto bus_detach_event;;
}
r = wfd_dbus_new(&wfd_dbus, loop, bus);
r = wfd_dbus_new(&wfd_dbus, event, bus);
if(0 > r) {
goto free_ctl_wfd;
}
@ -463,10 +561,7 @@ int main(int argc, char **argv)
goto free_wfd_dbus;
}
r = sd_event_loop(loop);
if(0 > r) {
log_warning("unabled to keep WFD service running: %s", strerror(errno));
}
g_main_loop_run(loop);
free_wfd_dbus:
wfd_dbus_free(wfd_dbus);
@ -478,9 +573,14 @@ bus_detach_event:
sd_bus_detach_event(bus);
unref_bus:
sd_bus_flush_close_unref(bus);
unref_source:
g_source_ref(source);
g_source_destroy(source);
unref_event:
sd_event_run(event, 0);
sd_event_unref(event);
unref_loop:
sd_event_run(loop, 0);
sd_event_unref(loop);
g_main_loop_unref(loop);
end:
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}