I'm new to C language
I use dbus_g_bus_get() to connect the Session Management signals:
static DBusGProxy * connect_to_session (void)
{
DBusGConnection *connection;
DBusGProxy *proxy;
GError *error = NULL;
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); /* line 1472 */
if (error) {
g_warning ("Couldn't connect to system bus: %s", error->message);
g_error_free(error);
return NULL;
}
/* Get the current session object */
proxy = dbus_g_proxy_new_for_name (connection,
"org.gnome.SessionManager",
"/org/gnome/SessionManager",
"org.gnome.SessionManager");
if (!proxy) {
g_warning ("Unable to get the SessionManager.");
dbus_g_connection_unref (connection);
return NULL;
}
dbus_g_proxy_add_signal (proxy, "SessionOver", G_TYPE_INVALID, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (proxy, "SessionOver", G_CALLBACK (session_die_cb), NULL, NULL);
g_object_set_data (G_OBJECT (proxy), "connection", connection);
return proxy;
}
call this in main:
int main(int argc, char* argv[])
{
--------------------------------------------
/* Connect the Session Management signals */
proxy = connect_to_session ();
if (proxy) {
DBusGConnection *conn;
conn = (DBusGConnection *)g_object_get_data (G_OBJECT (proxy), "connection");
if (conn)
dbus_g_connection_unref (conn);
g_object_unref (proxy);
}
return 0;
}
and valgrind output this:
32 bytes in 1 blocks are possibly lost in loss record 5,342 of 13,110
at 0x4C2C6AE: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
by 0x6F2ABEE: g_realloc (in /lib/x86_64-linux-gnu/libglib-2.0.so.0.3703.0)
by 0x6CBC577: g_type_set_qdata (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.3703.0)
by 0x513A3D4: ??? (in /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2)
by 0x512F48C: dbus_g_bus_get (in /usr/lib/x86_64-linux-gnu/libdbus-glib-1.so.2.2.2)
by 0x40B669: main (gui.c:1472)
I don't know if this report it is false or not.
Thanks
Valgrind has some issues dealing with glbal variables, there is a lot of posts hese at Stackoverflow. You are calling dbus_g_bus_get, and the return is a poiner to a global variable.
DBusGConnection* dbus_g_bus_get (DBusBusType type, GError **error);
Returns a connection to the given bus. The connection is a global variable shared with other callers of this function.
You could also try calling dbus_g_connection_ref after you get the connection.
Related
I'm having pipeline with appsink which pushes samples to appsrc which acts as a source to pipeline created by rtsp server. It works, I can connect to rtsp server and see the streamed video. The problem is latency. For some reason a lot of buffers is queued in the appsrc and the viewed stream has latency of more than two seconds.
I tried to find the source of latency and it looks like the data are started to being read from appsrc source pad after some time from the point the pipeline is started. The delay between the point the pipeline is started and the point data start to be read out from appsrc source pad is then transformed to it's latency.
I found this by reading out how many bytes is queued in appsrc each time I push the buffer to it. This value which I read out is continuously rising for some time. When the read out of data starts the current amout of the bytes stored in appsrc queue stay approximately the same for the rest of the time I stream the video.
Here is my test application which I'm using to test the correct functionality of this design.
#include <stdio.h>
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <gst/app/gstappsink.h>
#include <time.h>
#include <gst/rtsp-server/rtsp-server.h>
GMainLoop *loop;
GstElement *appsink;
GstElement *appsrc;
GstElement *appsink_pipeline;
/* Functions below print the Capabilities in a human-friendly format */
static gboolean print_field (GQuark field, const GValue * value, gpointer pfx) {
gchar *str = gst_value_serialize (value);
g_print ("%s %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);
g_free (str);
return TRUE;
}
static void print_caps (const GstCaps * caps, const gchar * pfx) {
guint i;
g_return_if_fail (caps != NULL);
if (gst_caps_is_any (caps)) {
g_print ("%sANY\n", pfx);
return;
}
if (gst_caps_is_empty (caps)) {
g_print ("%sEMPTY\n", pfx);
return;
}
for (i = 0; i < gst_caps_get_size (caps); i++) {
GstStructure *structure = gst_caps_get_structure (caps, i);
g_print ("%s%s\n", pfx, gst_structure_get_name (structure));
gst_structure_foreach (structure, print_field, (gpointer) pfx);
}
}
/* called when the appsink notifies us that there is a new buffer ready for
* processing */
static GstFlowReturn
on_new_sample_from_sink (GstElement * elt, void * data)
{
GstSample *sample;
GstFlowReturn ret = GST_FLOW_OK;
guint64 bytes;
/* get the sample from appsink */
sample = gst_app_sink_pull_sample (GST_APP_SINK (elt));
if(appsrc)
{
bytes = gst_app_src_get_current_level_bytes(GST_APP_SRC(appsrc));
g_print("buffered bytes before push %lu\n", bytes);
ret = gst_app_src_push_sample(GST_APP_SRC (appsrc), sample);
// bytes = gst_app_src_get_current_level_bytes(GST_APP_SRC(appsrc));
// if(ret == GST_FLOW_OK)
// g_print("pushed ok - buffered bytes after push %lu\n", bytes);
}
gst_sample_unref (sample);
return ret;
}
/* called when we get a GstMessage from the source pipeline when we get EOS, we
* notify the appsrc of it. */
static gboolean
on_source_message (GstBus * bus, GstMessage * message, void * data)
{
gint percent;
g_print ("%s\n", __func__);
switch (GST_MESSAGE_TYPE (message)) {
case GST_MESSAGE_EOS:
g_print ("The source got dry\n");
gst_app_src_end_of_stream (GST_APP_SRC (appsrc));
break;
case GST_MESSAGE_ERROR:
g_print ("Received error\n");
g_main_loop_quit (loop);
break;
case GST_MESSAGE_BUFFERING:
gst_message_parse_buffering (message, &percent);
g_print ("Buffering = %d\n", percent);
break;
default:
break;
}
return TRUE;
}
static GstFlowReturn need_data (GstElement * appsrc_loc,
guint length,
gpointer udata)
{
g_print("Need data\n");
return GST_FLOW_OK;
}
/* this timeout is periodically run to clean up the expired sessions from the
* pool. This needs to be run explicitly currently but might be done
* automatically as part of the mainloop. */
static gboolean
timeout (GstRTSPServer * server)
{
GstRTSPSessionPool *pool;
pool = gst_rtsp_server_get_session_pool (server);
gst_rtsp_session_pool_cleanup (pool);
g_object_unref (pool);
return TRUE;
}
void clientConnected(GstRTSPServer* server, GstRTSPClient* client, gpointer user)
{
g_print("%s\n", __func__);
}
static void media_state_cb(GstRTSPMedia *media, GstState state)
{
g_print("media state = %d\n", state);
}
static void
media_construct (GstRTSPMediaFactory * factory, GstRTSPMedia * media,
gpointer user_data)
{
GstElement *element;
g_print("%s\n", __func__);
/* get the element used for providing the streams of the media */
element = gst_rtsp_media_get_element (media);
/* get our appsrc, we named it 'appsrc' with the name property */
appsrc = gst_bin_get_by_name_recurse_up (GST_BIN (element), "appsrc");
g_signal_connect (appsrc, "need-data",
G_CALLBACK (need_data), NULL);
g_signal_connect (media, "new-state",
G_CALLBACK (media_state_cb), NULL);
gst_object_unref (element);
}
static void
media_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media,
gpointer user_data)
{
GstPad *pad;
GstCaps *caps;
gchar *caps_str;
GstElement *element;
g_print("%s\n", __func__);
/* get the element used for providing the streams of the media */
element = gst_rtsp_media_get_element (media);
/* get our appsrc, we named it 'mysrc' with the name property */
appsrc = gst_bin_get_by_name_recurse_up (GST_BIN (element), "appsrc");
pad = gst_element_get_static_pad (appsink, "sink");
if(pad)
{
g_print("Got pad\n");
caps = gst_pad_get_current_caps (pad);
if(caps)
{
caps_str = gst_caps_to_string (caps);
g_print("Got caps %s\n", caps_str);
g_object_set (G_OBJECT (appsrc), "caps", caps, NULL);
gst_caps_unref(caps);
}
}
/* this instructs appsrc that we will be dealing with timed buffer */
gst_util_set_object_arg (G_OBJECT (appsrc), "format", "time");
gst_object_unref (element);
}
int main (int argc, char *argv[]){
GstBus *bus;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory;
gchar src[] = "nvv4l2camerasrc device=/dev/video0 ! video/x-raw(memory:NVMM), width=1920, height=1080, format=UYVY, framerate=60/1 ! "
" queue max-size-buffers=3 leaky=downstream ! "
" nvvidconv name=conv ! video/x-raw(memory:NVMM), width=1280, height=720, format=NV12, framerate=60/1 ! "
" nvv4l2h264enc control-rate=1 bitrate=8000000 preset-level=1 profile=0 disable-cabac=1 maxperf-enable=1 name=encoder insert-sps-pps=1 insert-vui=1 idrinterval=30 ! "
" appsink name=appsink sync=false max-buffers=3";
gchar sink[] = "( appsrc name=appsrc format=3 stream-type=0 is-live=true blocksize=2097152 max-bytes=200000 ! "
" queue max-size-buffers=3 leaky=no ! "
" rtph264pay config-interval=1 name=pay0 )";
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* Create pipeline with appsink */
g_print("Creating pipeline with appsink\n");
appsink_pipeline = gst_parse_launch (src, NULL);
if (appsink_pipeline == NULL) {
g_print ("Bad source\n");
g_main_loop_unref (loop);
return -1;
}
/* to be notified of messages from this pipeline, mostly EOS */
bus = gst_element_get_bus (appsink_pipeline);
gst_bus_add_watch (bus, (GstBusFunc) on_source_message, appsink_pipeline);
gst_object_unref (bus);
/* Create push_buffer callback for appsink */
g_print("Creating push buffer callback\n");
appsink = gst_bin_get_by_name (GST_BIN (appsink_pipeline), "appsink");
g_object_set (G_OBJECT (appsink), "emit-signals", TRUE, "sync", FALSE, NULL);
g_signal_connect (appsink, "new-sample",
G_CALLBACK (on_new_sample_from_sink), NULL);
/* Create rtsp server with pipeline starting with appsrc */
g_print("Creating rtsp server\n");
/* create a server instance */
server = gst_rtsp_server_new ();
/* get the mount points for this server, every server has a default object
* that be used to map uri mount points to media factories */
mounts = gst_rtsp_server_get_mount_points (server);
/* make a media factory for a test stream. The default media factory can use
* gst-launch syntax to create pipelines.
* any launch line works as long as it contains elements named pay%d. Each
* element with pay%d names will be a stream */
factory = gst_rtsp_media_factory_new ();
gst_rtsp_media_factory_set_launch (factory, sink);
gst_rtsp_media_factory_set_shared(factory, TRUE);
/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
/* don't need the ref to the mapper anymore */
g_object_unref (mounts);
/* attach the server to the default maincontext */
if (gst_rtsp_server_attach (server, NULL) == 0)
goto failed;
/* add a timeout for the session cleanup */
g_timeout_add_seconds (2, (GSourceFunc) timeout, server);
g_signal_connect (server, "client-connected",
G_CALLBACK (clientConnected), NULL);
/* Create media-constructed callback to get appsrc reference */
g_print("Creating media-constructed callback\n");
g_signal_connect (factory, "media-constructed", (GCallback) media_construct,
NULL);
g_signal_connect (factory, "media-configure", (GCallback) media_configure,
NULL);
/* Push buffers from appsink to appsrc */
/* start serving, this never stops */
g_print("Running main loop\n");
gst_element_set_state (appsink_pipeline, GST_STATE_PLAYING);
g_main_loop_run (loop);
gst_element_set_state (appsink_pipeline, GST_STATE_NULL);
return 0;
/* ERRORS */
failed:
{
g_print ("failed to attach the server\n");
return -1;
}
}
I will appreciate every idea about what can cause this behavior and how to solve this.
Thanks a lot!
This latency problem may be due to many reasons but most of the time this problem is due to frames are not in SYNC. There is a lot of data in the queue.
To counter this problem need to test these test cases to find out the real problem.
Check the behavior with videotestsrc instead of the camera source.
Are you sure that after nvv4l2camerasrc queue is needed what will be the output if you skip the queue element.
You can also check with lower resolution input to get something from it.
what happened if you use v4l2src instead of nvv4l2camerasrc if your camera soruce is v4l2 complaince.
Thanks
I am using gst-rtsp-server and I want to be able to close an ongoing stream from the server. I am trying to use the gst_rtsp_client_close() function. However, when I call it the application sometimes becomes unresponsive. In the log I can see: GLib-CRITICAL **: g_main_context_unref: assertion 'g_atomic_int_get (&context->ref_count) > 0' failed​.
I have modified the test-uri example to trigger this issue. Whenever a client connects, a timer will be started. When the timer runs out, gst_rtsp_client_close() will be called for that client.
/* GStreamer
* Copyright (C) 2008 Wim Taymans <wim.taymans at gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <gst/gst.h>
#include <gst/rtsp-server/rtsp-server.h>
#include <gst/rtsp-server/rtsp-media-factory-uri.h>
#define DEFAULT_RTSP_PORT "8554"
static char *port = (char *) DEFAULT_RTSP_PORT;
static GOptionEntry entries[] = {
{"port", 'p', 0, G_OPTION_ARG_STRING, &port,
"Port to listen on (default: " DEFAULT_RTSP_PORT ")", "PORT"},
{NULL}
};
static void
client_closed(GstRTSPClient *client,
gpointer user_data)
{
g_print("client closed %p\n", client);
}
static gboolean
disconnect (GstRTSPClient * client)
{
g_print("disconnect client %p\n", client);
gst_rtsp_client_close(client);
return FALSE;
}
static void
client_connected(GstRTSPServer *server,
GstRTSPClient *client,
gpointer user_data)
{
g_print("client connected %p\n", client);
g_signal_connect(client, "closed", (GCallback)client_closed,
NULL);
g_timeout_add_seconds (8, (GSourceFunc) disconnect, client);
}
int
main (int argc, gchar * argv[])
{
GMainLoop *loop;
GstRTSPServer *server;
GstRTSPMountPoints *mounts;
GstRTSPMediaFactoryURI *factory;
GOptionContext *optctx;
GError *error = NULL;
gchar *uri;
guint major;
guint minor;
guint micro;
guint nano;
gst_version(&major, &minor, µ, &nano);
g_print("%s started. GST version %u.%u.%u.%u\n", argv[0], major, minor, micro, nano);
optctx = g_option_context_new ("<uri> - Test RTSP Server, URI");
g_option_context_add_main_entries (optctx, entries, NULL);
g_option_context_add_group (optctx, gst_init_get_option_group ());
if (!g_option_context_parse (optctx, &argc, &argv, &error)) {
g_printerr ("Error parsing options: %s\n", error->message);
g_option_context_free (optctx);
g_clear_error (&error);
return -1;
}
g_option_context_free (optctx);
if (argc < 2) {
g_printerr ("Please pass an URI or file as argument!\n");
return -1;
}
loop = g_main_loop_new (NULL, FALSE);
/* create a server instance */
server = gst_rtsp_server_new ();
g_object_set (server, "service", port, NULL);
g_signal_connect(server, "client-connected", (GCallback)client_connected,
NULL);
/* get the mount points for this server, every server has a default object
* that be used to map uri mount points to media factories */
mounts = gst_rtsp_server_get_mount_points (server);
/* make a URI media factory for a test stream. */
factory = gst_rtsp_media_factory_uri_new ();
/* check if URI is valid, otherwise convert filename to URI if it's a file */
if (gst_uri_is_valid (argv[1])) {
uri = g_strdup (argv[1]);
} else if (g_file_test (argv[1], G_FILE_TEST_EXISTS)) {
uri = gst_filename_to_uri (argv[1], NULL);
} else {
g_printerr ("Unrecognised command line argument '%s'.\n"
"Please pass an URI or file as argument!\n", argv[1]);
return -1;
}
gst_rtsp_media_factory_uri_set_uri (factory, uri);
g_free (uri);
/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test",
GST_RTSP_MEDIA_FACTORY (factory));
/* don't need the ref to the mapper anymore */
g_object_unref (mounts);
/* attach the server to the default maincontext */
if (gst_rtsp_server_attach (server, NULL) == 0)
goto failed;
/* start serving */
g_print ("stream ready at rtsp://127.0.0.1:%s/test\n", port);
g_main_loop_run (loop);
return 0;
/* ERRORS */
failed:
{
g_print ("failed to attach the server\n");
return -1;
}
}
I start the application with: ./close-test-uri.out ~/Videos/big_buck_bunny.mp4
and then I connect to the RTSP stream using a client (VLC): vlc -vvv "rtsp://127.0.0.1:8554/test"
The video will start playing and after 8 seconds it will (as expected), be disconnected. However, as mentioned before I get the critical error and the application becomes unresponsive (sometimes it crashes).
Am I using gst_rtsp_client_close() it the wrong way?
Thank you in advance!
Today, I tried to use polkit - an application-level toolkit for defining and handling the policy that allows unprivileged processes to speak to privileged processes. In order to understand it better, I tried to download this code:
#include <polkit/polkit.h>
static gboolean
on_tensec_timeout (gpointer user_data)
{
GMainLoop *loop = user_data;
g_print ("Ten seconds has passed. Now exiting.\n");
g_main_loop_quit (loop);
return FALSE;
}
static void
check_authorization_cb (PolkitAuthority *authority,
GAsyncResult *res,
gpointer user_data)
{
GMainLoop *loop = user_data;
PolkitAuthorizationResult *result;
GError *error;
error = NULL;
result = polkit_authority_check_authorization_finish (authority, res, &error);
if (error != NULL)
{
g_print ("Error checking authorization: %s\n", error->message);
g_error_free (error);
}
else
{
const gchar *result_str;
if (polkit_authorization_result_get_is_authorized (result))
{
result_str = "authorized";
}
else if (polkit_authorization_result_get_is_challenge (result))
{
result_str = "challenge";
}
else
{
result_str = "not authorized";
}
g_print ("Authorization result: %s\n", result_str);
}
g_print ("Authorization check has been cancelled and the dialog should now be hidden.\n"
"This process will exit in ten seconds.\n");
g_timeout_add (10000, on_tensec_timeout, loop);
}
static gboolean
do_cancel (GCancellable *cancellable)
{
g_print ("Timer has expired; cancelling authorization check\n");
g_cancellable_cancel (cancellable);
return FALSE;
}
int
main (int argc, char *argv[])
{
pid_t parent_pid;
const gchar *action_id;
GMainLoop *loop;
PolkitSubject *subject;
PolkitAuthority *authority;
GCancellable *cancellable;
g_type_init ();
if (argc != 2)
{
g_printerr ("usage: %s <action_id>\n", argv[0]);
return 1;
}
action_id = argv[1];
loop = g_main_loop_new (NULL, FALSE);
authority = polkit_authority_get_sync (NULL, NULL);
/* Typically mechanisms will use a PolkitSystemBusName since most
* clients communicate with the mechanism via D-Bus. However for
* this simple example we use the process id of the calling process.
*
* Note that if the parent was reaped we have to be careful not to
* check if init(1) is authorized (it always is).
*/
parent_pid = getppid ();
if (parent_pid == 1)
{
g_printerr ("Parent process was reaped by init(1)\n");
return 1;
}
subject = polkit_unix_process_new (parent_pid);
cancellable = g_cancellable_new ();
g_print ("Will cancel authorization check in 10 seconds\n");
/* Set up a 10 second timer to cancel the check */
g_timeout_add (10 * 1000,
(GSourceFunc) do_cancel,
cancellable);
polkit_authority_check_authorization (authority,
subject,
action_id,
NULL, /* PolkitDetails */
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
cancellable,
(GAsyncReadyCallback) check_authorization_cb,
loop);
g_main_loop_run (loop);
g_object_unref (authority);
g_object_unref (subject);
g_object_unref (cancellable);
g_main_loop_unref (loop);
return 0;
}
But when I tried to compile it with gcc, I received this output:
ciao.c:35:27: fatal error: polkit/polkit.h: File o directory non esistente
compilation terminated.
The path polkit/polkit.h is not in the system include path. Make sure you've downloaded and installed PolKit so that the headers and libraries are available.
I solved my problem adding this
pkg-config --cflags glib-2.0 polkit-gobject-1
and this
pkg-config --libs glib-2.0 polkit-gobject-1
to gcc compilation's command in this way
gcc `pkg-config --cflags glib-2.0 polkit-gobject-1` -o polkit PolicyKit/example.c `pkg-config --libs glib-2.0`
I would like to create an Asynchronous server and client application that communicate via sockets using GIO. As I am newbie to GIO, on browsing I got the below code - which is my client. I am unable to find any examples of the server. Please guide me in this regard.
GMainLoop *loop;
GMainContext *ctx;
struct conn
{
GSocketClient *client;
GSocketConnection *conn;
GInputStream *in;
GOutputStream *out;
gchar data[8192];
unsigned int count;
};
static void
read_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
printf("## %s\n", __FUNCTION__);
struct conn *c = (struct conn *)user_data;
gssize len = g_input_stream_read_finish(c->in, res, NULL);
g_input_stream_read_async(c->in, c->data, sizeof c->data / sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c);
if (c->count++ == 1) {
printf("End of life as I know it...\n");
g_main_loop_quit(loop);
}
}
static void
write_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
}
static void
connect_done_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
{
printf("## %s\n", __FUNCTION__);
struct conn *c = (struct conn *)user_data;
c->conn = g_socket_client_connect_to_host_finish(c->client, res, NULL);
printf("I'm\n");
c->in = g_io_stream_get_input_stream(G_IO_STREAM (c->conn));
c->out = g_io_stream_get_output_stream(G_IO_STREAM (c->conn));
char *data = "hello world!!!\n";
printf("I'm here\n");
g_output_stream_write_async(c->out, data, strlen(data), G_PRIORITY_DEFAULT, NULL, write_done_cb, c);
g_input_stream_read_async(c->in, c->data, sizeof c->data / sizeof *c->data, G_PRIORITY_DEFAULT, NULL, read_done_cb, c);
}
int
main(int argc, char **argv)
{
g_type_init();
struct conn *c = g_malloc0(sizeof *c);
ctx = g_main_context_new();
loop = g_main_loop_new(ctx, FALSE);
g_main_context_push_thread_default(ctx);
c->client = g_socket_client_new();
g_socket_client_connect_to_host_async(c->client, "localhost", 1500, NULL, connect_done_cb, c);
g_main_loop_run(loop);
g_io_stream_close(G_IO_STREAM(c->conn), NULL, NULL);
g_object_unref(c->client);
g_object_unref(c->conn);
g_main_context_pop_thread_default(ctx);
g_main_loop_unref(loop);
g_main_context_unref(ctx);
return 0;
}
Hope this would help you
#include <glib.h>
#include <gio/gio.h>
/* this function will get called everytime a client attempts to connect */
gboolean
incoming_callback (GSocketService *service,
GSocketConnection *connection,
GObject *source_object,
gpointer user_data)
{
g_print("Received Connection from client!\n");
GInputStream * istream = g_io_stream_get_input_stream (G_IO_STREAM (connection));
gchar message[1024];
g_input_stream_read (istream,
message,
1024,
NULL,
NULL);
g_print("Message was: \"%s\"\n", message);
return FALSE;
}
int
main (int argc, char **argv)
{
/* initialize glib */
g_type_init();
GError * error = NULL;
/* create the new socketservice */
GSocketService * service = g_socket_service_new ();
/* connect to the port */
g_socket_listener_add_inet_port ((GSocketListener*)service,
1500, /* your port goes here */
NULL,
&error);
/* don't forget to check for errors */
if (error != NULL)
{
g_error (error->message);
}
/* listen to the 'incoming' signal */
g_signal_connect (service,
"incoming",
G_CALLBACK (incoming_callback),
NULL);
/* start the socket service */
g_socket_service_start (service);
/* enter mainloop */
g_print ("Waiting for client!\n");
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
return 0;
}
I have dowloaded and installed http://gstreamer.freedesktop.org/data/pkg/windows/1.2.4.1/ gstreamer. Then I set up Visual Studio 2012 C++ project, add all *.props files. I want to try out Gstreamer Editing Services (GES) example project test4.c:
#include <ges/ges.h>
#include <gst/pbutils/encoding-profile.h>
GstEncodingProfile *make_encoding_profile (gchar * audio, gchar * container);
/* This example will take a series of files and create a audio-only timeline
* containing the first second of each file and render it to the output uri
* using ogg/vorbis */
/* make_encoding_profile
* simple method creating an encoding profile. This is here in
* order not to clutter the main function. */
GstEncodingProfile *
make_encoding_profile (gchar * audio, gchar * container)
{
GstEncodingContainerProfile *profile;
GstEncodingProfile *stream;
GstCaps *caps;
caps = gst_caps_from_string (container);
profile =
gst_encoding_container_profile_new ((gchar *) "ges-test4", NULL, caps,
NULL);
gst_caps_unref (caps);
caps = gst_caps_from_string (audio);
stream = (GstEncodingProfile *)
gst_encoding_audio_profile_new (caps, NULL, NULL, 0);
gst_encoding_container_profile_add_profile (profile, stream);
gst_caps_unref (caps);
return (GstEncodingProfile *) profile;
}
int
main (int argc, gchar ** argv)
{
GESPipeline *pipeline;
GESTimeline *timeline;
GESTrack *tracka;
GESLayer *layer;
GMainLoop *mainloop;
GstEncodingProfile *profile;
gchar *container = (gchar *) "application/ogg";
gchar *audio = (gchar *) "audio/x-vorbis";
gchar *output_uri;
guint i;
GError *err = NULL;
GOptionEntry options[] = {
{"format", 'f', 0, G_OPTION_ARG_STRING, &container,
"Container format", "<GstCaps>"},
{"aformat", 'a', 0, G_OPTION_ARG_STRING, &audio,
"Audio format", "<GstCaps>"},
{NULL}
};
GOptionContext *ctx;
ctx = g_option_context_new ("- renders a sequence of audio files.");
g_option_context_add_main_entries (ctx, options, NULL);
g_option_context_add_group (ctx, gst_init_get_option_group ());
if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
g_printerr ("Error initializing: %s\n", err->message);
g_option_context_free (ctx);
return -1;
}
if (argc < 3) {
g_print ("Usage: %s <output uri> <list of audio files>\n", argv[0]);
return -1;
}
/* Initialize GStreamer (this will parse environment variables and commandline
* arguments. */
gst_init (&argc, &argv);
/* Initialize the GStreamer Editing Services */
ges_init ();
/* Setup of an audio timeline */
/* This is our main GESTimeline */
timeline = ges_timeline_new ();
tracka = GES_TRACK (ges_audio_track_new ());
/* We are only going to be doing one layer of clips */
layer = ges_layer_new ();
/* Add the tracks and the layer to the timeline */
if (!ges_timeline_add_layer (timeline, layer))
return -1;
if (!ges_timeline_add_track (timeline, tracka))
return -1;
/* Here we've finished initializing our timeline, we're
* ready to start using it... by solely working with the layer ! */
for (i = 2; i < argc; i++) {
gchar *uri = gst_filename_to_uri (argv[i], NULL);
GESUriClip *src = ges_uri_clip_new (uri);
g_assert (src);
g_free (uri);
g_object_set (src, "start", ges_layer_get_duration (layer),
"duration", GST_SECOND, NULL);
/* Since we're using a GESSimpleLayer, objects will be automatically
* appended to the end of the layer */
ges_layer_add_clip (layer, (GESClip *) src);
}
/* In order to view our timeline, let's grab a convenience pipeline to put
* our timeline in. */
pipeline = ges_pipeline_new ();
/* Add the timeline to that pipeline */
if (!ges_pipeline_set_timeline (pipeline, timeline))
return -1;
/* RENDER SETTINGS ! */
/* We set our output URI and rendering setting on the pipeline */
if (gst_uri_is_valid (argv[1])) {
output_uri = g_strdup (argv[1]);
} else {
output_uri = gst_filename_to_uri (argv[1], NULL);
}
profile = make_encoding_profile (audio, container);
if (!ges_pipeline_set_render_settings (pipeline, output_uri, profile))
return -1;
/* We want the pipeline to render (without any preview) */
if (!ges_pipeline_set_mode (pipeline, GES_PIPELINE_MODE_SMART_RENDER))
return -1;
/* The following is standard usage of a GStreamer pipeline (note how you haven't
* had to care about GStreamer so far ?).
*
* We set the pipeline to playing ... */
gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
/* ... and we start a GMainLoop. GES **REQUIRES** a GMainLoop to be running in
* order to function properly ! */
mainloop = g_main_loop_new (NULL, FALSE);
/* Simple code to have the mainloop shutdown after 4s */
/* FIXME : We should wait for EOS ! */
g_timeout_add_seconds (argc - 1, (GSourceFunc) g_main_loop_quit, mainloop);
g_main_loop_run (mainloop);
return 0;
}
The program runs from the begining to the end without any errors, however
I can't get the music files playing. I think the problem lurks in this piece of code:
if (gst_uri_is_valid (argv[1])) {
output_uri = g_strdup (argv[1]);
} else {
output_uri = gst_filename_to_uri (argv[1], NULL);
}
I don't really know what to type as the first command line argument (the output dir is expected). When I provide any directory and launch program, it waits for a few seconds and then prints out "Press any key to continue...", however I can't hear the music playing neither I find any files in the provided output directory. What is more I was unable to hear any sounds then trying out test1.c, test2.c and test3.c test examples too. Maybe there is special way to provide arguments? My arguments looked like this: D:/output D:/mp3/1.mp3 D:/mp3/2.mp3 .