diff options
-rw-r--r-- | gst/siren/gstsirenenc.c | 214 | ||||
-rw-r--r-- | gst/siren/gstsirenenc.h | 15 |
2 files changed, 84 insertions, 145 deletions
diff --git a/gst/siren/gstsirenenc.c b/gst/siren/gstsirenenc.c index 5ffb6641..6dd78b1b 100644 --- a/gst/siren/gstsirenenc.c +++ b/gst/siren/gstsirenenc.c @@ -73,15 +73,10 @@ enum static void gst_siren_enc_dispose (GObject *object); -static GstFlowReturn gst_siren_enc_transform (GstBaseTransform *trans, - GstBuffer *inbuf, GstBuffer *outbuf); -static gboolean gst_siren_enc_transform_size (GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, guint size, - GstCaps *othercaps, guint *othersize); -static GstCaps * gst_siren_enc_transform_caps (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps); -static gboolean gst_siren_enc_start (GstBaseTransform *trans); -static gboolean gst_siren_enc_stop (GstBaseTransform *trans); +static GstFlowReturn +gst_siren_enc_chain (GstPad *pad, GstBuffer *buf); +static GstStateChangeReturn +gst_siren_change_state (GstElement *element, GstStateChange transition); static void @@ -91,8 +86,8 @@ _do_init (GType type) (sirenenc_debug, "sirenenc", 0, "sirenenc"); } -GST_BOILERPLATE_FULL (GstSirenEnc, gst_siren_enc, GstBaseTransform, - GST_TYPE_BASE_TRANSFORM, _do_init); +GST_BOILERPLATE_FULL (GstSirenEnc, gst_siren_enc, GstElement, + GST_TYPE_ELEMENT, _do_init); static void gst_siren_enc_base_init (gpointer klass) @@ -111,25 +106,16 @@ static void gst_siren_enc_class_init (GstSirenEncClass *klass) { GObjectClass *gobject_class; - GstBaseTransformClass *gstbasetransform_class; + GstElementClass *gstelement_class; gobject_class = (GObjectClass *) klass; - gstbasetransform_class = (GstBaseTransformClass *) klass; + gstelement_class = (GstElementClass *) klass; GST_DEBUG ("Initializing Class"); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_siren_enc_dispose); - gstbasetransform_class->transform = - GST_DEBUG_FUNCPTR (gst_siren_enc_transform); - gstbasetransform_class->transform_caps = - GST_DEBUG_FUNCPTR (gst_siren_enc_transform_caps); - gstbasetransform_class->transform_size = - GST_DEBUG_FUNCPTR (gst_siren_enc_transform_size); - gstbasetransform_class->start = - GST_DEBUG_FUNCPTR (gst_siren_enc_start); - gstbasetransform_class->stop = - GST_DEBUG_FUNCPTR (gst_siren_enc_stop); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_siren_change_state); parent_class = g_type_class_peek_parent (klass); @@ -141,9 +127,20 @@ gst_siren_enc_init (GstSirenEnc *enc, GstSirenEncClass *klass) { GST_DEBUG ("Initializing"); - enc->encoder = NULL; + enc->encoder = Siren7_NewEncoder (16000); enc->adapter = gst_adapter_new (); + enc->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink"); + enc->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); + + gst_pad_set_chain_function (enc->sinkpad, + GST_DEBUG_FUNCPTR (gst_siren_enc_chain)); + + gst_element_add_pad (GST_ELEMENT (enc), enc->sinkpad); + gst_element_add_pad (GST_ELEMENT (enc), enc->srcpad); + + enc->srccaps = gst_static_pad_template_get_caps (&srctemplate); + GST_DEBUG ("Init done"); } @@ -163,140 +160,60 @@ gst_siren_enc_dispose (GObject *object) enc->adapter = NULL; } - G_OBJECT_CLASS (parent_class)->dispose (object); - - GST_DEBUG ("Dispose done"); - -} - -static gboolean -gst_siren_enc_start (GstBaseTransform *trans) -{ - GstSirenEnc *enc = GST_SIREN_ENC (trans); - - GST_DEBUG ("Start"); - - if (enc->encoder) { - Siren7_CloseEncoder (enc->encoder); - enc->encoder = NULL; + if (enc->srccaps) + { + gst_caps_unref (enc->srccaps); + enc->srccaps = NULL; } - enc->encoder = Siren7_NewEncoder (16000); - gst_adapter_clear (enc->adapter); - - return enc->encoder != NULL; -} + G_OBJECT_CLASS (parent_class)->dispose (object); + GST_DEBUG ("Dispose done"); -static gboolean -gst_siren_enc_stop (GstBaseTransform *trans) -{ - GstSirenEnc *enc = GST_SIREN_ENC (trans); - - GST_DEBUG ("Stop"); - - if (enc->encoder) { - Siren7_CloseEncoder (enc->encoder); - enc->encoder = NULL; - } - gst_adapter_clear (enc->adapter); - return TRUE; -} - - -static gboolean gst_siren_enc_transform_size (GstBaseTransform *trans, - GstPadDirection direction, GstCaps *caps, guint size, - GstCaps *othercaps, guint *othersize) -{ - GstSirenEnc *enc = GST_SIREN_ENC (trans); - GstStructure *structure; - const gchar *in_name; - const gchar *out_name; - - if (caps == NULL || othercaps == NULL) { - GST_WARNING ("caps NULL"); - return FALSE; - } - - structure = gst_caps_get_structure (caps, 0); - in_name = gst_structure_get_name (structure); - structure = gst_caps_get_structure (othercaps, 0); - out_name = gst_structure_get_name (structure); - - GST_DEBUG ("Transform size from caps '%s' to '%s'", in_name, out_name); - - if (in_name == NULL || out_name == NULL) { - return FALSE; - } else if (strcmp (in_name, "audio/x-raw-int") == 0 && - strcmp (out_name, "audio/x-siren") == 0 ) { - size += gst_adapter_available (enc->adapter); - *othersize = size / 16; - *othersize -= *othersize % 40; - if ((size / 16) % 40 > 0) - *othersize+=40; - } else if (strcmp (in_name, "audio/x-siren") == 0 && - strcmp (out_name, "audio/x-raw-int") == 0 ) { - *othersize = size * 16; - *othersize -= *othersize % 640; - if ((size * 16) % 640 > 0) - *othersize+= 640; - } else { - GST_DEBUG ("Unknown in/out caps"); - return FALSE; - } - - GST_DEBUG ("Transform size %d to %d", size, *othersize); - - return TRUE; -} - -static GstCaps * gst_siren_enc_transform_caps (GstBaseTransform * base, - GstPadDirection direction, GstCaps * caps) -{ - GST_DEBUG ("Transforming caps"); - - if (direction == GST_PAD_SRC) { - return gst_static_pad_template_get_caps (&sinktemplate); - } else if (direction == GST_PAD_SINK) { - return gst_static_pad_template_get_caps (&srctemplate); - } - - /* Make gcc happy */ - return NULL; } static GstFlowReturn -gst_siren_enc_transform (GstBaseTransform *trans, GstBuffer *inbuf, - GstBuffer *outbuf) +gst_siren_enc_chain (GstPad *pad, GstBuffer *buf) { - - GstSirenEnc *enc = GST_SIREN_ENC (trans); + GstSirenEnc *enc = GST_SIREN_ENC (gst_pad_get_parent_element (pad)); GstFlowReturn ret = GST_FLOW_OK; + GstBuffer *encoded = NULL; guint8 *data = NULL; gint offset = 0; gint encode_ret = 0; + gint size = 0; GST_DEBUG ("Transform"); if (enc->encoder == NULL) { - GST_DEBUG ("Siren encoder not set"); + GST_WARNING ("Siren encoder not set"); return GST_FLOW_WRONG_STATE; } if (enc->adapter == NULL) { - GST_DEBUG ("Adapter not set"); - return GST_FLOW_UNEXPECTED; + GST_ERROR ("Adapter not set"); + return GST_FLOW_ERROR; } - gst_buffer_ref (inbuf); - gst_adapter_push (enc->adapter, inbuf); + gst_adapter_push (enc->adapter, buf); GST_DEBUG ("Received buffer of size %d with adapter of size : %d", - GST_BUFFER_SIZE (inbuf), gst_adapter_available (enc->adapter)); + GST_BUFFER_SIZE (buf), gst_adapter_available (enc->adapter)); + + size = gst_adapter_available (enc->adapter); + size /= 16; + size -= size % 40; + + if (size == 0) + return GST_FLOW_OK; + + ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad, + GST_BUFFER_OFFSET (buf) / 16, size, enc->srccaps, &encoded); + if (ret != GST_FLOW_OK) + return ret; - data = GST_BUFFER_DATA (outbuf); - offset = 0; - while(gst_adapter_available (enc->adapter) >= 640 && - offset + 40 <= GST_BUFFER_SIZE (outbuf) && + data = GST_BUFFER_DATA (encoded); + + while (gst_adapter_available (enc->adapter) >= 640 && ret == GST_FLOW_OK) { GST_DEBUG ("Encoding frame"); @@ -305,7 +222,7 @@ gst_siren_enc_transform (GstBaseTransform *trans, GstBuffer *inbuf, (guint8 *)gst_adapter_peek (enc->adapter, 640), data + offset); if (encode_ret != 0) { - GST_DEBUG ("Siren7_EncodeFrame returned %d", encode_ret); + GST_ERROR ("Siren7_EncodeFrame returned %d", encode_ret); ret = GST_FLOW_ERROR; } @@ -315,12 +232,37 @@ gst_siren_enc_transform (GstBaseTransform *trans, GstBuffer *inbuf, GST_DEBUG ("Finished encoding : %d", offset); - GST_BUFFER_SIZE (outbuf) = offset; + GST_BUFFER_SIZE (encoded) = offset; + + ret = gst_pad_push (enc->srcpad, encoded); return ret; } +static GstStateChangeReturn +gst_siren_change_state (GstElement *element, GstStateChange transition) +{ + GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; + GstSirenEnc *enc = GST_SIREN_ENC (element); + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); + + if (ret == GST_STATE_CHANGE_FAILURE) + return ret; + + switch (transition) + { + case GST_STATE_CHANGE_PAUSED_TO_READY: + GST_OBJECT_LOCK (element); + gst_adapter_clear (enc->adapter); + GST_OBJECT_UNLOCK (element); + break; + default: + break; + } + return ret; +} gboolean gst_siren_enc_plugin_init (GstPlugin *plugin) diff --git a/gst/siren/gstsirenenc.h b/gst/siren/gstsirenenc.h index 1b3937d3..1b404e03 100644 --- a/gst/siren/gstsirenenc.h +++ b/gst/siren/gstsirenenc.h @@ -24,7 +24,6 @@ #define __GST_SIREN_ENC_H__ #include <gst/gst.h> -#include <gst/base/gstbasetransform.h> #include <gst/base/gstadapter.h> #include "siren7.h" @@ -51,22 +50,20 @@ typedef struct _GstSirenEncPrivate GstSirenEncPrivate; struct _GstSirenEnc { - GstBaseTransform parent; + GstElement parent; SirenEncoder encoder; GstAdapter *adapter; - /*< private > */ - gpointer _gst_reserved[GST_PADDING]; + GstPad *srcpad; + GstPad *sinkpad; + + GstCaps *srccaps; }; struct _GstSirenEncClass { - GstBaseTransformClass parent_class; - - - /*< private > */ - gpointer _gst_reserved[GST_PADDING]; + GstElementClass parent_class; }; GType gst_siren_enc_get_type (void); |