1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-03-09 23:38:56 +00:00

miracle-wfdctl: encoding video stream with gstreamer library instead of

gst-launch-1.0
This commit is contained in:
Derek Dai 2017-03-03 17:15:30 +08:00
parent c458b273b1
commit 9b7d2a24cc
No known key found for this signature in database
GPG key ID: E109CC97553EF009
4 changed files with 48 additions and 86 deletions

View file

@ -21,6 +21,7 @@ find_package(PkgConfig)
pkg_check_modules (GLIB2 REQUIRED glib-2.0) pkg_check_modules (GLIB2 REQUIRED glib-2.0)
pkg_check_modules (UDEV REQUIRED libudev) pkg_check_modules (UDEV REQUIRED libudev)
pkg_check_modules (SYSTEMD REQUIRED libsystemd) pkg_check_modules (SYSTEMD REQUIRED libsystemd)
pkg_check_modules (GSTREAMER REQUIRED gstreamer-1.0)
include(CheckCCompilerFlag) include(CheckCCompilerFlag)
check_c_compiler_flag(-fstack-protector-strong HAS_STACK_PROTCTOR_STRONG) check_c_compiler_flag(-fstack-protector-strong HAS_STACK_PROTCTOR_STRONG)

View file

@ -57,7 +57,7 @@ set(miracle-wfdctl_SRCS ctl-cli.c
wfd-arg.c) wfd-arg.c)
include_directories(${CMAKE_BINARY_DIR} include_directories(${CMAKE_BINARY_DIR}
${GLIB2_INCLUDE_DIRS} ${GSTREAMER_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/src/shared) ${CMAKE_SOURCE_DIR}/src/shared)
@ -73,7 +73,9 @@ if(READLINE_FOUND)
target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY}) target_link_libraries(miracle-wfdctl ${READLINE_LIBRARY})
endif(READLINE_FOUND) endif(READLINE_FOUND)
target_link_libraries(miracle-wfdctl miracle-shared ${GLIB2_LIBRARIES}) target_link_libraries(miracle-wfdctl
miracle-shared
${GSTREAMER_LIBRARIES})
########### install files ############### ########### install files ###############

View file

@ -23,6 +23,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <gst/gst.h>
#include "wfd-session.h" #include "wfd-session.h"
#include "shl_log.h" #include "shl_log.h"
#include "rtsp.h" #include "rtsp.h"
@ -49,6 +50,8 @@ struct wfd_out_session
uint16_t height; uint16_t height;
enum wfd_resolution_standard std; enum wfd_resolution_standard std;
uint32_t mask; uint32_t mask;
GstElement *pipeline;
}; };
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[]; static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[];
@ -227,20 +230,6 @@ int wfd_out_session_initiate_io(struct wfd_session *s,
return 0; return 0;
} }
static void wfd_out_session_kill_gst(struct wfd_session *s)
{
pid_t pid;
struct wfd_out_session *os = wfd_out_session(s);
if(os->gst_term_source) {
sd_event_source_get_child_pid(os->gst_term_source, &pid);
kill(pid, SIGTERM);
sd_event_source_set_userdata(os->gst_term_source, NULL);
os->gst_term_source = NULL;
}
}
int wfd_out_session_resume(struct wfd_session *s) int wfd_out_session_resume(struct wfd_session *s)
{ {
return wfd_session_request(s, return wfd_session_request(s,
@ -280,7 +269,11 @@ void wfd_out_session_destroy(struct wfd_session *s)
os->display_name = NULL; os->display_name = NULL;
} }
wfd_out_session_kill_gst(s); if(os->pipeline) {
gst_element_set_state(os->pipeline, GST_STATE_NULL);
g_object_unref(os->pipeline);
os->pipeline = NULL;
}
} }
int wfd_out_session_initiate_request(struct wfd_session *s) int wfd_out_session_initiate_request(struct wfd_session *s)
@ -501,13 +494,14 @@ inline static char * uint16_to_str(uint16_t i, char *buf, size_t len)
return buf; return buf;
} }
static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out) static int wfd_out_session_create_pipeline(struct wfd_session *s)
{ {
sigset_t sigset;
char x[16], y[16], width[16], height[16], port[16]; char x[16], y[16], width[16], height[16], port[16];
struct wfd_out_session *os = wfd_out_session(s); struct wfd_out_session *os = wfd_out_session(s);
char * args[] = { GstElement *pipeline;
"gst-launch-1.0", GError *error = NULL;
GstStateChangeReturn r;
const char * pipeline_desc[] = {
"ximagesrc", "ximagesrc",
"use-damage=false", "use-damage=false",
"show-pointer=false", "show-pointer=false",
@ -519,10 +513,6 @@ static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out)
"!", "video/x-raw,", "!", "video/x-raw,",
"format=YV12", "format=YV12",
"!", "vaapih264enc", "!", "vaapih264enc",
/*"!", "video/x-h264,",*/
/*"stream-format=byte-steram,",*/
/*"profile=high",*/
/*"!", "queue",*/
"!", "mpegtsmux", "!", "mpegtsmux",
"!", "rtpmp2tpay", "!", "rtpmp2tpay",
"!", "udpsink", "!", "udpsink",
@ -531,47 +521,22 @@ static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out)
NULL NULL
}; };
pid_t p = fork(); pipeline = gst_parse_launchv(pipeline_desc, &error);
if(0 > p) { if(!pipeline) {
return p; if(error) {
log_error("failed to create pipeline: %s", error->message);
g_error_free(error);
} }
else if(0 < p) { return -1;
log_info("gstreamer (%d) is launched for session %u",
p,
s->id);
*out = p;
return 0;
} }
sigemptyset(&sigset); r = gst_element_set_state(pipeline, GST_STATE_READY);
sigaddset(&sigset, SIGTERM); if(GST_STATE_CHANGE_FAILURE == r) {
sigprocmask(SIG_UNBLOCK, &sigset, NULL); g_object_unref(pipeline);
return -1;
execvp(args[0], args);
exit(1);
}
static int wfd_out_session_handle_gst_term(sd_event_source *source,
const siginfo_t *si,
void *userdata)
{
struct wfd_out_session *os = userdata;
log_trace("gst-launch(%d) terminated", si->si_pid);
sd_event_source_unref(source);
if(!os) {
return 0;
} }
os->gst_term_source = NULL; os->pipeline = pipeline;
if(WFD_SESSION_STATE_PAUSED != wfd_session(os)->state) {
wfd_session_teardown(wfd_session(os));
}
return 0; return 0;
} }
@ -583,7 +548,7 @@ static int wfd_out_session_handle_pause_request(struct wfd_session *s,
_rtsp_message_unref_ struct rtsp_message *m = NULL; _rtsp_message_unref_ struct rtsp_message *m = NULL;
int r; int r;
wfd_out_session_kill_gst(s); gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_READY);
r = rtsp_message_new_reply_for(req, r = rtsp_message_new_reply_for(req,
&m, &m,
@ -606,7 +571,7 @@ static int wfd_out_session_handle_teardown_request(struct wfd_session *s,
_rtsp_message_unref_ struct rtsp_message *m = NULL; _rtsp_message_unref_ struct rtsp_message *m = NULL;
int r; int r;
wfd_out_session_kill_gst(s); gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_NULL);
r = rtsp_message_new_reply_for(req, r = rtsp_message_new_reply_for(req,
&m, &m,
@ -627,33 +592,19 @@ static int wfd_out_session_post_handle_play(sd_event_source *source,
void *userdata) void *userdata)
{ {
struct wfd_session *s = userdata; struct wfd_session *s = userdata;
int r, status; GstStateChangeReturn r;
pid_t gst;
sd_event_source_unref(source); sd_event_source_unref(source);
wfd_out_session(s)->gst_launch_source = NULL; wfd_out_session(s)->gst_launch_source = NULL;
if(getenv("DO_NOT_LAUNCH_GST")) { r = gst_element_set_state(wfd_out_session(s)->pipeline,
return 0; GST_STATE_PLAYING);
} if(GST_STATE_CHANGE_FAILURE == r) {
r = wfd_out_session_launch_gst(s, &gst);
if(0 > r) {
return r;
}
r = sd_event_add_child(ctl_wfd_get_loop(),
&wfd_out_session(s)->gst_term_source,
gst, WEXITED,
wfd_out_session_handle_gst_term,
s);
if(0 > r) {
kill(gst, SIGKILL);
waitpid(gst, &status, WNOHANG);
wfd_session_teardown(s); wfd_session_teardown(s);
return -1;
} }
return r; return 0;
} }
static int wfd_out_session_handle_play_request(struct wfd_session *s, static int wfd_out_session_handle_play_request(struct wfd_session *s,
@ -763,6 +714,11 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
return r; return r;
} }
r = wfd_out_session_create_pipeline(s);
if(0 > r) {
return r;
}
*out_rep = m; *out_rep = m;
m = NULL; m = NULL;

View file

@ -510,10 +510,12 @@ int main(int argc, char **argv)
log_max_sev = log_parse_arg(getenv("LOG_LEVEL")); log_max_sev = log_parse_arg(getenv("LOG_LEVEL"));
} }
gst_init(&argc, &argv);
loop = g_main_loop_new(NULL, FALSE); loop = g_main_loop_new(NULL, FALSE);
if(!loop) { if(!loop) {
r = -ENOMEM; r = -ENOMEM;
goto end; goto deinit_gst;
} }
r = sd_event_default(&event); r = sd_event_default(&event);
@ -581,7 +583,8 @@ unref_event:
sd_event_unref(event); sd_event_unref(event);
unref_loop: unref_loop:
g_main_loop_unref(loop); g_main_loop_unref(loop);
end: deinit_gst:
gst_deinit();
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
} }