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:
parent
91e1ee29ec
commit
03744ba53b
5 changed files with 83 additions and 205 deletions
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue