[empathy] Call: Bind the output properties from the main thread
- From: Sjoerd Simons <sjoerds src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [empathy] Call: Bind the output properties from the main thread
- Date: Fri, 18 Nov 2011 18:12:42 +0000 (UTC)
commit be42e8d30bedc020f96bbe719ac3c6620aa59b7e
Author: Sjoerd Simons <sjoerd simons collabora co uk>
Date: Fri Nov 18 10:05:57 2011 +0000
Call: Bind the output properties from the main thread
If we bind and sync the output volume from the non-main thread, we end
up calling gtk and clutter from the non-main thread.. Which leads to
crashes in OpenGL drivers and potenially kills your cat. Instead create
the audio output when the audio content is added, which happens from the
main thread. The output element is still only added to gstreamer
pipeline when needed though.
src/empathy-call-window.c | 84 +++++++++++++++++++++++++++-----------------
1 files changed, 51 insertions(+), 33 deletions(-)
---
diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c
index dc587e2..b900504 100644
--- a/src/empathy-call-window.c
+++ b/src/empathy-call-window.c
@@ -228,6 +228,7 @@ struct _EmpathyCallWindowPriv
GstElement *video_output_sink;
GstElement *audio_input;
GstElement *audio_output;
+ gboolean audio_output_added;
GstElement *pipeline;
GstElement *video_tee;
@@ -2530,6 +2531,7 @@ empathy_call_window_reset_pipeline (EmpathyCallWindow *self)
if (priv->audio_output != NULL)
g_object_unref (priv->audio_output);
priv->audio_output = NULL;
+ priv->audio_output_added = FALSE;
if (priv->video_tee != NULL)
g_object_unref (priv->video_tee);
@@ -2735,8 +2737,10 @@ empathy_call_window_content_removed_cb (EmpathyCallHandler *handler,
{
gst_element_set_state (priv->audio_output, GST_STATE_NULL);
- gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_output);
+ if (priv->audio_output_added)
+ gst_bin_remove (GST_BIN (priv->pipeline), priv->audio_output);
priv->audio_output = NULL;
+ priv->audio_output_added = FALSE;
}
}
else
@@ -2865,32 +2869,8 @@ empathy_call_window_get_audio_sink_pad (EmpathyCallWindow *self,
GstPad *pad;
GstPadTemplate *template;
- if (priv->audio_output == NULL)
+ if (!priv->audio_output_added)
{
- priv->audio_output = empathy_audio_sink_new ();
- g_object_ref_sink (priv->audio_output);
-
- /* volume button to output volume linking */
- g_object_bind_property (priv->audio_output, "volume",
- priv->volume_button, "value",
- G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
- g_object_bind_property_full (content, "requested-output-volume",
- priv->audio_output, "volume",
- G_BINDING_DEFAULT,
- audio_control_volume_to_element,
- element_volume_to_audio_control,
- NULL, NULL);
-
- /* Link volumes together, sync the current audio input volume property
- * back to farstream first */
- g_object_bind_property_full (priv->audio_output, "volume",
- content, "reported-output-volume",
- G_BINDING_SYNC_CREATE,
- element_volume_to_audio_control,
- audio_control_volume_to_element,
- NULL, NULL);
-
if (!gst_bin_add (GST_BIN (priv->pipeline), priv->audio_output))
{
g_warning ("Could not add audio sink to pipeline");
@@ -2905,13 +2885,6 @@ empathy_call_window_get_audio_sink_pad (EmpathyCallWindow *self,
}
}
- /* For raw audio conferences assume that the producer of the raw data
- * has already processed it, so turn off any echo cancellation and any
- * other audio improvements that come with it */
- empathy_audio_sink_set_echo_cancel (
- EMPATHY_GST_AUDIO_SINK (priv->audio_output),
- !empathy_call_window_content_is_raw (content));
-
template = gst_element_class_get_pad_template (
GST_ELEMENT_GET_CLASS (priv->audio_output), "sink%d");
@@ -3443,6 +3416,48 @@ empathy_call_window_src_added_cb (EmpathyCallHandler *handler,
return TRUE;
}
+static void
+empathy_call_window_prepare_audio_output (EmpathyCallWindow *self,
+ TfContent *content)
+{
+ EmpathyCallWindowPriv *priv = self->priv;
+
+ g_assert (priv->audio_output_added == FALSE);
+ g_assert (priv->audio_output == FALSE);
+
+ priv->audio_output = empathy_audio_sink_new ();
+ g_object_ref_sink (priv->audio_output);
+
+ /* volume button to output volume linking */
+ g_object_bind_property (priv->audio_output, "volume",
+ priv->volume_button, "value",
+ G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+ g_object_bind_property_full (content, "requested-output-volume",
+ priv->audio_output, "volume",
+ G_BINDING_DEFAULT,
+ audio_control_volume_to_element,
+ element_volume_to_audio_control,
+ NULL, NULL);
+
+ /* Link volumes together, sync the current audio input volume property
+ * back to farstream first */
+ g_object_bind_property_full (priv->audio_output, "volume",
+ content, "reported-output-volume",
+ G_BINDING_SYNC_CREATE,
+ element_volume_to_audio_control,
+ audio_control_volume_to_element,
+ NULL, NULL);
+
+ /* For raw audio conferences assume that the producer of the raw data
+ * has already processed it, so turn off any echo cancellation and any
+ * other audio improvements that come with it */
+ empathy_audio_sink_set_echo_cancel (
+ EMPATHY_GST_AUDIO_SINK (priv->audio_output),
+ !empathy_call_window_content_is_raw (content));
+}
+
+
static gboolean
empathy_call_window_content_added_cb (EmpathyCallHandler *handler,
TfContent *content, gpointer user_data)
@@ -3512,6 +3527,9 @@ empathy_call_window_content_added_cb (EmpathyCallHandler *handler,
break;
}
+ /* Prepare our audio output, not added yet though */
+ empathy_call_window_prepare_audio_output (self, content);
+
retval = TRUE;
break;
case FS_MEDIA_TYPE_VIDEO:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]