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:
parent
c458b273b1
commit
9b7d2a24cc
4 changed files with 48 additions and 86 deletions
|
@ -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)
|
||||||
|
|
|
@ -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 ###############
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
else if(0 < p) {
|
g_error_free(error);
|
||||||
log_info("gstreamer (%d) is launched for session %u",
|
}
|
||||||
p,
|
return -1;
|
||||||
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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue