mirror of
https://github.com/albfan/miraclecast.git
synced 2025-03-09 23:38:56 +00:00
miracle-wfdctl: add rtcp and audio supporting to gstreamer pipeline
This commit is contained in:
parent
5b7f9d29f6
commit
a06c0bc154
2 changed files with 89 additions and 9 deletions
|
@ -28,6 +28,9 @@
|
||||||
#include "shl_log.h"
|
#include "shl_log.h"
|
||||||
#include "rtsp.h"
|
#include "rtsp.h"
|
||||||
|
|
||||||
|
#define LOCAL_RTP_PORT 16384
|
||||||
|
#define LOCAL_RTCP_PORT 16385
|
||||||
|
|
||||||
enum wfd_display_type
|
enum wfd_display_type
|
||||||
{
|
{
|
||||||
WFD_DISPLAY_TYPE_UNKNOWN,
|
WFD_DISPLAY_TYPE_UNKNOWN,
|
||||||
|
@ -496,12 +499,13 @@ inline static char * uint16_to_str(uint16_t i, char *buf, size_t len)
|
||||||
|
|
||||||
static int wfd_out_session_create_pipeline(struct wfd_session *s)
|
static int wfd_out_session_create_pipeline(struct wfd_session *s)
|
||||||
{
|
{
|
||||||
char x[16], y[16], width[16], height[16], port[16];
|
char x[16], y[16], width[16], height[16];
|
||||||
|
char rrtp_port[16], rrtcp_port[16], lrtcp_port[16];
|
||||||
struct wfd_out_session *os = wfd_out_session(s);
|
struct wfd_out_session *os = wfd_out_session(s);
|
||||||
GstElement *pipeline;
|
GstElement *pipeline;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GstStateChangeReturn r;
|
GstStateChangeReturn r;
|
||||||
const char * pipeline_desc[] = {
|
const char *pipeline_desc[96] = {
|
||||||
"ximagesrc",
|
"ximagesrc",
|
||||||
"use-damage=false",
|
"use-damage=false",
|
||||||
"show-pointer=false",
|
"show-pointer=false",
|
||||||
|
@ -509,17 +513,68 @@ static int wfd_out_session_create_pipeline(struct wfd_session *s)
|
||||||
"starty=", uint16_to_str(os->x, y, sizeof(y)),
|
"starty=", uint16_to_str(os->x, y, sizeof(y)),
|
||||||
"endx=", uint16_to_str(os->width - 1, width, sizeof(width)),
|
"endx=", uint16_to_str(os->width - 1, width, sizeof(width)),
|
||||||
"endy=", uint16_to_str(os->height - 1, height, sizeof(height)),
|
"endy=", uint16_to_str(os->height - 1, height, sizeof(height)),
|
||||||
|
"!", "video/x-raw,",
|
||||||
|
"framerate=50/1",
|
||||||
"!", "vaapipostproc",
|
"!", "vaapipostproc",
|
||||||
"!", "video/x-raw,",
|
"!", "video/x-raw,",
|
||||||
"format=YV12",
|
"format=YV12",
|
||||||
"!", "vaapih264enc",
|
"!", "vaapih264enc",
|
||||||
|
"!", "queue",
|
||||||
|
"max-size-buffers=0",
|
||||||
|
"max-size-bytes=0",
|
||||||
"!", "mpegtsmux",
|
"!", "mpegtsmux",
|
||||||
|
"name=muxer",
|
||||||
"!", "rtpmp2tpay",
|
"!", "rtpmp2tpay",
|
||||||
|
"!", ".send_rtp_sink_0", "rtpbin",
|
||||||
|
"name=session",
|
||||||
|
"do-retransmission=true",
|
||||||
|
"ntp-time-source=3",
|
||||||
|
"buffer-mode=0",
|
||||||
|
"latency=30",
|
||||||
|
"max-misorder-time=40",
|
||||||
|
"!", "application/x-rtp",
|
||||||
"!", "udpsink",
|
"!", "udpsink",
|
||||||
|
"sync=false",
|
||||||
|
"async=false",
|
||||||
"host=", wfd_out_session_get_sink(s)->peer->remote_address,
|
"host=", wfd_out_session_get_sink(s)->peer->remote_address,
|
||||||
"port=", uint16_to_str(s->stream.rtp_port, port, sizeof(port)),
|
"port=", uint16_to_str(s->stream.rtp_port, rrtp_port,sizeof(rrtp_port)),
|
||||||
|
"pulsesrc",
|
||||||
|
"do-timestamp=true",
|
||||||
|
"client-name=miraclecast",
|
||||||
|
"device=\"alsa_output.pci-0000_00_1b.0.analog-stereo.monitor\"",
|
||||||
|
"!", "audioconvert",
|
||||||
|
"!", "audio/x-raw,",
|
||||||
|
"rate=48000,",
|
||||||
|
"channels=2",
|
||||||
|
"!", "avenc_aac",
|
||||||
|
"!", "queue",
|
||||||
|
"max-size-buffers=0",
|
||||||
|
"max-size-bytes=0",
|
||||||
|
"!", "muxer.",
|
||||||
|
"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
|
NULL
|
||||||
};
|
};
|
||||||
|
const char **tmp;
|
||||||
|
|
||||||
|
if(s->stream.rtcp_port) {
|
||||||
|
tmp = pipeline_desc;
|
||||||
|
while(*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.rtp_port, rrtp_port,sizeof(rrtp_port));
|
||||||
|
*tmp ++ = "sync=false";
|
||||||
|
*tmp ++ = "async=false";
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(rrtcp_port, sizeof(rrtcp_port), "%hu", s->stream.rtcp_port);
|
||||||
|
|
||||||
pipeline = gst_parse_launchv(pipeline_desc, &error);
|
pipeline = gst_parse_launchv(pipeline_desc, &error);
|
||||||
if(!pipeline) {
|
if(!pipeline) {
|
||||||
|
@ -658,7 +713,7 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
struct rtsp_message **out_rep)
|
struct rtsp_message **out_rep)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
const char *l;
|
char *l;
|
||||||
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
_rtsp_message_unref_ struct rtsp_message *m = NULL;
|
||||||
_shl_free_ char *sess = NULL, *trans = NULL;
|
_shl_free_ char *sess = NULL, *trans = NULL;
|
||||||
|
|
||||||
|
@ -680,11 +735,22 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
l += 12;
|
l += 12;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
s->stream.rtp_port = strtoul(l, NULL, 10);
|
s->stream.rtp_port = strtoul(l, &l, 10);
|
||||||
if(errno) {
|
if(errno) {
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if('-' == *l) {
|
||||||
|
errno = 0;
|
||||||
|
s->stream.rtcp_port = strtoul(l + 1, NULL, 10);
|
||||||
|
if(errno) {
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s->stream.rtcp_port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
r = rtsp_message_new_reply_for(req,
|
r = rtsp_message_new_reply_for(req,
|
||||||
&m,
|
&m,
|
||||||
RTSP_CODE_OK,
|
RTSP_CODE_OK,
|
||||||
|
@ -703,8 +769,11 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = asprintf(&trans, "RTP/AVP/UDP;unicast;client_port=%hd",
|
r = asprintf(&trans, "RTP/AVP/UDP;unicast;client_port=%hu%s;server_port=%u-%u",
|
||||||
s->stream.rtp_port);
|
s->stream.rtp_port,
|
||||||
|
l,
|
||||||
|
LOCAL_RTP_PORT,
|
||||||
|
LOCAL_RTCP_PORT);
|
||||||
if(0 > r) {
|
if(0 > r) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -725,6 +794,16 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wfd_out_session_handle_idr_request(struct wfd_session *s,
|
||||||
|
struct rtsp_message *req,
|
||||||
|
struct rtsp_message **out_rep)
|
||||||
|
{
|
||||||
|
return rtsp_message_new_reply_for(req,
|
||||||
|
out_rep,
|
||||||
|
RTSP_CODE_OK,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int wfd_out_session_request_trigger(struct wfd_session *s,
|
static int wfd_out_session_request_trigger(struct wfd_session *s,
|
||||||
const struct wfd_arg_list *args,
|
const struct wfd_arg_list *args,
|
||||||
struct rtsp_message **out)
|
struct rtsp_message **out)
|
||||||
|
@ -790,7 +869,7 @@ static int wfd_out_session_request_set_parameter(struct wfd_session *s,
|
||||||
|
|
||||||
r = asprintf(&body,
|
r = asprintf(&body,
|
||||||
"wfd_video_formats: 00 00 02 10 %08X %08X %08X 00 0000 0000 00 none none\n"
|
"wfd_video_formats: 00 00 02 10 %08X %08X %08X 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"
|
||||||
|
@ -908,7 +987,7 @@ static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[] = {
|
||||||
.handle_request = wfd_out_session_request_not_implement
|
.handle_request = wfd_out_session_request_not_implement
|
||||||
},
|
},
|
||||||
[RTSP_M13_REQUEST_IDR] = {
|
[RTSP_M13_REQUEST_IDR] = {
|
||||||
.handle_request = wfd_out_session_request_not_implement
|
.handle_request = wfd_out_session_handle_idr_request,
|
||||||
},
|
},
|
||||||
[RTSP_M14_ESTABLISH_UIBC] = {
|
[RTSP_M14_ESTABLISH_UIBC] = {
|
||||||
},
|
},
|
||||||
|
|
|
@ -108,6 +108,7 @@ 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;
|
||||||
|
uint16_t rtcp_port;
|
||||||
} stream;
|
} stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue