Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 6 Oct 2011 10:23:39 +0000 (12:23 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 6 Oct 2011 10:23:39 +0000 (12:23 +0200)
Conflicts:
ext/speex/gstspeexdec.c
ext/speex/gstspeexenc.c
gst/isomp4/atoms.c
gst/isomp4/gstqtmux.c

1  2 
ext/speex/gstspeexdec.c
ext/speex/gstspeexenc.c
gst/isomp4/atoms.c
gst/isomp4/atoms.h
gst/isomp4/gstqtmux.c
gst/isomp4/gstqtmux.h
gst/matroska/matroska-demux.c
sys/v4l2/gstv4l2object.c
sys/ximage/gstximagesrc.c

@@@ -77,44 -76,44 +77,31 @@@ GST_STATIC_PAD_TEMPLATE ("sink"
      GST_STATIC_CAPS ("audio/x-speex")
      );
  
 -GST_BOILERPLATE (GstSpeexDec, gst_speex_dec, GstAudioDecoder,
 -    GST_TYPE_AUDIO_DECODER);
 -
 +#define gst_speex_dec_parent_class parent_class
- G_DEFINE_TYPE (GstSpeexDec, gst_speex_dec, GST_TYPE_ELEMENT);
- static gboolean speex_dec_sink_event (GstPad * pad, GstEvent * event);
- static GstFlowReturn speex_dec_chain (GstPad * pad, GstBuffer * buf);
- static GstStateChangeReturn speex_dec_change_state (GstElement * element,
-     GstStateChange transition);
- static gboolean speex_dec_src_event (GstPad * pad, GstEvent * event);
- static gboolean speex_dec_src_query (GstPad * pad, GstQuery * query);
- static gboolean speex_dec_sink_query (GstPad * pad, GstQuery * query);
- static const GstQueryType *speex_get_src_query_types (GstPad * pad);
- static const GstQueryType *speex_get_sink_query_types (GstPad * pad);
- static gboolean speex_dec_convert (GstPad * pad,
-     GstFormat src_format, gint64 src_value,
-     GstFormat * dest_format, gint64 * dest_value);
++G_DEFINE_TYPE (GstSpeexDec, gst_speex_dec, GST_TYPE_AUDIO_DECODER);
+ static gboolean gst_speex_dec_start (GstAudioDecoder * dec);
+ static gboolean gst_speex_dec_stop (GstAudioDecoder * dec);
+ static gboolean gst_speex_dec_set_format (GstAudioDecoder * bdec,
+     GstCaps * caps);
+ static GstFlowReturn gst_speex_dec_handle_frame (GstAudioDecoder * dec,
+     GstBuffer * buffer);
  
  static void gst_speex_dec_get_property (GObject * object, guint prop_id,
      GValue * value, GParamSpec * pspec);
  static void gst_speex_dec_set_property (GObject * object, guint prop_id,
      const GValue * value, GParamSpec * pspec);
  
- static GstFlowReturn speex_dec_chain_parse_data (GstSpeexDec * dec,
-     GstBuffer * buf, GstClockTime timestamp, GstClockTime duration);
- static GstFlowReturn speex_dec_chain_parse_header (GstSpeexDec * dec,
-     GstBuffer * buf);
- static GstFlowReturn speex_dec_chain_parse_comments (GstSpeexDec * dec,
-     GstBuffer * buf);
  static void
 -gst_speex_dec_base_init (gpointer g_class)
 -{
 -  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
 -
 -  gst_element_class_add_pad_template (element_class,
 -      gst_static_pad_template_get (&speex_dec_src_factory));
 -  gst_element_class_add_pad_template (element_class,
 -      gst_static_pad_template_get (&speex_dec_sink_factory));
 -  gst_element_class_set_details_simple (element_class, "Speex audio decoder",
 -      "Codec/Decoder/Audio",
 -      "decode speex streams to audio", "Wim Taymans <wim@fluendo.com>");
 -}
 -
 -static void
  gst_speex_dec_class_init (GstSpeexDecClass * klass)
  {
    GObjectClass *gobject_class;
 +  GstElementClass *gstelement_class;
+   GstAudioDecoderClass *base_class;
  
    gobject_class = (GObjectClass *) klass;
 +  gstelement_class = (GstElementClass *) klass;
+   base_class = (GstAudioDecoderClass *) klass;
  
    gobject_class->set_property = gst_speex_dec_set_property;
    gobject_class->get_property = gst_speex_dec_get_property;
        g_param_spec_boolean ("enh", "Enh", "Enable perceptual enhancement",
            DEFAULT_ENH, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  
-   gstelement_class->change_state = GST_DEBUG_FUNCPTR (speex_dec_change_state);
 +  gst_element_class_add_pad_template (gstelement_class,
 +      gst_static_pad_template_get (&speex_dec_src_factory));
 +  gst_element_class_add_pad_template (gstelement_class,
 +      gst_static_pad_template_get (&speex_dec_sink_factory));
 +  gst_element_class_set_details_simple (gstelement_class, "Speex audio decoder",
 +      "Codec/Decoder/Audio",
 +      "decode speex streams to audio", "Wim Taymans <wim@fluendo.com>");
 +
    GST_DEBUG_CATEGORY_INIT (speexdec_debug, "speexdec", 0,
        "speex decoding element");
  }
@@@ -164,31 -157,8 +153,8 @@@ gst_speex_dec_reset (GstSpeexDec * dec
  }
  
  static void
 -gst_speex_dec_init (GstSpeexDec * dec, GstSpeexDecClass * g_class)
 +gst_speex_dec_init (GstSpeexDec * dec)
  {
-   dec->sinkpad =
-       gst_pad_new_from_static_template (&speex_dec_sink_factory, "sink");
-   gst_pad_set_chain_function (dec->sinkpad,
-       GST_DEBUG_FUNCPTR (speex_dec_chain));
-   gst_pad_set_event_function (dec->sinkpad,
-       GST_DEBUG_FUNCPTR (speex_dec_sink_event));
-   gst_pad_set_query_type_function (dec->sinkpad,
-       GST_DEBUG_FUNCPTR (speex_get_sink_query_types));
-   gst_pad_set_query_function (dec->sinkpad,
-       GST_DEBUG_FUNCPTR (speex_dec_sink_query));
-   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
-   dec->srcpad =
-       gst_pad_new_from_static_template (&speex_dec_src_factory, "src");
-   gst_pad_use_fixed_caps (dec->srcpad);
-   gst_pad_set_event_function (dec->srcpad,
-       GST_DEBUG_FUNCPTR (speex_dec_src_event));
-   gst_pad_set_query_type_function (dec->srcpad,
-       GST_DEBUG_FUNCPTR (speex_get_src_query_types));
-   gst_pad_set_query_function (dec->srcpad,
-       GST_DEBUG_FUNCPTR (speex_dec_src_query));
-   gst_element_add_pad (GST_ELEMENT (dec), dec->srcpad);
    dec->enh = DEFAULT_ENH;
  
    gst_speex_dec_reset (dec);
@@@ -555,16 -190,13 +186,16 @@@ gst_speex_dec_stop (GstAudioDecoder * d
  }
  
  static GstFlowReturn
speex_dec_chain_parse_header (GstSpeexDec * dec, GstBuffer * buf)
gst_speex_dec_parse_header (GstSpeexDec * dec, GstBuffer * buf)
  {
    GstCaps *caps;
 +  char *data;
 +  gsize size;
  
    /* get the header */
 -  dec->header = speex_packet_to_header ((char *) GST_BUFFER_DATA (buf),
 -      GST_BUFFER_SIZE (buf));
 +  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
 +  dec->header = speex_packet_to_header (data, size);
 +  gst_buffer_unmap (buf, data, size);
  
    if (!dec->header)
      goto no_header;
    speex_bits_init (&dec->bits);
  
    /* set caps */
 -  caps = gst_caps_new_simple ("audio/x-raw-int",
 +  caps = gst_caps_new_simple ("audio/x-raw",
 +      "format", G_TYPE_STRING, FORMAT_STR,
        "rate", G_TYPE_INT, dec->header->rate,
 -      "channels", G_TYPE_INT, dec->header->nb_channels,
 -      "signed", G_TYPE_BOOLEAN, TRUE,
 -      "endianness", G_TYPE_INT, G_BYTE_ORDER,
 -      "width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
 +      "channels", G_TYPE_INT, dec->header->nb_channels, NULL);
  
-   if (!gst_pad_set_caps (dec->srcpad, caps))
+   if (!gst_pad_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec), caps))
      goto nego_failed;
  
    gst_caps_unref (caps);
@@@ -696,17 -369,12 +366,11 @@@ gst_speex_dec_parse_data (GstSpeexDec 
    if (!dec->frame_duration)
      goto not_negotiated;
  
-   if (timestamp != -1) {
-     dec->segment.position = timestamp;
-   } else {
-     timestamp = dec->segment.position;
-   }
 -  if (G_LIKELY (GST_BUFFER_SIZE (buf))) {
 -    data = GST_BUFFER_DATA (buf);
 -    size = GST_BUFFER_SIZE (buf);
--
-   if (buf) {
++  if (G_LIKELY (gst_buffer_get_size (buf))) {
      /* send data to the bitstream */
 -    speex_bits_read_from (&dec->bits, (char *) data, size);
 +    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
 +    speex_bits_read_from (&dec->bits, data, size);
 +    gst_buffer_unmap (buf, data, size);
  
      fpp = dec->header->frames_per_packet;
      bits = &dec->bits;
  
      GST_LOG_OBJECT (dec, "decoding frame %d/%d, %d bits remaining", i, fpp,
          bits ? speex_bits_remaining (bits) : -1);
 -
 +#if 0
-     res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad,
+     res =
+         gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec),
          GST_BUFFER_OFFSET_NONE, dec->frame_size * dec->header->nb_channels * 2,
-         GST_PAD_CAPS (dec->srcpad), &outbuf);
+         GST_PAD_CAPS (GST_AUDIO_DECODER_SRC_PAD (dec)), &outbuf);
  
      if (res != GST_FLOW_OK) {
        GST_DEBUG_OBJECT (dec, "buf alloc flow: %s", gst_flow_get_name (res));
@@@ -805,28 -455,8 +458,28 @@@ not_negotiated
    }
  }
  
 +static gboolean
 +memcmp_buffers (GstBuffer * buf1, GstBuffer * buf2)
 +{
 +  gsize size1, size2;
 +  gpointer data1;
 +  gboolean res;
 +
 +  size1 = gst_buffer_get_size (buf1);
 +  size2 = gst_buffer_get_size (buf2);
 +
 +  if (size1 != size2)
 +    return FALSE;
 +
 +  data1 = gst_buffer_map (buf1, NULL, NULL, GST_MAP_READ);
 +  res = gst_buffer_memcmp (buf2, 0, data1, size1) == 0;
 +  gst_buffer_unmap (buf1, data1, size1);
 +
 +  return res;
 +}
 +
  static GstFlowReturn
speex_dec_chain (GstPad * pad, GstBuffer * buf)
gst_speex_dec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buf)
  {
    GstFlowReturn res;
    GstSpeexDec *dec;
    /* If we have the streamheader and vorbiscomment from the caps already
     * ignore them here */
    if (dec->streamheader && dec->vorbiscomment) {
 -    if (GST_BUFFER_SIZE (dec->streamheader) == GST_BUFFER_SIZE (buf)
 -        && memcmp (GST_BUFFER_DATA (dec->streamheader), GST_BUFFER_DATA (buf),
 -            GST_BUFFER_SIZE (buf)) == 0) {
 +    if (memcmp_buffers (dec->streamheader, buf)) {
+       GST_DEBUG_OBJECT (dec, "found streamheader");
+       gst_audio_decoder_finish_frame (bdec, NULL, 1);
        res = GST_FLOW_OK;
 -    } else if (GST_BUFFER_SIZE (dec->vorbiscomment) == GST_BUFFER_SIZE (buf)
 -        && memcmp (GST_BUFFER_DATA (dec->vorbiscomment), GST_BUFFER_DATA (buf),
 -            GST_BUFFER_SIZE (buf)) == 0) {
 +    } else if (memcmp_buffers (dec->vorbiscomment, buf)) {
+       GST_DEBUG_OBJECT (dec, "found vorbiscomments");
+       gst_audio_decoder_finish_frame (bdec, NULL, 1);
        res = GST_FLOW_OK;
      } else {
-       res =
-           speex_dec_chain_parse_data (dec, buf, GST_BUFFER_TIMESTAMP (buf),
-           GST_BUFFER_DURATION (buf));
+       res = gst_speex_dec_parse_data (dec, buf);
      }
    } else {
      /* Otherwise fall back to packet counting and assume that the
@@@ -143,26 -121,55 +121,35 @@@ static void gst_speex_enc_get_property 
      GValue * value, GParamSpec * pspec);
  static void gst_speex_enc_set_property (GObject * object, guint prop_id,
      const GValue * value, GParamSpec * pspec);
- static GstStateChangeReturn gst_speex_enc_change_state (GstElement * element,
-     GstStateChange transition);
  
- static GstFlowReturn gst_speex_enc_encode (GstSpeexEnc * enc, gboolean flush);
+ static GstFlowReturn gst_speex_enc_encode (GstSpeexEnc * enc, GstBuffer * buf);
+ static gboolean gst_speex_enc_start (GstAudioEncoder * enc);
+ static gboolean gst_speex_enc_stop (GstAudioEncoder * enc);
+ static gboolean gst_speex_enc_set_format (GstAudioEncoder * enc,
+     GstAudioInfo * info);
+ static GstFlowReturn gst_speex_enc_handle_frame (GstAudioEncoder * enc,
+     GstBuffer * in_buf);
+ static gboolean gst_speex_enc_sink_event (GstAudioEncoder * enc,
+     GstEvent * event);
  
 -static void
 -gst_speex_enc_setup_interfaces (GType speexenc_type)
 -{
 -  static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
 -
 -  g_type_add_interface_static (speexenc_type, GST_TYPE_TAG_SETTER,
 -      &tag_setter_info);
 -
 -  GST_DEBUG_CATEGORY_INIT (speexenc_debug, "speexenc", 0, "Speex encoder");
 -}
 -
 -GST_BOILERPLATE_FULL (GstSpeexEnc, gst_speex_enc, GstAudioEncoder,
 -    GST_TYPE_AUDIO_ENCODER, gst_speex_enc_setup_interfaces);
 -
 -static void
 -gst_speex_enc_base_init (gpointer g_class)
 -{
 -  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
 -
 -  gst_element_class_add_pad_template (element_class,
 -      gst_static_pad_template_get (&src_factory));
 -  gst_element_class_add_pad_template (element_class,
 -      gst_static_pad_template_get (&sink_factory));
 -  gst_element_class_set_details_simple (element_class, "Speex audio encoder",
 -      "Codec/Encoder/Audio",
 -      "Encodes audio in Speex format", "Wim Taymans <wim@fluendo.com>");
 -}
 +#define gst_speex_enc_parent_class parent_class
- G_DEFINE_TYPE_WITH_CODE (GstSpeexEnc, gst_speex_enc, GST_TYPE_ELEMENT,
++G_DEFINE_TYPE_WITH_CODE (GstSpeexEnc, gst_speex_enc, GST_TYPE_AUDIO_ENCODER,
 +    G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL);
 +    G_IMPLEMENT_INTERFACE (GST_TYPE_PRESET, NULL));
  
  static void
  gst_speex_enc_class_init (GstSpeexEncClass * klass)
  {
    GObjectClass *gobject_class;
 +  GstElementClass *gstelement_class;
+   GstAudioEncoderClass *base_class;
  
    gobject_class = (GObjectClass *) klass;
 +  gstelement_class = (GstElementClass *) klass;
+   base_class = (GstAudioEncoderClass *) klass;
  
 +  gobject_class->finalize = gst_speex_enc_finalize;
    gobject_class->set_property = gst_speex_enc_set_property;
    gobject_class->get_property = gst_speex_enc_get_property;
  
            "The last status message", NULL,
            G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
  
-   gstelement_class->change_state =
-       GST_DEBUG_FUNCPTR (gst_speex_enc_change_state);
 -  gobject_class->finalize = gst_speex_enc_finalize;
 +  gst_element_class_add_pad_template (gstelement_class,
 +      gst_static_pad_template_get (&src_factory));
 +  gst_element_class_add_pad_template (gstelement_class,
 +      gst_static_pad_template_get (&sink_factory));
 +  gst_element_class_set_details_simple (gstelement_class, "Speex audio encoder",
 +      "Codec/Encoder/Audio",
 +      "Encodes audio in Speex format", "Wim Taymans <wim@fluendo.com>");
 +
 +  GST_DEBUG_CATEGORY_INIT (speexenc_debug, "speexenc", 0, "Speex encoder");
  }
  
  static void
@@@ -238,95 -239,27 +227,27 @@@ gst_speex_enc_finalize (GObject * objec
    G_OBJECT_CLASS (parent_class)->finalize (object);
  }
  
- static gboolean
- gst_speex_enc_sink_setcaps (GstPad * pad, GstCaps * caps)
- {
-   GstSpeexEnc *enc;
-   GstStructure *structure;
-   enc = GST_SPEEX_ENC (GST_PAD_PARENT (pad));
-   enc->setup = FALSE;
-   structure = gst_caps_get_structure (caps, 0);
-   gst_structure_get_int (structure, "channels", &enc->channels);
-   gst_structure_get_int (structure, "rate", &enc->rate);
-   gst_speex_enc_setup (enc);
-   return enc->setup;
- }
- static GstCaps *
- gst_speex_enc_sink_getcaps (GstPad * pad, GstCaps * filter)
+ static void
 -gst_speex_enc_init (GstSpeexEnc * enc, GstSpeexEncClass * klass)
++gst_speex_enc_init (GstSpeexEnc * enc)
  {
-   GstCaps *caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
-   GstCaps *peercaps = NULL;
-   GstSpeexEnc *enc = GST_SPEEX_ENC (gst_pad_get_parent_element (pad));
-   peercaps = gst_pad_peer_get_caps (enc->srcpad, filter);
-   if (peercaps) {
-     if (!gst_caps_is_empty (peercaps) && !gst_caps_is_any (peercaps)) {
-       GstStructure *ps = gst_caps_get_structure (peercaps, 0);
-       GstStructure *s = gst_caps_get_structure (caps, 0);
-       gint rate, channels;
-       if (gst_structure_get_int (ps, "rate", &rate)) {
-         gst_structure_fixate_field_nearest_int (s, "rate", rate);
-       }
-       if (gst_structure_get_int (ps, "channels", &channels)) {
-         gst_structure_fixate_field_nearest_int (s, "channels", channels);
-       }
-     }
-     gst_caps_unref (peercaps);
-   }
-   gst_object_unref (enc);
+   GstAudioEncoder *benc = GST_AUDIO_ENCODER (enc);
  
-   return caps;
+   /* arrange granulepos marking (and required perfect ts) */
+   gst_audio_encoder_set_mark_granule (benc, TRUE);
+   gst_audio_encoder_set_perfect_timestamp (benc, TRUE);
  }
  
  static gboolean
- gst_speex_enc_convert_src (GstPad * pad, GstFormat src_format, gint64 src_value,
-     GstFormat dest_format, gint64 * dest_value)
+ gst_speex_enc_start (GstAudioEncoder * benc)
  {
-   gboolean res = TRUE;
-   GstSpeexEnc *enc;
-   gint64 avg;
-   enc = GST_SPEEX_ENC (GST_PAD_PARENT (pad));
+   GstSpeexEnc *enc = GST_SPEEX_ENC (benc);
  
-   if (enc->samples_in == 0 || enc->bytes_out == 0 || enc->rate == 0)
-     return FALSE;
-   avg = (enc->bytes_out * enc->rate) / (enc->samples_in);
+   GST_DEBUG_OBJECT (enc, "start");
+   speex_bits_init (&enc->bits);
+   enc->tags = gst_tag_list_new ();
+   enc->header_sent = FALSE;
  
-   switch (src_format) {
-     case GST_FORMAT_BYTES:
-       switch (dest_format) {
-         case GST_FORMAT_TIME:
-           *dest_value = src_value * GST_SECOND / avg;
-           break;
-         default:
-           res = FALSE;
-       }
-       break;
-     case GST_FORMAT_TIME:
-       switch (dest_format) {
-         case GST_FORMAT_BYTES:
-           *dest_value = src_value * avg / GST_SECOND;
-           break;
-         default:
-           res = FALSE;
-       }
-       break;
-     default:
-       res = FALSE;
-   }
-   return res;
+   return TRUE;
  }
  
  static gboolean
@@@ -772,79 -496,22 +484,20 @@@ gst_speex_enc_setup (GstSpeexEnc * enc
  static GstFlowReturn
  gst_speex_enc_push_buffer (GstSpeexEnc * enc, GstBuffer * buffer)
  {
--  guint size;
-   size = gst_buffer_get_size (buffer);
-   enc->bytes_out += size;
--
 -  size = GST_BUFFER_SIZE (buffer);
--  GST_DEBUG_OBJECT (enc, "pushing output buffer of size %u", size);
-   return gst_pad_push (enc->srcpad, buffer);
- }
- static GstCaps *
- gst_speex_enc_set_header_on_caps (GstCaps * caps, GstBuffer * buf1,
-     GstBuffer * buf2)
- {
-   GstStructure *structure = NULL;
-   GstBuffer *buf;
-   GValue array = { 0 };
-   GValue value = { 0 };
-   caps = gst_caps_make_writable (caps);
-   structure = gst_caps_get_structure (caps, 0);
++  GST_DEBUG_OBJECT (enc, "pushing output buffer of size %u",
++      gst_buffer_get_size (buffer));
  
-   g_assert (gst_buffer_is_writable (buf1));
-   g_assert (gst_buffer_is_writable (buf2));
-   /* mark buffers */
-   GST_BUFFER_FLAG_SET (buf1, GST_BUFFER_FLAG_IN_CAPS);
-   GST_BUFFER_FLAG_SET (buf2, GST_BUFFER_FLAG_IN_CAPS);
-   /* put buffers in a fixed list */
-   g_value_init (&array, GST_TYPE_ARRAY);
-   g_value_init (&value, GST_TYPE_BUFFER);
-   buf = gst_buffer_copy (buf1);
-   gst_value_set_buffer (&value, buf);
-   gst_buffer_unref (buf);
-   gst_value_array_append_value (&array, &value);
-   g_value_unset (&value);
-   g_value_init (&value, GST_TYPE_BUFFER);
-   buf = gst_buffer_copy (buf2);
-   gst_value_set_buffer (&value, buf);
-   gst_buffer_unref (buf);
-   gst_value_array_append_value (&array, &value);
-   gst_structure_set_value (structure, "streamheader", &array);
-   g_value_unset (&value);
-   g_value_unset (&array);
-   return caps;
+   return gst_pad_push (GST_AUDIO_ENCODER_SRC_PAD (enc), buffer);
  }
  
  static gboolean
- gst_speex_enc_sink_event (GstPad * pad, GstEvent * event)
+ gst_speex_enc_sink_event (GstAudioEncoder * benc, GstEvent * event)
  {
-   gboolean res = TRUE;
    GstSpeexEnc *enc;
  
-   enc = GST_SPEEX_ENC (gst_pad_get_parent (pad));
+   enc = GST_SPEEX_ENC (benc);
  
    switch (GST_EVENT_TYPE (event)) {
-     case GST_EVENT_CAPS:
-     {
-       GstCaps *caps;
-       gst_event_parse_caps (event, &caps);
-       res = gst_speex_enc_sink_setcaps (pad, caps);
-       gst_event_unref (event);
-       break;
-     }
-     case GST_EVENT_EOS:
-       if (enc->setup)
-         gst_speex_enc_encode (enc, TRUE);
-       res = gst_pad_event_default (pad, event);
-       break;
      case GST_EVENT_TAG:
      {
        if (enc->tags) {
  }
  
  static GstFlowReturn
- gst_speex_enc_encode (GstSpeexEnc * enc, gboolean flush)
+ gst_speex_enc_encode (GstSpeexEnc * enc, GstBuffer * buf)
  {
    gint frame_size = enc->frame_size;
-   gint bytes = frame_size * 2 * enc->channels;
 -  gint bytes = frame_size * 2 * enc->channels, samples, size;
++  gint bytes = frame_size * 2 * enc->channels, samples;
+   gint outsize, written, dtx_ret = 0;
 -  guint8 *data;
++  guint8 *data, *bdata, *outdata;
++  gsize bsize, size;
+   GstBuffer *outbuf;
    GstFlowReturn ret = GST_FLOW_OK;
  
-   if (flush && gst_adapter_available (enc->adapter) % bytes != 0) {
-     guint diff = gst_adapter_available (enc->adapter) % bytes;
-     GstBuffer *buf = gst_buffer_new_and_alloc (diff);
-     gst_buffer_memset (buf, 0, 0, diff);
-     gst_adapter_push (enc->adapter, buf);
-   }
+   if (G_LIKELY (buf)) {
 -    data = GST_BUFFER_DATA (buf);
 -    size = GST_BUFFER_SIZE (buf);
++    bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
 -    if (G_UNLIKELY (size % bytes)) {
++    if (G_UNLIKELY (bsize % bytes)) {
+       GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
 -      size = ((size / bytes) + 1) * bytes;
 +
-   while (gst_adapter_available (enc->adapter) >= bytes) {
-     gint16 *data;
-     gint outsize, written, dtx_ret;
-     GstBuffer *outbuf;
-     gchar *outdata;
++      size = ((bsize / bytes) + 1) * bytes;
+       data = g_malloc0 (size);
 -      memcpy (data, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
++      memcpy (data, bdata, bsize);
++      gst_buffer_unmap (buf, bdata, bsize);
++      bdata = NULL;
++    } else {
++      data = bdata;
++      size = bsize;
+     }
+   } else {
+     GST_DEBUG_OBJECT (enc, "nothing to drain");
+     goto done;
+   }
  
-     data = (gint16 *) gst_adapter_take (enc->adapter, bytes);
+   samples = size / (2 * enc->channels);
+   speex_bits_reset (&enc->bits);
  
-     enc->samples_in += frame_size;
+   /* FIXME what about dropped samples if DTS enabled ?? */
  
+   while (size) {
      GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size, bytes);
  
      if (enc->channels == 2) {
-       speex_encode_stereo_int (data, frame_size, &enc->bits);
+       speex_encode_stereo_int ((gint16 *) data, frame_size, &enc->bits);
      }
-     dtx_ret = speex_encode_int (enc->state, data, &enc->bits);
-     g_free (data);
+     dtx_ret += speex_encode_int (enc->state, (gint16 *) data, &enc->bits);
  
-     enc->frameno++;
-     enc->frameno_out++;
+     data += bytes;
+     size -= bytes;
+   }
  
-     if ((enc->frameno % enc->nframes) != 0)
-       continue;
+   speex_bits_insert_terminator (&enc->bits);
+   outsize = speex_bits_nbytes (&enc->bits);
  
-     speex_bits_insert_terminator (&enc->bits);
-     outsize = speex_bits_nbytes (&enc->bits);
++  if (bdata)
++    gst_buffer_unmap (buf, bdata, bsize);
 +
 +#if 0
-     ret = gst_pad_alloc_buffer_and_set_caps (enc->srcpad,
-         GST_BUFFER_OFFSET_NONE, outsize, GST_PAD_CAPS (enc->srcpad), &outbuf);
-     if ((GST_FLOW_OK != ret))
-       goto done;
+   ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
+       GST_BUFFER_OFFSET_NONE, outsize,
+       GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);
+   if ((GST_FLOW_OK != ret))
+     goto done;
 +#endif
-     outbuf = gst_buffer_new_allocate (NULL, outsize, 0);
++  outbuf = gst_buffer_new_allocate (NULL, outsize, 0);
++  outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
  
-     outdata = gst_buffer_map (outbuf, NULL, NULL, GST_MAP_WRITE);
-     written = speex_bits_write (&enc->bits, outdata, outsize);
 -  written = speex_bits_write (&enc->bits,
 -      (gchar *) GST_BUFFER_DATA (outbuf), outsize);
++  written = speex_bits_write (&enc->bits, (gchar *) outdata, outsize);
  
-     if (G_UNLIKELY (written != outsize)) {
-       GST_ERROR_OBJECT (enc, "short write: %d < %d bytes", written, outsize);
-     }
-     gst_buffer_unmap (outbuf, outdata, written);
+   if (G_UNLIKELY (written < outsize)) {
+     GST_ERROR_OBJECT (enc, "short write: %d < %d bytes", written, outsize);
 -    GST_BUFFER_SIZE (outbuf) = written;
+   } else if (G_UNLIKELY (written > outsize)) {
+     GST_ERROR_OBJECT (enc, "overrun: %d > %d bytes", written, outsize);
++    written = outsize;
+   }
++  gst_buffer_unmap (outbuf, outdata, written);
+   if (!dtx_ret)
+     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
  
-     speex_bits_reset (&enc->bits);
+   ret = gst_audio_encoder_finish_frame (GST_AUDIO_ENCODER (enc),
+       outbuf, samples);
  
-     if (!dtx_ret)
-       GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_GAP);
+ done:
+   return ret;
+ }
  
-     GST_BUFFER_TIMESTAMP (outbuf) = enc->start_ts +
-         gst_util_uint64_scale_int ((enc->frameno_out -
-             enc->nframes) * frame_size - enc->lookahead, GST_SECOND, enc->rate);
-     GST_BUFFER_DURATION (outbuf) =
-         gst_util_uint64_scale_int (frame_size * enc->nframes, GST_SECOND,
-         enc->rate);
-     /* set gp time and granulepos; see gst-plugins-base/ext/ogg/README */
-     GST_BUFFER_OFFSET_END (outbuf) = enc->granulepos_offset +
-         ((enc->frameno_out) * frame_size - enc->lookahead);
-     GST_BUFFER_OFFSET (outbuf) =
-         gst_util_uint64_scale_int (GST_BUFFER_OFFSET_END (outbuf), GST_SECOND,
-         enc->rate);
+ /*
+  * (really really) FIXME: move into core (dixit tpm)
+  */
+ /**
+  * _gst_caps_set_buffer_array:
+  * @caps: a #GstCaps
+  * @field: field in caps to set
+  * @buf: header buffers
+  *
+  * Adds given buffers to an array of buffers set as the given @field
+  * on the given @caps.  List of buffer arguments must be NULL-terminated.
+  *
+  * Returns: input caps with a streamheader field added, or NULL if some error
+  */
+ static GstCaps *
+ _gst_caps_set_buffer_array (GstCaps * caps, const gchar * field,
+     GstBuffer * buf, ...)
+ {
+   GstStructure *structure = NULL;
+   va_list va;
+   GValue array = { 0 };
+   GValue value = { 0 };
  
-     ret = gst_speex_enc_push_buffer (enc, outbuf);
+   g_return_val_if_fail (caps != NULL, NULL);
+   g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
+   g_return_val_if_fail (field != NULL, NULL);
  
-     if ((GST_FLOW_OK != ret) && (GST_FLOW_NOT_LINKED != ret))
-       goto done;
+   caps = gst_caps_make_writable (caps);
+   structure = gst_caps_get_structure (caps, 0);
+   g_value_init (&array, GST_TYPE_ARRAY);
+   va_start (va, buf);
+   /* put buffers in a fixed list */
+   while (buf) {
 -    g_assert (gst_buffer_is_metadata_writable (buf));
++    g_assert (gst_buffer_is_writable (buf));
+     /* mark buffer */
+     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
+     g_value_init (&value, GST_TYPE_BUFFER);
+     buf = gst_buffer_copy (buf);
+     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS);
+     gst_value_set_buffer (&value, buf);
+     gst_buffer_unref (buf);
+     gst_value_array_append_value (&array, &value);
+     g_value_unset (&value);
+     buf = va_arg (va, GstBuffer *);
    }
  
- done:
+   gst_structure_set_value (structure, field, &array);
+   g_value_unset (&array);
  
-   return ret;
+   return caps;
  }
  
  static GstFlowReturn
@@@ -981,8 -684,11 +683,9 @@@ gst_speex_enc_handle_frame (GstAudioEnc
  
      /* create header buffer */
      data = (guint8 *) speex_header_to_packet (&enc->header, &data_len);
-     buf1 = gst_speex_enc_buffer_from_data (enc, data, data_len, 0);
-     free (data);
 -    buf1 = gst_buffer_new ();
 -    GST_BUFFER_DATA (buf1) = GST_BUFFER_MALLOCDATA (buf1) = data;
 -    GST_BUFFER_SIZE (buf1) = data_len;
++    buf1 = gst_buffer_new_wrapped (data, data_len);
+     GST_BUFFER_OFFSET_END (buf1) = 0;
+     GST_BUFFER_OFFSET (buf1) = 0;
  
      /* create comment buffer */
      buf2 = gst_speex_enc_create_metadata_buffer (enc);
  
      /* negotiate with these caps */
      GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
-     gst_pad_set_caps (enc->srcpad, caps);
-     gst_caps_unref (caps);
  
 -    gst_buffer_set_caps (buf1, caps);
 -    gst_buffer_set_caps (buf2, caps);
 -    gst_caps_unref (caps);
 -
      /* push out buffers */
      ret = gst_speex_enc_push_buffer (enc, buf1);
  
      enc->header_sent = TRUE;
    }
  
-   /* Save the timestamp of the first buffer. This will be later
-    * used as offset for all following buffers */
-   if (enc->start_ts == GST_CLOCK_TIME_NONE) {
-     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
-       enc->start_ts = GST_BUFFER_TIMESTAMP (buf);
-       enc->granulepos_offset = gst_util_uint64_scale
-           (GST_BUFFER_TIMESTAMP (buf), enc->rate, GST_SECOND);
-     } else {
-       enc->start_ts = 0;
-       enc->granulepos_offset = 0;
-     }
-   }
-   /* Check if we have a continous stream, if not drop some samples or the buffer or
-    * insert some silence samples */
-   if (enc->next_ts != GST_CLOCK_TIME_NONE &&
-       GST_BUFFER_TIMESTAMP_IS_VALID (buf) &&
-       GST_BUFFER_TIMESTAMP (buf) < enc->next_ts) {
-     guint64 diff = enc->next_ts - GST_BUFFER_TIMESTAMP (buf);
-     guint64 diff_bytes;
-     GST_WARNING_OBJECT (enc, "Buffer is older than previous "
-         "timestamp + duration (%" GST_TIME_FORMAT "< %" GST_TIME_FORMAT
-         "), cannot handle. Clipping buffer.",
-         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)),
-         GST_TIME_ARGS (enc->next_ts));
-     diff_bytes = GST_CLOCK_TIME_TO_FRAMES (diff, enc->rate) * enc->channels * 2;
-     if (diff_bytes >= gst_buffer_get_size (buf)) {
-       gst_buffer_unref (buf);
-       return GST_FLOW_OK;
-     }
-     buf = gst_buffer_make_writable (buf);
-     gst_buffer_resize (buf, diff_bytes, -1);
-     GST_BUFFER_TIMESTAMP (buf) += diff;
-     if (GST_BUFFER_DURATION_IS_VALID (buf))
-       GST_BUFFER_DURATION (buf) -= diff;
-   }
+   GST_DEBUG_OBJECT (enc, "received buffer %p of %u bytes", buf,
 -      buf ? GST_BUFFER_SIZE (buf) : 0);
++      buf ? gst_buffer_get_size (buf) : 0);
  
-   if (enc->next_ts != GST_CLOCK_TIME_NONE
-       && GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
-     guint64 max_diff =
-         gst_util_uint64_scale (enc->frame_size, GST_SECOND, enc->rate);
-     if (GST_BUFFER_TIMESTAMP (buf) != enc->next_ts &&
-         GST_BUFFER_TIMESTAMP (buf) - enc->next_ts > max_diff) {
-       GST_WARNING_OBJECT (enc,
-           "Discontinuity detected: %" G_GUINT64_FORMAT " > %" G_GUINT64_FORMAT,
-           GST_BUFFER_TIMESTAMP (buf) - enc->next_ts, max_diff);
-       gst_speex_enc_encode (enc, TRUE);
-       enc->frameno_out = 0;
-       enc->start_ts = GST_BUFFER_TIMESTAMP (buf);
-       enc->granulepos_offset = gst_util_uint64_scale
-           (GST_BUFFER_TIMESTAMP (buf), enc->rate, GST_SECOND);
-     }
-   }
-   if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)
-       && GST_BUFFER_DURATION_IS_VALID (buf))
-     enc->next_ts = GST_BUFFER_TIMESTAMP (buf) + GST_BUFFER_DURATION (buf);
-   else
-     enc->next_ts = GST_CLOCK_TIME_NONE;
-   GST_DEBUG_OBJECT (enc, "received buffer of %u bytes",
-       gst_buffer_get_size (buf));
-   /* push buffer to adapter */
-   gst_adapter_push (enc->adapter, buf);
-   buf = NULL;
-   ret = gst_speex_enc_encode (enc, FALSE);
+   ret = gst_speex_enc_encode (enc, buf);
  
  done:
-   if (buf)
-     gst_buffer_unref (buf);
    return ret;
-   /* ERRORS */
- not_setup:
-   {
-     GST_ELEMENT_ERROR (enc, CORE, NEGOTIATION, (NULL),
-         ("encoder not initialized (input is not audio?)"));
-     ret = GST_FLOW_NOT_NEGOTIATED;
-     goto done;
-   }
  }
  
  
@@@ -3971,19 -4036,14 +4046,15 @@@ build_btrt_extension (guint32 buffer_si
  {
    AtomData *atom_data;
    GstBuffer *buf;
 +  guint8 *data;
  
-   if (buffer_size_db == 0 && avg_bitrate == 0 && max_bitrate == 0)
-     return 0;
 -  buf = gst_buffer_new_and_alloc (12);
--
 -  GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), buffer_size_db);
 -  GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf) + 4, max_bitrate);
 -  GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf) + 8, avg_bitrate);
 +  data = g_malloc (12);
 +  GST_WRITE_UINT32_BE (data, buffer_size_db);
 +  GST_WRITE_UINT32_BE (data + 4, max_bitrate);
 +  GST_WRITE_UINT32_BE (data + 8, avg_bitrate);
  
-   atom_data =
-       atom_data_new_from_gst_buffer (GST_MAKE_FOURCC ('b', 't', 'r', 't'), buf);
 +  buf = _gst_buffer_new_wrapped (data, 12, g_free);
+   atom_data = atom_data_new_from_gst_buffer (FOURCC_btrt, buf);
    gst_buffer_unref (buf);
  
    return build_atom_info_wrapper ((Atom *) atom_data, atom_data_copy_data,
Simple merge
@@@ -2147,8 -2144,9 +2163,9 @@@ gst_qt_mux_add_buffer (GstQTMux * qtmux
      buf = pad->prepare_buf_func (pad, buf, qtmux);
    }
  
-   if (G_LIKELY (buf != NULL && GST_CLOCK_TIME_IS_VALID (pad->first_ts))) {
+   if (G_LIKELY (buf != NULL && GST_CLOCK_TIME_IS_VALID (pad->first_ts) &&
+           pad->first_ts != 0)) {
 -    buf = gst_buffer_make_metadata_writable (buf);
 +    buf = gst_buffer_make_writable (buf);
      check_and_subtract_ts (qtmux, &GST_BUFFER_TIMESTAMP (buf), pad->first_ts);
    }
    /* when we obtain the first_ts we subtract from all stored buffers we have,
Simple merge
Simple merge
Simple merge
Simple merge