Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Tue, 4 Oct 2011 15:50:33 +0000 (17:50 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 4 Oct 2011 15:50:33 +0000 (17:50 +0200)
Conflicts:
ext/amrnb/amrnbdec.c

1  2 
ext/amrnb/amrnbdec.c

@@@ -96,34 -96,24 +96,26 @@@ static void gst_amrnbdec_set_property (
  static void gst_amrnbdec_get_property (GObject * object, guint prop_id,
      GValue * value, GParamSpec * pspec);
  
- static gboolean gst_amrnbdec_event (GstPad * pad, GstEvent * event);
- static GstFlowReturn gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer);
- static gboolean gst_amrnbdec_setcaps (GstPad * pad, GstCaps * caps);
- static GstStateChangeReturn gst_amrnbdec_state_change (GstElement * element,
-     GstStateChange transition);
static void gst_amrnbdec_finalize (GObject * object);
+ static gboolean gst_amrnbdec_start (GstAudioDecoder * dec);
+ static gboolean gst_amrnbdec_stop (GstAudioDecoder * dec);
+ static gboolean gst_amrnbdec_set_format (GstAudioDecoder * dec, GstCaps * caps);
+ static gboolean gst_amrnbdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
+     gint * offset, gint * length);
+ static GstFlowReturn gst_amrnbdec_handle_frame (GstAudioDecoder * dec,
    GstBuffer * buffer);
  
 -#define _do_init(bla) \
 -    GST_DEBUG_CATEGORY_INIT (gst_amrnbdec_debug, "amrnbdec", 0, "AMR-NB audio decoder");
 -
 -GST_BOILERPLATE_FULL (GstAmrnbDec, gst_amrnbdec, GstAudioDecoder,
 -    GST_TYPE_AUDIO_DECODER, _do_init);
 +#define gst_amrnbdec_parent_class parent_class
- G_DEFINE_TYPE (GstAmrnbDec, gst_amrnbdec, GST_TYPE_ELEMENT);
++G_DEFINE_TYPE (GstAmrnbDec, gst_amrnbdec, GST_TYPE_AUDIO_DECODER);
  
  static void
 -gst_amrnbdec_base_init (gpointer klass)
 +gst_amrnbdec_class_init (GstAmrnbDecClass * klass)
  {
 +  GObjectClass *object_class = G_OBJECT_CLASS (klass);
    GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-   object_class->finalize = gst_amrnbdec_finalize;
-   g_object_class_install_property (object_class, PROP_VARIANT,
-       g_param_spec_enum ("variant", "Variant",
-           "The decoder variant", GST_AMRNB_VARIANT_TYPE,
-           VARIANT_DEFAULT,
-           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-   element_class->change_state = GST_DEBUG_FUNCPTR (gst_amrnbdec_state_change);
++  GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
 +
 +  object_class->set_property = gst_amrnbdec_set_property;
 +  object_class->get_property = gst_amrnbdec_get_property;
  
    gst_element_class_add_pad_template (element_class,
        gst_static_pad_template_get (&sink_template));
        "Codec/Decoder/Audio",
        "Adaptive Multi-Rate Narrow-Band audio decoder",
        "GStreamer maintainers <gstreamer-devel@lists.sourceforge.net>");
 -}
 -
 -static void
 -gst_amrnbdec_class_init (GstAmrnbDecClass * klass)
 -{
 -  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 -  GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
 -
 -  object_class->set_property = gst_amrnbdec_set_property;
 -  object_class->get_property = gst_amrnbdec_get_property;
  
+   base_class->start = GST_DEBUG_FUNCPTR (gst_amrnbdec_start);
+   base_class->stop = GST_DEBUG_FUNCPTR (gst_amrnbdec_stop);
+   base_class->set_format = GST_DEBUG_FUNCPTR (gst_amrnbdec_set_format);
+   base_class->parse = GST_DEBUG_FUNCPTR (gst_amrnbdec_parse);
+   base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_amrnbdec_handle_frame);
+   g_object_class_install_property (object_class, PROP_VARIANT,
+       g_param_spec_enum ("variant", "Variant",
+           "The decoder variant", GST_AMRNB_VARIANT_TYPE,
+           VARIANT_DEFAULT,
+           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
++
 +  GST_DEBUG_CATEGORY_INIT (gst_amrnbdec_debug, "amrnbdec", 0,
 +      "AMR-NB audio decoder");
  }
  
  static void
 -gst_amrnbdec_init (GstAmrnbDec * amrnbdec, GstAmrnbDecClass * klass)
 +gst_amrnbdec_init (GstAmrnbDec * amrnbdec)
  {
-   /* create the sink pad */
-   amrnbdec->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
-   gst_pad_set_event_function (amrnbdec->sinkpad, gst_amrnbdec_event);
-   gst_pad_set_chain_function (amrnbdec->sinkpad, gst_amrnbdec_chain);
-   gst_element_add_pad (GST_ELEMENT (amrnbdec), amrnbdec->sinkpad);
+ }
+ static gboolean
+ gst_amrnbdec_start (GstAudioDecoder * dec)
+ {
+   GstAmrnbDec *amrnbdec = GST_AMRNBDEC (dec);
  
-   /* create the src pad */
-   amrnbdec->srcpad = gst_pad_new_from_static_template (&src_template, "src");
-   gst_pad_use_fixed_caps (amrnbdec->srcpad);
-   gst_element_add_pad (GST_ELEMENT (amrnbdec), amrnbdec->srcpad);
+   GST_DEBUG_OBJECT (dec, "start");
+   if (!(amrnbdec->handle = Decoder_Interface_init ()))
+     return FALSE;
  
-   amrnbdec->adapter = gst_adapter_new ();
+   amrnbdec->rate = 0;
+   amrnbdec->channels = 0;
  
-   /* init rest */
-   amrnbdec->handle = NULL;
+   return TRUE;
  }
  
- static void
- gst_amrnbdec_finalize (GObject * object)
+ static gboolean
+ gst_amrnbdec_stop (GstAudioDecoder * dec)
  {
-   GstAmrnbDec *amrnbdec;
-   amrnbdec = GST_AMRNBDEC (object);
+   GstAmrnbDec *amrnbdec = GST_AMRNBDEC (dec);
  
-   gst_adapter_clear (amrnbdec->adapter);
-   g_object_unref (amrnbdec->adapter);
+   GST_DEBUG_OBJECT (dec, "stop");
+   Decoder_Interface_exit (amrnbdec->handle);
  
-   G_OBJECT_CLASS (parent_class)->finalize (object);
+   return TRUE;
  }
  
  static void
@@@ -222,177 -229,93 +224,90 @@@ gst_amrnbdec_set_format (GstAudioDecode
    gst_structure_get_int (structure, "rate", &amrnbdec->rate);
  
    /* create reverse caps */
--  copy = gst_caps_new_simple ("audio/x-raw-int",
++  copy = gst_caps_new_simple ("audio/x-raw",
++      "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
        "channels", G_TYPE_INT, amrnbdec->channels,
--      "width", G_TYPE_INT, 16,
--      "depth", G_TYPE_INT, 16,
--      "endianness", G_TYPE_INT, G_BYTE_ORDER,
--      "rate", G_TYPE_INT, amrnbdec->rate, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
-   amrnbdec->duration = gst_util_uint64_scale_int (GST_SECOND, 160,
-       amrnbdec->rate * amrnbdec->channels);
--
-   gst_pad_set_caps (amrnbdec->srcpad, copy);
 -  gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), copy);
++      "rate", G_TYPE_INT, amrnbdec->rate, NULL);
++  gst_audio_decoder_set_outcaps (dec, copy);
    gst_caps_unref (copy);
  
-   gst_object_unref (amrnbdec);
    return TRUE;
  }
  
- static gboolean
- gst_amrnbdec_event (GstPad * pad, GstEvent * event)
+ static GstFlowReturn
+ gst_amrnbdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
+     gint * offset, gint * length)
  {
-   GstAmrnbDec *amrnbdec;
-   gboolean ret = TRUE;
+   GstAmrnbDec *amrnbdec = GST_AMRNBDEC (dec);
 -  const guint8 *data;
++  guint8 head[1];
+   guint size;
+   gboolean sync, eos;
+   gint block, mode;
  
-   amrnbdec = GST_AMRNBDEC (gst_pad_get_parent (pad));
+   size = gst_adapter_available (adapter);
+   g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
  
-   switch (GST_EVENT_TYPE (event)) {
-     case GST_EVENT_CAPS:
-     {
-       GstCaps *caps;
+   gst_audio_decoder_get_parse_state (dec, &sync, &eos);
  
-       gst_event_parse_caps (event, &caps);
-       ret = gst_amrnbdec_setcaps (pad, caps);
-       gst_event_unref (event);
-       break;
-     }
-     case GST_EVENT_FLUSH_START:
-       ret = gst_pad_push_event (amrnbdec->srcpad, event);
-       break;
-     case GST_EVENT_FLUSH_STOP:
-       ret = gst_pad_push_event (amrnbdec->srcpad, event);
-       gst_adapter_clear (amrnbdec->adapter);
-       amrnbdec->ts = -1;
-       break;
-     case GST_EVENT_EOS:
-       gst_adapter_clear (amrnbdec->adapter);
-       ret = gst_pad_push_event (amrnbdec->srcpad, event);
-       break;
-     case GST_EVENT_SEGMENT:
-     {
-       GstSegment seg;
-       gst_event_copy_segment (event, &seg);
-       /* we need time for now */
-       if (seg.format != GST_FORMAT_TIME)
-         goto newseg_wrong_format;
-       GST_DEBUG_OBJECT (amrnbdec, "segment: %" GST_SEGMENT_FORMAT, &seg);
+   /* need to peek data to get the size */
+   if (gst_adapter_available (adapter) < 1)
+     return GST_FLOW_ERROR;
  
-       /* now configure the values */
-       amrnbdec->segment = seg;
 -  data = gst_adapter_peek (adapter, 1);
++  gst_adapter_copy (adapter, head, 0, 1);
  
-       ret = gst_pad_push_event (amrnbdec->srcpad, event);
+   /* get size */
+   switch (amrnbdec->variant) {
+     case GST_AMRNB_VARIANT_IF1:
 -      mode = (data[0] >> 3) & 0x0F;
++      mode = (head[0] >> 3) & 0x0F;
+       block = block_size_if1[mode] + 1;
+       break;
+     case GST_AMRNB_VARIANT_IF2:
 -      mode = data[0] & 0x0F;
++      mode = head[0] & 0x0F;
+       block = block_size_if2[mode] + 1;
        break;
-     }
      default:
-       ret = gst_pad_push_event (amrnbdec->srcpad, event);
+       g_assert_not_reached ();
+       return GST_FLOW_ERROR;
        break;
    }
- done:
-   gst_object_unref (amrnbdec);
  
-   return ret;
+   GST_DEBUG_OBJECT (amrnbdec, "mode %d, block %d", mode, block);
  
-   /* ERRORS */
- newseg_wrong_format:
-   {
-     GST_DEBUG_OBJECT (amrnbdec, "received non TIME newsegment");
-     goto done;
-   }
+   *offset = 0;
+   *length = block;
+   return GST_FLOW_OK;
  }
  
  static GstFlowReturn
- gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
+ gst_amrnbdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
  {
    GstAmrnbDec *amrnbdec;
-   GstFlowReturn ret;
+   guint8 *data;
++  short *out_data;
+   GstBuffer *out;
  
-   amrnbdec = GST_AMRNBDEC (gst_pad_get_parent (pad));
+   amrnbdec = GST_AMRNBDEC (dec);
+   /* no fancy flushing */
 -  if (!buffer || !GST_BUFFER_SIZE (buffer))
++  if (!buffer || !gst_buffer_get_size (buffer))
+     return GST_FLOW_OK;
  
    if (amrnbdec->rate == 0 || amrnbdec->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 (amrnbdec->adapter);
-     amrnbdec->ts = -1;
-     amrnbdec->discont = TRUE;
-   }
-   /* take latest timestamp, FIXME timestamp is the one of the
-    * first buffer in the adapter. */
-   if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
-     amrnbdec->ts = GST_BUFFER_TIMESTAMP (buffer);
-   gst_adapter_push (amrnbdec->adapter, buffer);
-   ret = GST_FLOW_OK;
-   while (TRUE) {
-     GstBuffer *out;
-     guint8 head[1];
-     guint8 *data;
-     short *out_data;
-     gint block, mode;
-     /* need to peek data to get the size */
-     if (gst_adapter_available (amrnbdec->adapter) < 1)
-       break;
-     gst_adapter_copy (amrnbdec->adapter, head, 0, 1);
-     /* get size */
-     switch (amrnbdec->variant) {
-       case GST_AMRNB_VARIANT_IF1:
-         mode = (head[0] >> 3) & 0x0F;
-         block = block_size_if1[mode] + 1;
-         break;
-       case GST_AMRNB_VARIANT_IF2:
-         mode = head[0] & 0x0F;
-         block = block_size_if2[mode] + 1;
-         break;
-       default:
-         goto invalid_variant;
-     }
-     GST_DEBUG_OBJECT (amrnbdec, "mode %d, block %d", mode, block);
-     if (!block || gst_adapter_available (amrnbdec->adapter) < block)
-       break;
 -  /* the library seems to write into the source data, hence
 -   * the copy. */
 -  /* should not be a problem though */
 -  data = GST_BUFFER_DATA (buffer);
++  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
  
-     /* the library seems to write into the source data, hence
-      * the copy. */
-     data = gst_adapter_take (amrnbdec->adapter, block);
-     /* get output */
-     out = gst_buffer_new_and_alloc (160 * 2);
-     GST_BUFFER_DURATION (out) = amrnbdec->duration;
-     GST_BUFFER_TIMESTAMP (out) = amrnbdec->ts;
-     if (amrnbdec->ts != -1)
-       amrnbdec->ts += amrnbdec->duration;
-     if (amrnbdec->discont) {
-       GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT);
-       amrnbdec->discont = FALSE;
-     }
-     /* decode */
-     out_data = gst_buffer_map (out, NULL, NULL, GST_MAP_WRITE);
-     Decoder_Interface_Decode (amrnbdec->handle, data, out_data, 0);
-     gst_buffer_unmap (out, out_data, -1);
-     g_free (data);
-     /* send out */
-     ret = gst_pad_push (amrnbdec->srcpad, out);
-   }
+   /* get output */
+   out = gst_buffer_new_and_alloc (160 * 2);
 -
+   /* decode */
 -  Decoder_Interface_Decode (amrnbdec->handle, data,
 -      (short *) GST_BUFFER_DATA (out), 0);
++  out_data = gst_buffer_map (out, NULL, NULL, GST_MAP_WRITE);
++  Decoder_Interface_Decode (amrnbdec->handle, data, out_data, 0);
++  gst_buffer_unmap (out, out_data, 160 * 2);
 +
-   gst_object_unref (amrnbdec);
++  gst_buffer_unmap (buffer, data, -1);
  
-   return ret;
+   return gst_audio_decoder_finish_frame (dec, out, 1);
  
    /* ERRORS */
  not_negotiated: