1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-02-13 10:22:04 +00:00

miracle-wfdctl: run gst-launch to generate video stream with hardcoded

environment
This commit is contained in:
Derek Dai 2017-02-16 18:02:16 +08:00
parent 02e5c4beac
commit 34cc56dba8
No known key found for this signature in database
GPG key ID: E109CC97553EF009
4 changed files with 123 additions and 12 deletions

2
debian/control vendored
View file

@ -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

View file

@ -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"

View file

@ -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);

View file

@ -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);