Problem with Dbus and Gstreamer

Mirko Banchi mk.banchi at gmail.com
Tue Dec 28 02:39:00 PST 2010


Hi all, i'm new to DBus...i hope someone could help me. I've written a
plugin for Gstreamer...the only purpose of the plugin is to save the
last frame of a video. The element's struct is very simple:

----code----
struct _GstFrameServer
{
 GstElement element;

 GstPad *sinkpad, *srcpad;

 GstBuffer *lastframe;
};
------end code-------

in the init function of my GstElement i register the object in DBus:

------code------
static void
gst_frame_server_init (GstFrameServer * filter,
    GstFrameServerClass * gclass)
{
...

GError *error = NULL;
DBusGConnection *connection = NULL;
DBusGProxy *proxy;
guint result;

connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
if (connection == NULL)
{
  GST_ERROR ("Unable to get connection to dbus");
  g_error_free (error);
  return;
}
proxy = dbus_g_proxy_new_for_name (connection, DBUS_SERVICE_DBUS,
DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
if (!dbus_g_proxy_call (proxy, "RequestName", &error, G_TYPE_STRING,
"com.magenta.FrameServer", G_TYPE_UINT, 0, G_TYPE_INVALID,
G_TYPE_UINT, &result, G_TYPE_INVALID))
{
  GST_ERROR ("Unable to register service com.magenta.FrameServer");
  return;
}

dbus_g_object_type_install_info (GST_TYPE_FRAMESERVER,
&dbus_glib_frame_server_object_info);
dbus_g_connection_register_g_object
(connection,"/com/magenta/FrameServer", G_OBJECT(filter));
...
}

------end code------

note that dbus_glib_frame_server_object_info struct is the struct
autogenerated with dbus-binding-tool.
In particular in Dbus is exposed a method 'GetFrame' mapped on the
function gst_frame_server_get_frame that realizes the copy of the
frame in a GArray:

-------code--------
void
gst_frame_server_get_frame (GstFrameServer *self, GArray **buffer,
guint32 *h, guint32 *w, GError **error)
{
  ....
  *buffer = g_array_new (FALSE, FALSE, sizeof (gchar));

  g_mutex_lock (mutex);

  g_array_insert_vals (*buffer, 0, GST_BUFFER_DATA(self->lastframe),
GST_BUFFER_SIZE(self->lastframe));

  g_mutex_unlock (mutex);
}

-------end code------

Now we have also to take a look at the function gst_frame_server_chain
that is the function called when a frame is available from the
previous element in the gstreamer chain. This function only save the
frame:

-----code-----
static GstFlowReturn
gst_frame_server_chain (GstPad * pad, GstBuffer * buf)
{
  GstFrameServer *filter;

  filter = GST_FRAMESERVER (GST_OBJECT_PARENT (pad));

  ....

  //save the frame

  g_mutex_lock (mutex);

  if (filter->lastframe)
    gst_buffer_unref (filter->lastframe);
  filter->lastframe = gst_buffer_ref (buf);

  g_mutex_unlock (mutex);
}

----end code------

Now the problem: if i try to invoke the method 'GetFrame' i get an
error message:

Method invoked for GetFrame returned FALSE but did not set error.

However there is an interesting thing: If i remove the calls to
g_mutex_lock and g_mutex_unlock int the two functions
gst_frame_server_chain and in gst_frame_server_get_frame all works
fine and i can display the frame correctly in the client program i.e
the call to dbus_g_proxy_call doesn't fail. But the more interesting
thing is that if i add a call to a g_print after the call to
g_mutex_unlock in gst_frame_server_get_frame function all works fine
also with the calls to g_mutex_lock and g_mutex_unlock :(

-------code--------
void
gst_frame_server_get_frame (GstFrameServer *self, GArray **buffer,
guint32 *h, guint32 *w, GError **error)
{
  ....
  *buffer = g_array_new (FALSE, FALSE, sizeof (gchar));

  g_mutex_lock (mutex);

  g_array_insert_vals (*buffer, 0, GST_BUFFER_DATA(self->lastframe),
GST_BUFFER_SIZE(self->lastframe));

  g_mutex_unlock (mutex);
  g_print ("After g_mutex_unlock\n");
}

-------end code-----

I also compiled libdbus and libdbus-glib with debug symbols and i'm
trying to debug but i can't find the error.
Where could be the problem?

Thank you all for the help!

Regards,

Mirko


More information about the dbus mailing list