mirror of
https://github.com/albfan/miraclecast.git
synced 2025-03-09 23:38:56 +00:00
miracle-wfdctl: finish migration of source side rtsp protocol
This commit is contained in:
parent
3bcb8f51f6
commit
9dd805378e
5 changed files with 428 additions and 200 deletions
|
@ -162,7 +162,7 @@ enum wfd_session_state
|
||||||
{
|
{
|
||||||
WFD_SESSION_STATE_NULL,
|
WFD_SESSION_STATE_NULL,
|
||||||
WFD_SESSION_STATE_CONNECTING,
|
WFD_SESSION_STATE_CONNECTING,
|
||||||
WFD_SESSION_STATE_CAPS_EXCHAING,
|
WFD_SESSION_STATE_CAPS_EXCHANGING,
|
||||||
WFD_SESSION_STATE_ESTABLISHED,
|
WFD_SESSION_STATE_ESTABLISHED,
|
||||||
WFD_SESSION_STATE_SETING_UP,
|
WFD_SESSION_STATE_SETING_UP,
|
||||||
WFD_SESSION_STATE_PLAYING,
|
WFD_SESSION_STATE_PLAYING,
|
||||||
|
@ -174,7 +174,7 @@ int wfd_out_session_new(struct wfd_session **out, struct wfd_sink *sink);
|
||||||
int wfd_session_start(struct wfd_session *s, uint64_t id);
|
int wfd_session_start(struct wfd_session *s, uint64_t id);
|
||||||
enum wfd_session_dir wfd_session_get_dir(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);
|
uint64_t wfd_session_get_id(struct wfd_session *s);
|
||||||
const char * wfd_session_get_url(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_state wfd_session_get_state(struct wfd_session *s);
|
||||||
int wfd_session_is_started(struct wfd_session *s);
|
int wfd_session_is_started(struct wfd_session *s);
|
||||||
void wfd_session_end(struct wfd_session *s);
|
void wfd_session_end(struct wfd_session *s);
|
||||||
|
|
|
@ -489,7 +489,7 @@ static int wfd_dbus_session_get_sink(sd_bus *bus,
|
||||||
return sd_bus_message_append(reply, "o", sink_path);
|
return sd_bus_message_append(reply, "o", sink_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_dbus_session_get_url(sd_bus *bus,
|
static int wfd_dbus_get_session_presentation_url(sd_bus *bus,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *property,
|
const char *property,
|
||||||
|
@ -498,10 +498,12 @@ static int wfd_dbus_session_get_url(sd_bus *bus,
|
||||||
sd_bus_error *ret_error)
|
sd_bus_error *ret_error)
|
||||||
{
|
{
|
||||||
struct wfd_session *s = userdata;
|
struct wfd_session *s = userdata;
|
||||||
return sd_bus_message_append(reply, "s", wfd_session_get_url(s));
|
return sd_bus_message_append(reply,
|
||||||
|
"s",
|
||||||
|
wfd_session_get_stream_url(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_dbus_session_get_state(sd_bus *bus,
|
static int wfd_dbus_get_session_state(sd_bus *bus,
|
||||||
const char *path,
|
const char *path,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
const char *property,
|
const char *property,
|
||||||
|
@ -554,8 +556,8 @@ static const sd_bus_vtable wfd_dbus_session_vtable[] = {
|
||||||
SD_BUS_VTABLE_START(0),
|
SD_BUS_VTABLE_START(0),
|
||||||
SD_BUS_METHOD("End", NULL, NULL, wfd_dbus_session_end, 0),
|
SD_BUS_METHOD("End", NULL, NULL, wfd_dbus_session_end, 0),
|
||||||
SD_BUS_PROPERTY("Sink", "o", wfd_dbus_session_get_sink, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Sink", "o", wfd_dbus_session_get_sink, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Url", "o", wfd_dbus_session_get_url, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("Url", "o", wfd_dbus_get_session_presentation_url, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_PROPERTY("State", "i", wfd_dbus_session_get_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
SD_BUS_PROPERTY("State", "i", wfd_dbus_get_session_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||||
SD_BUS_VTABLE_END,
|
SD_BUS_VTABLE_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -186,67 +186,104 @@ static int wfd_out_session_initiate_request(struct wfd_session *s)
|
||||||
return wfd_session_request(s, RTSP_M1_REQUEST_SINK_OPTIONS);
|
return wfd_session_request(s, RTSP_M1_REQUEST_SINK_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static int wfd_out_session_handle_get_parameter_reply(struct rtsp *bus,*/
|
static int wfd_out_session_handle_get_parameter_reply(struct wfd_session *s,
|
||||||
/*struct rtsp_message *m,*/
|
struct rtsp_message *m,
|
||||||
/*void *userdata)*/
|
enum wfd_session_state *new_state,
|
||||||
/*{*/
|
enum rtsp_message_id *next_request)
|
||||||
/*struct wfd_session *s = userdata;*/
|
{
|
||||||
|
struct wfd_video_formats *vformats;
|
||||||
|
struct wfd_audio_codecs *acodecs;
|
||||||
|
uint16_t rtp_ports[2];
|
||||||
|
_shl_free_ char *t = NULL;
|
||||||
|
const char *l;
|
||||||
|
int r;
|
||||||
|
|
||||||
/*log_debug("received GET_PARAMETER reply (M3): %s\n",*/
|
if(!rtsp_message_read(m, "{<&>}", "wfd_video_formats", &l)) {
|
||||||
/*(char *) rtsp_message_get_raw(m));*/
|
r = wfd_video_formats_from_string(l, &vformats);
|
||||||
/*if(RTSP_CODE_OK != rtsp_message_get_code(m)) {*/
|
if(0 > r) {
|
||||||
/*wfd_session_end(wfd_session(userdata));*/
|
return r;
|
||||||
/*return -EPROTO;*/
|
}
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*return 0;*/
|
if(s->vformats) {
|
||||||
/*}*/
|
free(s->vformats);
|
||||||
|
}
|
||||||
|
s->vformats = vformats;
|
||||||
|
}
|
||||||
|
|
||||||
/*static int wfd_out_session_send_get_parameter(sd_event_source *source,*/
|
if(!rtsp_message_read(m, "{<&>}", "wfd_audio_codecs", &l)) {
|
||||||
/*void *userdata)*/
|
r = wfd_audio_codecs_from_string(l, &acodecs);
|
||||||
/*{*/
|
if(0 > r) {
|
||||||
/*struct wfd_session *s = userdata;*/
|
return r;
|
||||||
/*_rtsp_message_unref_ struct rtsp_message *m = NULL;*/
|
}
|
||||||
/*int r = rtsp_message_new_request(s->rtsp,*/
|
|
||||||
/*&m,*/
|
if(s->acodecs) {
|
||||||
/*"GET_PARAMETER",*/
|
free(s->acodecs);
|
||||||
/*s->url);*/
|
}
|
||||||
/*if (0 > r) {*/
|
s->acodecs = acodecs;
|
||||||
/*goto error;*/
|
}
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*r = rtsp_message_append(m, "{&}",*/
|
if(!rtsp_message_read(m, "{<&>}", "wfd_client_rtp_ports", &l)) {
|
||||||
/*"wfd_video_formats\n"*/
|
if(strncmp("RTP/AVP/UDP;unicast", l, 19)) {
|
||||||
/*"wfd_audio_codecs\n"*/
|
return -EPROTO;
|
||||||
/*"wfd_client_rtp_ports"*/
|
}
|
||||||
/*//"wfd_uibc_capability"*/
|
|
||||||
/*);*/
|
|
||||||
/*if (0 > r) {*/
|
|
||||||
/*goto error;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*rtsp_message_seal(m);*/
|
r = sscanf(l + 20, "%hd %hd %ms",
|
||||||
|
&rtp_ports[0],
|
||||||
|
&rtp_ports[1],
|
||||||
|
&t);
|
||||||
|
if(3 != r) {
|
||||||
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
/*r = rtsp_call_async(s->rtsp,*/
|
if(strncmp("mode=play", t, 9)) {
|
||||||
/*m,*/
|
return -EPROTO;
|
||||||
/*wfd_out_session_handle_get_parameter_reply,*/
|
}
|
||||||
/*s,*/
|
|
||||||
/*0,*/
|
|
||||||
/*NULL);*/
|
|
||||||
/*if (r < 0) {*/
|
|
||||||
/*goto error;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*log_debug("Sending GET_PARAMETER (M3): %s\n",*/
|
if(!rtp_ports[0] && !rtp_ports[1]) {
|
||||||
/*(char *) rtsp_message_get_raw(m));*/
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
/*return 0;*/
|
s->rtp_ports[0] = rtp_ports[0];
|
||||||
|
s->rtp_ports[1] = rtp_ports[1];
|
||||||
|
}
|
||||||
|
|
||||||
/*error:*/
|
*next_request = RTSP_M4_SET_PARAMETER;
|
||||||
/*wfd_session_end(s);*/
|
|
||||||
|
|
||||||
/*return r;*/
|
return 0;
|
||||||
/*}*/
|
}
|
||||||
|
|
||||||
|
static int wfd_out_session_request_get_parameter(struct wfd_session *s,
|
||||||
|
struct rtsp_message **out)
|
||||||
|
{
|
||||||
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
|
int r = rtsp_message_new_request(s->rtsp,
|
||||||
|
&m,
|
||||||
|
"GET_PARAMETER",
|
||||||
|
"rtsp://localhost/wfd1.0");
|
||||||
|
if (0 > r) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_append(m, "{&}",
|
||||||
|
"wfd_video_formats\n"
|
||||||
|
"wfd_audio_codecs\n"
|
||||||
|
"wfd_client_rtp_ports"
|
||||||
|
//"wfd_uibc_capability"
|
||||||
|
);
|
||||||
|
if (0 > r) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = m;
|
||||||
|
m = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
wfd_session_end(s);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static bool find_strv(const char *str, char **strv)
|
static bool find_strv(const char *str, char **strv)
|
||||||
{
|
{
|
||||||
|
@ -262,7 +299,9 @@ static bool find_strv(const char *str, char **strv)
|
||||||
|
|
||||||
static int wfd_out_session_handle_options_request(struct wfd_session *s,
|
static int wfd_out_session_handle_options_request(struct wfd_session *s,
|
||||||
struct rtsp_message *req,
|
struct rtsp_message *req,
|
||||||
struct rtsp_message **out_rep)
|
struct rtsp_message **out_rep,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request)
|
||||||
{
|
{
|
||||||
const char *require;
|
const char *require;
|
||||||
_rtsp_message_unref_ struct rtsp_message *rep = NULL;
|
_rtsp_message_unref_ struct rtsp_message *rep = NULL;
|
||||||
|
@ -298,11 +337,15 @@ static int wfd_out_session_handle_options_request(struct wfd_session *s,
|
||||||
*out_rep = rep;
|
*out_rep = rep;
|
||||||
rep = NULL;
|
rep = NULL;
|
||||||
|
|
||||||
|
*next_request = RTSP_M3_GET_PARAMETER;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_out_session_check_options_reply(struct wfd_session *s,
|
static int wfd_out_session_handle_options_reply(struct wfd_session *s,
|
||||||
struct rtsp_message *m)
|
struct rtsp_message *m,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
const char *public;
|
const char *public;
|
||||||
|
@ -356,102 +399,198 @@ static int wfd_out_session_request_options(struct wfd_session *s,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static int wfd_out_session_handle_options_request(struct rtsp *bus,*/
|
static int wfd_out_session_handle_play_request(struct wfd_session *s,
|
||||||
/*struct rtsp_message *request,*/
|
struct rtsp_message *req,
|
||||||
/*struct wfd_session *s)*/
|
struct rtsp_message **out_rep,
|
||||||
/*{*/
|
enum wfd_session_state *new_state,
|
||||||
/*}*/
|
enum rtsp_message_id *next_request)
|
||||||
|
|
||||||
static int wfd_out_session_handle_play_reply(struct rtsp *bus,
|
|
||||||
struct rtsp_message *m,
|
|
||||||
void *userdata)
|
|
||||||
{
|
{
|
||||||
/*struct wfd_session *s = userdata;*/
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
/*log_trace("received SETUP (M5) reply: %s",*/
|
|
||||||
/*(char *) rtsp_message_get_raw(m));*/
|
|
||||||
|
|
||||||
/*wfd_out_session_send_play(s);*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wfd_out_session_send_play(struct wfd_session *s)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wfd_out_session_handle_setup_reply(struct rtsp *bus,
|
|
||||||
struct rtsp_message *m,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
/*struct wfd_session *s = userdata;*/
|
|
||||||
/*log_trace("received SETUP (M5) reply: %s",*/
|
|
||||||
/*(char *) rtsp_message_get_raw(m));*/
|
|
||||||
|
|
||||||
/*wfd_out_session_send_play(s);*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wfd_out_session_handle_set_parameter_reply(struct rtsp *bus,
|
|
||||||
struct rtsp_message *m,
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
/*struct wfd_session *s = userdata;*/
|
|
||||||
/*log_trace("received SET_PARAMETER (M4) reply: %s",*/
|
|
||||||
/*(char *) rtsp_message_get_raw(m));*/
|
|
||||||
|
|
||||||
/*wfd_out_session_send_setup(s);*/
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wfd_out_session_send_set_parameter_request(struct wfd_session *s)
|
|
||||||
{
|
|
||||||
/*_rtsp_message_unref_ struct rtsp_message *req;*/
|
|
||||||
int r;
|
int r;
|
||||||
/*const static char tmp[] =*/
|
|
||||||
/*"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_uibc_capability: input_category_list=GENERIC\n;generic_cap_list=SingleTouch;hidc_cap_list=none;port=5100\n"*/
|
|
||||||
/*//"wfd_uibc_setting: disable\n"*/
|
|
||||||
/*"wfd_presentation_URL: %s/streamid=0 none\n"*/
|
|
||||||
/*"wfd_client_rtp_ports: %s %d %d mode=play";*/
|
|
||||||
|
|
||||||
/*r = rtsp_message_new_request(s->rtsp,*/
|
r = rtsp_message_new_reply_for(req,
|
||||||
/*&req,*/
|
&m,
|
||||||
/*"SET_PARAMETER",*/
|
RTSP_CODE_OK,
|
||||||
/*s->url);*/
|
NULL);
|
||||||
/*if (r < 0) {*/
|
if(0 > r) {
|
||||||
/*cli_vERR(r);*/
|
return r;
|
||||||
/*goto error;*/
|
}
|
||||||
/*}*/
|
|
||||||
|
r = rtsp_message_append(m, "<u>", "Session", (uint32_t) s->id);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/*snprintf(buf, sizeof(buf), tmp, s->url, s->sink.rtp_ports.profile,*/
|
*out_rep = m;
|
||||||
/*s->sink.rtp_ports.port0, s->sink.rtp_ports.port1);*/
|
m = NULL;
|
||||||
|
|
||||||
/*r = rtsp_message_append(req, "{&}", buf);*/
|
*new_state = WFD_SESSION_STATE_PLAYING;
|
||||||
/*if (r < 0) {*/
|
|
||||||
/*cli_vERR(r);*/
|
|
||||||
/*goto error;*/
|
|
||||||
/*}*/
|
|
||||||
|
|
||||||
/*rtsp_message_seal(req);*/
|
return 0;
|
||||||
/*cli_debug("OUTGOING (M4): %s\n", rtsp_message_get_raw(req));*/
|
}
|
||||||
|
|
||||||
/*r = rtsp_call_async(s->rtsp, req, src_set_parameter_rep_fn, s, 0, NULL);*/
|
static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
/*if (r < 0) {*/
|
struct rtsp_message *req,
|
||||||
/*cli_vERR(r);*/
|
struct rtsp_message **out_rep,
|
||||||
/*goto error;*/
|
enum wfd_session_state *new_state,
|
||||||
/*}*/
|
enum rtsp_message_id *next_request)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
const char *l;
|
||||||
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
|
_shl_free_ char *sess = NULL, *trans = NULL;
|
||||||
|
|
||||||
/*return 0;*/
|
r = rtsp_message_read(req, "<s>", "Transport", &l);
|
||||||
|
if(0 > r) {
|
||||||
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
/*error:*/
|
if(strncmp("RTP/AVP/UDP;unicast;", l, 20)) {
|
||||||
/*wfd_src_close(s);*/
|
return -EPROTO;
|
||||||
/*wfd_fn_src_disconnected(s);*/
|
}
|
||||||
|
|
||||||
return r;
|
l += 20;
|
||||||
|
|
||||||
|
if(strncmp("client_port=", l, 12)) {
|
||||||
|
return -EPROTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
l += 12;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
s->stream.rtp_port = strtoul(l, NULL, 10);
|
||||||
|
if(errno) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_new_reply_for(req,
|
||||||
|
&m,
|
||||||
|
RTSP_CODE_OK,
|
||||||
|
NULL);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = asprintf(&sess, "%" PRIu64 ";timeout=30", s->id);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_append(m, "<&>", "Session", sess);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = asprintf(&trans, "RTP/AVP/UDP;unicast;client_port=%hd",
|
||||||
|
s->stream.rtp_port);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_append(m, "<&>", "Transport", trans);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_rep = m;
|
||||||
|
m = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wfd_out_session_request_trigger(struct wfd_session *s,
|
||||||
|
struct rtsp_message **out)
|
||||||
|
{
|
||||||
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
switch(wfd_session_get_state(s)) {
|
||||||
|
case WFD_SESSION_STATE_ESTABLISHED:
|
||||||
|
r = rtsp_message_new_request(s->rtsp,
|
||||||
|
&m,
|
||||||
|
"SET_PARAMETER",
|
||||||
|
wfd_session_get_stream_url(s));
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_append(m, "{<s>}",
|
||||||
|
"wfd_trigger_method",
|
||||||
|
"SETUP");
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m) {
|
||||||
|
*out = m;
|
||||||
|
m = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wfd_out_session_handle_set_parameter_reply(struct wfd_session *s,
|
||||||
|
struct rtsp_message *m,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request)
|
||||||
|
{
|
||||||
|
*new_state = WFD_SESSION_STATE_ESTABLISHED;
|
||||||
|
*next_request = RTSP_M5_TRIGGER;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
||||||
|
struct rtsp_message **out)
|
||||||
|
{
|
||||||
|
_rtsp_message_unref_ struct rtsp_message *m;
|
||||||
|
_shl_free_ char *body = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = wfd_session_gen_stream_url(s,
|
||||||
|
wfd_out_session(s)->sink->peer->local_address,
|
||||||
|
WFD_STREAM_ID_PRIMARY);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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"
|
||||||
|
//"wfd_uibc_setting: disable\n",
|
||||||
|
wfd_session_get_stream_url(s),
|
||||||
|
s->rtp_ports[0],
|
||||||
|
s->rtp_ports[1]);
|
||||||
|
if(0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_new_request(s->rtsp,
|
||||||
|
&m,
|
||||||
|
"SET_PARAMETER",
|
||||||
|
"rtsp://localhost/wfd1.0");
|
||||||
|
if (0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = rtsp_message_append(m, "{&}", body);
|
||||||
|
if (0 > r) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = m;
|
||||||
|
m = NULL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wfd_session_vtable session_vtables[] = {
|
const struct wfd_session_vtable session_vtables[] = {
|
||||||
|
@ -467,20 +606,27 @@ const struct wfd_session_vtable session_vtables[] = {
|
||||||
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[] = {
|
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[] = {
|
||||||
[RTSP_M1_REQUEST_SINK_OPTIONS] = {
|
[RTSP_M1_REQUEST_SINK_OPTIONS] = {
|
||||||
.request = wfd_out_session_request_options,
|
.request = wfd_out_session_request_options,
|
||||||
.handle_reply = wfd_out_session_check_options_reply
|
.handle_reply = wfd_out_session_handle_options_reply
|
||||||
},
|
},
|
||||||
[RTSP_M2_REQUEST_SRC_OPTIONS] = {
|
[RTSP_M2_REQUEST_SRC_OPTIONS] = {
|
||||||
.handle_request = wfd_out_session_handle_options_request
|
.handle_request = wfd_out_session_handle_options_request
|
||||||
},
|
},
|
||||||
[RTSP_M3_GET_PARAMETER] = {
|
[RTSP_M3_GET_PARAMETER] = {
|
||||||
|
.request = wfd_out_session_request_get_parameter,
|
||||||
|
.handle_reply = wfd_out_session_handle_get_parameter_reply
|
||||||
},
|
},
|
||||||
[RTSP_M4_SET_PARAMETER] = {
|
[RTSP_M4_SET_PARAMETER] = {
|
||||||
|
.request = wfd_out_session_request_set_parameter,
|
||||||
|
.handle_reply = wfd_out_session_handle_set_parameter_reply
|
||||||
},
|
},
|
||||||
[RTSP_M5_TRIGGER] = {
|
[RTSP_M5_TRIGGER] = {
|
||||||
|
.request = wfd_out_session_request_trigger,
|
||||||
},
|
},
|
||||||
[RTSP_M6_SETUP] = {
|
[RTSP_M6_SETUP] = {
|
||||||
|
.handle_request = wfd_out_session_handle_setup_request,
|
||||||
},
|
},
|
||||||
[RTSP_M7_PLAY] = {
|
[RTSP_M7_PLAY] = {
|
||||||
|
.handle_request = wfd_out_session_handle_play_request,
|
||||||
},
|
},
|
||||||
[RTSP_M8_TEARDOWN] = {
|
[RTSP_M8_TEARDOWN] = {
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,14 +18,19 @@
|
||||||
*/
|
*/
|
||||||
#define LOG_SUBSYSTEM "wfd-session"
|
#define LOG_SUBSYSTEM "wfd-session"
|
||||||
|
|
||||||
|
#include "ctl.h"
|
||||||
#include "rtsp.h"
|
#include "rtsp.h"
|
||||||
#include "wfd-dbus.h"
|
#include "wfd-dbus.h"
|
||||||
#include "wfd-session.h"
|
#include "wfd-session.h"
|
||||||
#include "shl_macro.h"
|
#include "shl_macro.h"
|
||||||
|
|
||||||
#define rtsp_message_id_is_valid(id) ( \
|
#define rtsp_message_id_is_valid(_id) ( \
|
||||||
(id) >= RTSP_M1_REQUEST_SINK_OPTIONS && \
|
(_id) >= RTSP_M1_REQUEST_SINK_OPTIONS && \
|
||||||
(id) <= RTSP_M16_KEEPALIVE \
|
(_id) <= RTSP_M16_KEEPALIVE \
|
||||||
|
)
|
||||||
|
#define wfd_stream_id_is_valid(_id) ( \
|
||||||
|
(_id) >= WFD_STREAM_ID_PRIMARY && \
|
||||||
|
(_id) <= WFD_STREAM_ID_SECONDARY \
|
||||||
)
|
)
|
||||||
|
|
||||||
static const char *rtsp_message_names[];
|
static const char *rtsp_message_names[];
|
||||||
|
@ -47,26 +52,37 @@ static inline int wfd_session_do_request(struct wfd_session *s,
|
||||||
static inline int wfd_session_do_handle_request(struct wfd_session *s,
|
static inline int wfd_session_do_handle_request(struct wfd_session *s,
|
||||||
enum rtsp_message_id id,
|
enum rtsp_message_id id,
|
||||||
struct rtsp_message *req,
|
struct rtsp_message *req,
|
||||||
struct rtsp_message **out_rep)
|
struct rtsp_message **out_rep,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request)
|
||||||
{
|
{
|
||||||
if(!rtsp_message_id_is_valid(id)) {
|
if(!rtsp_message_id_is_valid(id)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
assert(s->rtsp_disp_tbl[id].handle_request);
|
assert(s->rtsp_disp_tbl[id].handle_request);
|
||||||
|
|
||||||
return (*s->rtsp_disp_tbl[id].handle_request)(s, req, out_rep);
|
return (*s->rtsp_disp_tbl[id].handle_request)(s,
|
||||||
|
req,
|
||||||
|
out_rep,
|
||||||
|
new_state,
|
||||||
|
next_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int wfd_session_do_handle_reply(struct wfd_session *s,
|
static inline int wfd_session_do_handle_reply(struct wfd_session *s,
|
||||||
enum rtsp_message_id id,
|
enum rtsp_message_id id,
|
||||||
struct rtsp_message *m)
|
struct rtsp_message *m,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request)
|
||||||
{
|
{
|
||||||
if(!rtsp_message_id_is_valid(id)) {
|
if(!rtsp_message_id_is_valid(id)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
assert(s->rtsp_disp_tbl[id].handle_reply);
|
|
||||||
|
if(!s->rtsp_disp_tbl[id].handle_reply) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (*s->rtsp_disp_tbl[id].handle_reply)(s, m);
|
return (*s->rtsp_disp_tbl[id].handle_reply)(s, m, new_state, next_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t wfd_session_get_id(struct wfd_session *s)
|
uint64_t wfd_session_get_id(struct wfd_session *s)
|
||||||
|
@ -115,12 +131,18 @@ void wfd_session_end(struct wfd_session *s)
|
||||||
s->rtsp = NULL;
|
s->rtsp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s->url) {
|
wfd_video_formats_free(s->vformats);
|
||||||
free(s->url);
|
s->vformats = NULL;
|
||||||
s->url = NULL;
|
wfd_audio_codecs_free(s->acodecs);
|
||||||
}
|
s->acodecs = NULL;
|
||||||
|
|
||||||
|
free(s->stream.url);
|
||||||
|
s->stream.url = NULL;
|
||||||
|
|
||||||
|
s->last_request = RTSP_M_UNKNOWN;
|
||||||
wfd_session_set_state(s, WFD_SESSION_STATE_NULL);
|
wfd_session_set_state(s, WFD_SESSION_STATE_NULL);
|
||||||
|
s->rtp_ports[0] = 0;
|
||||||
|
s->rtp_ports[1] = 0;
|
||||||
|
|
||||||
if(wfd_is_out_session(s)) {
|
if(wfd_is_out_session(s)) {
|
||||||
wfd_fn_out_session_ended(s);
|
wfd_fn_out_session_ended(s);
|
||||||
|
@ -149,11 +171,6 @@ enum wfd_session_dir wfd_session_get_dir(struct wfd_session *s)
|
||||||
return s->dir;
|
return s->dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * wfd_session_get_url(struct wfd_session *s)
|
|
||||||
{
|
|
||||||
return s->url;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t * wfd_session_to_htable(struct wfd_session *s)
|
uint64_t * wfd_session_to_htable(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
return &s->id;
|
return &s->id;
|
||||||
|
@ -164,13 +181,27 @@ struct wfd_session * wfd_session_from_htable(uint64_t *e)
|
||||||
return shl_htable_entry(e, struct wfd_session, id);
|
return shl_htable_entry(e, struct wfd_session, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_session_set_url(struct wfd_session *s, const char *addr)
|
const char * wfd_session_get_stream_url(struct wfd_session *s)
|
||||||
|
{
|
||||||
|
return s->stream.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wfd_session_gen_stream_url(struct wfd_session *s,
|
||||||
|
const char *local_addr,
|
||||||
|
enum wfd_stream_id id)
|
||||||
{
|
{
|
||||||
char *url;
|
char *url;
|
||||||
int r = asprintf(&url, "rtsp://%s/wfd1.0", addr);
|
int r;
|
||||||
|
|
||||||
|
if(!wfd_stream_id_is_valid(id)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = asprintf(&url, "rtsp://%s/wfd1.0/streamid=%d", local_addr, id);
|
||||||
if(0 <= r) {
|
if(0 <= r) {
|
||||||
free(s->url);
|
free(s->stream.url);
|
||||||
s->url = url;
|
s->stream.url = url;
|
||||||
|
url = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -206,7 +237,7 @@ static enum rtsp_message_id wfd_session_message_to_id(struct wfd_session *s,
|
||||||
return RTSP_M13_REQUEST_IDR;
|
return RTSP_M13_REQUEST_IDR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 >= rtsp_message_read(m, "{<>}", "wfd_uibc_capability") && s->url) {
|
if(0 >= rtsp_message_read(m, "{<>}", "wfd_uibc_capability")) { // && s->url) {
|
||||||
return RTSP_M14_ESTABLISH_UIBC;
|
return RTSP_M14_ESTABLISH_UIBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,7 +245,7 @@ static enum rtsp_message_id wfd_session_message_to_id(struct wfd_session *s,
|
||||||
return RTSP_M15_ENABLE_UIBC;
|
return RTSP_M15_ENABLE_UIBC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!s->url) {
|
if(WFD_SESSION_STATE_CAPS_EXCHANGING == s->state) {
|
||||||
return RTSP_M4_SET_PARAMETER;
|
return RTSP_M4_SET_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,65 +284,79 @@ static enum rtsp_message_id wfd_session_message_to_id(struct wfd_session *s,
|
||||||
return RTSP_M_UNKNOWN;
|
return RTSP_M_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_session_dispatch_request(struct rtsp *bus,
|
static int wfd_session_handle_request(struct rtsp *bus,
|
||||||
struct rtsp_message *m,
|
struct rtsp_message *m,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
_rtsp_message_unref_ struct rtsp_message *rep = NULL;
|
_rtsp_message_unref_ struct rtsp_message *rep = NULL;
|
||||||
struct wfd_session *s = userdata;
|
struct wfd_session *s = userdata;
|
||||||
enum rtsp_message_id id;
|
enum rtsp_message_id id, next_request = RTSP_M_UNKNOWN;
|
||||||
|
enum wfd_session_state new_state = WFD_SESSION_STATE_NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
id = wfd_session_message_to_id(s, m);
|
id = wfd_session_message_to_id(s, m);
|
||||||
if(RTSP_M_UNKNOWN == id) {
|
if(RTSP_M_UNKNOWN == id) {
|
||||||
r = -EPROTO;
|
r = -EPROTO;
|
||||||
goto end;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_trace("received %s (M%d) request: %s", rtsp_message_id_to_string(id),
|
log_trace("received %s (M%d) request: %s", rtsp_message_id_to_string(id),
|
||||||
id,
|
id,
|
||||||
(char *) rtsp_message_get_raw(m));
|
(char *) rtsp_message_get_raw(m));
|
||||||
|
|
||||||
r = wfd_session_do_handle_request(s, id, m, &rep);
|
r = wfd_session_do_handle_request(s,
|
||||||
|
id,
|
||||||
|
m,
|
||||||
|
&rep,
|
||||||
|
&new_state,
|
||||||
|
&next_request);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
goto end;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
r = rtsp_message_set_cookie(rep, id);
|
|
||||||
if(0 > r) {
|
|
||||||
goto end;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = rtsp_message_seal(rep);
|
r = rtsp_message_seal(rep);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
goto end;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = rtsp_send(bus, rep);
|
r = rtsp_send(bus, rep);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
goto end;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_trace("sending %s (M%d) reply: %s", rtsp_message_id_to_string(id),
|
log_trace("sending %s (M%d) reply: %s", rtsp_message_id_to_string(id),
|
||||||
id,
|
id,
|
||||||
(char *) rtsp_message_get_raw(rep));
|
(char *) rtsp_message_get_raw(rep));
|
||||||
|
|
||||||
end:
|
if(WFD_SESSION_STATE_NULL != new_state) {
|
||||||
if (0 > r) {
|
wfd_session_set_state(s, new_state);
|
||||||
wfd_session_end(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(rtsp_message_id_is_valid(next_request)) {
|
||||||
|
r = wfd_session_request(s, next_request);
|
||||||
|
if(0 > r) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
wfd_session_end(s);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wfd_session_dispatch_reply(struct rtsp *bus,
|
static int wfd_session_handle_reply(struct rtsp *bus,
|
||||||
struct rtsp_message *m,
|
struct rtsp_message *m,
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
enum rtsp_message_id id;
|
enum rtsp_message_id id;
|
||||||
struct wfd_session *s = userdata;
|
struct wfd_session *s = userdata;
|
||||||
|
enum wfd_session_state new_state = WFD_SESSION_STATE_NULL;
|
||||||
|
enum rtsp_message_id next_request = RTSP_M_UNKNOWN;
|
||||||
|
|
||||||
if(!m) {
|
if(!m) {
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -322,18 +367,29 @@ static int wfd_session_dispatch_reply(struct rtsp *bus,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
id = (enum rtsp_message_id) rtsp_message_get_cookie(m);
|
id = s->last_request;
|
||||||
|
|
||||||
log_trace("received %s (M%d) reply: %s",
|
log_trace("received %s (M%d) reply: %s",
|
||||||
rtsp_message_id_to_string(id),
|
rtsp_message_id_to_string(id),
|
||||||
id,
|
id,
|
||||||
(char *) rtsp_message_get_raw(m));
|
(char *) rtsp_message_get_raw(m));
|
||||||
|
|
||||||
r = wfd_session_do_handle_reply(s, id, m);
|
r = wfd_session_do_handle_reply(s, id, m, &new_state, &next_request);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(WFD_SESSION_STATE_NULL != new_state) {
|
||||||
|
wfd_session_set_state(s, new_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rtsp_message_id_is_valid(next_request)) {
|
||||||
|
r = wfd_session_request(s, next_request);
|
||||||
|
if(0 > r) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
@ -345,7 +401,6 @@ int wfd_session_request(struct wfd_session *s, enum rtsp_message_id id)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
uint64_t cookie = id;
|
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
|
@ -361,14 +416,16 @@ int wfd_session_request(struct wfd_session *s, enum rtsp_message_id id)
|
||||||
|
|
||||||
r = rtsp_call_async(s->rtsp,
|
r = rtsp_call_async(s->rtsp,
|
||||||
m,
|
m,
|
||||||
wfd_session_dispatch_reply,
|
wfd_session_handle_reply,
|
||||||
s,
|
s,
|
||||||
0,
|
0,
|
||||||
&cookie);
|
NULL);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s->last_request = id;
|
||||||
|
|
||||||
log_trace("sending %s (M%d) request: %s",
|
log_trace("sending %s (M%d) request: %s",
|
||||||
rtsp_message_id_to_string(id),
|
rtsp_message_id_to_string(id),
|
||||||
id,
|
id,
|
||||||
|
@ -414,7 +471,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = rtsp_add_match(rtsp, wfd_session_dispatch_request, s);
|
r = rtsp_add_match(rtsp, wfd_session_handle_request, s);
|
||||||
if (0 > r) {
|
if (0 > r) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
@ -422,7 +479,7 @@ static int wfd_session_handle_io(sd_event_source *source,
|
||||||
s->rtsp = rtsp;
|
s->rtsp = rtsp;
|
||||||
rtsp = NULL;
|
rtsp = NULL;
|
||||||
|
|
||||||
wfd_session_set_state(s, WFD_SESSION_STATE_CAPS_EXCHAING);
|
wfd_session_set_state(s, WFD_SESSION_STATE_CAPS_EXCHANGING);
|
||||||
|
|
||||||
r = (*session_vtables[s->dir].initiate_request)(s);
|
r = (*session_vtables[s->dir].initiate_request)(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,16 +51,26 @@ enum rtsp_message_id
|
||||||
RTSP_M16_KEEPALIVE,
|
RTSP_M16_KEEPALIVE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wfd_stream_id
|
||||||
|
{
|
||||||
|
WFD_STREAM_ID_PRIMARY,
|
||||||
|
WFD_STREAM_ID_SECONDARY,
|
||||||
|
};
|
||||||
|
|
||||||
struct rtsp_dispatch_entry
|
struct rtsp_dispatch_entry
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
int (*request)(struct wfd_session *s, struct rtsp_message **out);
|
int (*request)(struct wfd_session *s, struct rtsp_message **out);
|
||||||
int (*handle_request)(struct wfd_session *s,
|
int (*handle_request)(struct wfd_session *s,
|
||||||
struct rtsp_message *req,
|
struct rtsp_message *req,
|
||||||
struct rtsp_message **out_rep);
|
struct rtsp_message **out_rep,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request);
|
||||||
};
|
};
|
||||||
int (*handle_reply)(struct wfd_session *s, struct rtsp_message *m);
|
int (*handle_reply)(struct wfd_session *s,
|
||||||
enum rtsp_message_id next_request;
|
struct rtsp_message *m,
|
||||||
|
enum wfd_session_state *new_state,
|
||||||
|
enum rtsp_message_id *next_request);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wfd_session_vtable
|
struct wfd_session_vtable
|
||||||
|
@ -76,16 +86,29 @@ struct wfd_session
|
||||||
{
|
{
|
||||||
enum wfd_session_dir dir;
|
enum wfd_session_dir dir;
|
||||||
enum wfd_session_state state;
|
enum wfd_session_state state;
|
||||||
uint64_t id;
|
enum rtsp_message_id last_request;
|
||||||
char *url;
|
|
||||||
struct rtsp *rtsp;
|
|
||||||
const struct rtsp_dispatch_entry *rtsp_disp_tbl;
|
const struct rtsp_dispatch_entry *rtsp_disp_tbl;
|
||||||
|
|
||||||
|
uint64_t id;
|
||||||
|
struct rtsp *rtsp;
|
||||||
|
uint16_t rtp_ports[2];
|
||||||
|
struct wfd_video_formats *vformats;
|
||||||
|
struct wfd_audio_codecs *acodecs;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
enum wfd_stream_id id;
|
||||||
|
char *url;
|
||||||
|
uint16_t rtp_port;
|
||||||
|
} stream;
|
||||||
|
|
||||||
bool destructed: 1;
|
bool destructed: 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
int wfd_session_gen_stream_url(struct wfd_session *s,
|
||||||
|
const char *local_addr,
|
||||||
|
enum wfd_stream_id id);
|
||||||
|
|
||||||
#endif /* MIRACLE_OUT_SESSION_H */
|
#endif /* MIRACLE_OUT_SESSION_H */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue