Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and adds timestamps
authorMaciej Katafiasz <mathrick@mathrick.org>
Mon, 24 Jan 2005 21:57:15 +0000 (21:57 +0000)
committerMaciej Katafiasz <mathrick@mathrick.org>
Mon, 24 Jan 2005 21:57:15 +0000 (21:57 +0000)
Original commit message from CVS:
Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and
adds timestamps

ChangeLog
ext/gsm/gstgsmdec.c
ext/gsm/gstgsmdec.h
ext/gsm/gstgsmenc.c
ext/gsm/gstgsmenc.h

index 6ced994..49540c5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-01-24  Jeffrey C. Ollie
+
+       reviewed by: Maciej Katafiasz  <mathrick@freedesktop.org>
+
+       * ext/gsm/gstgsmdec.c: (gst_gsmdec_init), (gst_gsmdec_chain):
+       * ext/gsm/gstgsmdec.h:
+       * ext/gsm/gstgsmenc.c: (gst_gsmenc_init), (gst_gsmenc_chain):
+       * ext/gsm/gstgsmenc.h:
+       Fix rate to 8kHz as per spec, removes obscure errors when no rate
+       was given by property. Add proper buffer timestamps and offsets.
+
 2005-01-24  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * gst-libs/gst/riff/riff-media.c:
index 26b6d02..c44067b 100644 (file)
@@ -51,8 +51,6 @@ static void gst_gsmdec_class_init (GstGSMDec * klass);
 static void gst_gsmdec_init (GstGSMDec * gsmdec);
 
 static void gst_gsmdec_chain (GstPad * pad, GstData * _data);
-static GstCaps *gst_gsmdec_getcaps (GstPad * pad);
-static GstPadLinkReturn gst_gsmdec_link (GstPad * pad, const GstCaps * caps);
 
 static GstElementClass *parent_class = NULL;
 
@@ -86,8 +84,7 @@ static GstStaticPadTemplate gsmdec_sink_template =
 GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-gsm, "
-        "rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
+    GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
     );
 
 static GstStaticPadTemplate gsmdec_src_template =
@@ -98,8 +95,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
         "endianness = (int) BYTE_ORDER, "
         "signed = (boolean) true, "
         "width = (int) 16, "
-        "depth = (int) 16, "
-        "rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
+        "depth = (int) 16, " "rate = (int) 8000, " "channels = (int) 1")
     );
 
 static void
@@ -134,132 +130,102 @@ gst_gsmdec_init (GstGSMDec * gsmdec)
       gst_pad_new_from_template (gst_static_pad_template_get
       (&gsmdec_sink_template), "sink");
   gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
-  gst_pad_set_getcaps_function (gsmdec->sinkpad, gst_gsmdec_getcaps);
-  gst_pad_set_link_function (gsmdec->sinkpad, gst_gsmdec_link);
   gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
 
   gsmdec->srcpad =
       gst_pad_new_from_template (gst_static_pad_template_get
       (&gsmdec_src_template), "src");
-  gst_pad_set_getcaps_function (gsmdec->srcpad, gst_gsmdec_getcaps);
-  gst_pad_set_link_function (gsmdec->srcpad, gst_gsmdec_link);
   gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
 
   gsmdec->state = gsm_create ();
   gsmdec->bufsize = 0;
-}
-
-static GstCaps *
-gst_gsmdec_getcaps (GstPad * pad)
-{
-  GstGSMDec *gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
-  const GValue *rate_value;
-  GstPad *otherpad;
-  GstCaps *othercaps, *basecaps;
-
-  if (pad == gsmdec->srcpad) {
-    otherpad = gsmdec->sinkpad;
-    basecaps = gst_caps_new_simple ("audio/x-raw-int",
-        "endianness", G_TYPE_INT, G_BYTE_ORDER,
-        "signed", G_TYPE_BOOLEAN, TRUE,
-        "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
-  } else {
-    otherpad = gsmdec->srcpad;
-    basecaps = gst_caps_new_simple ("audio/x-gsm", NULL);
-  }
-
-  othercaps = gst_pad_get_allowed_caps (otherpad);
-  rate_value = gst_structure_get_value (gst_caps_get_structure (othercaps,
-          0), "rate");
-  gst_structure_set_value (gst_caps_get_structure (basecaps, 0), "rate",
-      rate_value);
-  gst_caps_set_simple (basecaps, "channels", G_TYPE_INT, 1, NULL);
-
-  return basecaps;
-}
-
-static GstPadLinkReturn
-gst_gsmdec_link (GstPad * pad, const GstCaps * caps)
-{
-  GstGSMDec *gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
-  GstPad *otherpad;
-  GstCaps *othercaps;
-  gint rate;
-  GstStructure *structure;
-
-  structure = gst_caps_get_structure (caps, 0);
-  gst_structure_get_int (structure, "rate", &rate);
-
-  if (pad == gsmdec->sinkpad) {
-    otherpad = gsmdec->srcpad;
-    othercaps = gst_caps_new_simple ("audio/x-raw-int",
-        "endianness", G_TYPE_INT, G_BYTE_ORDER,
-        "signed", G_TYPE_BOOLEAN, TRUE,
-        "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
-  } else {
-    otherpad = gsmdec->sinkpad;
-    othercaps = gst_caps_new_simple ("audio/x-gsm", NULL);
-  }
-
-  gst_caps_set_simple (othercaps,
-      "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, 1, NULL);
-
-  return gst_pad_try_set_caps (otherpad, othercaps);
+  gsmdec->next_ts = 0;
+  gsmdec->next_of = 0;
 }
 
 static void
 gst_gsmdec_chain (GstPad * pad, GstData * _data)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstGSMDec *gsmdec;
-  gsm_byte *data;
-  guint size;
 
   g_return_if_fail (pad != NULL);
   g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
-  /*g_return_if_fail(GST_IS_BUFFER(buf)); */
+  g_return_if_fail (_data != NULL);
 
   gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
 
-  data = (gsm_byte *) GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
-
-  if (gsmdec->bufsize && (gsmdec->bufsize + size >= 33)) {
-    GstBuffer *outbuf;
-
-    memcpy (gsmdec->buffer + gsmdec->bufsize, data,
-        (33 - gsmdec->bufsize) * sizeof (gsm_byte));
-
-    outbuf = gst_buffer_new ();
-    GST_BUFFER_DATA (outbuf) = g_malloc (160 * sizeof (gsm_signal));
-    GST_BUFFER_SIZE (outbuf) = 160 * sizeof (gsm_signal);
-
-    gsm_decode (gsmdec->state, gsmdec->buffer,
-        (gsm_signal *) GST_BUFFER_DATA (outbuf));
-
-    gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
-
-    size -= (33 - gsmdec->bufsize);
-    data += (33 - gsmdec->bufsize);
-    gsmdec->bufsize = 0;
-  }
-
-  while (size >= 33) {
-    GstBuffer *outbuf;
-
-    outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
-    gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf));
-    gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
-
-    size -= 33;
-    data += 33;
+  if (GST_IS_EVENT (_data)) {
+    GstEvent *event = GST_EVENT (_data);
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_EOS:{
+        gst_element_set_eos (GST_ELEMENT (gsmdec));
+        gst_pad_push (gsmdec->srcpad, _data);
+        break;
+      }
+      case GST_EVENT_DISCONTINUOUS:{
+        /* drop the discontinuity */
+        break;
+      }
+      default:{
+        gst_pad_event_default (pad, event);
+        break;
+      }
+    }
+    return;
+  } else if (GST_IS_BUFFER (_data)) {
+    GstBuffer *buf = GST_BUFFER (_data);
+    gsm_byte *data = (gsm_byte *) GST_BUFFER_DATA (buf);
+    guint size = GST_BUFFER_SIZE (buf);
+
+    if (gsmdec->bufsize && (gsmdec->bufsize + size >= 33)) {
+      GstBuffer *outbuf;
+
+      memcpy (gsmdec->buffer + gsmdec->bufsize, data,
+          (33 - gsmdec->bufsize) * sizeof (gsm_byte));
+
+      outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
+      GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->next_ts;
+      GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
+      GST_BUFFER_OFFSET (outbuf) = gsmdec->next_of;
+      GST_BUFFER_OFFSET_END (outbuf) = gsmdec->next_of + 160 - 1;
+      gsmdec->next_ts += 20 * GST_MSECOND;
+      gsmdec->next_of += 160;
+
+      gsm_decode (gsmdec->state, gsmdec->buffer,
+          (gsm_signal *) GST_BUFFER_DATA (outbuf));
+
+      gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
+
+      size -= (33 - gsmdec->bufsize);
+      data += (33 - gsmdec->bufsize);
+      gsmdec->bufsize = 0;
+    }
+
+    while (size >= 33) {
+      GstBuffer *outbuf;
+
+      outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
+      GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->next_ts;
+      GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
+      GST_BUFFER_OFFSET (outbuf) = gsmdec->next_of;
+      GST_BUFFER_OFFSET_END (outbuf) = gsmdec->next_of + 160 - 1;
+      gsmdec->next_ts += 20 * GST_MSECOND;
+      gsmdec->next_of += 160;
+
+      gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf));
+      gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
+
+      size -= 33;
+      data += 33;
+    }
+
+    if (size) {
+      memcpy (gsmdec->buffer + gsmdec->bufsize, data, size * sizeof (gsm_byte));
+      gsmdec->bufsize += size;
+    }
+
+    gst_buffer_unref (buf);
+    return;
   }
-
-  if (size) {
-    memcpy (gsmdec->buffer + gsmdec->bufsize, data, size * sizeof (gsm_byte));
-    gsmdec->bufsize += size;
-  }
-
-  gst_buffer_unref (buf);
 }
index 0544128..4de6d9b 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-
 #ifndef __GST_GSMDEC_H__
 #define __GST_GSMDEC_H__
 
-
 #include <gst/gst.h>
 
 #ifdef GSM_HEADER_IN_SUBDIR
 #include <gsm.h>
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
+G_BEGIN_DECLS
 
 #define GST_TYPE_GSMDEC \
   (gst_gsmdec_get_type())
@@ -49,27 +44,27 @@ extern "C" {
 typedef struct _GstGSMDec GstGSMDec;
 typedef struct _GstGSMDecClass GstGSMDecClass;
 
-struct _GstGSMDec {
+struct _GstGSMDec
+{
   GstElement element;
 
   /* pads */
-  GstPad *sinkpad,*srcpad;
+  GstPad *sinkpad, *srcpad;
 
   gsm state;
   gsm_byte buffer[33];
   gint bufsize;
+  GstClockTime next_ts;
+  gint64 next_of;
 };
 
-struct _GstGSMDecClass {
+struct _GstGSMDecClass
+{
   GstElementClass parent_class;
 };
 
-GType gst_gsmdec_get_type(void);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GType gst_gsmdec_get_type (void);
 
+G_END_DECLS
 
 #endif /* __GST_GSMDEC_H__ */
index 06b9b21..f15efff 100644 (file)
@@ -52,8 +52,6 @@ static void gst_gsmenc_class_init (GstGSMEnc * klass);
 static void gst_gsmenc_init (GstGSMEnc * gsmenc);
 
 static void gst_gsmenc_chain (GstPad * pad, GstData * _data);
-static GstPadLinkReturn gst_gsmenc_sinkconnect (GstPad * pad,
-    const GstCaps * caps);
 
 static GstElementClass *parent_class = NULL;
 static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 };
@@ -86,8 +84,7 @@ static GstStaticPadTemplate gsmenc_src_template =
 GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS ("audio/x-gsm, "
-        "rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
+    GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
     );
 
 static GstStaticPadTemplate gsmenc_sink_template =
@@ -98,8 +95,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
         "endianness = (int) BYTE_ORDER, "
         "signed = (boolean) true, "
         "width = (int) 16, "
-        "depth = (int) 16, "
-        "rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
+        "depth = (int) 16, " "rate = (int) 8000, " "channels = (int) 1")
     );
 
 static void
@@ -141,7 +137,6 @@ gst_gsmenc_init (GstGSMEnc * gsmenc)
       (&gsmenc_sink_template), "sink");
   gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
   gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
-  gst_pad_set_link_function (gsmenc->sinkpad, gst_gsmenc_sinkconnect);
 
   gsmenc->srcpad =
       gst_pad_new_from_template (gst_static_pad_template_get
@@ -151,89 +146,90 @@ gst_gsmenc_init (GstGSMEnc * gsmenc)
   gsmenc->state = gsm_create ();
   gsmenc->bufsize = 0;
   gsmenc->next_ts = 0;
-  gsmenc->rate = 8000;
-}
-
-static GstPadLinkReturn
-gst_gsmenc_sinkconnect (GstPad * pad, const GstCaps * caps)
-{
-  GstGSMEnc *gsmenc;
-  GstStructure *structure;
-
-  gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
-
-  structure = gst_caps_get_structure (caps, 0);
-  gst_structure_get_int (structure, "rate", &gsmenc->rate);
-  if (gst_pad_try_set_caps (gsmenc->srcpad,
-          gst_caps_new_simple ("audio/x-gsm",
-              "rate", G_TYPE_INT, gsmenc->rate,
-              "channels", G_TYPE_INT, 1, NULL)) > 0) {
-    return GST_PAD_LINK_OK;
-  }
-  return GST_PAD_LINK_REFUSED;
-
 }
 
 static void
 gst_gsmenc_chain (GstPad * pad, GstData * _data)
 {
-  GstBuffer *buf = GST_BUFFER (_data);
   GstGSMEnc *gsmenc;
-  gsm_signal *data;
-  guint size;
 
   g_return_if_fail (pad != NULL);
   g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (buf != NULL);
+  g_return_if_fail (_data != NULL);
 
   gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad));
 
-  data = (gsm_signal *) GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf) / sizeof (gsm_signal);
-
-  if (gsmenc->bufsize && (gsmenc->bufsize + size >= 160)) {
-    GstBuffer *outbuf;
-
-    memcpy (gsmenc->buffer + gsmenc->bufsize, data,
-        (160 - gsmenc->bufsize) * sizeof (gsm_signal));
-
-    outbuf = gst_buffer_new ();
-    GST_BUFFER_DATA (outbuf) = g_malloc (33 * sizeof (gsm_byte));
-    GST_BUFFER_SIZE (outbuf) = 33 * sizeof (gsm_byte);
-
-    gsm_encode (gsmenc->state, gsmenc->buffer,
-        (gsm_byte *) GST_BUFFER_DATA (outbuf));
-
-    GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
-    gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
-    gsmenc->next_ts += (160.0 / gsmenc->rate) * 1000000;
-
-    size -= (160 - gsmenc->bufsize);
-    data += (160 - gsmenc->bufsize);
-    gsmenc->bufsize = 0;
+  if (GST_IS_EVENT (_data)) {
+    GstEvent *event = GST_EVENT (_data);
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_EOS:{
+        gst_element_set_eos (GST_ELEMENT (gsmenc));
+        gst_pad_push (gsmenc->srcpad, _data);
+        break;
+      }
+      case GST_EVENT_DISCONTINUOUS:{
+        /* drop the discontinuity */
+        break;
+      }
+      default:{
+        gst_pad_event_default (pad, event);
+        break;
+      }
+    }
+    return;
+  } else if (GST_IS_BUFFER (_data)) {
+    GstBuffer *buf = GST_BUFFER (_data);
+    gsm_signal *data;
+    guint size;
+
+    data = (gsm_signal *) GST_BUFFER_DATA (buf);
+    size = GST_BUFFER_SIZE (buf) / sizeof (gsm_signal);
+
+    if (gsmenc->bufsize && (gsmenc->bufsize + size >= 160)) {
+      GstBuffer *outbuf;
+
+      memcpy (gsmenc->buffer + gsmenc->bufsize, data,
+          (160 - gsmenc->bufsize) * sizeof (gsm_signal));
+
+      outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
+      GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
+      GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
+      gsmenc->next_ts += 20 * GST_MSECOND;
+
+      gsm_encode (gsmenc->state, gsmenc->buffer,
+          (gsm_byte *) GST_BUFFER_DATA (outbuf));
+
+      gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
+
+      size -= (160 - gsmenc->bufsize);
+      data += (160 - gsmenc->bufsize);
+      gsmenc->bufsize = 0;
+    }
+
+    while (size >= 160) {
+      GstBuffer *outbuf;
+
+      outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
+      GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
+      GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
+      gsmenc->next_ts += 20 * GST_MSECOND;
+
+      gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
+
+      gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
+
+      size -= 160;
+      data += 160;
+    }
+
+    if (size) {
+      memcpy (gsmenc->buffer + gsmenc->bufsize, data,
+          size * sizeof (gsm_signal));
+      gsmenc->bufsize += size;
+    }
+
+    gst_buffer_unref (buf);
+    return;
   }
-
-  while (size >= 160) {
-    GstBuffer *outbuf;
-
-    outbuf = gst_buffer_new ();
-    GST_BUFFER_DATA (outbuf) = g_malloc (33 * sizeof (gsm_byte));
-    GST_BUFFER_SIZE (outbuf) = 33 * sizeof (gsm_byte);
-
-    gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
-
-    GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
-    gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
-    gsmenc->next_ts += (160 / gsmenc->rate) * GST_SECOND;
-
-    size -= 160;
-    data += 160;
-  }
-
-  if (size) {
-    memcpy (gsmenc->buffer + gsmenc->bufsize, data, size * sizeof (gsm_signal));
-    gsmenc->bufsize += size;
-  }
-
-  gst_buffer_unref (buf);
 }
index 2366ed6..cfc8872 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
-
 #ifndef __GST_GSMENC_H__
 #define __GST_GSMENC_H__
 
-
 #include <gst/gst.h>
 
 #ifdef GSM_HEADER_IN_SUBDIR
 #include <gsm.h>
 #endif
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
+G_BEGIN_DECLS
 
 #define GST_TYPE_GSMENC \
   (gst_gsmenc_get_type())
@@ -49,33 +44,29 @@ extern "C" {
 typedef struct _GstGSMEnc GstGSMEnc;
 typedef struct _GstGSMEncClass GstGSMEncClass;
 
-struct _GstGSMEnc {
+struct _GstGSMEnc
+{
   GstElement element;
 
   /* pads */
-  GstPad *sinkpad,*srcpad;
+  GstPad *sinkpad, *srcpad;
 
   gsm state;
   gsm_signal buffer[160];
   gint bufsize;
-
-  guint64 next_ts;
-  gint rate;
+  GstClockTime next_ts;
 };
 
-struct _GstGSMEncClass {
+struct _GstGSMEncClass
+{
   GstElementClass parent_class;
 
   /* signals */
-  void (*frame_encoded) (GstElement *element);
+  void (*frame_encoded) (GstElement * element);
 };
 
-GType gst_gsmenc_get_type(void);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GType gst_gsmenc_get_type (void);
 
+G_END_DECLS
 
 #endif /* __GST_GSMENC_H__ */