queue: add silent property to suppress signal emission
authorStefan Kost <ensonic@users.sf.net>
Fri, 27 Aug 2010 12:35:49 +0000 (15:35 +0300)
committerStefan Kost <ensonic@users.sf.net>
Mon, 30 Aug 2010 06:46:53 +0000 (09:46 +0300)
Allow to turn off signal emission and therefore extra locking if this is not needed.
Fixes #621299

plugins/elements/gstqueue.c
plugins/elements/gstqueue.h

index 34d08ed..6bf1c48 100644 (file)
@@ -118,7 +118,7 @@ enum
   PROP_MIN_THRESHOLD_BYTES,
   PROP_MIN_THRESHOLD_TIME,
   PROP_LEAKY,
-  /* FILL ME */
+  PROP_SILENT
 };
 
 /* default property values */
@@ -351,6 +351,19 @@ gst_queue_class_init (GstQueueClass * klass)
           GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  /**
+   * GstQueue:silent
+   *
+   * Don't emit queue signals. Makes queues more lightweight if no signals are
+   * needed.
+   *
+   * Since: 0.10.31
+   */
+  g_object_class_install_property (gobject_class, PROP_SILENT,
+      g_param_spec_boolean ("silent", "Silent",
+          "Don't emit queue signals", FALSE,
+          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
   gobject_class->finalize = gst_queue_finalize;
 
   /* Registering debug symbols for function pointers */
@@ -934,9 +947,14 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
    * the user defined as "full". Note that this only applies to buffers.
    * We always handle events and they don't count in our statistics. */
   while (gst_queue_is_filled (queue)) {
-    GST_QUEUE_MUTEX_UNLOCK (queue);
-    g_signal_emit (queue, gst_queue_signals[SIGNAL_OVERRUN], 0);
-    GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    if (!queue->silent) {
+      GST_QUEUE_MUTEX_UNLOCK (queue);
+      g_signal_emit (queue, gst_queue_signals[SIGNAL_OVERRUN], 0);
+      GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    } else {
+      if (queue->srcresult != GST_FLOW_OK)
+        goto out_flushing;
+    }
 
     /* we recheck, the signal could have changed the thresholds */
     if (!gst_queue_is_filled (queue))
@@ -971,9 +989,14 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
 
         GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is not full");
 
-        GST_QUEUE_MUTEX_UNLOCK (queue);
-        g_signal_emit (queue, gst_queue_signals[SIGNAL_RUNNING], 0);
-        GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+        if (!queue->silent) {
+          GST_QUEUE_MUTEX_UNLOCK (queue);
+          g_signal_emit (queue, gst_queue_signals[SIGNAL_RUNNING], 0);
+          GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+        } else {
+          if (queue->srcresult != GST_FLOW_OK)
+            goto out_flushing;
+        }
         break;
       }
     }
@@ -1193,22 +1216,33 @@ gst_queue_loop (GstPad * pad)
   GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
 
   while (gst_queue_is_empty (queue)) {
-    GST_QUEUE_MUTEX_UNLOCK (queue);
-    g_signal_emit (queue, gst_queue_signals[SIGNAL_UNDERRUN], 0);
-    GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is empty");
-    GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    if (!queue->silent) {
+      GST_QUEUE_MUTEX_UNLOCK (queue);
+      g_signal_emit (queue, gst_queue_signals[SIGNAL_UNDERRUN], 0);
+      GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is empty");
+      GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    } else {
+      GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is empty");
+      if (queue->srcresult != GST_FLOW_OK)
+        goto out_flushing;
+    }
 
     /* we recheck, the signal could have changed the thresholds */
     while (gst_queue_is_empty (queue)) {
       GST_QUEUE_WAIT_ADD_CHECK (queue, out_flushing);
     }
-    GST_QUEUE_MUTEX_UNLOCK (queue);
 
-    g_signal_emit (queue, gst_queue_signals[SIGNAL_RUNNING], 0);
-    g_signal_emit (queue, gst_queue_signals[SIGNAL_PUSHING], 0);
-    GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is not empty");
-
-    GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    if (!queue->silent) {
+      GST_QUEUE_MUTEX_UNLOCK (queue);
+      g_signal_emit (queue, gst_queue_signals[SIGNAL_RUNNING], 0);
+      g_signal_emit (queue, gst_queue_signals[SIGNAL_PUSHING], 0);
+      GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is not empty");
+      GST_QUEUE_MUTEX_LOCK_CHECK (queue, out_flushing);
+    } else {
+      GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "queue is not empty");
+      if (queue->srcresult != GST_FLOW_OK)
+        goto out_flushing;
+    }
   }
 
   ret = gst_queue_push_one (queue);
@@ -1459,6 +1493,9 @@ gst_queue_set_property (GObject * object,
     case PROP_LEAKY:
       queue->leaky = g_value_get_enum (value);
       break;
+    case PROP_SILENT:
+      queue->silent = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1506,6 +1543,9 @@ gst_queue_get_property (GObject * object,
     case PROP_LEAKY:
       g_value_set_enum (value, queue->leaky);
       break;
+    case PROP_SILENT:
+      g_value_set_boolean (value, queue->silent);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
index 1499c07..203b508 100644 (file)
@@ -113,6 +113,8 @@ struct _GstQueue {
 
   gboolean head_needs_discont, tail_needs_discont;
   gboolean push_newsegment;
+  
+  gboolean silent;      /* don't emit signals */ 
 };
 
 struct _GstQueueClass {