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

rename dbus name back to org.freedesktop.miracle.Sender and variety kinds of tunning

This commit is contained in:
Derek Dai 2016-12-16 11:23:26 +08:00
parent 91e1ee29ec
commit 03744ba53b
No known key found for this signature in database
GPG key ID: E109CC97553EF009
5 changed files with 83 additions and 205 deletions

View file

@ -391,7 +391,7 @@ static int src_send_set_parameter(struct ctl_src *s)
_rtsp_message_unref_ struct rtsp_message *req; _rtsp_message_unref_ struct rtsp_message *req;
int r; int r;
const static char tmp[] = const static char tmp[] =
"wfd_video_formats: 38 00 02 10 00000080 00000000 00000000 00 0000 0000 00 none none\n" "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_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_capability: input_category_list=GENERIC\n;generic_cap_list=SingleTouch;hidc_cap_list=none;port=5100\n"
//"wfd_uibc_setting: disable\n" //"wfd_uibc_setting: disable\n"

View file

@ -463,94 +463,6 @@ static const struct cli_cmd cli_cmds[] = {
{ }, { },
}; };
static void spawn_gst(struct ctl_src *s)
{
pid_t pid;
int fd_journal;
sigset_t mask;
if (src_pid > 0)
return;
pid = fork();
if (pid < 0) {
return cli_vERRNO();
} else if (!pid) {
/* child */
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, NULL);
/* redirect stdout/stderr to journal */
fd_journal = sd_journal_stream_fd("miracle-srcctl-gst",
LOG_DEBUG,
false);
if (fd_journal >= 0) {
/* dup journal-fd to stdout and stderr */
dup2(fd_journal, 1);
dup2(fd_journal, 2);
} else {
/* no journal? redirect stdout to parent's stderr */
dup2(2, 1);
}
launch_sender(s);
_exit(1);
} else {
src_pid = pid;
}
}
void launch_sender(struct ctl_src *s) {
char * argv[64];
char resolution[64];
char port[64];
char uibc_portStr[64];
int i = 0;
argv[i++] = "miracle-sender";
if (gst_audio_en) {
argv[i++] = "--acodec";
argv[i++] = "aac";
}
argv[i++] = "--host";
argv[i++] = inet_ntoa(((struct sockaddr_in *) &s->addr)->sin_addr);
argv[i++] = "-p";
sprintf(port, "%d", rtsp_port);
argv[i++] = port;
// if (s->hres && s->vres) {
// sprintf(resolution, "%dx%d", s->hres, s->vres);
// argv[i++] = "-r";
// argv[i++] = resolution;
// }
argv[i] = NULL;
if (execvpe(argv[0], argv, environ) < 0) {
cli_debug("stream sender failed (%d): %m", errno);
int i = 0;
cli_debug("printing environment: ");
while (environ[i]) {
cli_debug("%s", environ[i++]);
}
}
}
//void launch_uibc_daemon(int port) {
// char *argv[64];
// char portStr[64];
// int i = 0;
// argv[i++] = "miracle-uibcctl";
// argv[i++] = "localhost";
// sprintf(portStr, "%d", port);
// argv[i++] = portStr;
// argv[i] = NULL;
//
// cli_debug("uibc daemon: %s", argv[0]);
// execvpe(argv[0], argv, environ);
//}
//
static void kill_gst(void) static void kill_gst(void)
{ {
if (src_pid <= 0) if (src_pid <= 0)
@ -614,7 +526,7 @@ void ctl_fn_src_setup(struct ctl_src *s)
":0", ":0",
1920, 1920,
1080, 1080,
30, 25,
FALSE, FALSE,
NULL, NULL,
&error); &error);
@ -632,9 +544,6 @@ void ctl_fn_src_playing(struct ctl_src *s)
GError *error = NULL; GError *error = NULL;
cli_printf("SRC got play request\n"); cli_printf("SRC got play request\n");
// TODO src_connected must be true, why if() failed?
//if (src_connected)
//spawn_gst(s);
if(!sender) { if(!sender) {
cli_error("SRC not setup yet"); cli_error("SRC not setup yet");
@ -647,7 +556,7 @@ void ctl_fn_src_playing(struct ctl_src *s)
return; return;
} }
g_info("SRC sender playing"); cli_printf("SRC sender playing\n");
} }
void ctl_fn_peer_new(struct ctl_peer *p) void ctl_fn_peer_new(struct ctl_peer *p)
@ -933,8 +842,6 @@ static int parse_argv(int argc, char *argv[])
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int r; int r;
GError *error = NULL;
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
r = parse_argv(argc, argv); r = parse_argv(argc, argv);

View file

@ -21,7 +21,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sender-iface.c
COMMAND ${GDBUS_CODEGEN_EXEC} COMMAND ${GDBUS_CODEGEN_EXEC}
ARGS --generate-c-code sender-iface ARGS --generate-c-code sender-iface
--annotate org.freedesktop.miracle.Sender org.gtk.GDBus.C.Name Sender --annotate org.freedesktop.miracle.Sender org.gtk.GDBus.C.Name Sender
--interface-prefix org.freedesktop.miracle --interface-prefix org.freedesktop.miracle.Sender
${CMAKE_CURRENT_SOURCE_DIR}/sender-iface.xml ${CMAKE_CURRENT_SOURCE_DIR}/sender-iface.xml
DEPENDS sender-iface.xml DEPENDS sender-iface.xml
COMMENT "generating sender interface" COMMENT "generating sender interface"

View file

@ -60,29 +60,26 @@ static gchar *arg_acodec = NULL;
static gboolean arg_audio_only = FALSE; static gboolean arg_audio_only = FALSE;
static guint arg_refresh_rate = 30; static guint arg_refresh_rate = 25;
static gboolean arg_interleave = FALSE;
static char * arg_h264_profile = NULL;
static const char *vpipeline_desc = static const char *vpipeline_desc =
"ximagesrc name=vsrc use-damage=false show-pointer=false do-timestamp=true starty=%d startx=%d endy=%d endx=%d " "ximagesrc name=vsrc use-damage=false show-pointer=false starty=%d startx=%d endy=%d endx=%d "
"capsfilter name=caps_framerate caps=\"video/x-raw, framerate=%d/1\" " "capsfilter name=caps_framerate caps=\"video/x-raw, framerate=%u/1\" "
"videoscale name=vscale " //"videoscale name=vscale "
"capsfilter name=caps_scale caps=\"video/x-raw, width=%d, height=%d\" " //"capsfilter name=caps_scale caps=\"video/x-raw, width=%d, height=%d\" "
"autovideoconvert name=vconv " "autovideoconvert name=vconv "
"capsfilter name=caps_format caps=\"video/x-raw, format=I420\" " "capsfilter name=caps_format caps=\"video/x-raw, format=I420\" "
"encodebin name=vencoder " //"encodebin name=vencoder "
"queue name=vqueue max-size-buffers=0 max-size-bytes=0 " "vaapih264enc name=vencoder max-bframes=0 "
"mpegtsmux name=muxer alignment=7 " "capsfilter name=caps_vencoder caps=\"video/x-h264, profile=high\" "
"capsfilter name=caps_muxer caps=\"video/mpegts, packetsize=188, systemstream=true\" " //"queue name=vqueue max-size-buffers=0 max-size-bytes=0 "
"mpegtsmux name=muxer "
"rtpmp2tpay name=rtppay " "rtpmp2tpay name=rtppay "
"udpsink name=sink host=\"%s\" port=%d "; "udpsink name=sink host=\"%s\" port=%d ";
//"filesink name=sink location=vaapi.mp2t ";
static const char *apipeline_desc = static const char *apipeline_desc =
//"pulsesrc name=asrc device=\"%s\" " "pulsesrc name=asrc device=\"%s\" "
"audiotestsrc name=asrc "
"audioconvert name=aconv " "audioconvert name=aconv "
"audioresample name=aresample " "audioresample name=aresample "
"encodebin name=aencoder " "encodebin name=aencoder "
@ -192,7 +189,15 @@ static int link_elements(GstBin *bin, const char *name, ...)
name1 = name; name1 = name;
while((name2 = va_arg(argv, const char *))) { while((name2 = va_arg(argv, const char *))) {
GstElement *e1 = gst_bin_get_by_name(bin, name1); GstElement *e1 = gst_bin_get_by_name(bin, name1);
if(!e1) {
g_warning("no such element: %s", name1);
return -1;
}
GstElement *e2 = gst_bin_get_by_name(bin, name2); GstElement *e2 = gst_bin_get_by_name(bin, name2);
if(!e2) {
g_warning("no such element: %s", name2);
return -1;
}
gboolean linked = gst_element_link(e1, e2); gboolean linked = gst_element_link(e1, e2);
g_object_unref(G_OBJECT(e2)); g_object_unref(G_OBJECT(e2));
g_object_unref(G_OBJECT(e1)); g_object_unref(G_OBJECT(e1));
@ -234,6 +239,23 @@ void on_gst_message_state_changed(struct SenderImpl *self,
self->method_invoke); self->method_invoke);
self->method_invoke = NULL; self->method_invoke = NULL;
} }
g_info("sender playing");
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(self->pipeline),
GST_DEBUG_GRAPH_SHOW_ALL,
"miracle-sender-playing");
break;
case GST_STATE_READY:
g_object_set(self->skeleton, "state", "paused", NULL);
if(self->method_invoke) {
sender_complete_prepare(SENDER(self->skeleton),
self->method_invoke);
self->method_invoke = NULL;
}
g_info("sender ready");
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(self->pipeline),
GST_DEBUG_GRAPH_SHOW_ALL,
"miracle-sender-ready");
break; break;
case GST_STATE_PAUSED: case GST_STATE_PAUSED:
g_object_set(self->skeleton, "state", "paused", NULL); g_object_set(self->skeleton, "state", "paused", NULL);
@ -242,6 +264,7 @@ void on_gst_message_state_changed(struct SenderImpl *self,
self->method_invoke); self->method_invoke);
self->method_invoke = NULL; self->method_invoke = NULL;
} }
g_info("sender paused");
break; break;
default: default:
break; break;
@ -267,7 +290,7 @@ void on_gst_message(struct SenderImpl *self,
GstMessage *message, GstMessage *message,
GstBus *bus) GstBus *bus)
{ {
g_debug("Gstreamer message: %s", GST_MESSAGE_TYPE_NAME(message)); g_debug("pipeline message: %s", GST_MESSAGE_TYPE_NAME(message));
switch(GST_MESSAGE_TYPE(message)) { switch(GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR: case GST_MESSAGE_ERROR:
on_gst_message_error(self, message); on_gst_message_error(self, message);
@ -306,8 +329,8 @@ static int prepare_pipeline(struct SenderImpl *self)
screen_bottom, screen_bottom,
screen_right, screen_right,
arg_refresh_rate, arg_refresh_rate,
arg_width ? arg_width : screen_right - screen_left + 1, //arg_width ? arg_width : screen_right - screen_left + 1,
arg_height ? arg_height : screen_bottom - screen_top + 1, //arg_height ? arg_height : screen_bottom - screen_top + 1,
arg_host, arg_host,
arg_port); arg_port);
@ -317,6 +340,8 @@ static int prepare_pipeline(struct SenderImpl *self)
"alsa_output.pci-0000_00_1b.0.analog-stereo.monitor"); "alsa_output.pci-0000_00_1b.0.analog-stereo.monitor");
} }
g_debug("finale pipeline: %s", desc->str);
self->pipeline = gst_parse_launch(desc->str, &error); self->pipeline = gst_parse_launch(desc->str, &error);
if(error) { if(error) {
g_error("%s", error->message); g_error("%s", error->message);
@ -325,27 +350,30 @@ static int prepare_pipeline(struct SenderImpl *self)
gst_element_set_name(GST_ELEMENT(self->pipeline), "pipeline"); gst_element_set_name(GST_ELEMENT(self->pipeline), "pipeline");
GstEncodingVideoProfile *vencode_profile = gst_encoding_video_profile_new( /*GstEncodingVideoProfile *vencode_profile = gst_encoding_video_profile_new(*/
gst_caps_from_string("video/x-h264, profile=high"), /*gst_caps_from_string("video/x-h264, profile=high"),*/
NULL, /*NULL,*/
gst_caps_new_any(), /*gst_caps_new_any(),*/
0); /*0);*/
GstElement *vencoder = gst_bin_get_by_name(GST_BIN(self->pipeline), "vencoder"); GstElement *vencoder = gst_bin_get_by_name(GST_BIN(self->pipeline), "vencoder");
g_object_set(G_OBJECT(vencoder), "tune", 0x4, NULL); g_object_set(G_OBJECT(vencoder),
g_object_set(G_OBJECT(vencoder), "profile", vencode_profile, NULL); //"profile", vencode_profile,
"max-bframes", 0,
NULL);
g_object_unref(G_OBJECT(vencoder)); g_object_unref(G_OBJECT(vencoder));
//g_object_unref(G_OBJECT(vencode_profile));
if(arg_acodec) { if(arg_acodec) {
const char *format; const char *format;
if(!strncmp("aac", arg_acodec, 3)) { if(!strncmp("ac3", arg_acodec, 3)) {
format = "audio/mpeg, framed=true, mpegversion=4, stream-format=adts";
}
else if(!strncmp("ac3", arg_acodec, 3)) {
format = "audio/x-ac3, framed=true"; format = "audio/x-ac3, framed=true";
} }
else if(!strncmp("pcm", arg_acodec, 3)) { else if(!strncmp("pcm", arg_acodec, 3)) {
format = "audio/x-lpcm"; format = "audio/x-lpcm";
} }
else {
format = "audio/mpeg, framed=true, mpegversion=4, stream-format=adts";
}
GstEncodingAudioProfile *aencode_profile = gst_encoding_audio_profile_new( GstEncodingAudioProfile *aencode_profile = gst_encoding_audio_profile_new(
gst_caps_from_string(format), gst_caps_from_string(format),
NULL, NULL,
@ -359,14 +387,14 @@ static int prepare_pipeline(struct SenderImpl *self)
result = link_elements(GST_BIN(self->pipeline), result = link_elements(GST_BIN(self->pipeline),
"vsrc", "vsrc",
"caps_framerate", "caps_framerate",
"vscale", //"vscale",
"caps_scale", //"caps_scale",
"vconv", "vconv",
"caps_format", "caps_format",
"vencoder", "vencoder",
"vqueue", "caps_vencoder",
//"vqueue",
"muxer", "muxer",
"caps_muxer",
"rtppay", "rtppay",
"sink", "sink",
NULL); NULL);
@ -389,7 +417,7 @@ static int prepare_pipeline(struct SenderImpl *self)
g_signal_connect_swapped(bus, "message", G_CALLBACK(on_gst_message), self); g_signal_connect_swapped(bus, "message", G_CALLBACK(on_gst_message), self);
gst_bus_add_signal_watch(bus); gst_bus_add_signal_watch(bus);
gst_element_set_state(self->pipeline, GST_STATE_PAUSED); gst_element_set_state(self->pipeline, GST_STATE_READY);
goto free_desc; goto free_desc;
@ -412,6 +440,8 @@ static void sender_on_name_acquired(GDBusConnection *conn,
GError *error = NULL; GError *error = NULL;
gboolean result; gboolean result;
g_info("dbus name org.freedesktop.miracle acquired");
self->skeleton = sender_skeleton_new(); self->skeleton = sender_skeleton_new();
g_signal_connect_swapped(self->skeleton, g_signal_connect_swapped(self->skeleton,
"handle-prepare", "handle-prepare",
@ -434,7 +464,7 @@ static void sender_on_name_acquired(GDBusConnection *conn,
result = g_dbus_interface_skeleton_export( result = g_dbus_interface_skeleton_export(
G_DBUS_INTERFACE_SKELETON(self->skeleton), G_DBUS_INTERFACE_SKELETON(self->skeleton),
conn, conn,
"/org/freedesktop/miracle/Senders/0", "/org/freedesktop/miracle/Sender/0",
&error); &error);
if(!result) { if(!result) {
g_error("failed to expose object"); g_error("failed to expose object");
@ -463,6 +493,8 @@ static gint sender_impl_init(struct SenderImpl *self)
goto end; goto end;
} }
g_info("trying to acquire dbus name org.freedesktop.miracle...");
self->bus_owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, self->bus_owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
"org.freedesktop.miracle", "org.freedesktop.miracle",
G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_NONE,
@ -515,6 +547,13 @@ static gboolean sender_impl_prepare(struct SenderImpl *self,
return TRUE; return TRUE;
} }
static gboolean start_play(gpointer user_data)
{
gst_element_set_state(((struct SenderImpl *) user_data)->pipeline, GST_STATE_PLAYING);
return FALSE;
}
static gboolean sender_impl_play(struct SenderImpl *self, static gboolean sender_impl_play(struct SenderImpl *self,
GDBusMethodInvocation *invocation) GDBusMethodInvocation *invocation)
{ {
@ -536,7 +575,7 @@ static gboolean sender_impl_play(struct SenderImpl *self,
self->method_invoke = invocation; self->method_invoke = invocation;
gst_element_set_state(self->pipeline, GST_STATE_PLAYING); g_timeout_add_seconds(1, start_play, self);
return TRUE; return TRUE;
} }
@ -594,13 +633,11 @@ end:
return TRUE; return TRUE;
} }
static gboolean sender_impl_run(struct SenderImpl *self) static void sender_impl_run(struct SenderImpl *self)
{ {
g_main_loop_run(self->loop); g_main_loop_run(self->loop);
} }
static void arg_enable_audio();
static GOptionEntry entries[] = { static GOptionEntry entries[] = {
{ "host", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &arg_host, "the hostname of sink", "" }, { "host", 0, G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &arg_host, "the hostname of sink", "" },
{ "port", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_INT, &arg_port, "the port which sink is waiting for RTP string", "" }, { "port", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_INT, &arg_port, "the port which sink is waiting for RTP string", "" },
@ -636,7 +673,7 @@ static void arg_parse(int *argc, char ***args)
g_option_context_free(opt_context); g_option_context_free(opt_context);
} }
static void gst_rerank(const char *name, ...) static void gst_raise_rank(const char *name, ...)
{ {
va_list names; va_list names;
GstRegistry *reg = gst_registry_get(); GstRegistry *reg = gst_registry_get();
@ -671,7 +708,7 @@ int main(int argc, char *args[])
gdk_init(&argc, &args); gdk_init(&argc, &args);
gst_init(&argc, &args); gst_init(&argc, &args);
gst_pb_utils_init(); gst_pb_utils_init();
//gst_rerank("vaapih264enc", "vaapienc_h264", "glcolorconvert", NULL); gst_raise_rank("vaapih264enc", "vaapienc_h264", "glcolorconvert", NULL);
sender = sender_impl_new(); sender = sender_impl_new();
if(!sender) { if(!sender) {
@ -684,7 +721,7 @@ int main(int argc, char *args[])
sender_impl_run(sender); sender_impl_run(sender);
g_object_unref(sender); sender_impl_free(sender);
return 0; return 0;
} }

View file

@ -1,66 +0,0 @@
#!/usr/bin/python3
import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')
gi.require_version('GstPbutils', '1.0')
from gi.repository import GLib
from gi.repository import Gst, GstBase, GstPbutils
Gst.init(None)
GstPbutils.pb_utils_init()
pipeline = Gst.ElementFactory.make('pipeline')
ximagesrc = Gst.ElementFactory.make('ximagesrc')
ximagesrc.set_property('use-damage', False)
ximagesrc.set_property('show-pointer', False)
ximagesrc.set_property('do-timestamp', True)
ximagesrc.set_property('startx', 0)
ximagesrc.set_property('starty', 0)
ximagesrc.set_property('endx', 1919)
ximagesrc.set_property('endy', 1079)
pipeline.add(ximagesrc)
vscale = Gst.ElementFactory.make('videoscale')
pipeline.add(vscale)
ximagesrc.link(vscale)
vconvert = Gst.ElementFactory.make('videoconvert')
pipeline.add(vconvert)
vscale.link(vconvert)
filter = Gst.ElementFactory.make('capsfilter')
filter.set_property('caps', Gst.Caps.from_string('video/x-raw, format=I420, framerate=30/1, width=1920, height=1080'))
pipeline.add(filter)
vconvert.link(filter)
encoder = Gst.ElementFactory.make('encodebin')
#cont_profile = GstPbutils.EncodingContainerProfile.new('mpegts',
# None,
# Gst.Caps.from_string('video/mpegts, packetsize=188, systemstream=true'),
# None)
vencode_profile = GstPbutils.EncodingVideoProfile.new(Gst.Caps.from_string('video/x-h264'),
None,
Gst.Caps.new_any(),
1)
#cont_profile.add_profile(vencode_profile)
encoder.set_property('profile', vencode_profile)
pipeline.add(encoder)
filter.link(encoder)
mpegtsmux = Gst.ElementFactory.make('mpegtsmux')
mpegtsmux.set_property('alignment', 7)
pipeline.add(mpegtsmux)
encoder.link(mpegtsmux)
sink = Gst.ElementFactory.make('filesink')
sink.set_property('location', 'xxx')
pipeline.add(sink)
mpegtsmux.link(sink)
pipeline.set_state(Gst.State.PLAYING)
loop = GLib.MainLoop()
loop.run()