mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-13 10:01:55 +00:00
miracle-wfdctl: run gst-launch to generate video stream with hardcoded
environment
This commit is contained in:
parent
02e5c4beac
commit
34cc56dba8
4 changed files with 123 additions and 12 deletions
2
debian/control
vendored
2
debian/control
vendored
|
@ -8,5 +8,5 @@ Homepage: https://github.com/derekdai/miraclecast
|
|||
|
||||
Package: miraclecast
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, gstreamer1.0-tools, gstreamer1.0-vaapi
|
||||
Description: Connect external monitors to your system via Wifi-Display specification also known as Miracast
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
#define LOG_SUBSYSTEM "wfd-session"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "wfd-session.h"
|
||||
#include "shl_log.h"
|
||||
|
@ -171,6 +173,11 @@ static int wfd_out_session_initiate_io(struct wfd_session *s,
|
|||
static void wfd_out_session_end(struct wfd_session *s)
|
||||
{
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
|
||||
if(-1 != s->stream.gst) {
|
||||
kill(s->stream.gst, SIGTERM);
|
||||
}
|
||||
|
||||
if(0 <= os->fd) {
|
||||
close(os->fd);
|
||||
os->fd = -1;
|
||||
|
@ -399,6 +406,80 @@ static int wfd_out_session_request_options(struct wfd_session *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_out_session_launch_gst(struct wfd_session *s, pid_t *out)
|
||||
{
|
||||
sigset_t sigset;
|
||||
char port[10];
|
||||
char * args[] = {
|
||||
"gst-launch-1.0",
|
||||
"-v",
|
||||
"ximagesrc",
|
||||
"use-damage=false",
|
||||
"show-pointer=false",
|
||||
"startx=0",
|
||||
"starty=0",
|
||||
"endx=1279",
|
||||
"endy=719",
|
||||
"!", "vaapipostproc",
|
||||
"!", "video/x-raw,",
|
||||
"format=YV12",
|
||||
"!", "vaapih264enc",
|
||||
/*"!", "video/x-h264,",*/
|
||||
/*"stream-format=byte-steram,",*/
|
||||
/*"profile=high",*/
|
||||
/*"!", "queue",*/
|
||||
"!", "mpegtsmux",
|
||||
"!", "rtpmp2tpay",
|
||||
"!", "udpsink",
|
||||
"host=", wfd_out_session_get_sink(s)->peer->remote_address,
|
||||
"port=", port,
|
||||
NULL
|
||||
};
|
||||
|
||||
snprintf(port, sizeof(port), "%hu", s->stream.rtp_port);
|
||||
|
||||
pid_t p = fork();
|
||||
if(0 > p) {
|
||||
return p;
|
||||
}
|
||||
else if(0 < p) {
|
||||
*out = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGTERM);
|
||||
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
|
||||
|
||||
execvpe(args[0],
|
||||
args,
|
||||
(char *[]) {
|
||||
"XDG_RUNTIME_DIR=/run/user/1000",
|
||||
"GST_DEBUG=3",
|
||||
"DISPLAY=:0",
|
||||
"XAUTHORITY=/run/user/1000/gdm/Xauthority",
|
||||
NULL
|
||||
});
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static int wfd_out_sessoin_handle_gst_term(sd_event_source *source,
|
||||
const siginfo_t *si,
|
||||
void *userdata)
|
||||
{
|
||||
struct wfd_session *s = userdata;
|
||||
|
||||
log_trace("gst-launch(%d) terminated", si->si_pid);
|
||||
|
||||
if(WFD_SESSION_STATE_TEARING_DOWN != wfd_session_get_state(s)) {
|
||||
s->stream.gst = -1;
|
||||
wfd_session_end(s);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep,
|
||||
|
@ -407,7 +488,8 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
{
|
||||
_shl_free_ char *v;
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
int r;
|
||||
pid_t gst;
|
||||
int r, status;
|
||||
|
||||
r = rtsp_message_new_reply_for(req,
|
||||
&m,
|
||||
|
@ -432,6 +514,24 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
return r;
|
||||
}
|
||||
|
||||
r = wfd_out_session_launch_gst(s, &gst);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_event_add_child(ctl_wfd_get_loop(),
|
||||
NULL,
|
||||
gst, WEXITED,
|
||||
wfd_out_sessoin_handle_gst_term,
|
||||
s);
|
||||
if(0 > r) {
|
||||
kill(gst, SIGKILL);
|
||||
waitpid(gst, &status, WNOHANG);
|
||||
return r;
|
||||
}
|
||||
|
||||
s->stream.gst = gst;
|
||||
|
||||
*out_rep = m;
|
||||
m = NULL;
|
||||
|
||||
|
@ -572,8 +672,8 @@ static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
|||
s->stream.id = WFD_STREAM_ID_PRIMARY;
|
||||
|
||||
r = asprintf(&body,
|
||||
"wfd_video_formats: 38 00 02 10 00000080 00000000 00000000 00 0000 0000 11 none none\n"
|
||||
"wfd_audio_codecs: AAC 00000001 00\n"
|
||||
"wfd_video_formats: 00 00 02 10 00001401 00000000 00000000 00 0000 0000 00 none none\n"
|
||||
//"wfd_audio_codecs: AAC 00000001 00\n"
|
||||
"wfd_presentation_URL: %s none\n"
|
||||
"wfd_client_rtp_ports: %u %u mode=play",
|
||||
//"wfd_uibc_capability: input_category_list=GENERIC\n;generic_cap_list=SingleTouch;hidc_cap_list=none;port=5100\n"
|
||||
|
|
|
@ -124,6 +124,8 @@ void wfd_session_end(struct wfd_session *s)
|
|||
|
||||
log_info("session %lu ended", s->id);
|
||||
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN);
|
||||
|
||||
(*session_vtables[s->dir].end)(s);
|
||||
|
||||
if(s->rtsp) {
|
||||
|
@ -131,18 +133,24 @@ void wfd_session_end(struct wfd_session *s)
|
|||
s->rtsp = NULL;
|
||||
}
|
||||
|
||||
if(s->vformats) {
|
||||
wfd_video_formats_free(s->vformats);
|
||||
s->vformats = NULL;
|
||||
}
|
||||
|
||||
if(s->acodecs) {
|
||||
wfd_audio_codecs_free(s->acodecs);
|
||||
s->acodecs = NULL;
|
||||
}
|
||||
|
||||
if(s->stream.url) {
|
||||
free(s->stream.url);
|
||||
s->stream.url = NULL;
|
||||
}
|
||||
|
||||
s->last_request = RTSP_M_UNKNOWN;
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_NULL);
|
||||
s->rtp_ports[0] = 0;
|
||||
s->rtp_ports[1] = 0;
|
||||
s->last_request = RTSP_M_UNKNOWN;
|
||||
|
||||
if(wfd_is_out_session(s)) {
|
||||
wfd_fn_out_session_ended(s);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#ifndef MIRACLE_OUT_SESSION_H
|
||||
#define MIRACLE_OUT_SESSION_H
|
||||
|
||||
#include <unistd.h>
|
||||
#include "ctl.h"
|
||||
|
||||
#define wfd_out_session(s) (assert(wfd_is_out_session(s)), (struct wfd_out_session *) (s))
|
||||
|
@ -99,11 +100,13 @@ struct wfd_session
|
|||
enum wfd_stream_id id;
|
||||
char *url;
|
||||
uint16_t rtp_port;
|
||||
pid_t gst;
|
||||
} stream;
|
||||
|
||||
bool destructed: 1;
|
||||
};
|
||||
|
||||
int wfd_session_init(struct wfd_session *s);
|
||||
const char * rtsp_message_id_to_string(enum rtsp_message_id id);
|
||||
struct wfd_sink * wfd_out_session_get_sink(struct wfd_session *s);
|
||||
int wfd_session_request(struct wfd_session *s, enum rtsp_message_id id);
|
||||
|
|
Loading…
Reference in a new issue