gst/law/: Ported alaw and mulaw plugins to 0.9, fixed the negotiation as well.
authorWim Taymans <wim.taymans@gmail.com>
Fri, 6 May 2005 14:08:56 +0000 (14:08 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Fri, 6 May 2005 14:08:56 +0000 (14:08 +0000)
Original commit message from CVS:
* gst/law/alaw-decode.c: (alawdec_getcaps), (alawdec_setcaps),
(gst_alawdec_init), (gst_alawdec_chain):
* gst/law/alaw-encode.c: (alawenc_getcaps), (alawenc_setcaps),
(gst_alawenc_init), (gst_alawenc_chain):
* gst/law/mulaw-decode.c: (mulawdec_getcaps), (mulawdec_setcaps),
(gst_mulawdec_init), (gst_mulawdec_chain):
* gst/law/mulaw-encode.c: (mulawenc_getcaps), (mulawenc_setcaps),
(gst_mulawenc_init), (gst_mulawenc_chain):
Ported alaw and mulaw plugins to 0.9, fixed the negotiation as
well.

ChangeLog
gst/law/alaw-decode.c
gst/law/alaw-encode.c
gst/law/mulaw-decode.c
gst/law/mulaw-encode.c

index 70bae26..29f28f4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2005-05-06  Wim Taymans  <wim@fluendo.com>
+
+       * gst/law/alaw-decode.c: (alawdec_getcaps), (alawdec_setcaps),
+       (gst_alawdec_init), (gst_alawdec_chain):
+       * gst/law/alaw-encode.c: (alawenc_getcaps), (alawenc_setcaps),
+       (gst_alawenc_init), (gst_alawenc_chain):
+       * gst/law/mulaw-decode.c: (mulawdec_getcaps), (mulawdec_setcaps),
+       (gst_mulawdec_init), (gst_mulawdec_chain):
+       * gst/law/mulaw-encode.c: (mulawenc_getcaps), (mulawenc_setcaps),
+       (gst_mulawenc_init), (gst_mulawenc_chain):
+       Ported alaw and mulaw plugins to 0.9, fixed the negotiation as
+       well.
+
 2005-05-06  Christian Schaller  <uraeus@gnome.org>
 
        * ext/alsa: removed plugins that are now in gst-plugins-base
index 44a6cb8..7cf7a37 100644 (file)
@@ -43,7 +43,7 @@ static void gst_alawdec_class_init (GstALawDecClass * klass);
 static void gst_alawdec_base_init (GstALawDecClass * klass);
 static void gst_alawdec_init (GstALawDec * alawdec);
 
-static void gst_alawdec_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_alawdec_chain (GstPad * pad, GstBuffer * buffer);
 
 static GstElementClass *parent_class = NULL;
 
@@ -74,78 +74,92 @@ alaw_to_s16 (guint8 a_val)
 static GstCaps *
 alawdec_getcaps (GstPad * pad)
 {
-  GstALawDec *alawdec = GST_ALAWDEC (gst_pad_get_parent (pad));
+  GstALawDec *alawdec;
   GstPad *otherpad;
   GstCaps *base_caps, *othercaps;
-  GstStructure *structure;
-  const GValue *rate, *chans;
+
+  alawdec = GST_ALAWDEC (GST_PAD_PARENT (pad));
+
+  /*  we can do what our template says */
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
 
   if (pad == alawdec->sinkpad) {
     otherpad = alawdec->srcpad;
-    base_caps = gst_caps_new_simple ("audio/x-alaw", NULL);
   } else {
     otherpad = alawdec->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-raw-int",
-        "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
-        "signed", G_TYPE_BOOLEAN, TRUE,
-        "endianness", G_TYPE_INT, G_BYTE_ORDER,
-        "signed", G_TYPE_BOOLEAN, TRUE, NULL);
   }
-  othercaps = gst_pad_get_allowed_caps (otherpad);
-
-  /* Not fully correct, but usually, all structures in a caps have
-   * the same samplerate and channels range. */
-  structure = gst_caps_get_structure (othercaps, 0);
-  rate = gst_structure_get_value (structure, "rate");
-  chans = gst_structure_get_value (structure, "channels");
-  if (!rate || !chans)
-    return gst_caps_new_empty ();
-
-  /* Set the samplerate/channels on the to-be-returned caps */
-  structure = gst_caps_get_structure (base_caps, 0);
-  gst_structure_set_value (structure, "rate", rate);
-  gst_structure_set_value (structure, "channels", chans);
-  gst_caps_free (othercaps);
+  /* now intersect rate and channels from peer caps */
+  othercaps = gst_pad_peer_get_caps (otherpad);
+  if (othercaps) {
+    GstStructure *structure;
+    const GValue *orate, *ochans;
+    const GValue *rate, *chans;
+    GValue irate = { 0 }, ichans = {
+    0};
+
+    structure = gst_caps_get_structure (othercaps, 0);
+    orate = gst_structure_get_value (structure, "rate");
+    ochans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    structure = gst_caps_get_structure (base_caps, 0);
+    rate = gst_structure_get_value (structure, "rate");
+    chans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    gst_value_intersect (&irate, orate, rate);
+    gst_value_intersect (&ichans, ochans, chans);
+
+    /* Set the samplerate/channels on the to-be-returned caps */
+    structure = gst_caps_get_structure (base_caps, 0);
+    gst_structure_set_value (structure, "rate", &irate);
+    gst_structure_set_value (structure, "channels", &ichans);
+
+    gst_caps_unref (othercaps);
+  }
 
+done:
   return base_caps;
 }
 
-static GstPadLinkReturn
-alawdec_link (GstPad * pad, const GstCaps * caps)
+static gboolean
+alawdec_setcaps (GstPad * pad, GstCaps * caps)
 {
-  GstALawDec *alawdec = GST_ALAWDEC (gst_pad_get_parent (pad));
+  GstALawDec *alawdec;
   GstPad *otherpad;
   GstStructure *structure;
   const GValue *rate, *chans;
   GstCaps *base_caps;
-  GstPadLinkReturn link_return;
 
+  alawdec = GST_ALAWDEC (GST_PAD_PARENT (pad));
+
+  /* take rate and channels */
   structure = gst_caps_get_structure (caps, 0);
   rate = gst_structure_get_value (structure, "rate");
   chans = gst_structure_get_value (structure, "channels");
   if (!rate || !chans)
-    return GST_PAD_LINK_REFUSED;
+    return FALSE;
 
   if (pad == alawdec->srcpad) {
     otherpad = alawdec->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-alaw", NULL);
   } else {
     otherpad = alawdec->srcpad;
-    base_caps = 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, NULL);
   }
 
+  /* fill in values for otherpad */
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
   structure = gst_caps_get_structure (base_caps, 0);
   gst_structure_set_value (structure, "rate", rate);
   gst_structure_set_value (structure, "channels", chans);
 
-  link_return = gst_pad_try_set_caps (otherpad, base_caps);
+  /* and set on otherpad */
+  gst_pad_set_caps (otherpad, base_caps);
 
-  gst_caps_free (base_caps);
+  gst_caps_unref (base_caps);
 
-  return link_return;
+  return TRUE;
 }
 
 GType
@@ -199,47 +213,41 @@ static void
 gst_alawdec_init (GstALawDec * alawdec)
 {
   alawdec->sinkpad = gst_pad_new_from_template (alawdec_sink_template, "sink");
-  gst_pad_set_link_function (alawdec->sinkpad, alawdec_link);
+  gst_pad_set_setcaps_function (alawdec->sinkpad, alawdec_setcaps);
   gst_pad_set_getcaps_function (alawdec->sinkpad, alawdec_getcaps);
   gst_pad_set_chain_function (alawdec->sinkpad, gst_alawdec_chain);
   gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->sinkpad);
 
   alawdec->srcpad = gst_pad_new_from_template (alawdec_src_template, "src");
-  gst_pad_set_link_function (alawdec->srcpad, alawdec_link);
+  gst_pad_set_setcaps_function (alawdec->srcpad, alawdec_setcaps);
   gst_pad_set_getcaps_function (alawdec->srcpad, alawdec_getcaps);
   gst_element_add_pad (GST_ELEMENT (alawdec), alawdec->srcpad);
 }
 
-static void
-gst_alawdec_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_alawdec_chain (GstPad * pad, GstBuffer * buffer)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstALawDec *alawdec;
   gint16 *linear_data;
   guint8 *alaw_data;
   GstBuffer *outbuf;
   gint i;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
   alawdec = GST_ALAWDEC (GST_OBJECT_PARENT (pad));
-  g_return_if_fail (alawdec != NULL);
-  g_return_if_fail (GST_IS_ALAWDEC (alawdec));
 
-  alaw_data = (guint8 *) GST_BUFFER_DATA (buf);
-  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) * 2);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+  alaw_data = (guint8 *) GST_BUFFER_DATA (buffer);
+  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) * 2);
+  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
+  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (alawdec->srcpad));
   linear_data = (gint16 *) GST_BUFFER_DATA (outbuf);
 
-  for (i = 0; i < GST_BUFFER_SIZE (buf); i++) {
+  for (i = 0; i < GST_BUFFER_SIZE (buffer); i++) {
     *linear_data = alaw_to_s16 (*alaw_data);
     linear_data++;
     alaw_data++;
   }
 
-  gst_buffer_unref (buf);
-  gst_pad_push (alawdec->srcpad, GST_DATA (outbuf));
+  gst_buffer_unref (buffer);
+  return gst_pad_push (alawdec->srcpad, outbuf);
 }
index b4cd643..e7bf33e 100644 (file)
@@ -43,7 +43,7 @@ static void gst_alawenc_class_init (GstALawEncClass * klass);
 static void gst_alawenc_base_init (GstALawEncClass * klass);
 static void gst_alawenc_init (GstALawEnc * alawenc);
 
-static void gst_alawenc_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_alawenc_chain (GstPad * pad, GstBuffer * buffer);
 
 /*
  * s16_to_alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
@@ -117,77 +117,89 @@ static GstElementClass *parent_class = NULL;
 static GstCaps *
 alawenc_getcaps (GstPad * pad)
 {
-  GstALawEnc *alawenc = GST_ALAWENC (gst_pad_get_parent (pad));
+  GstALawEnc *alawenc;
   GstPad *otherpad;
-  GstCaps *base_caps, *othercaps;
+  GstCaps *base_caps, *othercaps, *result;
   GstStructure *structure;
   const GValue *rate, *chans;
 
+  alawenc = GST_ALAWENC (GST_PAD_PARENT (pad));
+
+  /* we can do what our template says */
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+
   if (pad == alawenc->srcpad) {
     otherpad = alawenc->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-alaw", NULL);
   } else {
     otherpad = alawenc->srcpad;
-    base_caps = 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, NULL);
   }
-  othercaps = gst_pad_get_allowed_caps (otherpad);
-
-  /* Not fully correct, but usually, all structures in a caps have
-   * the same samplerate and channels range. */
-  structure = gst_caps_get_structure (othercaps, 0);
-  rate = gst_structure_get_value (structure, "rate");
-  chans = gst_structure_get_value (structure, "channels");
-  if (!rate || !chans)
-    return gst_caps_new_empty ();
-
-  /* Set the samplerate/channels on the to-be-returned caps */
-  structure = gst_caps_get_structure (base_caps, 0);
-  gst_structure_set_value (structure, "rate", rate);
-  gst_structure_set_value (structure, "channels", chans);
-  gst_caps_free (othercaps);
-
+  othercaps = gst_pad_peer_get_caps (otherpad);
+  if (othercaps) {
+    GstStructure *structure;
+    const GValue *orate, *ochans;
+    const GValue *rate, *chans;
+    GValue irate = { 0 }, ichans = {
+    0};
+
+    structure = gst_caps_get_structure (othercaps, 0);
+    orate = gst_structure_get_value (structure, "rate");
+    ochans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    structure = gst_caps_get_structure (base_caps, 0);
+    rate = gst_structure_get_value (structure, "rate");
+    chans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    gst_value_intersect (&irate, orate, rate);
+    gst_value_intersect (&ichans, ochans, chans);
+
+    /* Set the samplerate/channels on the to-be-returned caps */
+    structure = gst_caps_get_structure (base_caps, 0);
+    gst_structure_set_value (structure, "rate", &irate);
+    gst_structure_set_value (structure, "channels", &ichans);
+
+    gst_caps_unref (othercaps);
+  }
+done:
   return base_caps;
 }
 
-static GstPadLinkReturn
-alawenc_link (GstPad * pad, const GstCaps * caps)
+static gboolean
+alawenc_setcaps (GstPad * pad, GstCaps * caps)
 {
-  GstALawEnc *alawenc = GST_ALAWENC (gst_pad_get_parent (pad));
+  GstALawEnc *alawenc;
   GstPad *otherpad;
   GstStructure *structure;
   const GValue *rate, *chans;
   GstCaps *base_caps;
-  GstPadLinkReturn link_return;
+
+  alawenc = GST_ALAWENC (GST_PAD_PARENT (pad));
 
   structure = gst_caps_get_structure (caps, 0);
   rate = gst_structure_get_value (structure, "rate");
   chans = gst_structure_get_value (structure, "channels");
   if (!rate || !chans)
-    return GST_PAD_LINK_REFUSED;
+    return FALSE;
 
   if (pad == alawenc->sinkpad) {
     otherpad = alawenc->srcpad;
-    base_caps = gst_caps_new_simple ("audio/x-alaw", NULL);
   } else {
     otherpad = alawenc->sinkpad;
-    base_caps = 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, NULL);
   }
 
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
   structure = gst_caps_get_structure (base_caps, 0);
   gst_structure_set_value (structure, "rate", rate);
   gst_structure_set_value (structure, "channels", chans);
 
-  link_return = gst_pad_try_set_caps (otherpad, base_caps);
+  gst_pad_set_caps (otherpad, base_caps);
 
-  gst_caps_free (base_caps);
+  gst_caps_unref (base_caps);
 
-  return link_return;
+  return TRUE;
 }
 
 GType
@@ -241,39 +253,33 @@ static void
 gst_alawenc_init (GstALawEnc * alawenc)
 {
   alawenc->sinkpad = gst_pad_new_from_template (alawenc_sink_template, "sink");
-  gst_pad_set_link_function (alawenc->sinkpad, alawenc_link);
+  gst_pad_set_setcaps_function (alawenc->sinkpad, alawenc_setcaps);
   gst_pad_set_getcaps_function (alawenc->sinkpad, alawenc_getcaps);
   gst_pad_set_chain_function (alawenc->sinkpad, gst_alawenc_chain);
   gst_element_add_pad (GST_ELEMENT (alawenc), alawenc->sinkpad);
 
   alawenc->srcpad = gst_pad_new_from_template (alawenc_src_template, "src");
-  gst_pad_set_link_function (alawenc->srcpad, alawenc_link);
+  gst_pad_set_setcaps_function (alawenc->srcpad, alawenc_setcaps);
   gst_pad_set_getcaps_function (alawenc->srcpad, alawenc_getcaps);
   gst_element_add_pad (GST_ELEMENT (alawenc), alawenc->srcpad);
 }
 
-static void
-gst_alawenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_alawenc_chain (GstPad * pad, GstBuffer * buffer)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstALawEnc *alawenc;
   gint16 *linear_data;
   guint8 *alaw_data;
   GstBuffer *outbuf;
   gint i;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
   alawenc = GST_ALAWENC (GST_OBJECT_PARENT (pad));
-  g_return_if_fail (alawenc != NULL);
-  g_return_if_fail (GST_IS_ALAWENC (alawenc));
 
-  linear_data = (gint16 *) GST_BUFFER_DATA (buf);
-  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) / 2);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+  linear_data = (gint16 *) GST_BUFFER_DATA (buffer);
+  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) / 2);
+  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
+  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (alawenc->srcpad));
   alaw_data = (guint8 *) GST_BUFFER_DATA (outbuf);
 
   for (i = 0; i < GST_BUFFER_SIZE (outbuf); i++) {
@@ -282,6 +288,7 @@ gst_alawenc_chain (GstPad * pad, GstData * _data)
     linear_data++;
   }
 
-  gst_buffer_unref (buf);
-  gst_pad_push (alawenc->srcpad, GST_DATA (outbuf));
+  gst_buffer_unref (buffer);
+
+  return gst_pad_push (alawenc->srcpad, outbuf);
 }
index 35c365f..23df98e 100644 (file)
@@ -42,7 +42,7 @@ static void gst_mulawdec_class_init (GstMuLawDecClass * klass);
 static void gst_mulawdec_base_init (GstMuLawDecClass * klass);
 static void gst_mulawdec_init (GstMuLawDec * mulawdec);
 
-static void gst_mulawdec_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer);
 
 static GstElementClass *parent_class = NULL;
 
@@ -51,80 +51,85 @@ static GstElementClass *parent_class = NULL;
 static GstCaps *
 mulawdec_getcaps (GstPad * pad)
 {
-  GstMuLawDec *mulawdec = GST_MULAWDEC (gst_pad_get_parent (pad));
+  GstMuLawDec *mulawdec;
   GstPad *otherpad;
   GstCaps *base_caps, *othercaps;
-  GstStructure *structure;
-  const GValue *rate, *chans;
+
+  mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
+
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
 
   if (pad == mulawdec->sinkpad) {
     otherpad = mulawdec->srcpad;
-    base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
   } else {
     otherpad = mulawdec->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-raw-int",
-        "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16,
-        "signed", G_TYPE_BOOLEAN, TRUE,
-        "endianness", G_TYPE_INT, G_BYTE_ORDER,
-        "signed", G_TYPE_BOOLEAN, TRUE, NULL);
   }
-  othercaps = gst_pad_get_allowed_caps (otherpad);
-
-  /* Not fully correct, but usually, all structures in a caps have
-   * the same samplerate and channels range. */
-  structure = gst_caps_get_structure (othercaps, 0);
-  rate = gst_structure_get_value (structure, "rate");
-  chans = gst_structure_get_value (structure, "channels");
-  if (!rate || !chans)
-    return gst_caps_new_empty ();
-
-  /* Set the samplerate/channels on the to-be-returned caps */
-  structure = gst_caps_get_structure (base_caps, 0);
-  gst_structure_set_value (structure, "rate", rate);
-  gst_structure_set_value (structure, "channels", chans);
-  gst_caps_free (othercaps);
-
+  othercaps = gst_pad_peer_get_caps (otherpad);
+  if (othercaps) {
+    GstStructure *structure;
+    const GValue *orate, *ochans;
+    const GValue *rate, *chans;
+    GValue irate = { 0 }, ichans = {
+    0};
+
+    structure = gst_caps_get_structure (othercaps, 0);
+    orate = gst_structure_get_value (structure, "rate");
+    ochans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    structure = gst_caps_get_structure (base_caps, 0);
+    rate = gst_structure_get_value (structure, "rate");
+    chans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    gst_value_intersect (&irate, orate, rate);
+    gst_value_intersect (&ichans, ochans, chans);
+
+    /* Set the samplerate/channels on the to-be-returned caps */
+    structure = gst_caps_get_structure (base_caps, 0);
+    gst_structure_set_value (structure, "rate", &irate);
+    gst_structure_set_value (structure, "channels", &ichans);
+
+    gst_caps_unref (othercaps);
+  }
+done:
   return base_caps;
 }
 
-static GstPadLinkReturn
-mulawdec_link (GstPad * pad, const GstCaps * caps)
+static gboolean
+mulawdec_setcaps (GstPad * pad, GstCaps * caps)
 {
-  GstMuLawDec *mulawdec = GST_MULAWDEC (gst_pad_get_parent (pad));
+  GstMuLawDec *mulawdec;
   GstPad *otherpad;
   GstStructure *structure;
   const GValue *rate, *chans;
   GstCaps *base_caps;
-  GstPadLinkReturn link_return;
 
+  mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad));
 
   structure = gst_caps_get_structure (caps, 0);
   rate = gst_structure_get_value (structure, "rate");
   chans = gst_structure_get_value (structure, "channels");
   if (!rate || !chans)
-    return GST_PAD_LINK_REFUSED;
+    return FALSE;
 
   if (pad == mulawdec->srcpad) {
     otherpad = mulawdec->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
   } else {
     otherpad = mulawdec->srcpad;
-    base_caps = 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, NULL);
   }
 
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
   structure = gst_caps_get_structure (base_caps, 0);
   gst_structure_set_value (structure, "rate", rate);
   gst_structure_set_value (structure, "channels", chans);
 
-  link_return = gst_pad_try_set_caps (otherpad, base_caps);
-
-  gst_caps_free (base_caps);
-
-  return link_return;
+  gst_pad_set_caps (otherpad, base_caps);
+  gst_caps_unref (base_caps);
 
+  return TRUE;
 }
 
 GType
@@ -179,42 +184,37 @@ gst_mulawdec_init (GstMuLawDec * mulawdec)
 {
   mulawdec->sinkpad =
       gst_pad_new_from_template (mulawdec_sink_template, "sink");
-  gst_pad_set_link_function (mulawdec->sinkpad, mulawdec_link);
+  gst_pad_set_setcaps_function (mulawdec->sinkpad, mulawdec_setcaps);
   gst_pad_set_getcaps_function (mulawdec->sinkpad, mulawdec_getcaps);
   gst_pad_set_chain_function (mulawdec->sinkpad, gst_mulawdec_chain);
   gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->sinkpad);
 
   mulawdec->srcpad = gst_pad_new_from_template (mulawdec_src_template, "src");
-  gst_pad_set_link_function (mulawdec->srcpad, mulawdec_link);
+  gst_pad_set_setcaps_function (mulawdec->srcpad, mulawdec_setcaps);
   gst_pad_set_getcaps_function (mulawdec->srcpad, mulawdec_getcaps);
   gst_element_add_pad (GST_ELEMENT (mulawdec), mulawdec->srcpad);
 }
 
-static void
-gst_mulawdec_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstMuLawDec *mulawdec;
   gint16 *linear_data;
   guint8 *mulaw_data;
   GstBuffer *outbuf;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
   mulawdec = GST_MULAWDEC (GST_OBJECT_PARENT (pad));
-  g_return_if_fail (mulawdec != NULL);
-  g_return_if_fail (GST_IS_MULAWDEC (mulawdec));
 
-  mulaw_data = (guint8 *) GST_BUFFER_DATA (buf);
-  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) * 2);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+  mulaw_data = (guint8 *) GST_BUFFER_DATA (buffer);
+  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) * 2);
+  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
+  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawdec->srcpad));
   linear_data = (gint16 *) GST_BUFFER_DATA (outbuf);
 
-  mulaw_decode (mulaw_data, linear_data, GST_BUFFER_SIZE (buf));
+  mulaw_decode (mulaw_data, linear_data, GST_BUFFER_SIZE (buffer));
+
+  gst_buffer_unref (buffer);
 
-  gst_buffer_unref (buf);
-  gst_pad_push (mulawdec->srcpad, GST_DATA (outbuf));
+  return gst_pad_push (mulawdec->srcpad, outbuf);
 }
index 305165b..4a2576a 100644 (file)
@@ -42,7 +42,7 @@ static void gst_mulawenc_class_init (GstMuLawEncClass * klass);
 static void gst_mulawenc_base_init (GstMuLawEncClass * klass);
 static void gst_mulawenc_init (GstMuLawEnc * mulawenc);
 
-static void gst_mulawenc_chain (GstPad * pad, GstData * _data);
+static GstFlowReturn gst_mulawenc_chain (GstPad * pad, GstBuffer * buffer);
 
 static GstElementClass *parent_class = NULL;
 
@@ -51,77 +51,85 @@ static GstElementClass *parent_class = NULL;
 static GstCaps *
 mulawenc_getcaps (GstPad * pad)
 {
-  GstMuLawEnc *mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
+  GstMuLawEnc *mulawenc;
   GstPad *otherpad;
   GstCaps *base_caps, *othercaps;
-  GstStructure *structure;
-  const GValue *rate, *chans;
+
+  mulawenc = GST_MULAWENC (GST_PAD_PARENT (pad));
+
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
 
   if (pad == mulawenc->srcpad) {
     otherpad = mulawenc->sinkpad;
-    base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
   } else {
     otherpad = mulawenc->srcpad;
-    base_caps = 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, NULL);
   }
-  othercaps = gst_pad_get_allowed_caps (otherpad);
-
-  /* Not fully correct, but usually, all structures in a caps have
-   * the same samplerate and channels range. */
-  structure = gst_caps_get_structure (othercaps, 0);
-  rate = gst_structure_get_value (structure, "rate");
-  chans = gst_structure_get_value (structure, "channels");
-  if (!rate || !chans)
-    return gst_caps_new_empty ();
-
-  /* Set the samplerate/channels on the to-be-returned caps */
-  structure = gst_caps_get_structure (base_caps, 0);
-  gst_structure_set_value (structure, "rate", rate);
-  gst_structure_set_value (structure, "channels", chans);
-  gst_caps_free (othercaps);
-
+  othercaps = gst_pad_peer_get_caps (otherpad);
+  if (othercaps) {
+    GstStructure *structure;
+    const GValue *orate, *ochans;
+    const GValue *rate, *chans;
+    GValue irate = { 0 }, ichans = {
+    0};
+
+    structure = gst_caps_get_structure (othercaps, 0);
+    orate = gst_structure_get_value (structure, "rate");
+    ochans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    structure = gst_caps_get_structure (base_caps, 0);
+    rate = gst_structure_get_value (structure, "rate");
+    chans = gst_structure_get_value (structure, "channels");
+    if (!rate || !chans)
+      goto done;
+
+    gst_value_intersect (&irate, orate, rate);
+    gst_value_intersect (&ichans, ochans, chans);
+
+    /* Set the samplerate/channels on the to-be-returned caps */
+    structure = gst_caps_get_structure (base_caps, 0);
+    gst_structure_set_value (structure, "rate", &irate);
+    gst_structure_set_value (structure, "channels", &ichans);
+
+    gst_caps_unref (othercaps);
+  }
+done:
   return base_caps;
 }
 
-static GstPadLinkReturn
-mulawenc_link (GstPad * pad, const GstCaps * caps)
+static gboolean
+mulawenc_setcaps (GstPad * pad, GstCaps * caps)
 {
-  GstMuLawEnc *mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
+  GstMuLawEnc *mulawenc;
   GstPad *otherpad;
   GstStructure *structure;
   const GValue *rate, *chans;
   GstCaps *base_caps;
-  GstPadLinkReturn link_return;
+
+  mulawenc = GST_MULAWENC (gst_pad_get_parent (pad));
 
   structure = gst_caps_get_structure (caps, 0);
   rate = gst_structure_get_value (structure, "rate");
   chans = gst_structure_get_value (structure, "channels");
   if (!rate || !chans)
-    return GST_PAD_LINK_REFUSED;
+    return FALSE;
 
   if (pad == mulawenc->sinkpad) {
     otherpad = mulawenc->srcpad;
-    base_caps = gst_caps_new_simple ("audio/x-mulaw", NULL);
   } else {
     otherpad = mulawenc->sinkpad;
-    base_caps = 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, NULL);
   }
+  base_caps = gst_caps_copy (gst_pad_get_pad_template_caps (otherpad));
 
   structure = gst_caps_get_structure (base_caps, 0);
   gst_structure_set_value (structure, "rate", rate);
   gst_structure_set_value (structure, "channels", chans);
 
-  link_return = gst_pad_try_set_caps (otherpad, base_caps);
+  gst_pad_set_caps (otherpad, base_caps);
+  gst_caps_unref (base_caps);
 
-  gst_caps_free (base_caps);
-
-  return link_return;
+  return TRUE;
 }
 
 GType
@@ -176,41 +184,37 @@ gst_mulawenc_init (GstMuLawEnc * mulawenc)
 {
   mulawenc->sinkpad =
       gst_pad_new_from_template (mulawenc_sink_template, "sink");
-  gst_pad_set_link_function (mulawenc->sinkpad, mulawenc_link);
+  gst_pad_set_setcaps_function (mulawenc->sinkpad, mulawenc_setcaps);
   gst_pad_set_getcaps_function (mulawenc->sinkpad, mulawenc_getcaps);
   gst_pad_set_chain_function (mulawenc->sinkpad, gst_mulawenc_chain);
   gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->sinkpad);
 
   mulawenc->srcpad = gst_pad_new_from_template (mulawenc_src_template, "src");
-  gst_pad_set_link_function (mulawenc->srcpad, mulawenc_link);
+  gst_pad_set_setcaps_function (mulawenc->srcpad, mulawenc_setcaps);
   gst_pad_set_getcaps_function (mulawenc->srcpad, mulawenc_getcaps);
   gst_element_add_pad (GST_ELEMENT (mulawenc), mulawenc->srcpad);
 }
 
-static void
-gst_mulawenc_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_mulawenc_chain (GstPad * pad, GstBuffer * buffer)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstMuLawEnc *mulawenc;
   gint16 *linear_data;
   guint8 *mulaw_data;
   GstBuffer *outbuf;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-
   mulawenc = GST_MULAWENC (GST_OBJECT_PARENT (pad));
-  g_return_if_fail (mulawenc != NULL);
-  g_return_if_fail (GST_IS_MULAWENC (mulawenc));
 
-  linear_data = (gint16 *) GST_BUFFER_DATA (buf);
-  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buf) / 2);
-  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
-  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);
+  linear_data = (gint16 *) GST_BUFFER_DATA (buffer);
+  outbuf = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (buffer) / 2);
+  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer);
+  GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer);
+  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawenc->srcpad));
   mulaw_data = (gint8 *) GST_BUFFER_DATA (outbuf);
+
   mulaw_encode (linear_data, mulaw_data, GST_BUFFER_SIZE (outbuf));
 
-  gst_buffer_unref (buf);
-  gst_pad_push (mulawenc->srcpad, GST_DATA (outbuf));
+  gst_buffer_unref (buffer);
+
+  return gst_pad_push (mulawenc->srcpad, outbuf);
 }