mirror of
https://github.com/albfan/miraclecast.git
synced 2025-02-15 02:01:58 +00:00
miracle-dispd: extract encoder from dispd, part 2
Change-Id: Ie61daa87a83b875013c525fe3f15222bf9057926
This commit is contained in:
parent
f1f5ee2385
commit
dbe5ea612a
6 changed files with 270 additions and 529 deletions
|
@ -115,7 +115,7 @@ internal class GstEncoder : DispdEncoder, GLib.Object
|
|||
startx=%u starty=%u endx=%u endy=%u
|
||||
! video/x-raw, framerate=%u/1
|
||||
! videoscale method=0
|
||||
! video/x-raw, width=640, height=480
|
||||
! video/x-raw, width=1920, height=1080
|
||||
! videoconvert dither=0
|
||||
! video/x-raw, format=YV12
|
||||
! x264enc pass=4 b-adapt=false key-int-max=%u speed-preset=4 tune=4
|
||||
|
@ -137,10 +137,10 @@ internal class GstEncoder : DispdEncoder, GLib.Object
|
|||
: 0,
|
||||
configs.contains(DispdEncoderConfig.WIDTH)
|
||||
? configs.get(DispdEncoderConfig.WIDTH).get_uint32() - 1
|
||||
: 640,
|
||||
: 1919,
|
||||
configs.contains(DispdEncoderConfig.HEIGHT)
|
||||
? configs.get(DispdEncoderConfig.HEIGHT).get_uint32() - 1
|
||||
: 480,
|
||||
: 1079,
|
||||
framerate,
|
||||
framerate,
|
||||
configs.contains(DispdEncoderConfig.AUDIO_TYPE)
|
||||
|
|
|
@ -95,11 +95,10 @@ int wfd_session_pause(struct wfd_session *s);
|
|||
int wfd_session_teardown(struct wfd_session *s);
|
||||
|
||||
int wfd_session_is_established(struct wfd_session *s);
|
||||
uint64_t wfd_session_get_id(struct wfd_session *s);
|
||||
unsigned int wfd_session_get_id(struct wfd_session *s);
|
||||
const char * wfd_session_get_stream_url(struct wfd_session *s);
|
||||
enum wfd_session_state wfd_session_get_state(struct wfd_session *s);
|
||||
enum wfd_session_dir wfd_session_get_dir(struct wfd_session *s);
|
||||
uint64_t wfd_session_get_id(struct wfd_session *s);
|
||||
struct wfd_sink * wfd_out_session_get_sink(struct wfd_session *s);
|
||||
|
||||
enum wfd_display_server_type wfd_session_get_disp_type(struct wfd_session *s);
|
||||
|
|
|
@ -167,13 +167,11 @@ int ctl_wfd_find_sink_by_label(struct ctl_wfd *wfd,
|
|||
{
|
||||
char **entry;
|
||||
int r = shl_htable_lookup_str(&wfd->sinks, label, NULL, &entry);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
if(r && out) {
|
||||
*out = wfd_sink_from_htable(entry);
|
||||
}
|
||||
|
||||
*out = wfd_sink_from_htable(entry);
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ctl_wfd_remove_sink_by_label(struct ctl_wfd *wfd,
|
||||
|
@ -369,7 +367,7 @@ void ctl_fn_peer_new(struct ctl_peer *p)
|
|||
r = wfd_sube_parse(sube_str, &sube);
|
||||
if(0 > r) {
|
||||
log_debug("peer %s has invalid subelement", p->label);
|
||||
return;
|
||||
return log_vERRNO();
|
||||
}
|
||||
|
||||
if(wfd_sube_device_is_sink(&sube)) {
|
||||
|
@ -379,7 +377,7 @@ void ctl_fn_peer_new(struct ctl_peer *p)
|
|||
p->friendly_name,
|
||||
p->p2p_mac,
|
||||
strerror(errno));
|
||||
return;
|
||||
return log_vERRNO();
|
||||
}
|
||||
|
||||
r = wfd_fn_sink_new(s);
|
||||
|
@ -387,7 +385,7 @@ void ctl_fn_peer_new(struct ctl_peer *p)
|
|||
log_warning("failed to publish newly added sink (%s): %s",
|
||||
wfd_sink_get_label(s),
|
||||
strerror(errno));
|
||||
return;
|
||||
return log_vERRNO();
|
||||
}
|
||||
|
||||
log_info("sink %s added", s->label);
|
||||
|
|
|
@ -52,7 +52,7 @@ int wfd_dbus_new(struct wfd_dbus **out, sd_event *loop, sd_bus *bus)
|
|||
{
|
||||
struct wfd_dbus *wfd_dbus = calloc(1, sizeof(struct wfd_dbus));
|
||||
if(!wfd_dbus) {
|
||||
return -ENOMEM;
|
||||
return log_ENOMEM();
|
||||
}
|
||||
|
||||
wfd_dbus->bus = sd_bus_ref(bus);
|
||||
|
@ -86,22 +86,32 @@ void wfd_dbus_free(struct wfd_dbus *wfd_dbus)
|
|||
|
||||
static inline int wfd_dbus_get_sink_path(struct wfd_sink *s, char **out)
|
||||
{
|
||||
return sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
||||
int r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/sink",
|
||||
wfd_sink_get_label(s),
|
||||
out);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int wfd_dbus_get_session_path(struct wfd_session *s, char **out)
|
||||
{
|
||||
char buf[64];
|
||||
int r = snprintf(buf, sizeof(buf), "%" PRIu64, wfd_session_get_id(s));
|
||||
int r = snprintf(buf, sizeof(buf), "%u", wfd_session_get_id(s));
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_path_encode("/org/freedesktop/miracle/wfd/session",
|
||||
r = sd_bus_path_encode("/org/freedesktop/miracle/wfd/session",
|
||||
buf,
|
||||
out);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_enum(sd_bus *bus,
|
||||
|
@ -126,7 +136,7 @@ static int wfd_dbus_enum(sd_bus *bus,
|
|||
|
||||
nodes = malloc((wfd->n_sinks + wfd->n_sessions + 1) * sizeof(char *));
|
||||
if(!nodes) {
|
||||
return -ENOMEM;
|
||||
return log_ENOMEM();
|
||||
}
|
||||
|
||||
ctl_wfd_foreach_sink(sink, wfd) {
|
||||
|
@ -155,7 +165,7 @@ free_nodes:
|
|||
free(nodes[i]);
|
||||
}
|
||||
free(nodes);
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
int _wfd_dbus_object_removed(struct wfd_dbus *wfd_dbus,
|
||||
|
@ -176,32 +186,37 @@ int _wfd_dbus_object_removed(struct wfd_dbus *wfd_dbus,
|
|||
"org.freedesktop.DBus.ObjectManager",
|
||||
"InterfacesRemoved");
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(m, "o", path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_bus_message_open_container(m, 'a', "s");
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
for(i = 0; i < n_ifaces; i ++) {
|
||||
r = sd_bus_message_append(m, "s", ifaces[i]);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_send(wfd_dbus->bus, m, NULL);
|
||||
r = sd_bus_send(wfd_dbus->bus, m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _wfd_dbus_object_added(struct wfd_dbus *wfd_dbus,
|
||||
|
@ -222,32 +237,37 @@ int _wfd_dbus_object_added(struct wfd_dbus *wfd_dbus,
|
|||
"org.freedesktop.DBus.ObjectManager",
|
||||
"InterfacesAdded");
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(m, "o", path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_bus_message_open_container(m, 'a', "{sa{sv}}");
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
for(i = 0; i < n_ifaces; i ++) {
|
||||
r = sd_bus_message_append(m, "{sa{sv}}", ifaces[i], 0);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_send(wfd_dbus->bus, m, NULL);
|
||||
r = sd_bus_send(wfd_dbus->bus, m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wfd_fn_sink_new(struct wfd_sink *s)
|
||||
|
@ -255,10 +275,15 @@ int wfd_fn_sink_new(struct wfd_sink *s)
|
|||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_sink_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return wfd_dbus_object_added(path, "org.freedesktop.miracle.wfd.Sink");
|
||||
r = wfd_dbus_object_added(path, "org.freedesktop.miracle.wfd.Sink");
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wfd_fn_sink_free(struct wfd_sink *s)
|
||||
|
@ -266,10 +291,15 @@ int wfd_fn_sink_free(struct wfd_sink *s)
|
|||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_sink_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return wfd_dbus_object_removed(path, "org.freedesktop.miracle.wfd.Sink");
|
||||
r = wfd_dbus_object_removed(path, "org.freedesktop.miracle.wfd.Sink");
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _wfd_fn_sink_properties_changed(struct wfd_sink *s, char **names)
|
||||
|
@ -284,13 +314,18 @@ int _wfd_fn_sink_properties_changed(struct wfd_sink *s, char **names)
|
|||
|
||||
r = wfd_dbus_get_sink_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_emit_properties_changed_strv(wfd_dbus->bus,
|
||||
r = sd_bus_emit_properties_changed_strv(wfd_dbus->bus,
|
||||
path,
|
||||
"org.freedesktop.miracle.wfd.Sink",
|
||||
names);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_find_sink(sd_bus *bus,
|
||||
|
@ -322,10 +357,15 @@ int wfd_fn_session_new(struct wfd_session *s)
|
|||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_session_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return wfd_dbus_object_added(path, "org.freedesktop.miracle.wfd.Session");
|
||||
r = wfd_dbus_object_added(path, "org.freedesktop.miracle.wfd.Session");
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wfd_fn_session_free(struct wfd_session *s)
|
||||
|
@ -333,11 +373,15 @@ int wfd_fn_session_free(struct wfd_session *s)
|
|||
_shl_free_ char *path = NULL;
|
||||
int r = wfd_dbus_get_session_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return wfd_dbus_object_removed(path,
|
||||
"org.freedesktop.miracle.wfd.Session");
|
||||
r = wfd_dbus_object_removed(path, "org.freedesktop.miracle.wfd.Session");
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_find_session(sd_bus *bus,
|
||||
|
@ -353,7 +397,7 @@ static int wfd_dbus_find_session(sd_bus *bus,
|
|||
"/org/freedesktop/miracle/wfd/session",
|
||||
&node);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = ctl_wfd_find_session_by_id(ctl_wfd_get(),
|
||||
|
@ -389,28 +433,28 @@ static int wfd_dbus_sink_start_session(sd_bus_message *m,
|
|||
&rect.height,
|
||||
&audio_dev);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sscanf(disp, "%m[^:]://%ms",
|
||||
&disp_type_name,
|
||||
&disp_name);
|
||||
if(r != 2) {
|
||||
return -EINVAL;
|
||||
return log_EINVAL();
|
||||
}
|
||||
|
||||
if(strcmp("x", disp_type_name)) {
|
||||
return -EINVAL;
|
||||
return log_EINVAL();
|
||||
}
|
||||
|
||||
r = wfd_sink_create_session(sink, &sess);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
wfd_session_set_disp_type(sess, WFD_DISPLAY_SERVER_TYPE_X);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
disp_params = strchr(disp_name, '?');
|
||||
|
@ -420,79 +464,51 @@ static int wfd_dbus_sink_start_session(sd_bus_message *m,
|
|||
|
||||
r = wfd_session_set_disp_name(sess, disp_name);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_set_disp_params(sess, disp_params);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_set_disp_auth(sess, disp_auth);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_set_disp_dimension(sess, &rect);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_set_audio_type(sess, WFD_AUDIO_SERVER_TYPE_PULSE_AUDIO);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_set_audio_type(sess, WFD_AUDIO_SERVER_TYPE_PULSE_AUDIO);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_session_start(sess);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_dbus_get_session_path(sess, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(m, "o", path);
|
||||
}
|
||||
r = sd_bus_reply_method_return(m, "o", path);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
//static int wfd_dbus_sink_get_audio_formats(sd_bus *bus,
|
||||
// const char *path,
|
||||
// const char *interface,
|
||||
// const char *property,
|
||||
// sd_bus_message *reply,
|
||||
// void *userdata,
|
||||
// sd_bus_error *ret_error)
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
//static int wfd_dbus_sink_get_video_formats(sd_bus *bus,
|
||||
// const char *path,
|
||||
// const char *interface,
|
||||
// const char *property,
|
||||
// sd_bus_message *reply,
|
||||
// void *userdata,
|
||||
// sd_bus_error *ret_error)
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
//
|
||||
//static int wfd_dbus_sink_has_video(sd_bus *bus,
|
||||
// const char *path,
|
||||
// const char *interface,
|
||||
// const char *property,
|
||||
// sd_bus_message *reply,
|
||||
// void *userdata,
|
||||
// sd_bus_error *ret_error)
|
||||
//{
|
||||
// return 0;
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_sink_get_session(sd_bus *bus,
|
||||
const char *path,
|
||||
|
@ -507,18 +523,21 @@ static int wfd_dbus_sink_get_session(sd_bus *bus,
|
|||
int r;
|
||||
|
||||
if(s->session) {
|
||||
wfd_dbus_get_session_path(s->session, &session_path);
|
||||
r = wfd_dbus_get_session_path(s->session, &session_path);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
}
|
||||
else {
|
||||
session_path = strdup("/");
|
||||
}
|
||||
if(!session_path) {
|
||||
return -ENOMEM;
|
||||
if(!session_path) {
|
||||
return log_ENOMEM();
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(reply, "o", session_path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -538,12 +557,12 @@ static int wfd_dbus_sink_get_peer(sd_bus *bus,
|
|||
s->label,
|
||||
&peer_path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(reply, "o", peer_path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -569,14 +588,19 @@ static int wfd_dbus_session_resume(sd_bus_message *m,
|
|||
if(wfd_session_is_established(s)) {
|
||||
r = wfd_session_resume(s);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(m, NULL);
|
||||
r = sd_bus_reply_method_return(m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_session_pause(sd_bus_message *m,
|
||||
|
@ -589,14 +613,19 @@ static int wfd_dbus_session_pause(sd_bus_message *m,
|
|||
if(wfd_session_is_established(s)) {
|
||||
r = wfd_session_pause(s);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(m, NULL);
|
||||
r = sd_bus_reply_method_return(m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_session_teardown(sd_bus_message *m,
|
||||
|
@ -606,10 +635,15 @@ static int wfd_dbus_session_teardown(sd_bus_message *m,
|
|||
struct wfd_session *s = userdata;
|
||||
int r = wfd_session_teardown(s);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_reply_method_return(m, NULL);
|
||||
r = sd_bus_reply_method_return(m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_session_get_sink(sd_bus *bus,
|
||||
|
@ -624,19 +658,19 @@ static int wfd_dbus_session_get_sink(sd_bus *bus,
|
|||
_shl_free_ char *sink_path = NULL;
|
||||
int r;
|
||||
|
||||
if(wfd_session_get_id(s) != WFD_SESSION_DIR_OUT) {
|
||||
if(wfd_session_get_dir(s) != WFD_SESSION_DIR_OUT) {
|
||||
sink_path = strdup("/");
|
||||
}
|
||||
else {
|
||||
wfd_dbus_get_sink_path(wfd_out_session_get_sink(s), &sink_path);
|
||||
}
|
||||
if(!sink_path) {
|
||||
return -ENOMEM;
|
||||
return log_ENOMEM();
|
||||
}
|
||||
|
||||
r = sd_bus_message_append(reply, "o", sink_path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -655,7 +689,7 @@ static int wfd_dbus_get_session_presentation_url(sd_bus *bus,
|
|||
"s",
|
||||
wfd_session_get_stream_url(s) ? : "");
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -672,7 +706,7 @@ static int wfd_dbus_get_session_state(sd_bus *bus,
|
|||
struct wfd_session *s = userdata;
|
||||
int r = sd_bus_message_append(reply, "i", wfd_session_get_state(s));
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -690,22 +724,34 @@ int _wfd_fn_session_properties_changed(struct wfd_session *s, char **names)
|
|||
|
||||
r = wfd_dbus_get_session_path(s, &path);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return sd_bus_emit_properties_changed_strv(wfd_dbus_get()->bus,
|
||||
r = sd_bus_emit_properties_changed_strv(wfd_dbus_get()->bus,
|
||||
path,
|
||||
"org.freedesktop.miracle.wfd.Session",
|
||||
names);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_dbus_shutdown(sd_bus_message *m,
|
||||
void *userdata,
|
||||
sd_bus_error *ret_error)
|
||||
{
|
||||
int r;
|
||||
|
||||
ctl_wfd_shutdown(ctl_wfd_get());
|
||||
|
||||
return sd_bus_reply_method_return(m, NULL);
|
||||
r = sd_bus_reply_method_return(m, NULL);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const sd_bus_vtable wfd_dbus_vtable[] = {
|
||||
|
|
|
@ -38,21 +38,13 @@ struct wfd_out_session
|
|||
struct wfd_session parent;
|
||||
struct wfd_sink *sink;
|
||||
int fd;
|
||||
sd_event_source *gst_launch_source;
|
||||
sd_event_source *gst_term_source;
|
||||
|
||||
sd_event_source *encoder_source;
|
||||
|
||||
const char *display_param_name;
|
||||
const char *display_param_value;
|
||||
enum wfd_resolution_standard std;
|
||||
uint32_t mask;
|
||||
|
||||
/*GstElement *pipeline;*/
|
||||
/*GstBus *bus;*/
|
||||
struct dispd_encoder *encoder;
|
||||
};
|
||||
|
||||
static int force_proc_exit(pid_t pid);
|
||||
static void on_encoder_state_changed(struct dispd_encoder *e,
|
||||
enum dispd_encoder_state state,
|
||||
void *userdata);
|
||||
|
||||
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[];
|
||||
|
||||
|
@ -62,15 +54,8 @@ int wfd_out_session_new(struct wfd_session **out,
|
|||
{
|
||||
_wfd_session_unref_ struct wfd_session *s;
|
||||
struct wfd_out_session *os;
|
||||
//enum wfd_resolution_standard std;
|
||||
//uint32_t mask;
|
||||
int r;
|
||||
|
||||
// r = vfd_get_mask_from_resolution(width, height, &std, &mask);
|
||||
// if(0 > r) {
|
||||
// return -EINVAL;
|
||||
// }
|
||||
|
||||
s = calloc(1, sizeof(struct wfd_out_session));
|
||||
if(!s) {
|
||||
return -ENOMEM;
|
||||
|
@ -87,6 +72,14 @@ int wfd_out_session_new(struct wfd_session **out,
|
|||
os = wfd_out_session(s);
|
||||
os->fd = -1;
|
||||
os->sink = sink;
|
||||
|
||||
//enum wfd_resolution_standard std;
|
||||
//uint32_t mask;
|
||||
// r = vfd_get_mask_from_resolution(width, height, &std, &mask);
|
||||
// if(0 > r) {
|
||||
// return -EINVAL;
|
||||
// }
|
||||
|
||||
// os->mask = mask;
|
||||
// os->std = std;
|
||||
//
|
||||
|
@ -205,6 +198,16 @@ int wfd_out_session_initiate_io(struct wfd_session *s,
|
|||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = dispd_encoder_spawn(&os->encoder, s);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
dispd_encoder_set_handler(os->encoder, on_encoder_state_changed, s);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
log_trace("socket listening on %s:%hu",
|
||||
p->local_address,
|
||||
wfd_sube_device_get_rtsp_port(&sube));
|
||||
|
@ -240,38 +243,18 @@ int wfd_out_session_teardown(struct wfd_session *s)
|
|||
|
||||
void wfd_out_session_destroy(struct wfd_session *s)
|
||||
{
|
||||
pid_t pid;
|
||||
// pid_t pid;
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
if(0 <= os->fd) {
|
||||
close(os->fd);
|
||||
os->fd = -1;
|
||||
}
|
||||
|
||||
if(os->encoder_source) {
|
||||
sd_event_source_get_child_pid(os->encoder_source, &pid);
|
||||
kill(pid, SIGTERM);
|
||||
|
||||
sd_event_source_set_userdata(os->encoder_source, NULL);
|
||||
sd_event_source_unref(os->encoder_source);
|
||||
os->encoder_source = NULL;
|
||||
if(os->encoder) {
|
||||
dispd_encoder_set_handler(os->encoder, NULL, NULL);
|
||||
dispd_encoder_unref(os->encoder);
|
||||
os->encoder = NULL;
|
||||
}
|
||||
|
||||
/*if(os->gst_launch_source) {*/
|
||||
/*sd_event_source_unref(os->gst_launch_source);*/
|
||||
/*os->gst_launch_source = NULL;*/
|
||||
/*}*/
|
||||
|
||||
/*if(os->bus) {*/
|
||||
/*gst_bus_remove_watch(os->bus);*/
|
||||
/*g_object_unref(os->bus);*/
|
||||
/*os->bus = NULL;*/
|
||||
/*}*/
|
||||
|
||||
/*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)
|
||||
|
@ -484,44 +467,6 @@ static int wfd_out_session_request_options(struct wfd_session *s,
|
|||
return 0;
|
||||
}
|
||||
|
||||
//static gboolean wfd_out_session_handle_gst_message(GstBus *bus,
|
||||
// GstMessage *m,
|
||||
// gpointer userdata)
|
||||
//{
|
||||
// struct wfd_session *s = userdata;
|
||||
// struct wfd_out_session *os = userdata;
|
||||
// GstState old_state, new_state;
|
||||
//
|
||||
// switch(GST_MESSAGE_TYPE(m)) {
|
||||
// case GST_MESSAGE_STATE_CHANGED:
|
||||
// if(os->pipeline != (void *) GST_MESSAGE_SRC(m)) {
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// gst_message_parse_state_changed(m, &old_state, &new_state, NULL);
|
||||
// if(GST_STATE_PLAYING == new_state) {
|
||||
// log_info("stream is playing");
|
||||
// wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING);
|
||||
// }
|
||||
// else if(GST_STATE_PLAYING == old_state &&
|
||||
// GST_STATE_PAUSED == new_state) {
|
||||
// log_info("stream is paused");
|
||||
// wfd_session_set_state(s, WFD_SESSION_STATE_PAUSED);
|
||||
// }
|
||||
// break;
|
||||
// case GST_MESSAGE_EOS:
|
||||
// case GST_MESSAGE_ERROR:
|
||||
// log_warning("%s encounter unexpected error or EOS",
|
||||
// GST_MESSAGE_SRC_NAME(m));
|
||||
// wfd_session_teardown(s);
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// return TRUE;
|
||||
//}
|
||||
|
||||
inline static char * uint16_to_str(uint16_t i, char *buf, size_t len)
|
||||
{
|
||||
snprintf(buf, len, "%u", i);
|
||||
|
@ -536,276 +481,6 @@ inline static char * quote_str(const char *s, char *d, size_t len)
|
|||
return d;
|
||||
}
|
||||
|
||||
static int force_proc_exit(pid_t pid)
|
||||
{
|
||||
siginfo_t siginfo;
|
||||
int r = kill(pid, SIGKILL);
|
||||
if(0 > r) {
|
||||
log_warning("failed to kill encoder (pid %d): %s",
|
||||
pid,
|
||||
strerror(errno));
|
||||
return r;
|
||||
}
|
||||
|
||||
r = waitid(P_PID, pid, &siginfo, 0);
|
||||
if(0 > r) {
|
||||
log_warning("failed to wait for encoder (pid %d) exit: %s",
|
||||
pid,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int wfd_out_session_handle_encoder_exit(sd_event_source *source,
|
||||
const siginfo_t *siginfo,
|
||||
void *userdata)
|
||||
{
|
||||
struct wfd_out_session *os = userdata;
|
||||
pid_t pid;
|
||||
|
||||
sd_event_source_get_child_pid(source, &pid);
|
||||
log_info("encoder %d exited", pid);
|
||||
|
||||
sd_event_source_set_enabled(source, false);
|
||||
sd_event_source_unref(source);
|
||||
|
||||
if(os) {
|
||||
os->encoder_source = NULL;
|
||||
wfd_session_teardown(wfd_session(os));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_out_session_create_pipeline(struct wfd_session *s)
|
||||
{
|
||||
int r;
|
||||
pid_t pid;
|
||||
sigset_t mask;
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
|
||||
if(os->encoder_source) {
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if(0 > pid) {
|
||||
return pid;
|
||||
}
|
||||
else if(0 < pid) {
|
||||
log_info("forked child %d", pid);
|
||||
r = sd_event_add_child(ctl_wfd_get_loop(),
|
||||
&os->encoder_source,
|
||||
pid,
|
||||
WEXITED,
|
||||
wfd_out_session_handle_encoder_exit,
|
||||
s);
|
||||
if(0 > r) {
|
||||
force_proc_exit(pid);
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_info("exec gstencoder");
|
||||
|
||||
setuid(1000);
|
||||
setgid(1000);
|
||||
|
||||
sigemptyset(&mask);
|
||||
sigprocmask(SIG_SETMASK, &mask, NULL);
|
||||
|
||||
r = execvpe("gstencoder",
|
||||
(char *[]){ "gstencoder", NULL },
|
||||
(char *[]){ "DISPLAY=:0", "XAUTHORITY=/run/user/1000/gdm/Xauthority", "G_MESSAGES_DEBUG=all", "DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus", NULL });
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
//static int wfd_out_session_create_pipeline(struct wfd_session *s)
|
||||
//{
|
||||
// char rrtp_port[16], rrtcp_port[16], lrtcp_port[16];
|
||||
// char audio_dev[256];
|
||||
// char vsrc_param1[16] = "", vsrc_param2[16] = "";
|
||||
// char vsrc_param3[16] = "", vsrc_param4[16] = "";
|
||||
// struct wfd_out_session *os = wfd_out_session(s);
|
||||
// GstElement *pipeline;
|
||||
// GstElement *vsrc;
|
||||
// GstBus *bus;
|
||||
// GError *error = NULL;
|
||||
// const char **tmp;
|
||||
// int r;
|
||||
// const char *pipeline_desc[128] = {
|
||||
// "ximagesrc",
|
||||
// "name=vsrc",
|
||||
// "use-damage=false",
|
||||
// "show-pointer=false",
|
||||
// vsrc_param1,
|
||||
// vsrc_param2,
|
||||
// vsrc_param3,
|
||||
// vsrc_param4,
|
||||
// "!", "video/x-raw,",
|
||||
// "framerate=30/1",
|
||||
// //"!", "vaapipostproc",
|
||||
// // "scale-method=2", /* high quality scaling mode */
|
||||
// // "format=3", /* yv12" */
|
||||
// //"!", "vaapih264enc",
|
||||
// // "rate-control=1",
|
||||
// // "num-slices=1", /* in WFD spec, one slice per frame */
|
||||
// // "max-bframes=0", /* in H264 CHP, no bframe supporting */
|
||||
// // "cabac=true", /* in H264 CHP, CABAC entropy codeing is supported, but need more processing to decode */
|
||||
// // "dct8x8=true", /* in H264 CHP, DTC is supported */
|
||||
// // "cpb-length=50", /* shortent buffer in order to decrease latency */
|
||||
// // "keyframe-period=30",
|
||||
// // /* "bitrate=62500", */ /* the max bitrate of H264 level 4.2, crashing my dongle, let codec decide */
|
||||
// "!", "videoscale",
|
||||
// "method=0",
|
||||
// "!", "video/x-raw,",
|
||||
// "width=1920,",
|
||||
// "height=1080",
|
||||
// "!", "videoconvert",
|
||||
// "dither=0",
|
||||
// "!", "video/x-raw,",
|
||||
// "format=YV12"
|
||||
// "!", "x264enc",
|
||||
// "pass=4", /* constant quantizer */
|
||||
// "b-adapt=false", /* no bframe suppport in CHP */
|
||||
// "key-int-max=30", /* send IDR pictures per second */
|
||||
// "speed-preset=4", /* faster */
|
||||
// "tune=4", /* zero latency */
|
||||
// "!", "h264parse",
|
||||
// "!", "video/x-h264,",
|
||||
// "alignment=nal,",
|
||||
// "stream-format=byte-stream"
|
||||
// "!", "queue",
|
||||
// "max-size-buffers=0",
|
||||
// "max-size-bytes=0",
|
||||
// "!", "mpegtsmux",
|
||||
// "name=muxer",
|
||||
// "!", "rtpmp2tpay",
|
||||
// "!", ".send_rtp_sink_0", "rtpbin",
|
||||
// "name=session",
|
||||
// "do-retransmission=true",
|
||||
// "do-sync-event=true",
|
||||
// "do-lost=true",
|
||||
// "ntp-time-source=3",
|
||||
// "buffer-mode=0",
|
||||
// "latency=20",
|
||||
// "max-misorder-time=30",
|
||||
// "!", "application/x-rtp",
|
||||
// "!", "udpsink",
|
||||
// "sync=false",
|
||||
// "async=false",
|
||||
// "host=", wfd_out_session_get_sink(s)->peer->remote_address,
|
||||
// "port=", uint16_to_str(s->stream.rtp_port, rrtp_port,sizeof(rrtp_port)),
|
||||
// "udpsrc",
|
||||
// "address=", wfd_out_session_get_sink(s)->peer->local_address,
|
||||
// "port=", uint16_to_str(LOCAL_RTCP_PORT, lrtcp_port,sizeof(lrtcp_port)),
|
||||
// "reuse=true",
|
||||
// "!", "session.recv_rtcp_sink_0",
|
||||
// NULL
|
||||
// };
|
||||
//
|
||||
// if(s->stream.rtcp_port) {
|
||||
// for(tmp = pipeline_desc; *tmp; ++tmp);
|
||||
// *tmp ++ = "session.send_rtcp_src_0";
|
||||
// *tmp ++ = "!";
|
||||
// *tmp ++ = "udpsink";
|
||||
// *tmp ++ = "host=";
|
||||
// *tmp ++ = wfd_out_session_get_sink(s)->peer->remote_address;
|
||||
// *tmp ++ = "port=";
|
||||
// *tmp ++ = uint16_to_str(s->stream.rtcp_port, rrtcp_port,sizeof(rrtcp_port));
|
||||
// *tmp ++ = "sync=false";
|
||||
// *tmp ++ = "async=false";
|
||||
// *tmp ++ = NULL;
|
||||
// }
|
||||
//
|
||||
// if(*os->audio_dev) {
|
||||
// for(tmp = pipeline_desc; *tmp; ++tmp);
|
||||
// *tmp ++ = "pulsesrc";
|
||||
// *tmp ++ = "do-timestamp=true";
|
||||
// *tmp ++ = "client-name=miraclecast";
|
||||
// *tmp ++ = "device=";
|
||||
// *tmp ++ = quote_str(os->audio_dev, audio_dev, sizeof(audio_dev));
|
||||
// *tmp ++ = "!";
|
||||
// *tmp ++ = "voaacenc";
|
||||
// *tmp ++ = "mark-granule=true";
|
||||
// *tmp ++ = "hard-resync=true";
|
||||
// *tmp ++ = "tolerance=40";
|
||||
// *tmp ++ = "!";
|
||||
// *tmp ++ = "audio/mpeg,";
|
||||
// *tmp ++ = "rate=48000,";
|
||||
// *tmp ++ = "channels=2,";
|
||||
// *tmp ++ = "stream-format=adts,";
|
||||
// *tmp ++ = "base-profile=lc";
|
||||
// *tmp ++ = "!";
|
||||
// *tmp ++ = "queue";
|
||||
// *tmp ++ = "max-size-buffers=0";
|
||||
// *tmp ++ = "max-size-bytes=0";
|
||||
// *tmp ++ = "max-size-time=0";
|
||||
// *tmp ++ = "!";
|
||||
// *tmp ++ = "muxer.";
|
||||
// *tmp ++ = NULL;
|
||||
// }
|
||||
//
|
||||
// /* bad pratice, but since we are in the same process,
|
||||
// I think this is the only way to do it */
|
||||
// if(WFD_DISPLAY_TYPE_X == os->display_type) {
|
||||
// r = setenv("XAUTHORITY", os->authority, 1);
|
||||
// if(0 > r) {
|
||||
// return r;
|
||||
// }
|
||||
//
|
||||
// r = setenv("DISPLAY", os->display_name, 1);
|
||||
// if(0 > r) {
|
||||
// return r;
|
||||
// }
|
||||
//
|
||||
// if(!os->display_param_name) {
|
||||
// snprintf(vsrc_param1, sizeof(vsrc_param1), "startx=%hu", os->x);
|
||||
// snprintf(vsrc_param2, sizeof(vsrc_param2), "starty=%hu", os->y);
|
||||
// snprintf(vsrc_param3, sizeof(vsrc_param3), "endx=%d", os->x + os->width - 1);
|
||||
// snprintf(vsrc_param4, sizeof(vsrc_param4), "endy=%d", os->y + os->height - 1);
|
||||
// }
|
||||
// else if(!strcmp("xid", os->display_param_name) ||
|
||||
// !strcmp("xname", os->display_param_name)) {
|
||||
// snprintf(vsrc_param1, sizeof(vsrc_param1),
|
||||
// "%s=\"%s\"",
|
||||
// os->display_param_name,
|
||||
// os->display_param_value);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// pipeline = gst_parse_launchv(pipeline_desc, &error);
|
||||
// if(!pipeline) {
|
||||
// if(error) {
|
||||
// log_error("failed to create pipeline: %s", error->message);
|
||||
// g_error_free(error);
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// vsrc = gst_bin_get_by_name(GST_BIN(pipeline), "vsrc");
|
||||
// gst_base_src_set_live(GST_BASE_SRC(vsrc), true);
|
||||
// g_object_unref(vsrc);
|
||||
// vsrc = NULL;
|
||||
//
|
||||
// r = gst_element_set_state(pipeline, GST_STATE_PAUSED);
|
||||
// if(GST_STATE_CHANGE_FAILURE == r) {
|
||||
// g_object_unref(pipeline);
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// bus = gst_element_get_bus(pipeline);
|
||||
// gst_bus_add_watch(bus, wfd_out_session_handle_gst_message, s);
|
||||
//
|
||||
// os->pipeline = pipeline;
|
||||
// os->bus = bus;
|
||||
//
|
||||
// return 0;
|
||||
//}
|
||||
|
||||
static int wfd_out_session_handle_pause_request(struct wfd_session *s,
|
||||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
|
@ -813,10 +488,10 @@ static int wfd_out_session_handle_pause_request(struct wfd_session *s,
|
|||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
int r;
|
||||
|
||||
// r = gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_READY);
|
||||
// if(GST_STATE_CHANGE_FAILURE == r) {
|
||||
// return -1;
|
||||
// }
|
||||
r = dispd_encoder_pause(wfd_out_session(s)->encoder);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = rtsp_message_new_reply_for(req,
|
||||
&m,
|
||||
|
@ -836,25 +511,22 @@ static int wfd_out_session_handle_teardown_request(struct wfd_session *s,
|
|||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
{
|
||||
pid_t pid;
|
||||
// pid_t pid;
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
/*_rtsp_message_unref_ struct rtsp_message *m = NULL;*/
|
||||
// _rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
int r;
|
||||
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN);
|
||||
/*gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_NULL);*/
|
||||
// if(!os->encoder_source) {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
if(!os->encoder_source) {
|
||||
return 0;
|
||||
}
|
||||
// r = sd_event_source_get_child_pid(os->encoder_source, &pid);
|
||||
// if(0 > r) {
|
||||
// return log_ERRNO();
|
||||
// }
|
||||
|
||||
r = sd_event_source_get_child_pid(os->encoder_source, &pid);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
log_info("terminating encoder %d", pid);
|
||||
r = kill(pid, SIGTERM);
|
||||
// log_info("terminating encoder %d", pid);
|
||||
// r = kill(pid, SIGTERM);
|
||||
|
||||
/*r = rtsp_message_new_reply_for(req,*/
|
||||
/*&m,*/
|
||||
|
@ -864,30 +536,14 @@ static int wfd_out_session_handle_teardown_request(struct wfd_session *s,
|
|||
/*return log_ERRNO();*/
|
||||
/*}*/
|
||||
|
||||
r = dispd_encoder_stop(os->encoder);
|
||||
|
||||
/**out_rep = m;*/
|
||||
/*m = NULL;*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wfd_out_session_post_handle_play(sd_event_source *source,
|
||||
uint64_t t,
|
||||
void *userdata)
|
||||
{
|
||||
struct wfd_session *s = userdata;
|
||||
//GstStateChangeReturn r;
|
||||
|
||||
sd_event_source_unref(source);
|
||||
wfd_out_session(s)->gst_launch_source = NULL;
|
||||
|
||||
/*r = gst_element_set_state(wfd_out_session(s)->pipeline,*/
|
||||
/*GST_STATE_PLAYING);*/
|
||||
/*if(GST_STATE_CHANGE_FAILURE == r) {*/
|
||||
/*wfd_session_teardown(s);*/
|
||||
/*return -1;*/
|
||||
/*}*/
|
||||
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -896,8 +552,9 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
{
|
||||
_shl_free_ char *v = NULL;
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
_shl_free_ char *v = NULL;
|
||||
struct dispd_encoder *e;
|
||||
uint64_t now;
|
||||
int r;
|
||||
|
||||
|
@ -909,12 +566,12 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = asprintf(&v, "%d;timeout=30", s->stream.id);
|
||||
r = asprintf(&v, "%X", wfd_session_get_id(s));
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = rtsp_message_append(m, "<s>", "Session", v);
|
||||
r = rtsp_message_append(m, "<&>", "Session", v);
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
@ -924,26 +581,64 @@ static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
|||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = sd_event_add_time(ctl_wfd_get_loop(),
|
||||
&wfd_out_session(s)->gst_launch_source,
|
||||
CLOCK_MONOTONIC,
|
||||
100 * 1000 + now, 0,
|
||||
wfd_out_session_post_handle_play,
|
||||
s);
|
||||
if(0 <= r) {
|
||||
*out_rep = m;
|
||||
m = NULL;
|
||||
e = wfd_out_session(s)->encoder;
|
||||
if(DISPD_ENCODER_STATE_CONFIGURED <= dispd_encoder_get_state(e)) {
|
||||
r = dispd_encoder_start(e);
|
||||
}
|
||||
|
||||
*out_rep = (rtsp_message_ref(m), m);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void on_encoder_state_changed(struct dispd_encoder *e,
|
||||
enum dispd_encoder_state state,
|
||||
void *userdata)
|
||||
{
|
||||
int r = 0;
|
||||
struct wfd_session *s = userdata;
|
||||
|
||||
switch(state) {
|
||||
case DISPD_ENCODER_STATE_SPAWNED:
|
||||
if(WFD_SESSION_STATE_SETTING_UP == wfd_session_get_state(s)) {
|
||||
r = dispd_encoder_configure(wfd_out_session(s)->encoder, s);
|
||||
}
|
||||
break;
|
||||
case DISPD_ENCODER_STATE_CONFIGURED:
|
||||
if(WFD_SESSION_STATE_SETTING_UP == wfd_session_get_state(s)) {
|
||||
r = dispd_encoder_start(e);
|
||||
}
|
||||
break;
|
||||
case DISPD_ENCODER_STATE_READY:
|
||||
break;
|
||||
case DISPD_ENCODER_STATE_STARTED:
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING);
|
||||
break;
|
||||
case DISPD_ENCODER_STATE_PAUSED:
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_PAUSED);
|
||||
break;
|
||||
case DISPD_ENCODER_STATE_TERMINATED:
|
||||
wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN);
|
||||
wfd_session_teardown(s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(0 > r) {
|
||||
return log_vERRNO();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
{
|
||||
int r;
|
||||
char *l;
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
_shl_free_ char *sess = NULL, *trans = NULL;
|
||||
|
||||
|
@ -989,7 +684,7 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
|||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = asprintf(&sess, "%X;timeout=30", s->id);
|
||||
r = asprintf(&sess, "%X;timeout=30", wfd_session_get_id(s));
|
||||
if(0 > r) {
|
||||
return log_ERRNO();
|
||||
}
|
||||
|
@ -1013,13 +708,11 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
|||
return log_ERRNO();
|
||||
}
|
||||
|
||||
r = wfd_out_session_create_pipeline(s);
|
||||
if(0 > r) {
|
||||
return r;
|
||||
if(DISPD_ENCODER_STATE_SPAWNED == dispd_encoder_get_state(os->encoder)) {
|
||||
dispd_encoder_configure(os->encoder, s);
|
||||
}
|
||||
|
||||
*out_rep = m;
|
||||
m = NULL;
|
||||
*out_rep = (rtsp_message_ref(m), m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1083,7 +776,6 @@ static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
|||
const struct wfd_arg_list *args,
|
||||
struct rtsp_message **out)
|
||||
{
|
||||
struct wfd_out_session *os = wfd_out_session(s);
|
||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||
_shl_free_ char *body = NULL;
|
||||
int r;
|
||||
|
@ -1104,7 +796,7 @@ static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
|||
"wfd_client_rtp_ports: RTP/AVP/UDP;unicast %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_setting: disable\n",
|
||||
WFD_RESOLUTION_STANDARD_CEA == os->std ? 0x80 : 0,
|
||||
0x80,
|
||||
0,
|
||||
0,
|
||||
wfd_session_get_stream_url(s),
|
||||
|
@ -1179,6 +871,12 @@ static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[] = {
|
|||
},
|
||||
[RTSP_M6_SETUP] = {
|
||||
.handle_request = wfd_out_session_handle_setup_request,
|
||||
.rule = wfd_arg_list(
|
||||
wfd_arg_dict(
|
||||
wfd_arg_u(WFD_SESSION_ARG_NEW_STATE),
|
||||
wfd_arg_u(WFD_SESSION_STATE_SETTING_UP)
|
||||
),
|
||||
)
|
||||
},
|
||||
[RTSP_M7_PLAY] = {
|
||||
.handle_request = wfd_out_session_handle_play_request,
|
||||
|
|
|
@ -61,7 +61,7 @@ const struct wfd_session_vtable session_vtbl[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static inline int wfd_session_do_request(struct wfd_session *s,
|
||||
static int wfd_session_do_request(struct wfd_session *s,
|
||||
enum rtsp_message_id id,
|
||||
const struct wfd_arg_list *args,
|
||||
struct rtsp_message **out)
|
||||
|
@ -78,7 +78,7 @@ static inline int wfd_session_do_request(struct wfd_session *s,
|
|||
return (*s->rtsp_disp_tbl[id].request)(s, args, out);
|
||||
}
|
||||
|
||||
static inline int wfd_session_do_handle_request(struct wfd_session *s,
|
||||
static int wfd_session_do_handle_request(struct wfd_session *s,
|
||||
enum rtsp_message_id id,
|
||||
struct rtsp_message *req,
|
||||
struct rtsp_message **out_rep)
|
||||
|
@ -97,7 +97,7 @@ static inline int wfd_session_do_handle_request(struct wfd_session *s,
|
|||
out_rep);
|
||||
}
|
||||
|
||||
static inline int wfd_session_do_handle_reply(struct wfd_session *s,
|
||||
static int wfd_session_do_handle_reply(struct wfd_session *s,
|
||||
enum rtsp_message_id id,
|
||||
struct rtsp_message *m)
|
||||
{
|
||||
|
@ -112,7 +112,7 @@ static inline int wfd_session_do_handle_reply(struct wfd_session *s,
|
|||
return (*s->rtsp_disp_tbl[id].handle_reply)(s, m);
|
||||
}
|
||||
|
||||
uint64_t wfd_session_get_id(struct wfd_session *s)
|
||||
unsigned int wfd_session_get_id(struct wfd_session *s)
|
||||
{
|
||||
return s->id;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue