diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/gsm/gstgsm.c | 14 | ||||
-rw-r--r-- | ext/gsm/gstgsmdec.c | 92 | ||||
-rw-r--r-- | ext/gsm/gstgsmdec.h | 10 | ||||
-rw-r--r-- | ext/gsm/gstgsmenc.c | 144 | ||||
-rw-r--r-- | ext/gsm/gstgsmenc.h | 7 |
5 files changed, 89 insertions, 178 deletions
diff --git a/ext/gsm/gstgsm.c b/ext/gsm/gstgsm.c index c71dacb0..60140716 100644 --- a/ext/gsm/gstgsm.c +++ b/ext/gsm/gstgsm.c @@ -1,5 +1,7 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> +/* + * Farsight + * GStreamer GSM encoder/decoder (uses WAV49 compiled libgsm) + * Copyright (C) 2005 Philippe Khalaf <burger@speedy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -29,14 +31,14 @@ plugin_init (GstPlugin * plugin) { if (!gst_element_register (plugin, "gsmenc", GST_RANK_NONE, GST_TYPE_GSMENC)) return FALSE; - if (!gst_element_register (plugin, "gsmdec", GST_RANK_PRIMARY, - GST_TYPE_GSMDEC)) + if (!gst_element_register (plugin, "gsmdec", GST_RANK_NONE, GST_TYPE_GSMDEC)) return FALSE; + return TRUE; } GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "gsm", - "GSM Elements Plugin", - plugin_init, VERSION, "LGPL", GST_PACKAGE, GST_ORIGIN) + "GSM encoder/decoder", + plugin_init, VERSION, "LGPL", "Farsight", "http://farsight.sf.net") diff --git a/ext/gsm/gstgsmdec.c b/ext/gsm/gstgsmdec.c index f3ce9cf5..c2ff695d 100644 --- a/ext/gsm/gstgsmdec.c +++ b/ext/gsm/gstgsmdec.c @@ -1,5 +1,7 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> +/* + * Farsight + * GStreamer GSM decoder + * Copyright (C) 2005 Philippe Khalaf <burger@speedy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,12 +27,15 @@ #include "gstgsmdec.h" +GST_DEBUG_CATEGORY (gsmdec_debug); +#define GST_CAT_DEFAULT (gsmdec_debug) + /* elementfactory information */ GstElementDetails gst_gsmdec_details = { "GSM audio decoder", "Codec/Decoder/Audio", "Decodes GSM encoded audio", - "Wim Taymans <wim.taymans@chello.be>", + "Philippe Khalaf <burger@speedy.org>", }; /* GSMDec signals and args */ @@ -42,15 +47,15 @@ enum enum { + /* FILL ME */ ARG_0 - /* FILL ME */ }; static void gst_gsmdec_base_init (gpointer g_class); static void gst_gsmdec_class_init (GstGSMDec * klass); static void gst_gsmdec_init (GstGSMDec * gsmdec); -static GstFlowReturn gst_gsmdec_chain (GstPad * pad, GstBuffer * buffer); +static GstFlowReturn gst_gsmdec_chain (GstPad * pad, GstBuffer * buf); static GstElementClass *parent_class = NULL; @@ -118,13 +123,13 @@ gst_gsmdec_class_init (GstGSMDec * klass) gstelement_class = (GstElementClass *) klass; parent_class = g_type_class_ref (GST_TYPE_ELEMENT); + + GST_DEBUG_CATEGORY_INIT (gsmdec_debug, "gsmdec", 0, "GSM Decoder"); } static void gst_gsmdec_init (GstGSMDec * gsmdec) { - GST_DEBUG ("gst_gsmdec_init: initializing"); - /* create the sink and src pads */ gsmdec->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get @@ -138,72 +143,63 @@ gst_gsmdec_init (GstGSMDec * gsmdec) gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad); gsmdec->state = gsm_create (); - gsmdec->bufsize = 0; - gsmdec->next_ts = 0; + // turn on WAN49 handling + gint use_wav49 = 0; + + gsm_option (gsmdec->state, GSM_OPT_WAV49, &use_wav49); + gsmdec->next_of = 0; + gsmdec->next_ts = 0; } static GstFlowReturn gst_gsmdec_chain (GstPad * pad, GstBuffer * buf) { GstGSMDec *gsmdec; + gsm_byte *data; + + g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); gsmdec = GST_GSMDEC (gst_pad_get_parent (pad)); + g_return_val_if_fail (GST_IS_GSMDEC (gsmdec), GST_FLOW_ERROR); - gsm_byte *data = (gsm_byte *) GST_BUFFER_DATA (buf); - guint size = GST_BUFFER_SIZE (buf); + g_return_val_if_fail (GST_PAD_IS_LINKED (gsmdec->srcpad), GST_FLOW_ERROR); - if (gsmdec->bufsize && (gsmdec->bufsize + size >= 33)) { + // do we have enough bytes to read a header + if (GST_BUFFER_SIZE (buf) >= 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; - gst_buffer_set_caps (outbuf, gst_pad_get_caps (gsmdec->srcpad)); + // TODO take new segment in consideration, if not given restart + // timestamps at 0 + if (GST_BUFFER_TIMESTAMP (buf) == GST_CLOCK_TIME_NONE) { + /* If we are not given any timestamp */ + GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->next_ts; + gsmdec->next_ts += 20 * GST_MSECOND; + } + + else { + /* But if you insist on giving us a timestamp, you are welcome. */ + GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf); + } - 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, 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; gst_buffer_set_caps (outbuf, gst_pad_get_caps (gsmdec->srcpad)); - - gsmdec->next_ts += 20 * GST_MSECOND; gsmdec->next_of += 160; + data = (gsm_byte *) GST_BUFFER_DATA (buf); gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf)); - gst_pad_push (gsmdec->srcpad, outbuf); - size -= 33; - data += 33; + GST_DEBUG ("Pushing buffer of size %d ts %" GST_TIME_FORMAT, + GST_BUFFER_SIZE (outbuf), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); + //gst_util_dump_mem (GST_BUFFER_DATA(outbuf), GST_BUFFER_SIZE (outbuf)); + gst_pad_push (gsmdec->srcpad, outbuf); } - if (size) { - memcpy (gsmdec->buffer + gsmdec->bufsize, data, size * sizeof (gsm_byte)); - gsmdec->bufsize += size; - } + gst_buffer_unref (buf); return GST_FLOW_OK; - } diff --git a/ext/gsm/gstgsmdec.h b/ext/gsm/gstgsmdec.h index 4de6d9b6..b8767c74 100644 --- a/ext/gsm/gstgsmdec.h +++ b/ext/gsm/gstgsmdec.h @@ -1,5 +1,7 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> +/* + * Farsight + * GStreamer GSM decoder (uses WAV49 compiled libgsm) + * Copyright (C) 2005 Philippe Khalaf <burger@speedy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -52,10 +54,8 @@ struct _GstGSMDec GstPad *sinkpad, *srcpad; gsm state; - gsm_byte buffer[33]; - gint bufsize; - GstClockTime next_ts; gint64 next_of; + GstClockTime next_ts; }; struct _GstGSMDecClass diff --git a/ext/gsm/gstgsmenc.c b/ext/gsm/gstgsmenc.c index 43d7f2db..c4a39e46 100644 --- a/ext/gsm/gstgsmenc.c +++ b/ext/gsm/gstgsmenc.c @@ -1,5 +1,7 @@ -/* GStreamer - * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu> +/* + * Farsight + * GStreamer GSM encoder + * Copyright (C) 2005 Philippe Khalaf <burger@speedy.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -25,26 +27,28 @@ #include "gstgsmenc.h" +GST_DEBUG_CATEGORY (gsmenc_debug); +#define GST_CAT_DEFAULT (gsmenc_debug) + /* elementfactory information */ GstElementDetails gst_gsmenc_details = { "GSM audio encoder", "Codec/Encoder/Audio", - "Encodes audio using GSM", - "Wim Taymans <wim.taymans@chello.be>", + "Encodes GSM audio", + "Philippe Khalaf <burger@speedy.org>", }; /* GSMEnc signals and args */ enum { - FRAME_ENCODED, /* FILL ME */ LAST_SIGNAL }; enum { + /* FILL ME */ ARG_0 - /* FILL ME */ }; static void gst_gsmenc_base_init (gpointer g_class); @@ -54,10 +58,6 @@ static void gst_gsmenc_init (GstGSMEnc * gsmenc); static GstFlowReturn gst_gsmenc_chain (GstPad * pad, GstBuffer * buf); static GstElementClass *parent_class = NULL; -static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 }; - -static gboolean gst_gsmenc_sink_event (GstPad * pad, GstEvent * event); - GType gst_gsmenc_get_type (void) @@ -124,13 +124,9 @@ gst_gsmenc_class_init (GstGSMEnc * klass) parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - gst_gsmenc_signals[FRAME_ENCODED] = - g_signal_new ("frame-encoded", G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstGSMEncClass, frame_encoded), NULL, - NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + GST_DEBUG_CATEGORY_INIT (gsmenc_debug, "gsmenc", 0, "GSM Encoder"); } - static void gst_gsmenc_init (GstGSMEnc * gsmenc) { @@ -140,7 +136,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_event_function (gsmenc->sinkpad, gst_gsmenc_sink_event); gsmenc->srcpad = gst_pad_new_from_template (gst_static_pad_template_get @@ -148,42 +143,14 @@ gst_gsmenc_init (GstGSMEnc * gsmenc) gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->srcpad); gsmenc->state = gsm_create (); - gsmenc->bufsize = 0; - gsmenc->next_ts = 0; - gsmenc->firstBuf = TRUE; -} - -static gboolean -gst_gsmenc_sink_event (GstPad * pad, GstEvent * event) -{ + // turn on WAN49 handling + gint use_wav49 = 0; - GstGSMEnc *gsmenc; + gsm_option (gsmenc->state, GSM_OPT_WAV49, &use_wav49); - gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad)); - gboolean ret = TRUE; - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_EOS: - { - GST_STREAM_LOCK (pad); - ret = gst_pad_push_event (gsmenc->srcpad, event); - GST_STREAM_UNLOCK (pad); - break; - } - case GST_EVENT_NEWSEGMENT: - { - /* drop the discontinuity */ - gst_event_unref (event); - break; - } - default: - { - gst_pad_event_default (pad, event); - break; - } - } - return ret; + gsmenc->adapter = gst_adapter_new (); + gsmenc->next_ts = 0; } static GstFlowReturn @@ -191,51 +158,18 @@ gst_gsmenc_chain (GstPad * pad, GstBuffer * buf) { GstGSMEnc *gsmenc; gsm_signal *data; - guint size; - GstFlowReturn ret = GST_FLOW_OK; - gsmenc = GST_GSMENC (gst_pad_get_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; + g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR); - 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_buffer_set_caps (outbuf, GST_PAD_CAPS (gsmenc->srcpad)); - - if (gsmenc->firstBuf) { - gst_pad_push_event (gsmenc->srcpad, - gst_event_new_newsegment (FALSE, 1.0, GST_FORMAT_DEFAULT, - 0, GST_CLOCK_TIME_NONE, 0)); - gsmenc->firstBuf = FALSE; - } - - ret = gst_pad_push (gsmenc->srcpad, outbuf); + gsmenc = GST_GSMENC (gst_pad_get_parent (pad)); + g_return_val_if_fail (GST_IS_GSMENC (gsmenc), GST_FLOW_ERROR); - if (ret != GST_FLOW_OK) { - gst_buffer_unref (outbuf); - goto error; - } + g_return_val_if_fail (GST_PAD_IS_LINKED (gsmenc->srcpad), GST_FLOW_ERROR); - size -= (160 - gsmenc->bufsize); - data += (160 - gsmenc->bufsize); - gsmenc->bufsize = 0; + gst_adapter_push (gsmenc->adapter, buf); - } + while (gst_adapter_available (gsmenc->adapter) >= 320) { - while (size >= 160) { GstBuffer *outbuf; outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte)); @@ -243,34 +177,16 @@ gst_gsmenc_chain (GstPad * pad, GstBuffer * buf) GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND; gsmenc->next_ts += 20 * GST_MSECOND; + // encode 160 16-bit samples into 33 bytes + data = (gsm_signal *) gst_adapter_peek (gsmenc->adapter, 320); gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf)); + gst_adapter_flush (gsmenc->adapter, 320); - gst_buffer_set_caps (outbuf, GST_PAD_CAPS (gsmenc->srcpad)); - if (gsmenc->firstBuf) { - gst_pad_push_event (gsmenc->srcpad, - gst_event_new_newsegment (FALSE, 1.0, GST_FORMAT_DEFAULT, - 0, GST_CLOCK_TIME_NONE, 0)); - gsmenc->firstBuf = FALSE; - } - ret = gst_pad_push (gsmenc->srcpad, outbuf); - - if (ret != GST_FLOW_OK) { - gst_buffer_unref (outbuf); - goto error; - } - - size -= 160; - data += 160; + gst_buffer_set_caps (outbuf, gst_pad_get_caps (gsmenc->srcpad)); + GST_DEBUG ("Pushing buffer of size %d", GST_BUFFER_SIZE (outbuf)); + //gst_util_dump_mem (GST_BUFFER_DATA(outbuf), GST_BUFFER_SIZE (outbuf)); + gst_pad_push (gsmenc->srcpad, outbuf); } - if (size) { - memcpy (gsmenc->buffer + gsmenc->bufsize, data, size * sizeof (gsm_signal)); - gsmenc->bufsize += size; - } - -error: - - gst_object_unref (gsmenc); - return ret; - + return GST_FLOW_OK; } diff --git a/ext/gsm/gstgsmenc.h b/ext/gsm/gstgsmenc.h index a5f1f87e..af30c80c 100644 --- a/ext/gsm/gstgsmenc.h +++ b/ext/gsm/gstgsmenc.h @@ -21,6 +21,7 @@ #define __GST_GSMENC_H__ #include <gst/gst.h> +#include <gst/base/gstadapter.h> #ifdef GSM_HEADER_IN_SUBDIR #include <gsm/gsm.h> @@ -50,10 +51,9 @@ struct _GstGSMEnc /* pads */ GstPad *sinkpad, *srcpad; + GstAdapter *adapter; gsm state; - gsm_signal buffer[160]; - gint bufsize; GstClockTime next_ts; gboolean firstBuf; }; @@ -61,9 +61,6 @@ struct _GstGSMEnc struct _GstGSMEncClass { GstElementClass parent_class; - - /* signals */ - void (*frame_encoded) (GstElement * element); }; GType gst_gsmenc_get_type (void); |