From 03744ba53bb80ef563a72e8acecd15c7ac74c9d9 Mon Sep 17 00:00:00 2001 From: Derek Dai Date: Fri, 16 Dec 2016 11:23:26 +0800 Subject: [PATCH] rename dbus name back to org.freedesktop.miracle.Sender and variety kinds of tunning --- src/ctl/ctl-src.c | 2 +- src/ctl/srcctl.c | 97 +----------------------------- src/stream/CMakeLists.txt | 2 +- src/stream/sender.c | 121 +++++++++++++++++++++++++------------- src/stream/sender.py | 66 --------------------- 5 files changed, 83 insertions(+), 205 deletions(-) delete mode 100755 src/stream/sender.py diff --git a/src/ctl/ctl-src.c b/src/ctl/ctl-src.c index e3f7b2e..9f6d08c 100644 --- a/src/ctl/ctl-src.c +++ b/src/ctl/ctl-src.c @@ -391,7 +391,7 @@ static int src_send_set_parameter(struct ctl_src *s) _rtsp_message_unref_ struct rtsp_message *req; int r; 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_uibc_capability: input_category_list=GENERIC\n;generic_cap_list=SingleTouch;hidc_cap_list=none;port=5100\n" //"wfd_uibc_setting: disable\n" diff --git a/src/ctl/srcctl.c b/src/ctl/srcctl.c index 3d8fd93..3ef9974 100644 --- a/src/ctl/srcctl.c +++ b/src/ctl/srcctl.c @@ -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) { if (src_pid <= 0) @@ -614,7 +526,7 @@ void ctl_fn_src_setup(struct ctl_src *s) ":0", 1920, 1080, - 30, + 25, FALSE, NULL, &error); @@ -632,9 +544,6 @@ void ctl_fn_src_playing(struct ctl_src *s) GError *error = NULL; cli_printf("SRC got play request\n"); - // TODO src_connected must be true, why if() failed? - //if (src_connected) - //spawn_gst(s); if(!sender) { cli_error("SRC not setup yet"); @@ -647,7 +556,7 @@ void ctl_fn_src_playing(struct ctl_src *s) return; } - g_info("SRC sender playing"); + cli_printf("SRC sender playing\n"); } 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 r; - GError *error = NULL; - setlocale(LC_ALL, ""); r = parse_argv(argc, argv); diff --git a/src/stream/CMakeLists.txt b/src/stream/CMakeLists.txt index c8d754e..5296219 100644 --- a/src/stream/CMakeLists.txt +++ b/src/stream/CMakeLists.txt @@ -21,7 +21,7 @@ add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sender-iface.c COMMAND ${GDBUS_CODEGEN_EXEC} ARGS --generate-c-code sender-iface --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 DEPENDS sender-iface.xml COMMENT "generating sender interface" diff --git a/src/stream/sender.c b/src/stream/sender.c index f178159..10bf1fe 100644 --- a/src/stream/sender.c +++ b/src/stream/sender.c @@ -60,29 +60,26 @@ static gchar *arg_acodec = NULL; static gboolean arg_audio_only = FALSE; -static guint arg_refresh_rate = 30; - -static gboolean arg_interleave = FALSE; - -static char * arg_h264_profile = NULL; +static guint arg_refresh_rate = 25; 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 " - "capsfilter name=caps_framerate caps=\"video/x-raw, framerate=%d/1\" " - "videoscale name=vscale " - "capsfilter name=caps_scale caps=\"video/x-raw, width=%d, height=%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=%u/1\" " + //"videoscale name=vscale " + //"capsfilter name=caps_scale caps=\"video/x-raw, width=%d, height=%d\" " "autovideoconvert name=vconv " "capsfilter name=caps_format caps=\"video/x-raw, format=I420\" " - "encodebin name=vencoder " - "queue name=vqueue max-size-buffers=0 max-size-bytes=0 " - "mpegtsmux name=muxer alignment=7 " - "capsfilter name=caps_muxer caps=\"video/mpegts, packetsize=188, systemstream=true\" " + //"encodebin name=vencoder " + "vaapih264enc name=vencoder max-bframes=0 " + "capsfilter name=caps_vencoder caps=\"video/x-h264, profile=high\" " + //"queue name=vqueue max-size-buffers=0 max-size-bytes=0 " + "mpegtsmux name=muxer " "rtpmp2tpay name=rtppay " "udpsink name=sink host=\"%s\" port=%d "; + //"filesink name=sink location=vaapi.mp2t "; static const char *apipeline_desc = - //"pulsesrc name=asrc device=\"%s\" " - "audiotestsrc name=asrc " + "pulsesrc name=asrc device=\"%s\" " "audioconvert name=aconv " "audioresample name=aresample " "encodebin name=aencoder " @@ -192,7 +189,15 @@ static int link_elements(GstBin *bin, const char *name, ...) name1 = name; while((name2 = va_arg(argv, const char *))) { 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); + if(!e2) { + g_warning("no such element: %s", name2); + return -1; + } gboolean linked = gst_element_link(e1, e2); g_object_unref(G_OBJECT(e2)); 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 = 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; case GST_STATE_PAUSED: 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 = NULL; } + g_info("sender paused"); break; default: break; @@ -267,7 +290,7 @@ void on_gst_message(struct SenderImpl *self, GstMessage *message, 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)) { case GST_MESSAGE_ERROR: on_gst_message_error(self, message); @@ -306,8 +329,8 @@ static int prepare_pipeline(struct SenderImpl *self) screen_bottom, screen_right, arg_refresh_rate, - arg_width ? arg_width : screen_right - screen_left + 1, - arg_height ? arg_height : screen_bottom - screen_top + 1, + //arg_width ? arg_width : screen_right - screen_left + 1, + //arg_height ? arg_height : screen_bottom - screen_top + 1, arg_host, arg_port); @@ -317,6 +340,8 @@ static int prepare_pipeline(struct SenderImpl *self) "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); if(error) { 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"); - GstEncodingVideoProfile *vencode_profile = gst_encoding_video_profile_new( - gst_caps_from_string("video/x-h264, profile=high"), - NULL, - gst_caps_new_any(), - 0); + /*GstEncodingVideoProfile *vencode_profile = gst_encoding_video_profile_new(*/ + /*gst_caps_from_string("video/x-h264, profile=high"),*/ + /*NULL,*/ + /*gst_caps_new_any(),*/ + /*0);*/ 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), "profile", vencode_profile, NULL); + g_object_set(G_OBJECT(vencoder), + //"profile", vencode_profile, + "max-bframes", 0, + NULL); g_object_unref(G_OBJECT(vencoder)); + //g_object_unref(G_OBJECT(vencode_profile)); if(arg_acodec) { const char *format; - if(!strncmp("aac", arg_acodec, 3)) { - format = "audio/mpeg, framed=true, mpegversion=4, stream-format=adts"; - } - else if(!strncmp("ac3", arg_acodec, 3)) { + if(!strncmp("ac3", arg_acodec, 3)) { format = "audio/x-ac3, framed=true"; } else if(!strncmp("pcm", arg_acodec, 3)) { format = "audio/x-lpcm"; } + else { + format = "audio/mpeg, framed=true, mpegversion=4, stream-format=adts"; + } GstEncodingAudioProfile *aencode_profile = gst_encoding_audio_profile_new( gst_caps_from_string(format), NULL, @@ -359,14 +387,14 @@ static int prepare_pipeline(struct SenderImpl *self) result = link_elements(GST_BIN(self->pipeline), "vsrc", "caps_framerate", - "vscale", - "caps_scale", + //"vscale", + //"caps_scale", "vconv", "caps_format", "vencoder", - "vqueue", + "caps_vencoder", + //"vqueue", "muxer", - "caps_muxer", "rtppay", "sink", NULL); @@ -389,7 +417,7 @@ static int prepare_pipeline(struct SenderImpl *self) g_signal_connect_swapped(bus, "message", G_CALLBACK(on_gst_message), self); 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; @@ -412,6 +440,8 @@ static void sender_on_name_acquired(GDBusConnection *conn, GError *error = NULL; gboolean result; + g_info("dbus name org.freedesktop.miracle acquired"); + self->skeleton = sender_skeleton_new(); g_signal_connect_swapped(self->skeleton, "handle-prepare", @@ -434,7 +464,7 @@ static void sender_on_name_acquired(GDBusConnection *conn, result = g_dbus_interface_skeleton_export( G_DBUS_INTERFACE_SKELETON(self->skeleton), conn, - "/org/freedesktop/miracle/Senders/0", + "/org/freedesktop/miracle/Sender/0", &error); if(!result) { g_error("failed to expose object"); @@ -463,6 +493,8 @@ static gint sender_impl_init(struct SenderImpl *self) goto end; } + g_info("trying to acquire dbus name org.freedesktop.miracle..."); + self->bus_owner_id = g_bus_own_name(G_BUS_TYPE_SESSION, "org.freedesktop.miracle", G_BUS_NAME_OWNER_FLAGS_NONE, @@ -515,6 +547,13 @@ static gboolean sender_impl_prepare(struct SenderImpl *self, 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, GDBusMethodInvocation *invocation) { @@ -536,7 +575,7 @@ static gboolean sender_impl_play(struct SenderImpl *self, self->method_invoke = invocation; - gst_element_set_state(self->pipeline, GST_STATE_PLAYING); + g_timeout_add_seconds(1, start_play, self); return TRUE; } @@ -594,13 +633,11 @@ end: return TRUE; } -static gboolean sender_impl_run(struct SenderImpl *self) +static void sender_impl_run(struct SenderImpl *self) { g_main_loop_run(self->loop); } -static void arg_enable_audio(); - static GOptionEntry entries[] = { { "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", "" }, @@ -636,7 +673,7 @@ static void arg_parse(int *argc, char ***args) g_option_context_free(opt_context); } -static void gst_rerank(const char *name, ...) +static void gst_raise_rank(const char *name, ...) { va_list names; GstRegistry *reg = gst_registry_get(); @@ -671,7 +708,7 @@ int main(int argc, char *args[]) gdk_init(&argc, &args); gst_init(&argc, &args); gst_pb_utils_init(); - //gst_rerank("vaapih264enc", "vaapienc_h264", "glcolorconvert", NULL); + gst_raise_rank("vaapih264enc", "vaapienc_h264", "glcolorconvert", NULL); sender = sender_impl_new(); if(!sender) { @@ -684,7 +721,7 @@ int main(int argc, char *args[]) sender_impl_run(sender); - g_object_unref(sender); + sender_impl_free(sender); return 0; } diff --git a/src/stream/sender.py b/src/stream/sender.py deleted file mode 100755 index fa0252e..0000000 --- a/src/stream/sender.py +++ /dev/null @@ -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() -