mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-15 04:42:06 +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
|
Package: miraclecast
|
||||||
Architecture: any
|
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
|
Description: Connect external monitors to your system via Wifi-Display specification also known as Miracast
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
*/
|
*/
|
||||||
#define LOG_SUBSYSTEM "wfd-session"
|
#define LOG_SUBSYSTEM "wfd-session"
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include "wfd-session.h"
|
#include "wfd-session.h"
|
||||||
#include "shl_log.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)
|
static void wfd_out_session_end(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
struct wfd_out_session *os = wfd_out_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) {
|
if(0 <= os->fd) {
|
||||||
close(os->fd);
|
close(os->fd);
|
||||||
os->fd = -1;
|
os->fd = -1;
|
||||||
|
@ -399,6 +406,80 @@ static int wfd_out_session_request_options(struct wfd_session *s,
|
||||||
return 0;
|
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,
|
static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||||
struct rtsp_message *req,
|
struct rtsp_message *req,
|
||||||
struct rtsp_message **out_rep,
|
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;
|
_shl_free_ char *v;
|
||||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
int r;
|
pid_t gst;
|
||||||
|
int r, status;
|
||||||
|
|
||||||
r = rtsp_message_new_reply_for(req,
|
r = rtsp_message_new_reply_for(req,
|
||||||
&m,
|
&m,
|
||||||
|
@ -432,6 +514,24 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||||
return r;
|
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;
|
*out_rep = m;
|
||||||
m = NULL;
|
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;
|
s->stream.id = WFD_STREAM_ID_PRIMARY;
|
||||||
|
|
||||||
r = asprintf(&body,
|
r = asprintf(&body,
|
||||||
"wfd_video_formats: 38 00 02 10 00000080 00000000 00000000 00 0000 0000 11 none none\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_audio_codecs: AAC 00000001 00\n"
|
||||||
"wfd_presentation_URL: %s none\n"
|
"wfd_presentation_URL: %s none\n"
|
||||||
"wfd_client_rtp_ports: %u %u mode=play",
|
"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"
|
//"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);
|
log_info("session %lu ended", s->id);
|
||||||
|
|
||||||
|
wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN);
|
||||||
|
|
||||||
(*session_vtables[s->dir].end)(s);
|
(*session_vtables[s->dir].end)(s);
|
||||||
|
|
||||||
if(s->rtsp) {
|
if(s->rtsp) {
|
||||||
|
@ -131,18 +133,24 @@ void wfd_session_end(struct wfd_session *s)
|
||||||
s->rtsp = NULL;
|
s->rtsp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wfd_video_formats_free(s->vformats);
|
if(s->vformats) {
|
||||||
s->vformats = NULL;
|
wfd_video_formats_free(s->vformats);
|
||||||
wfd_audio_codecs_free(s->acodecs);
|
s->vformats = NULL;
|
||||||
s->acodecs = NULL;
|
}
|
||||||
|
|
||||||
free(s->stream.url);
|
if(s->acodecs) {
|
||||||
s->stream.url = NULL;
|
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[0] = 0;
|
||||||
s->rtp_ports[1] = 0;
|
s->rtp_ports[1] = 0;
|
||||||
|
s->last_request = RTSP_M_UNKNOWN;
|
||||||
|
|
||||||
if(wfd_is_out_session(s)) {
|
if(wfd_is_out_session(s)) {
|
||||||
wfd_fn_out_session_ended(s);
|
wfd_fn_out_session_ended(s);
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#ifndef MIRACLE_OUT_SESSION_H
|
#ifndef MIRACLE_OUT_SESSION_H
|
||||||
#define MIRACLE_OUT_SESSION_H
|
#define MIRACLE_OUT_SESSION_H
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
#include "ctl.h"
|
#include "ctl.h"
|
||||||
|
|
||||||
#define wfd_out_session(s) (assert(wfd_is_out_session(s)), (struct wfd_out_session *) (s))
|
#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;
|
enum wfd_stream_id id;
|
||||||
char *url;
|
char *url;
|
||||||
uint16_t rtp_port;
|
uint16_t rtp_port;
|
||||||
|
pid_t gst;
|
||||||
} stream;
|
} stream;
|
||||||
|
|
||||||
bool destructed: 1;
|
bool destructed: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int wfd_session_init(struct wfd_session *s);
|
||||||
const char * rtsp_message_id_to_string(enum rtsp_message_id id);
|
const char * rtsp_message_id_to_string(enum rtsp_message_id id);
|
||||||
struct wfd_sink * wfd_out_session_get_sink(struct wfd_session *s);
|
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);
|
int wfd_session_request(struct wfd_session *s, enum rtsp_message_id id);
|
||||||
|
|
Loading…
Reference in a new issue