[MOVED FROM GST-P-FARSIGHT] Do wierd casting of the volume to make MSVC happy
[platform/upstream/gstreamer.git] / gst / dtmf / gstdtmfsrc.c
index 9dca9a4..4b2f9a2 100644 (file)
@@ -64,7 +64,9 @@
  * <entry>0-1</entry>
  * <entry>The application uses this field to specify which of the two methods
  * specified in RFC 2833 to use. The value should be 0 for tones and 1 for
- * named events. This element is only capable of generating tones.
+ * named events. Tones are specified by their frequencies and events are specied
+ * by their number. This element can only take events as input. Do not confuse
+ * with "method" which specified the output.
  * </entry>
  * </row>
  * <row>
@@ -91,9 +93,9 @@
  * <row>
  * <entry>method</entry>
  * <entry>G_TYPE_INT</entry>
- * <entry>1</entry>
- * <entry>The method used for sending event, this element will react if this field
- * is absent or 2.
+ * <entry>2</entry>
+ * <entry>The method used for sending event, this element will react if this
+ * field is absent or 2.
  * </entry>
  * </row>
  * </tbody>
  * <para>
  * <programlisting>
  * structure = gst_structure_new ("dtmf-event",
- *                    "type", G_TYPE_INT, 0,
+ *                    "type", G_TYPE_INT, 1,
  *                    "number", G_TYPE_INT, 1,
  *                    "volume", G_TYPE_INT, 25,
  *                    "start", G_TYPE_BOOLEAN, TRUE, NULL);
 
 #include "gstdtmfsrc.h"
 
-#define GST_TONE_DTMF_TYPE_EVENT 0
+#define GST_TONE_DTMF_TYPE_EVENT 1
 #define DEFAULT_PACKET_INTERVAL  50 /* ms */
 #define MIN_PACKET_INTERVAL      10 /* ms */
 #define MAX_PACKET_INTERVAL      50 /* ms */
-#define SAMPLE_RATE              8000
+#define DEFAULT_SAMPLE_RATE      8000
 #define SAMPLE_SIZE              16
 #define CHANNELS                 1
 #define MIN_EVENT                0
@@ -225,7 +227,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS ("audio/x-raw-int, "
         "width = (int) 16, "
         "depth = (int) 16, "
-        "endianness = (int) 1234, "
+        "endianness = (int) " G_STRINGIFY (G_BYTE_ORDER) ", "
         "signed = (bool) true, "
         "rate = (int) 8000, "
         "channels = (int) 1")
@@ -242,18 +244,16 @@ static void gst_dtmf_src_get_property (GObject * object, guint prop_id,
 static gboolean gst_dtmf_src_handle_event (GstBaseSrc *src, GstEvent * event);
 static GstStateChangeReturn gst_dtmf_src_change_state (GstElement * element,
     GstStateChange transition);
-static void gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key,
-    float duration, GstBuffer * buffer);
 static GstFlowReturn gst_dtmf_src_create (GstBaseSrc * basesrc,
     guint64 offset, guint length, GstBuffer ** buffer);
 static void gst_dtmf_src_add_start_event (GstDTMFSrc *dtmfsrc,
     gint event_number, gint event_volume);
 static void gst_dtmf_src_add_stop_event (GstDTMFSrc *dtmfsrc);
 
-static void gst_dtmf_src_get_times (GstBaseSrc * basesrc,
-    GstBuffer * buffer, GstClockTime * start, GstClockTime * end);
-
+static gboolean gst_dtmf_src_unlock (GstBaseSrc *src);
 
+static gboolean gst_dtmf_src_unlock_stop (GstBaseSrc *src);
+static gboolean gst_dtmf_src_negotiate (GstBaseSrc * basesrc);
 
 static void
 gst_dtmf_src_base_init (gpointer g_class)
@@ -288,19 +288,23 @@ gst_dtmf_src_class_init (GstDTMFSrcClass * klass)
       GST_DEBUG_FUNCPTR (gst_dtmf_src_get_property);
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_INTERVAL,
-      g_param_spec_int ("interval", "Interval between tone packets",
+      g_param_spec_uint ("interval", "Interval between tone packets",
           "Interval in ms between two tone packets", MIN_PACKET_INTERVAL,
           MAX_PACKET_INTERVAL, DEFAULT_PACKET_INTERVAL, G_PARAM_READWRITE));
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_dtmf_src_change_state);
+  gstbasesrc_class->unlock =
+      GST_DEBUG_FUNCPTR (gst_dtmf_src_unlock);
+  gstbasesrc_class->unlock_stop =
+      GST_DEBUG_FUNCPTR (gst_dtmf_src_unlock_stop);
 
   gstbasesrc_class->event =
       GST_DEBUG_FUNCPTR (gst_dtmf_src_handle_event);
-  gstbasesrc_class->get_times =
-      GST_DEBUG_FUNCPTR (gst_dtmf_src_get_times);
   gstbasesrc_class->create =
       GST_DEBUG_FUNCPTR (gst_dtmf_src_create);
+  gstbasesrc_class->negotiate =
+      GST_DEBUG_FUNCPTR (gst_dtmf_src_negotiate);
 }
 
 
@@ -316,7 +320,7 @@ gst_dtmf_src_init (GstDTMFSrc * dtmfsrc, GstDTMFSrcClass *g_class)
   dtmfsrc->event_queue = g_async_queue_new ();
   dtmfsrc->last_event = NULL;
 
-  dtmfsrc->clock_id = NULL;
+  dtmfsrc->sample_rate = DEFAULT_SAMPLE_RATE;
 
   GST_DEBUG_OBJECT (dtmfsrc, "init done");
 }
@@ -428,7 +432,7 @@ gst_dtmf_src_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_INTERVAL:
-      dtmfsrc->interval = g_value_get_int (value);
+      dtmfsrc->interval = g_value_get_uint (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -476,11 +480,15 @@ gst_dtmf_prepare_timestamps (GstDTMFSrc *dtmfsrc)
   GstClock *clock;
   GstClockTime base_time;
 
-  base_time = GST_ELEMENT_CAST (dtmfsrc)->base_time;
+  base_time = gst_element_get_base_time (GST_ELEMENT (dtmfsrc));
 
   clock = gst_element_get_clock (GST_ELEMENT (dtmfsrc));
   if (clock != NULL) {
+#ifdef MAEMO_BROKEN
+    dtmfsrc->timestamp = gst_clock_get_time (clock);
+#else
     dtmfsrc->timestamp = gst_clock_get_time (clock) - base_time;
+#endif
     gst_object_unref (clock);
   } else {
     gchar *dtmf_name = gst_element_get_name (dtmfsrc);
@@ -518,12 +526,13 @@ gst_dtmf_src_add_stop_event (GstDTMFSrc *dtmfsrc)
 }
 
 static void
-gst_dtmf_src_generate_silence(GstBuffer * buffer, float duration)
+gst_dtmf_src_generate_silence(GstBuffer * buffer, float duration,
+    gint sample_rate)
 {
   gint buf_size;
 
   /* Create a buffer with data set to 0 */
-  buf_size = ((duration/1000)*SAMPLE_RATE*SAMPLE_SIZE*CHANNELS)/8;
+  buf_size = ((duration/1000)*sample_rate*SAMPLE_SIZE*CHANNELS)/8;
   GST_BUFFER_SIZE (buffer) = buf_size;
   GST_BUFFER_MALLOCDATA (buffer) = g_malloc0(buf_size);
   GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
@@ -532,7 +541,7 @@ gst_dtmf_src_generate_silence(GstBuffer * buffer, float duration)
 
 static void
 gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key, float duration,
-    GstBuffer * buffer)
+    GstBuffer * buffer, gint sample_rate)
 {
   gint16 *p;
   gint tone_size;
@@ -541,7 +550,7 @@ gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key, float duration,
   double volume_factor;
 
   /* Create a buffer for the tone */
-  tone_size = ((duration/1000)*SAMPLE_RATE*SAMPLE_SIZE*CHANNELS)/8;
+  tone_size = ((duration/1000)*sample_rate*SAMPLE_SIZE*CHANNELS)/8;
   GST_BUFFER_SIZE (buffer) = tone_size;
   GST_BUFFER_MALLOCDATA (buffer) = g_malloc(tone_size);
   GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
@@ -558,8 +567,8 @@ gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key, float duration,
     /*
      * We add the fundamental frequencies together.
      */
-    f1 = sin(2 * M_PI * key.low_frequency * (event->sample / SAMPLE_RATE));
-    f2 = sin(2 * M_PI * key.high_frequency * (event->sample / SAMPLE_RATE));
+    f1 = sin(2 * M_PI * key.low_frequency * (event->sample / sample_rate));
+    f2 = sin(2 * M_PI * key.high_frequency * (event->sample / sample_rate));
 
     amplitude = (f1 + f2) / 2;
 
@@ -576,28 +585,6 @@ gst_dtmf_src_generate_tone(GstDTMFSrcEvent *event, DTMF_KEY key, float duration,
   }
 }
 
-static void
-gst_dtmf_src_get_times (GstBaseSrc * basesrc, GstBuffer * buffer,
-    GstClockTime * start, GstClockTime * end)
-{
-  /* for live sources, sync on the timestamp of the buffer */
-  if (gst_base_src_is_live (basesrc)) {
-    GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
-
-    if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
-      /* get duration to calculate end time */
-      GstClockTime duration = GST_BUFFER_DURATION (buffer);
-
-      *start = timestamp;
-      if (GST_CLOCK_TIME_IS_VALID (duration)) {
-        *end = *start + duration;
-      }
-    }
-  } else {
-    *start = -1;
-    *end = -1;
-  }
-}
 
 
 static GstBuffer *
@@ -620,11 +607,12 @@ gst_dtmf_src_create_next_tone_packet (GstDTMFSrc *dtmfsrc,
 
   if (send_silence) {
     GST_DEBUG_OBJECT (dtmfsrc,  "Generating silence");
-    gst_dtmf_src_generate_silence (buf, dtmfsrc->interval);
+    gst_dtmf_src_generate_silence (buf, dtmfsrc->interval,
+        dtmfsrc->sample_rate);
   } else {
     GST_DEBUG_OBJECT (dtmfsrc,  "Generating tone");
     gst_dtmf_src_generate_tone(event, DTMF_KEYS[event->event_number],
-        dtmfsrc->interval, buf);
+        dtmfsrc->interval, buf, dtmfsrc->sample_rate);
   }
   event->packet_count++;
 
@@ -645,83 +633,255 @@ gst_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset,
     guint length, GstBuffer ** buffer)
 {
   GstBuffer *buf = NULL;
-  GstFlowReturn ret;
   GstDTMFSrcEvent *event;
   GstDTMFSrc * dtmfsrc;
+  GstClock *clock;
+  GstClockID *clockid;
+  GstClockReturn clockret;
 
   dtmfsrc = GST_DTMF_SRC (basesrc);
 
-  g_async_queue_ref (dtmfsrc->event_queue);
-
- start:
-  if (dtmfsrc->last_event == NULL) {
-    GST_DEBUG_OBJECT (dtmfsrc, "popping");
-    event = g_async_queue_pop (dtmfsrc->event_queue);
-
-    GST_DEBUG_OBJECT (dtmfsrc, "popped %d", event->event_type);
-
-    if (event->event_type == DTMF_EVENT_TYPE_STOP) {
-      GST_WARNING_OBJECT (dtmfsrc,
-          "Received a DTMF stop event when already stopped");
-    } else if (event->event_type == DTMF_EVENT_TYPE_START) {
-      gst_dtmf_prepare_timestamps (dtmfsrc);
-
-      /* Don't forget to get exclusive access to the stream */
-      gst_dtmf_src_set_stream_lock (dtmfsrc, TRUE);
-
-      event->packet_count = 0;
-      dtmfsrc->last_event = event;
-    } else if (event->event_type == DTMF_EVENT_TYPE_PAUSE_TASK) {
-      /*
-       * We're pushing it back because it has to stay in there until
-       * the task is really paused (and the queue will then be flushed)
-       */
-      GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
-      g_async_queue_push (dtmfsrc->event_queue, event);
-      g_async_queue_unref (dtmfsrc->event_queue);
-    }
-  } else if (dtmfsrc->last_event->packet_count  * dtmfsrc->interval >=
-      MIN_DUTY_CYCLE) {
-    event = g_async_queue_try_pop (dtmfsrc->event_queue);
-
-    if (event != NULL) {
-      if (event->event_type == DTMF_EVENT_TYPE_START) {
-        GST_WARNING_OBJECT (dtmfsrc,
-            "Received two consecutive DTMF start events");
-      } else if (event->event_type == DTMF_EVENT_TYPE_STOP) {
-        gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
-        g_free (dtmfsrc->last_event);
-        dtmfsrc->last_event = NULL;
-        goto start;
-      } else if (event->event_type == DTMF_EVENT_TYPE_PAUSE_TASK) {
-        /*
-         * We're pushing it back because it has to stay in there until
-         * the task is really paused (and the queue will then be flushed)
-         */
-        GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
-        g_async_queue_push (dtmfsrc->event_queue, event);
-        g_async_queue_unref (dtmfsrc->event_queue);
+  do {
+
+    if (dtmfsrc->last_event == NULL) {
+      GST_DEBUG_OBJECT (dtmfsrc, "popping");
+      event = g_async_queue_pop (dtmfsrc->event_queue);
+
+      GST_DEBUG_OBJECT (dtmfsrc, "popped %d", event->event_type);
+
+      switch (event->event_type) {
+        case DTMF_EVENT_TYPE_STOP:
+          GST_WARNING_OBJECT (dtmfsrc,
+              "Received a DTMF stop event when already stopped");
+          break;
+        case DTMF_EVENT_TYPE_START:
+          gst_dtmf_prepare_timestamps (dtmfsrc);
+
+          /* Don't forget to get exclusive access to the stream */
+          gst_dtmf_src_set_stream_lock (dtmfsrc, TRUE);
+
+          event->packet_count = 0;
+          dtmfsrc->last_event = event;
+          event = NULL;
+          break;
+        case DTMF_EVENT_TYPE_PAUSE_TASK:
+          /*
+           * We're pushing it back because it has to stay in there until
+           * the task is really paused (and the queue will then be flushed)
+           */
+          GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
+          GST_OBJECT_LOCK (dtmfsrc);
+          if (dtmfsrc->paused) {
+            g_async_queue_push (dtmfsrc->event_queue, event);
+            goto paused_locked;
+          }
+          GST_OBJECT_UNLOCK (dtmfsrc);
+          break;
+      }
+      if (event)
+        g_free (event);
+    } else if (dtmfsrc->last_event->packet_count  * dtmfsrc->interval >=
+        MIN_DUTY_CYCLE) {
+      event = g_async_queue_try_pop (dtmfsrc->event_queue);
+
+      if (event != NULL) {
+
+        switch (event->event_type) {
+          case DTMF_EVENT_TYPE_START:
+            GST_WARNING_OBJECT (dtmfsrc,
+                "Received two consecutive DTMF start events");
+            break;
+          case DTMF_EVENT_TYPE_STOP:
+            gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
+
+            g_free (dtmfsrc->last_event);
+            dtmfsrc->last_event = NULL;
+            break;
+          case DTMF_EVENT_TYPE_PAUSE_TASK:
+            /*
+             * We're pushing it back because it has to stay in there until
+             * the task is really paused (and the queue will then be flushed)
+             */
+            GST_DEBUG_OBJECT (dtmfsrc, "pushing pause_task...");
+
+            GST_OBJECT_LOCK (dtmfsrc);
+            if (dtmfsrc->paused) {
+              g_async_queue_push (dtmfsrc->event_queue, event);
+              goto paused_locked;
+            }
+            GST_OBJECT_UNLOCK (dtmfsrc);
+
+            break;
+        }
+        g_free (event);
       }
     }
+  } while (dtmfsrc->last_event == NULL);
+
+  GST_DEBUG_OBJECT (dtmfsrc, "end event check, now wait for the proper time");
+
+  clock = gst_element_get_clock (GST_ELEMENT (basesrc));
+
+#ifdef MAEMO_BROKEN
+  clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp);
+#else
+  clockid = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp +
+      gst_element_get_base_time (GST_ELEMENT (dtmfsrc)));
+#endif
+  gst_object_unref (clock);
+
+  GST_OBJECT_LOCK (dtmfsrc);
+  if (!dtmfsrc->paused) {
+    dtmfsrc->clockid = clockid;
+    GST_OBJECT_UNLOCK (dtmfsrc);
+
+    clockret = gst_clock_id_wait (clockid, NULL);
+
+    GST_OBJECT_LOCK (dtmfsrc);
+    if (dtmfsrc->paused)
+      clockret = GST_CLOCK_UNSCHEDULED;
+  } else  {
+    clockret = GST_CLOCK_UNSCHEDULED;
+  }
+  gst_clock_id_unref (clockid);
+  dtmfsrc->clockid = NULL;
+  GST_OBJECT_UNLOCK (dtmfsrc);
+
+  if (clockret == GST_CLOCK_UNSCHEDULED) {
+    goto paused;
   }
-  g_async_queue_unref (dtmfsrc->event_queue);
 
-  GST_DEBUG_OBJECT (dtmfsrc, "end event check");
+  buf = gst_dtmf_src_create_next_tone_packet (dtmfsrc, dtmfsrc->last_event);
+
+  GST_DEBUG_OBJECT (dtmfsrc, "Created buffer of size %d", GST_BUFFER_SIZE (buf));
+  *buffer = buf;
+
+  GST_DEBUG_OBJECT (dtmfsrc, "returning a buffer");
+  return GST_FLOW_OK;
+
+ paused_locked:
+  GST_OBJECT_UNLOCK (dtmfsrc);
+
+ paused:
 
   if (dtmfsrc->last_event) {
-    buf = gst_dtmf_src_create_next_tone_packet (dtmfsrc, dtmfsrc->last_event);
+    GST_DEBUG_OBJECT (dtmfsrc, "Stopping current event");
+    /* Don't forget to release the stream lock */
+    gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
+    g_free (dtmfsrc->last_event);
+    dtmfsrc->last_event = NULL;
+  }
+
+  return GST_FLOW_WRONG_STATE;
+
+}
+
+static gboolean
+gst_dtmf_src_unlock (GstBaseSrc *src) {
+  GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (src);
+  GstDTMFSrcEvent *event = NULL;
+
+  GST_DEBUG_OBJECT (dtmfsrc, "Called unlock");
+
+  GST_OBJECT_LOCK (dtmfsrc);
+  dtmfsrc->paused = TRUE;
+  if (dtmfsrc->clockid) {
+    gst_clock_id_unschedule (dtmfsrc->clockid);
+  }
+  GST_OBJECT_UNLOCK (dtmfsrc);
+
+  GST_DEBUG_OBJECT (dtmfsrc, "Pushing the PAUSE_TASK event on unlock request");
+  event = g_malloc (sizeof(GstDTMFSrcEvent));
+  event->event_type = DTMF_EVENT_TYPE_PAUSE_TASK;
+  g_async_queue_push (dtmfsrc->event_queue, event);
+
+  return TRUE;
+}
+
 
-    GST_DEBUG_OBJECT (dtmfsrc, "Created buffer of size %d", GST_BUFFER_SIZE (buf));
-    *buffer = buf;
-    ret = GST_FLOW_OK;
+static gboolean
+gst_dtmf_src_unlock_stop (GstBaseSrc *src) {
+  GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (src);
+
+  GST_DEBUG_OBJECT (dtmfsrc, "Unlock stopped");
+
+  GST_OBJECT_LOCK (dtmfsrc);
+  dtmfsrc->paused = FALSE;
+  GST_OBJECT_UNLOCK (dtmfsrc);
+
+  return TRUE;
+}
+
+
+static gboolean
+gst_dtmf_src_negotiate (GstBaseSrc * basesrc)
+{
+  GstCaps *srccaps, *peercaps;
+  GstDTMFSrc *dtmfsrc = GST_DTMF_SRC (basesrc);
+  gboolean ret = FALSE;
+
+  srccaps = gst_caps_new_simple ("audio/x-raw-int",
+      "width", G_TYPE_INT, 16,
+      "depth", G_TYPE_INT, 16,
+      "endianness", G_TYPE_INT, G_BYTE_ORDER,
+      "signed", G_TYPE_BOOLEAN, TRUE,
+      "channels", G_TYPE_INT, 1,
+      NULL);
+
+  peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
+
+  if (peercaps == NULL) {
+    /* no peer caps, just add the other properties */
+    gst_caps_set_simple (srccaps,
+        "rate", G_TYPE_INT, dtmfsrc->sample_rate,
+        NULL);
   } else {
-    *buffer = NULL;
-    ret = GST_FLOW_WRONG_STATE;
+    GstStructure *s;
+    gint sample_rate;
+    GstCaps *temp = NULL;
+
+    /* peer provides caps we can use to fixate, intersect. This always returns a
+     * writable caps. */
+    temp = gst_caps_intersect (srccaps, peercaps);
+    gst_caps_unref (srccaps);
+    gst_caps_unref (peercaps);
+
+    if (!temp) {
+      GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
+      return FALSE;
+    }
+
+    if (gst_caps_is_empty (temp)) {
+      GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
+      gst_caps_unref (temp);
+      return FALSE;
+    }
+
+    /* now fixate, start by taking the first caps */
+    gst_caps_truncate (temp);
+    srccaps = temp;
+
+    /* get first structure */
+    s = gst_caps_get_structure (srccaps, 0);
+
+    if (gst_structure_get_int (s, "rate", &sample_rate))
+    {
+      dtmfsrc->sample_rate = sample_rate;
+      GST_LOG_OBJECT (dtmfsrc, "using rate from caps %d",
+          dtmfsrc->sample_rate);
+    } else {
+      GST_LOG_OBJECT (dtmfsrc, "using existing rate %d",
+          dtmfsrc->sample_rate);
+    }
+    gst_structure_set (s, "rate", G_TYPE_INT, dtmfsrc->sample_rate,
+        NULL);
   }
 
-  GST_DEBUG_OBJECT (dtmfsrc, "returning");
-  return ret;
+  ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
 
+  gst_caps_unref (srccaps);
+
+  return ret;
 }
 
 static GstStateChangeReturn
@@ -736,7 +896,6 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_READY_TO_PAUSED:
-    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       /* Flushing the event queue */
       event = g_async_queue_try_pop (dtmfsrc->event_queue);
 
@@ -744,6 +903,7 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
         g_free (event);
         event = g_async_queue_try_pop (dtmfsrc->event_queue);
       }
+      no_preroll = TRUE;
       break;
     default:
       break;
@@ -756,13 +916,10 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
 
   switch (transition) {
     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
-      if (dtmfsrc->last_event) {
-        /* Don't forget to release the stream lock */
-        gst_dtmf_src_set_stream_lock (dtmfsrc, FALSE);
-        g_free (dtmfsrc->last_event);
-        dtmfsrc->last_event = NULL;
-      }
-
+      no_preroll = TRUE;
+      break;
+    case GST_STATE_CHANGE_PAUSED_TO_READY:
+      GST_DEBUG_OBJECT (dtmfsrc, "Flushing event queue");
       /* Flushing the event queue */
       event = g_async_queue_try_pop (dtmfsrc->event_queue);
 
@@ -771,15 +928,7 @@ gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
         event = g_async_queue_try_pop (dtmfsrc->event_queue);
       }
 
-      /* Indicate that we don't do PRE_ROLL */
-      no_preroll = TRUE;
       break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      event = g_malloc (sizeof(GstDTMFSrcEvent));
-      event->event_type = DTMF_EVENT_TYPE_PAUSE_TASK;
-      g_async_queue_push (dtmfsrc->event_queue, event);
-
-      event = NULL;
     default:
       break;
   }