summaryrefslogtreecommitdiffstats
path: root/ext/gsm
diff options
context:
space:
mode:
Diffstat (limited to 'ext/gsm')
-rw-r--r--ext/gsm/gstgsmdec.c190
-rw-r--r--ext/gsm/gstgsmdec.h25
-rw-r--r--ext/gsm/gstgsmenc.c154
-rw-r--r--ext/gsm/gstgsmenc.h29
4 files changed, 173 insertions, 225 deletions
diff --git a/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c
index 26b6d02c..c44067b3 100644
--- a/ext/gsm/gstgsmdec.c
+++ b/ext/gsm/gstgsmdec.c
@@ -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);
}
diff --git a/ext/gsm/gstgsmdec.h b/ext/gsm/gstgsmdec.h
index 0544128b..4de6d9b6 100644
--- a/ext/gsm/gstgsmdec.h
+++ b/ext/gsm/gstgsmdec.h
@@ -17,11 +17,9 @@
* Boston, MA 02111-1307, USA.
*/
-
#ifndef __GST_GSMDEC_H__
#define __GST_GSMDEC_H__
-
#include <gst/gst.h>
#ifdef GSM_HEADER_IN_SUBDIR
@@ -30,10 +28,7 @@
#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__ */
diff --git a/ext/gsm/gstgsmenc.c b/ext/gsm/gstgsmenc.c
index 06b9b212..f15efffb 100644
--- a/ext/gsm/gstgsmenc.c
+++ b/ext/gsm/gstgsmenc.c
@@ -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);
}
diff --git a/ext/gsm/gstgsmenc.h b/ext/gsm/gstgsmenc.h
index 2366ed69..cfc88722 100644
--- a/ext/gsm/gstgsmenc.h
+++ b/ext/gsm/gstgsmenc.h
@@ -17,11 +17,9 @@
* Boston, MA 02111-1307, USA.
*/
-
#ifndef __GST_GSMENC_H__
#define __GST_GSMENC_H__
-
#include <gst/gst.h>
#ifdef GSM_HEADER_IN_SUBDIR
@@ -30,10 +28,7 @@
#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__ */