Index: ext/speex/gstspeexenc.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-good/ext/speex/gstspeexenc.c,v
retrieving revision 1.50
diff -u -p -r1.50 gstspeexenc.c
--- ext/speex/gstspeexenc.c	12 Oct 2006 19:02:51 -0000	1.50
+++ ext/speex/gstspeexenc.c	13 Aug 2007 21:06:33 -0000
@@ -48,7 +48,9 @@ static GstStaticPadTemplate sink_factory
 static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-speex")
+    GST_STATIC_CAPS ("audio/x-speex, "
+        "rate = (int) [ 6000, 48000 ], "
+        "channels = (int) [ 1, 2]")
     );
 
 static const GstElementDetails speexenc_details =
@@ -220,6 +222,39 @@ gst_speex_enc_sink_setcaps (GstPad * pad
   return enc->setup;
 }
 
+
+static GstCaps *
+gst_speex_enc_sink_getcaps (GstPad *pad)
+{
+  GstCaps * caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+  GstCaps * peercaps = NULL;
+  GstSpeexEnc *enc = GST_SPEEX_ENC (gst_pad_get_parent_element (pad));
+
+  peercaps = gst_pad_peer_get_caps (enc->srcpad);
+
+  if (peercaps) {
+    if (!gst_caps_is_empty (peercaps)) {
+      GstStructure * ps = gst_caps_get_structure (peercaps, 0);
+      GstStructure * s = gst_caps_get_structure (caps, 0);;
+      gint rate, channels;
+
+      if (gst_structure_get_int (ps, "rate", &rate)) {
+        gst_structure_fixate_field_nearest_int (s, "rate", rate);
+      }
+
+      if (gst_structure_get_int (ps, "channels", &channels)) {
+        gst_structure_fixate_field_nearest_int (s, "channels", channels);
+      }
+    }
+    gst_caps_unref (peercaps);
+  }
+
+  gst_object_unref (enc);
+
+  return caps;
+}
+
+
 static gboolean
 gst_speex_enc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
     GstFormat * dest_format, gint64 * dest_value)
@@ -458,6 +493,8 @@ gst_speex_enc_init (GstSpeexEnc * enc, G
       GST_DEBUG_FUNCPTR (gst_speex_enc_chain));
   gst_pad_set_setcaps_function (enc->sinkpad,
       GST_DEBUG_FUNCPTR (gst_speex_enc_sink_setcaps));
+  gst_pad_set_getcaps_function (enc->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_speex_enc_sink_getcaps));
   gst_pad_set_query_function (enc->sinkpad,
       GST_DEBUG_FUNCPTR (gst_speex_enc_sink_query));
 
@@ -781,6 +818,10 @@ gst_speex_enc_chain (GstPad * pad, GstBu
     caps = gst_pad_get_caps (enc->srcpad);
     caps = gst_speex_enc_set_header_on_caps (caps, buf1, buf2);
 
+    gst_caps_set_simple (caps,
+        "rate", G_TYPE_INT, enc->rate,
+        "channels", G_TYPE_INT, enc->channels, NULL);
+
     /* negotiate with these caps */
     GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
     gst_pad_set_caps (enc->srcpad, caps);
Index: gst/rtp/gstrtpspeexpay.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-good/gst/rtp/gstrtpspeexpay.c,v
retrieving revision 1.13
diff -u -p -r1.13 gstrtpspeexpay.c
--- gst/rtp/gstrtpspeexpay.c	5 Mar 2007 16:39:29 -0000	1.13
+++ gst/rtp/gstrtpspeexpay.c	13 Aug 2007 21:06:33 -0000
@@ -41,7 +41,9 @@ static GstStaticPadTemplate gst_rtp_spee
 GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-speex")
+    GST_STATIC_CAPS ("audio/x-speex, "
+        "rate = (int) [ 6000, 48000 ], "
+        "channels = (int) 1")
     );
 
 static GstStaticPadTemplate gst_rtp_speex_pay_src_template =
@@ -61,6 +63,8 @@ static GstStateChangeReturn gst_rtp_spee
 
 static gboolean gst_rtp_speex_pay_setcaps (GstBaseRTPPayload * payload,
     GstCaps * caps);
+static GstCaps * gst_rtp_speex_pay_getcaps (GstBaseRTPPayload * payload,
+    GstPad * pad);
 static GstFlowReturn gst_rtp_speex_pay_handle_buffer (GstBaseRTPPayload *
     payload, GstBuffer * buffer);
 
@@ -96,6 +100,7 @@ gst_rtp_speex_pay_class_init (GstRtpSPEE
   gstelement_class->change_state = gst_rtp_speex_pay_change_state;
 
   gstbasertppayload_class->set_caps = gst_rtp_speex_pay_setcaps;
+  gstbasertppayload_class->get_caps = gst_rtp_speex_pay_getcaps;
   gstbasertppayload_class->handle_buffer = gst_rtp_speex_pay_handle_buffer;
 }
 
@@ -114,6 +119,33 @@ gst_rtp_speex_pay_setcaps (GstBaseRTPPay
   return TRUE;
 }
 
+
+static GstCaps *
+gst_rtp_speex_pay_getcaps (GstBaseRTPPayload * payload, GstPad * pad)
+{
+  GstCaps * otherpadcaps;
+  GstCaps * caps;
+
+  otherpadcaps = gst_pad_get_allowed_caps(payload->srcpad);
+  caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+
+  if (otherpadcaps) {
+    if (!gst_caps_is_empty (otherpadcaps)) {
+      GstStructure * ps = gst_caps_get_structure (otherpadcaps, 0);
+      GstStructure * s = gst_caps_get_structure (caps, 0);
+      gint clock_rate;
+
+      if (gst_structure_get_int (ps, "clock-rate", &clock_rate)) {
+        gst_structure_fixate_field_nearest_int (s, "rate", clock_rate);
+      }
+    }
+
+    gst_caps_unref (otherpadcaps);
+  }
+
+  return caps;
+}
+
 static gboolean
 gst_rtp_speex_pay_parse_ident (GstRtpSPEEXPay * rtpspeexpay,
     const guint8 * data, guint size)
