]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gst-plugins-ugly0-10.git/commitdiff
amrwbdec: port to audiodecoder
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Wed, 5 Oct 2011 10:05:34 +0000 (12:05 +0200)
committerNikhil Devshatwar <a0132237@ti.com>
Fri, 17 May 2013 09:40:45 +0000 (15:10 +0530)
ext/amrwbdec/Makefile.am
ext/amrwbdec/amrwbdec.c
ext/amrwbdec/amrwbdec.h

index 08eda533e3e2b588bb61b34461f1ba7a1103cb23..2f822f0735efcaa746cfa59b6d04cd5e5d292981 100644 (file)
@@ -4,8 +4,11 @@ libgstamrwbdec_la_SOURCES = \
        amrwb.c \
        amrwbdec.c
 
-libgstamrwbdec_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AMRWB_CFLAGS)
-libgstamrwbdec_la_LIBADD = $(GST_BASE_LIBS) $(GST_LIBS) $(AMRWB_LIBS)
+libgstamrwbdec_la_CFLAGS = -DGST_USE_UNSTABLE_API $(GST_PLUGINS_BASE_CFLAGS) \
+       $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AMRWB_CFLAGS)
+libgstamrwbdec_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) \
+       -lgstaudio-@GST_MAJORMINOR@ \
+       $(GST_BASE_LIBS) $(GST_LIBS) $(AMRWB_LIBS)
 libgstamrwbdec_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstamrwbdec_la_LIBTOOLFLAGS = --tag=disable-static
 
index 51f759d8550cc4a0d6446142cbafa61dd3b3f8e9..e00dd99d129af3b1476bce474ab9471a63754881 100644 (file)
@@ -66,19 +66,19 @@ static const unsigned char block_size[16] =
   6, 0, 0, 0, 0, 1, 1
 };
 
-static gboolean gst_amrwbdec_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_amrwbdec_chain (GstPad * pad, GstBuffer * buffer);
-static gboolean gst_amrwbdec_setcaps (GstPad * pad, GstCaps * caps);
-static GstStateChangeReturn gst_amrwbdec_state_change (GstElement * element,
-    GstStateChange transition);
-
-static void gst_amrwbdec_finalize (GObject * object);
+static gboolean gst_amrwbdec_start (GstAudioDecoder * dec);
+static gboolean gst_amrwbdec_stop (GstAudioDecoder * dec);
+static gboolean gst_amrwbdec_set_format (GstAudioDecoder * dec, GstCaps * caps);
+static gboolean gst_amrwbdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
+    gint * offset, gint * length);
+static GstFlowReturn gst_amrwbdec_handle_frame (GstAudioDecoder * dec,
+    GstBuffer * buffer);
 
 #define _do_init(bla) \
     GST_DEBUG_CATEGORY_INIT (gst_amrwbdec_debug, "amrwbdec", 0, "AMR-WB audio decoder");
 
-GST_BOILERPLATE_FULL (GstAmrwbDec, gst_amrwbdec, GstElement, GST_TYPE_ELEMENT,
-    _do_init);
+GST_BOILERPLATE_FULL (GstAmrwbDec, gst_amrwbdec, GstAudioDecoder,
+    GST_TYPE_AUDIO_DECODER, _do_init);
 
 static void
 gst_amrwbdec_base_init (gpointer klass)
@@ -99,60 +99,54 @@ gst_amrwbdec_base_init (gpointer klass)
 static void
 gst_amrwbdec_class_init (GstAmrwbDecClass * klass)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
 
-  object_class->finalize = gst_amrwbdec_finalize;
-
-  element_class->change_state = GST_DEBUG_FUNCPTR (gst_amrwbdec_state_change);
+  base_class->start = GST_DEBUG_FUNCPTR (gst_amrwbdec_start);
+  base_class->stop = GST_DEBUG_FUNCPTR (gst_amrwbdec_stop);
+  base_class->set_format = GST_DEBUG_FUNCPTR (gst_amrwbdec_set_format);
+  base_class->parse = GST_DEBUG_FUNCPTR (gst_amrwbdec_parse);
+  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_amrwbdec_handle_frame);
 }
 
 static void
 gst_amrwbdec_init (GstAmrwbDec * amrwbdec, GstAmrwbDecClass * klass)
 {
-  /* create the sink pad */
-  amrwbdec->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
-  gst_pad_set_setcaps_function (amrwbdec->sinkpad, gst_amrwbdec_setcaps);
-  gst_pad_set_event_function (amrwbdec->sinkpad, gst_amrwbdec_event);
-  gst_pad_set_chain_function (amrwbdec->sinkpad, gst_amrwbdec_chain);
-  gst_element_add_pad (GST_ELEMENT (amrwbdec), amrwbdec->sinkpad);
-
-  /* create the src pad */
-  amrwbdec->srcpad = gst_pad_new_from_static_template (&src_template, "src");
-  gst_pad_use_fixed_caps (amrwbdec->srcpad);
-  gst_element_add_pad (GST_ELEMENT (amrwbdec), amrwbdec->srcpad);
-
-  amrwbdec->adapter = gst_adapter_new ();
-
-  /* init rest */
-  amrwbdec->handle = NULL;
-  amrwbdec->channels = 0;
-  amrwbdec->rate = 0;
-  amrwbdec->duration = 0;
-  amrwbdec->ts = -1;
 }
 
-static void
-gst_amrwbdec_finalize (GObject * object)
+static gboolean
+gst_amrwbdec_start (GstAudioDecoder * dec)
 {
-  GstAmrwbDec *amrwbdec;
+  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);
 
-  amrwbdec = GST_AMRWBDEC (object);
+  GST_DEBUG_OBJECT (dec, "start");
+  if (!(amrwbdec->handle = D_IF_init ()))
+    return FALSE;
 
-  gst_adapter_clear (amrwbdec->adapter);
-  g_object_unref (amrwbdec->adapter);
+  amrwbdec->rate = 0;
+  amrwbdec->channels = 0;
 
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  return TRUE;
 }
 
 static gboolean
-gst_amrwbdec_setcaps (GstPad * pad, GstCaps * caps)
+gst_amrwbdec_stop (GstAudioDecoder * dec)
+{
+  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);
+
+  GST_DEBUG_OBJECT (dec, "stop");
+  D_IF_exit (amrwbdec->handle);
+
+  return TRUE;
+}
+
+static gboolean
+gst_amrwbdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
 {
   GstStructure *structure;
   GstAmrwbDec *amrwbdec;
   GstCaps *copy;
 
-  amrwbdec = GST_AMRWBDEC (gst_pad_get_parent (pad));
+  amrwbdec = GST_AMRWBDEC (dec);
 
   structure = gst_caps_get_structure (caps, 0);
 
@@ -168,215 +162,85 @@ gst_amrwbdec_setcaps (GstPad * pad, GstCaps * caps)
       "endianness", G_TYPE_INT, G_BYTE_ORDER,
       "rate", G_TYPE_INT, amrwbdec->rate, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
 
-  amrwbdec->duration = gst_util_uint64_scale_int (GST_SECOND, L_FRAME16k,
-      amrwbdec->rate * amrwbdec->channels);
-
-  gst_pad_set_caps (amrwbdec->srcpad, copy);
+  gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (amrwbdec), copy);
   gst_caps_unref (copy);
 
-  gst_object_unref (amrwbdec);
-
   return TRUE;
 }
 
-static gboolean
-gst_amrwbdec_event (GstPad * pad, GstEvent * event)
+static GstFlowReturn
+gst_amrwbdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
+    gint * offset, gint * length)
 {
-  GstAmrwbDec *amrwbdec;
-  gboolean ret = TRUE;
-
-  amrwbdec = GST_AMRWBDEC (gst_pad_get_parent (pad));
-
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_FLUSH_START:
-      ret = gst_pad_push_event (amrwbdec->srcpad, event);
-      break;
-    case GST_EVENT_FLUSH_STOP:
-      ret = gst_pad_push_event (amrwbdec->srcpad, event);
-      gst_adapter_clear (amrwbdec->adapter);
-      amrwbdec->ts = -1;
-      break;
-    case GST_EVENT_EOS:
-      gst_adapter_clear (amrwbdec->adapter);
-      ret = gst_pad_push_event (amrwbdec->srcpad, event);
-      break;
-    case GST_EVENT_NEWSEGMENT:
-    {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      /* we need time for now */
-      if (format != GST_FORMAT_TIME)
-        goto newseg_wrong_format;
-
-      GST_DEBUG_OBJECT (amrwbdec,
-          "newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
-          ", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
-          update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
-          GST_TIME_ARGS (time));
-
-      /* now configure the values */
-      gst_segment_set_newsegment_full (&amrwbdec->segment, update,
-          rate, arate, format, start, stop, time);
-      ret = gst_pad_push_event (amrwbdec->srcpad, event);
-    }
-      break;
-    default:
-      ret = gst_pad_push_event (amrwbdec->srcpad, event);
-      break;
+  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);
+  const guint8 *data;
+  guint size;
+  gboolean sync, eos;
+  gint block, mode;
+
+  size = gst_adapter_available (adapter);
+  g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
+
+  gst_audio_decoder_get_parse_state (dec, &sync, &eos);
+
+  /* need to peek data to get the size */
+  if (gst_adapter_available (adapter) < 1)
+    return GST_FLOW_ERROR;
+
+  data = gst_adapter_peek (adapter, 1);
+  mode = (data[0] >> 3) & 0x0F;
+  block = block_size[mode];
+
+  GST_DEBUG_OBJECT (amrwbdec, "mode %d, block %d", mode, block);
+
+  if (block) {
+    *offset = 0;
+    *length = block;
+  } else {
+    /* no frame yet, skip one byte */
+    GST_LOG_OBJECT (amrwbdec, "skipping byte");
+    *offset = 1;
+    return GST_FLOW_UNEXPECTED;
   }
-done:
-  gst_object_unref (amrwbdec);
-
-  return ret;
 
-  /* ERRORS */
-newseg_wrong_format:
-  {
-    GST_DEBUG_OBJECT (amrwbdec, "received non TIME newsegment");
-    goto done;
-  }
+  return GST_FLOW_OK;
 }
 
 static GstFlowReturn
-gst_amrwbdec_chain (GstPad * pad, GstBuffer * buffer)
+gst_amrwbdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
 {
   GstAmrwbDec *amrwbdec;
-  GstFlowReturn ret = GST_FLOW_OK;
+  GstBuffer *out;
+  const guint8 *data;
+
+  amrwbdec = GST_AMRWBDEC (dec);
 
-  amrwbdec = GST_AMRWBDEC (gst_pad_get_parent (pad));
+  /* no fancy flushing */
+  if (!buffer || !GST_BUFFER_SIZE (buffer))
+    return GST_FLOW_OK;
 
   if (amrwbdec->rate == 0 || amrwbdec->channels == 0)
     goto not_negotiated;
 
-  /* discontinuity, don't combine samples before and after the
-   * DISCONT */
-  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
-    gst_adapter_clear (amrwbdec->adapter);
-    amrwbdec->ts = -1;
-    amrwbdec->discont = TRUE;
-  }
+  /* the library seems to write into the source data, hence the copy. */
+  /* should be no problem */
+  data = GST_BUFFER_DATA (buffer);
 
-  /* take latest timestamp, FIXME timestamp is the one of the
-   * first buffer in the adapter. */
-  if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-    amrwbdec->ts = GST_BUFFER_TIMESTAMP (buffer);
+  /* get output */
+  out = gst_buffer_new_and_alloc (sizeof (gint16) * L_FRAME16k);
 
-  gst_adapter_push (amrwbdec->adapter, buffer);
+  /* decode */
+  D_IF_decode (amrwbdec->handle, (unsigned char *) data,
+      (Word16 *) GST_BUFFER_DATA (out), _good_frame);
 
-  while (TRUE) {
-    GstBuffer *out;
-    const guint8 *data;
-    gint block, mode;
-
-    /* need to peek data to get the size */
-    if (gst_adapter_available (amrwbdec->adapter) < 1)
-      break;
-    data = gst_adapter_peek (amrwbdec->adapter, 1);
-
-    /* get size */
-    mode = (data[0] >> 3) & 0x0F;
-    block = block_size[mode];
-
-    GST_DEBUG_OBJECT (amrwbdec, "mode %d, block %d", mode, block);
-
-    if (!block) {
-      GST_LOG_OBJECT (amrwbdec, "skipping byte");
-      gst_adapter_flush (amrwbdec->adapter, 1);
-      continue;
-    }
-
-    if (gst_adapter_available (amrwbdec->adapter) < block)
-      break;
-
-    /* the library seems to write into the source data, hence the copy. */
-    data = gst_adapter_take (amrwbdec->adapter, block);
-
-    /* get output */
-    out = gst_buffer_new_and_alloc (sizeof (gint16) * L_FRAME16k);
-
-    GST_BUFFER_DURATION (out) = amrwbdec->duration;
-    GST_BUFFER_TIMESTAMP (out) = amrwbdec->ts;
-
-    if (amrwbdec->ts != -1)
-      amrwbdec->ts += amrwbdec->duration;
-    if (amrwbdec->discont) {
-      GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT);
-      amrwbdec->discont = FALSE;
-    }
-
-    gst_buffer_set_caps (out, GST_PAD_CAPS (amrwbdec->srcpad));
-
-    /* decode */
-    D_IF_decode (amrwbdec->handle, (unsigned char *) data,
-        (Word16 *) GST_BUFFER_DATA (out), _good_frame);
-
-    g_free ((gpointer) data);
-
-    /* send out */
-    ret = gst_pad_push (amrwbdec->srcpad, out);
-  }
-
-  gst_object_unref (amrwbdec);
-  return ret;
+  /* send out */
+  return gst_audio_decoder_finish_frame (dec, out, 1);
 
   /* ERRORS */
 not_negotiated:
   {
     GST_ELEMENT_ERROR (amrwbdec, STREAM, TYPE_NOT_FOUND, (NULL),
         ("Decoder is not initialized"));
-    gst_object_unref (amrwbdec);
     return GST_FLOW_NOT_NEGOTIATED;
   }
 }
-
-static GstStateChangeReturn
-gst_amrwbdec_state_change (GstElement * element, GstStateChange transition)
-{
-  GstAmrwbDec *amrwbdec;
-  GstStateChangeReturn ret;
-
-  amrwbdec = GST_AMRWBDEC (element);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_NULL_TO_READY:
-      if (!(amrwbdec->handle = D_IF_init ()))
-        goto init_failed;
-      break;
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      gst_adapter_clear (amrwbdec->adapter);
-      amrwbdec->rate = 0;
-      amrwbdec->channels = 0;
-      amrwbdec->ts = -1;
-      amrwbdec->discont = TRUE;
-      gst_segment_init (&amrwbdec->segment, GST_FORMAT_TIME);
-      break;
-    default:
-      break;
-  }
-
-  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_NULL:
-      D_IF_exit (amrwbdec->handle);
-      break;
-    default:
-      break;
-  }
-
-  return ret;
-
-  /* ERRORS */
-init_failed:
-  {
-    GST_ELEMENT_ERROR (amrwbdec, LIBRARY, INIT, (NULL),
-        ("Failed to open AMR Decoder"));
-    return GST_STATE_CHANGE_FAILURE;
-  }
-}
index e41157ab934de067fe1261ab7f764706a1d2c0d0..c3528fca0058392f5217f1e1472dc049efd21bcc 100644 (file)
@@ -21,7 +21,7 @@
 #define __GST_AMRWBDEC_H__
 
 #include <gst/gst.h>
-#include <gst/base/gstadapter.h>
+#include <gst/audio/gstaudiodecoder.h>
 #include <dec_if.h>
 #include <if_rom.h>
 
@@ -47,27 +47,17 @@ typedef struct _GstAmrwbDecClass GstAmrwbDecClass;
  * Opaque data structure.
  */
 struct _GstAmrwbDec {
-  GstElement element;
-
-  /* pads */
-  GstPad *sinkpad, *srcpad;
-  guint64 ts;
-
-  GstAdapter *adapter;
+  GstAudioDecoder element;
 
   /* library handle */
   void *handle;
 
   /* output settings */
   gint channels, rate;
-  gint duration;
-
-  GstSegment        segment;
-  gboolean          discont;
 };
 
 struct _GstAmrwbDecClass {
-  GstElementClass parent_class;
+  GstAudioDecoderClass parent_class;
 };
 
 GType gst_amrwbdec_get_type (void);