1
0
Fork 0
mirror of https://github.com/albfan/miraclecast.git synced 2025-03-09 23:38:56 +00:00

miracle-dispd: put back gstreamer

in this version, the pipeline can be stopped properly, but the gst &
glib allocated memory can't be release cleanly (which won't
accumulate)

Change-Id: I242b106158db647070e7852b84f6f90b6bbd96f4
This commit is contained in:
Derek Dai 2017-04-13 10:55:50 +08:00
parent e117704d4e
commit e0a3b62e6b
3 changed files with 265 additions and 257 deletions

View file

@ -23,6 +23,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <gst/gst.h>
#include <systemd/sd-event.h> #include <systemd/sd-event.h>
#include <systemd/sd-daemon.h> #include <systemd/sd-daemon.h>
#include "ctl.h" #include "ctl.h"
@ -451,6 +452,8 @@ int main(int argc, char **argv)
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
setlocale(LC_TIME, "en_US.UTF-8"); setlocale(LC_TIME, "en_US.UTF-8");
gst_init(&argc, &argv);
if(getenv("LOG_LEVEL")) { if(getenv("LOG_LEVEL")) {
log_max_sev = log_parse_arg(getenv("LOG_LEVEL")); log_max_sev = log_parse_arg(getenv("LOG_LEVEL"));
} }
@ -518,6 +521,7 @@ disable_watchdog:
unref_event: unref_event:
sd_event_unref(event); sd_event_unref(event);
end: end:
gst_deinit();
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
} }

View file

@ -1,5 +1,7 @@
inc = include_directories('../..', '../ctl',) inc = include_directories('../..', '../ctl',)
deps = [libsystemd, libmiracle_shared_dep] gst1 = dependency('gstreamer-1.0')
gst1_base = dependency('gstreamer-base-1.0')
deps = [libsystemd, libmiracle_shared_dep, gst1, gst1_base]
if readline.found() if readline.found()
deps += [readline] deps += [readline]
endif endif

View file

@ -24,6 +24,8 @@
#include <unistd.h> #include <unistd.h>
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <gst/gst.h>
#include <gst/base/gstbasesrc.h>
#include "wfd-session.h" #include "wfd-session.h"
#include "shl_log.h" #include "shl_log.h"
#include "rtsp.h" #include "rtsp.h"
@ -59,8 +61,8 @@ struct wfd_out_session
uint32_t mask; uint32_t mask;
char *audio_dev; char *audio_dev;
/*GstElement *pipeline;*/ GstElement *pipeline;
/*GstBus *bus;*/ GstBus *bus;
}; };
static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[]; static const struct rtsp_dispatch_entry out_session_rtsp_disp_tbl[];
@ -320,17 +322,17 @@ void wfd_out_session_destroy(struct wfd_session *s)
os->authority = NULL; os->authority = NULL;
} }
/*if(os->bus) {*/ if(os->bus) {
/*gst_bus_remove_watch(os->bus);*/ gst_bus_remove_watch(os->bus);
/*g_object_unref(os->bus);*/ g_object_unref(os->bus);
/*os->bus = NULL;*/ os->bus = NULL;
/*}*/ }
/*if(os->pipeline) {*/ if(os->pipeline) {
/*gst_element_set_state(os->pipeline, GST_STATE_NULL);*/ gst_element_set_state(os->pipeline, GST_STATE_NULL);
/*g_object_unref(os->pipeline);*/ g_object_unref(os->pipeline);
/*os->pipeline = NULL;*/ os->pipeline = NULL;
/*}*/ }
} }
int wfd_out_session_initiate_request(struct wfd_session *s) int wfd_out_session_initiate_request(struct wfd_session *s)
@ -544,43 +546,43 @@ static int wfd_out_session_request_options(struct wfd_session *s,
return 0; return 0;
} }
//static gboolean wfd_out_session_handle_gst_message(GstBus *bus, static gboolean wfd_out_session_handle_gst_message(GstBus *bus,
// GstMessage *m, GstMessage *m,
// gpointer userdata) gpointer userdata)
//{ {
// struct wfd_session *s = userdata; struct wfd_session *s = userdata;
// struct wfd_out_session *os = userdata; struct wfd_out_session *os = userdata;
// GstState old_state, new_state; GstState old_state, new_state;
//
// switch(GST_MESSAGE_TYPE(m)) { switch(GST_MESSAGE_TYPE(m)) {
// case GST_MESSAGE_STATE_CHANGED: case GST_MESSAGE_STATE_CHANGED:
// if(os->pipeline != (void *) GST_MESSAGE_SRC(m)) { if(os->pipeline != (void *) GST_MESSAGE_SRC(m)) {
// break; break;
// } }
//
// gst_message_parse_state_changed(m, &old_state, &new_state, NULL); gst_message_parse_state_changed(m, &old_state, &new_state, NULL);
// if(GST_STATE_PLAYING == new_state) { if(GST_STATE_PLAYING == new_state) {
// log_info("stream is playing"); log_info("stream is playing");
// wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING); wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING);
// } }
// else if(GST_STATE_PLAYING == old_state && else if(GST_STATE_PLAYING == old_state &&
// GST_STATE_PAUSED == new_state) { GST_STATE_PAUSED == new_state) {
// log_info("stream is paused"); log_info("stream is paused");
// wfd_session_set_state(s, WFD_SESSION_STATE_PAUSED); wfd_session_set_state(s, WFD_SESSION_STATE_PAUSED);
// } }
// break; break;
// case GST_MESSAGE_EOS: case GST_MESSAGE_EOS:
// case GST_MESSAGE_ERROR: case GST_MESSAGE_ERROR:
// log_warning("%s encounter unexpected error or EOS", log_warning("%s encounter unexpected error or EOS",
// GST_MESSAGE_SRC_NAME(m)); GST_MESSAGE_SRC_NAME(m));
// wfd_session_teardown(s); wfd_session_teardown(s);
// break; break;
// default: default:
// break; break;
// } }
//
// return TRUE; return TRUE;
//} }
inline static char * uint16_to_str(uint16_t i, char *buf, size_t len) inline static char * uint16_to_str(uint16_t i, char *buf, size_t len)
{ {
@ -596,188 +598,188 @@ inline static char * quote_str(const char *s, char *d, size_t len)
return d; return d;
} }
//static int wfd_out_session_create_pipeline(struct wfd_session *s) static int wfd_out_session_create_pipeline(struct wfd_session *s)
//{ {
// char rrtp_port[16], rrtcp_port[16], lrtcp_port[16]; char rrtp_port[16], rrtcp_port[16], lrtcp_port[16];
// char audio_dev[256]; char audio_dev[256];
// char vsrc_param1[16] = "", vsrc_param2[16] = ""; char vsrc_param1[16] = "", vsrc_param2[16] = "";
// char vsrc_param3[16] = "", vsrc_param4[16] = ""; char vsrc_param3[16] = "", vsrc_param4[16] = "";
// struct wfd_out_session *os = wfd_out_session(s); struct wfd_out_session *os = wfd_out_session(s);
// GstElement *pipeline; GstElement *pipeline;
// GstElement *vsrc; GstElement *vsrc;
// GstBus *bus; GstBus *bus;
// GError *error = NULL; GError *error = NULL;
// const char **tmp; const char **tmp;
// int r; int r;
// const char *pipeline_desc[128] = { const char *pipeline_desc[128] = {
// "ximagesrc", "ximagesrc",
// "name=vsrc", "name=vsrc",
// "use-damage=false", "use-damage=false",
// "show-pointer=false", "show-pointer=false",
// vsrc_param1, vsrc_param1,
// vsrc_param2, vsrc_param2,
// vsrc_param3, vsrc_param3,
// vsrc_param4, vsrc_param4,
// "!", "video/x-raw,", "!", "video/x-raw,",
// "framerate=30/1", "framerate=30/1",
// //"!", "vaapipostproc", //"!", "vaapipostproc",
// // "scale-method=2", /* high quality scaling mode */ // "scale-method=2", /* high quality scaling mode */
// // "format=3", /* yv12" */ // "format=3", /* yv12" */
// //"!", "vaapih264enc", //"!", "vaapih264enc",
// // "rate-control=1", // "rate-control=1",
// // "num-slices=1", /* in WFD spec, one slice per frame */ // "num-slices=1", /* in WFD spec, one slice per frame */
// // "max-bframes=0", /* in H264 CHP, no bframe supporting */ // "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 */ // "cabac=true", /* in H264 CHP, CABAC entropy codeing is supported, but need more processing to decode */
// // "dct8x8=true", /* in H264 CHP, DTC is supported */ // "dct8x8=true", /* in H264 CHP, DTC is supported */
// // "cpb-length=50", /* shortent buffer in order to decrease latency */ // "cpb-length=50", /* shortent buffer in order to decrease latency */
// // "keyframe-period=30", // "keyframe-period=30",
// // /* "bitrate=62500", */ /* the max bitrate of H264 level 4.2, crashing my dongle, let codec decide */ // /* "bitrate=62500", */ /* the max bitrate of H264 level 4.2, crashing my dongle, let codec decide */
// "!", "videoscale", "!", "videoscale",
// "method=0", "method=0",
// "!", "video/x-raw,", "!", "video/x-raw,",
// "width=1920,", "width=1920,",
// "height=1080", "height=1080",
// "!", "videoconvert", "!", "videoconvert",
// "dither=0", "dither=0",
// "!", "video/x-raw,", "!", "video/x-raw,",
// "format=YV12" "format=YV12"
// "!", "x264enc", "!", "x264enc",
// "pass=4", /* constant quantizer */ "pass=4", /* constant quantizer */
// "b-adapt=false", /* no bframe suppport in CHP */ "b-adapt=false", /* no bframe suppport in CHP */
// "key-int-max=30", /* send IDR pictures per second */ "key-int-max=30", /* send IDR pictures per second */
// "speed-preset=4", /* faster */ "speed-preset=4", /* faster */
// "tune=4", /* zero latency */ "tune=4", /* zero latency */
// "!", "h264parse", "!", "h264parse",
// "!", "video/x-h264,", "!", "video/x-h264,",
// "alignment=nal,", "alignment=nal,",
// "stream-format=byte-stream" "stream-format=byte-stream"
// "!", "queue", "!", "queue",
// "max-size-buffers=0", "max-size-buffers=0",
// "max-size-bytes=0", "max-size-bytes=0",
// "!", "mpegtsmux", "!", "mpegtsmux",
// "name=muxer", "name=muxer",
// "!", "rtpmp2tpay", "!", "rtpmp2tpay",
// "!", ".send_rtp_sink_0", "rtpbin", "!", ".send_rtp_sink_0", "rtpbin",
// "name=session", "name=session",
// "do-retransmission=true", "do-retransmission=true",
// "do-sync-event=true", "do-sync-event=true",
// "do-lost=true", "do-lost=true",
// "ntp-time-source=3", "ntp-time-source=3",
// "buffer-mode=0", "buffer-mode=0",
// "latency=20", "latency=20",
// "max-misorder-time=30", "max-misorder-time=30",
// "!", "application/x-rtp", "!", "application/x-rtp",
// "!", "udpsink", "!", "udpsink",
// "sync=false", "sync=false",
// "async=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, rrtp_port,sizeof(rrtp_port)), "port=", uint16_to_str(s->stream.rtp_port, rrtp_port,sizeof(rrtp_port)),
// "udpsrc", "udpsrc",
// "address=", wfd_out_session_get_sink(s)->peer->local_address, "address=", wfd_out_session_get_sink(s)->peer->local_address,
// "port=", uint16_to_str(LOCAL_RTCP_PORT, lrtcp_port,sizeof(lrtcp_port)), "port=", uint16_to_str(LOCAL_RTCP_PORT, lrtcp_port,sizeof(lrtcp_port)),
// "reuse=true", "reuse=true",
// "!", "session.recv_rtcp_sink_0", "!", "session.recv_rtcp_sink_0",
// NULL NULL
// }; };
//
// if(s->stream.rtcp_port) { if(s->stream.rtcp_port) {
// for(tmp = pipeline_desc; *tmp; ++tmp); for(tmp = pipeline_desc; *tmp; ++tmp);
// *tmp ++ = "session.send_rtcp_src_0"; *tmp ++ = "session.send_rtcp_src_0";
// *tmp ++ = "!"; *tmp ++ = "!";
// *tmp ++ = "udpsink"; *tmp ++ = "udpsink";
// *tmp ++ = "host="; *tmp ++ = "host=";
// *tmp ++ = wfd_out_session_get_sink(s)->peer->remote_address; *tmp ++ = wfd_out_session_get_sink(s)->peer->remote_address;
// *tmp ++ = "port="; *tmp ++ = "port=";
// *tmp ++ = uint16_to_str(s->stream.rtcp_port, rrtcp_port,sizeof(rrtcp_port)); *tmp ++ = uint16_to_str(s->stream.rtcp_port, rrtcp_port,sizeof(rrtcp_port));
// *tmp ++ = "sync=false"; *tmp ++ = "sync=false";
// *tmp ++ = "async=false"; *tmp ++ = "async=false";
// *tmp ++ = NULL; *tmp ++ = NULL;
// } }
//
// if(*os->audio_dev) { if(*os->audio_dev) {
// for(tmp = pipeline_desc; *tmp; ++tmp); for(tmp = pipeline_desc; *tmp; ++tmp);
// *tmp ++ = "pulsesrc"; *tmp ++ = "pulsesrc";
// *tmp ++ = "do-timestamp=true"; *tmp ++ = "do-timestamp=true";
// *tmp ++ = "client-name=miraclecast"; *tmp ++ = "client-name=miraclecast";
// *tmp ++ = "device="; *tmp ++ = "device=";
// *tmp ++ = quote_str(os->audio_dev, audio_dev, sizeof(audio_dev)); *tmp ++ = quote_str(os->audio_dev, audio_dev, sizeof(audio_dev));
// *tmp ++ = "!"; *tmp ++ = "!";
// *tmp ++ = "voaacenc"; *tmp ++ = "voaacenc";
// *tmp ++ = "mark-granule=true"; *tmp ++ = "mark-granule=true";
// *tmp ++ = "hard-resync=true"; *tmp ++ = "hard-resync=true";
// *tmp ++ = "tolerance=40"; *tmp ++ = "tolerance=40";
// *tmp ++ = "!"; *tmp ++ = "!";
// *tmp ++ = "audio/mpeg,"; *tmp ++ = "audio/mpeg,";
// *tmp ++ = "rate=48000,"; *tmp ++ = "rate=48000,";
// *tmp ++ = "channels=2,"; *tmp ++ = "channels=2,";
// *tmp ++ = "stream-format=adts,"; *tmp ++ = "stream-format=adts,";
// *tmp ++ = "base-profile=lc"; *tmp ++ = "base-profile=lc";
// *tmp ++ = "!"; *tmp ++ = "!";
// *tmp ++ = "queue"; *tmp ++ = "queue";
// *tmp ++ = "max-size-buffers=0"; *tmp ++ = "max-size-buffers=0";
// *tmp ++ = "max-size-bytes=0"; *tmp ++ = "max-size-bytes=0";
// *tmp ++ = "max-size-time=0"; *tmp ++ = "max-size-time=0";
// *tmp ++ = "!"; *tmp ++ = "!";
// *tmp ++ = "muxer."; *tmp ++ = "muxer.";
// *tmp ++ = NULL; *tmp ++ = NULL;
// } }
//
// /* bad pratice, but since we are in the same process, /* bad pratice, but since we are in the same process,
// I think this is the only way to do it */ I think this is the only way to do it */
// if(WFD_DISPLAY_TYPE_X == os->display_type) { if(WFD_DISPLAY_TYPE_X == os->display_type) {
// r = setenv("XAUTHORITY", os->authority, 1); r = setenv("XAUTHORITY", os->authority, 1);
// if(0 > r) { if(0 > r) {
// return r; return r;
// } }
//
// r = setenv("DISPLAY", os->display_name, 1); r = setenv("DISPLAY", os->display_name, 1);
// if(0 > r) { if(0 > r) {
// return r; return r;
// } }
//
// if(!os->display_param_name) { if(!os->display_param_name) {
// snprintf(vsrc_param1, sizeof(vsrc_param1), "startx=%hu", os->x); snprintf(vsrc_param1, sizeof(vsrc_param1), "startx=%hu", os->x);
// snprintf(vsrc_param2, sizeof(vsrc_param2), "starty=%hu", os->y); 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_param3, sizeof(vsrc_param3), "endx=%d", os->x + os->width - 1);
// snprintf(vsrc_param4, sizeof(vsrc_param4), "endy=%d", os->y + os->height - 1); snprintf(vsrc_param4, sizeof(vsrc_param4), "endy=%d", os->y + os->height - 1);
// } }
// else if(!strcmp("xid", os->display_param_name) || else if(!strcmp("xid", os->display_param_name) ||
// !strcmp("xname", os->display_param_name)) { !strcmp("xname", os->display_param_name)) {
// snprintf(vsrc_param1, sizeof(vsrc_param1), snprintf(vsrc_param1, sizeof(vsrc_param1),
// "%s=\"%s\"", "%s=\"%s\"",
// os->display_param_name, os->display_param_name,
// os->display_param_value); os->display_param_value);
// } }
// } }
//
// pipeline = gst_parse_launchv(pipeline_desc, &error); pipeline = gst_parse_launchv(pipeline_desc, &error);
// if(!pipeline) { if(!pipeline) {
// if(error) { if(error) {
// log_error("failed to create pipeline: %s", error->message); log_error("failed to create pipeline: %s", error->message);
// g_error_free(error); g_error_free(error);
// } }
// return -1; return -1;
// } }
//
// vsrc = gst_bin_get_by_name(GST_BIN(pipeline), "vsrc"); vsrc = gst_bin_get_by_name(GST_BIN(pipeline), "vsrc");
// gst_base_src_set_live(GST_BASE_SRC(vsrc), true); gst_base_src_set_live(GST_BASE_SRC(vsrc), true);
// g_object_unref(vsrc); g_object_unref(vsrc);
// vsrc = NULL; vsrc = NULL;
//
// r = gst_element_set_state(pipeline, GST_STATE_PAUSED); r = gst_element_set_state(pipeline, GST_STATE_PAUSED);
// if(GST_STATE_CHANGE_FAILURE == r) { if(GST_STATE_CHANGE_FAILURE == r) {
// g_object_unref(pipeline); g_object_unref(pipeline);
// return -1; return -1;
// } }
//
// bus = gst_element_get_bus(pipeline); bus = gst_element_get_bus(pipeline);
// gst_bus_add_watch(bus, wfd_out_session_handle_gst_message, s); gst_bus_add_watch(bus, wfd_out_session_handle_gst_message, s);
//
// os->pipeline = pipeline; os->pipeline = pipeline;
// os->bus = bus; os->bus = bus;
//
// return 0; return 0;
//} }
static int wfd_out_session_handle_pause_request(struct wfd_session *s, static int wfd_out_session_handle_pause_request(struct wfd_session *s,
struct rtsp_message *req, struct rtsp_message *req,
@ -786,10 +788,10 @@ static int wfd_out_session_handle_pause_request(struct wfd_session *s,
_rtsp_message_unref_ struct rtsp_message *m = NULL; _rtsp_message_unref_ struct rtsp_message *m = NULL;
int r; int r;
// r = gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_READY); r = gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_READY);
// if(GST_STATE_CHANGE_FAILURE == r) { if(GST_STATE_CHANGE_FAILURE == r) {
// return -1; return -1;
// } }
r = rtsp_message_new_reply_for(req, r = rtsp_message_new_reply_for(req,
&m, &m,
@ -813,18 +815,18 @@ static int wfd_out_session_handle_teardown_request(struct wfd_session *s,
int r; int r;
wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN); wfd_session_set_state(s, WFD_SESSION_STATE_TEARING_DOWN);
/*gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_NULL);*/ gst_element_set_state(wfd_out_session(s)->pipeline, GST_STATE_NULL);
/*r = rtsp_message_new_reply_for(req,*/ r = rtsp_message_new_reply_for(req,
/*&m,*/ &m,
/*RTSP_CODE_OK,*/ RTSP_CODE_OK,
/*NULL);*/ NULL);
/*if(0 > r) {*/ if(0 > r) {
/*return r;*/ return r;
/*}*/ }
/**out_rep = m;*/ *out_rep = m;
/*m = NULL;*/ m = NULL;
return 0; return 0;
} }
@ -834,17 +836,17 @@ static int wfd_out_session_post_handle_play(sd_event_source *source,
void *userdata) void *userdata)
{ {
struct wfd_session *s = userdata; struct wfd_session *s = userdata;
//GstStateChangeReturn r; GstStateChangeReturn r;
sd_event_source_unref(source); sd_event_source_unref(source);
wfd_out_session(s)->gst_launch_source = NULL; wfd_out_session(s)->gst_launch_source = NULL;
/*r = gst_element_set_state(wfd_out_session(s)->pipeline,*/ r = gst_element_set_state(wfd_out_session(s)->pipeline,
/*GST_STATE_PLAYING);*/ GST_STATE_PLAYING);
/*if(GST_STATE_CHANGE_FAILURE == r) {*/ if(GST_STATE_CHANGE_FAILURE == r) {
/*wfd_session_teardown(s);*/ wfd_session_teardown(s);
/*return -1;*/ return -1;
/*}*/ }
wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING); wfd_session_set_state(s, WFD_SESSION_STATE_PLAYING);
@ -972,10 +974,10 @@ static int wfd_out_session_handle_setup_request(struct wfd_session *s,
return r; return r;
} }
/*r = wfd_out_session_create_pipeline(s);*/ r = wfd_out_session_create_pipeline(s);
/*if(0 > r) {*/ if(0 > r) {
/*return r;*/ return r;
/*}*/ }
*out_rep = m; *out_rep = m;
m = NULL; m = NULL;