From 9d608aed4da8cf0bfc96f348c5d70f64e4b51168 Mon Sep 17 00:00:00 2001 From: Maciej Katafiasz Date: Mon, 24 Jan 2005 21:57:15 +0000 Subject: Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and adds timestamps Original commit message from CVS: Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and adds timestamps --- ChangeLog | 11 +++ ext/gsm/gstgsmdec.c | 190 +++++++++++++++++++++------------------------------- ext/gsm/gstgsmdec.h | 25 +++---- ext/gsm/gstgsmenc.c | 154 +++++++++++++++++++++--------------------- ext/gsm/gstgsmenc.h | 29 +++----- 5 files changed, 184 insertions(+), 225 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ced9945..49540c59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-01-24 Jeffrey C. Ollie + + reviewed by: Maciej Katafiasz + + * 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 * gst-libs/gst/riff/riff-media.c: 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 #ifdef GSM_HEADER_IN_SUBDIR @@ -30,10 +28,7 @@ #include #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 #ifdef GSM_HEADER_IN_SUBDIR @@ -30,10 +28,7 @@ #include #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__ */ -- cgit v1.2.1