[MOVED FROM GST-P-FARSIGHT] Do wierd casting of the volume to make MSVC happy
[platform/upstream/gstreamer.git] / gst / dtmf / gstdtmfsrc.c
index 55c1a4a..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 named events.
+ * 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>
@@ -251,6 +253,7 @@ static void gst_dtmf_src_add_stop_event (GstDTMFSrc *dtmfsrc);
 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)
@@ -300,7 +303,8 @@ gst_dtmf_src_class_init (GstDTMFSrcClass * klass)
       GST_DEBUG_FUNCPTR (gst_dtmf_src_handle_event);
   gstbasesrc_class->create =
       GST_DEBUG_FUNCPTR (gst_dtmf_src_create);
-
+  gstbasesrc_class->negotiate =
+      GST_DEBUG_FUNCPTR (gst_dtmf_src_negotiate);
 }
 
 
@@ -809,6 +813,77 @@ gst_dtmf_src_unlock_stop (GstBaseSrc *src) {
 }
 
 
+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 {
+    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);
+  }
+
+  ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
+
+  gst_caps_unref (srccaps);
+
+  return ret;
+}
+
 static GstStateChangeReturn
 gst_dtmf_src_change_state (GstElement * element, GstStateChange transition)
 {