Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 23 Nov 2011 10:08:39 +0000 (11:08 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 23 Nov 2011 10:08:39 +0000 (11:08 +0100)
Conflicts:
ext/opus/gstopusdec.c
ext/opus/gstopusenc.c
ext/opus/gstopusparse.c
gst/audiovisualizers/gstwavescope.c
gst/filter/Makefile.am
gst/filter/gstfilter.c
gst/filter/gstiir.c
gst/playondemand/gstplayondemand.c

1  2 
ext/opus/gstopusdec.c
ext/opus/gstopusenc.c

@@@ -235,25 -255,32 +246,30 @@@ opus_dec_chain_parse_data (GstOpusDec 
      size = 0;
    }
  
-   samples =
-       opus_packet_get_samples_per_frame (data,
-       dec->sample_rate) * opus_packet_get_nb_frames (data, size);
-   GST_DEBUG ("bandwidth %d", opus_packet_get_bandwidth (data));
-   GST_DEBUG ("samples %d", samples);
+   if (data) {
+     samples =
+         opus_packet_get_samples_per_frame (data,
+         dec->sample_rate) * opus_packet_get_nb_frames (data, size);
+     packet_size = samples * dec->n_channels * 2;
+     GST_DEBUG_OBJECT (dec, "bandwidth %d", opus_packet_get_bandwidth (data));
+     GST_DEBUG_OBJECT (dec, "samples %d", samples);
+   } else {
+     /* use maximum size (120 ms) as we do now know in advance how many samples
+        will be returned */
+     samples = 120 * dec->sample_rate / 1000;
+   }
 -  packet_size = samples * dec->n_channels * 2;
 -
 -  res = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_DECODER_SRC_PAD (dec),
 -      GST_BUFFER_OFFSET_NONE, packet_size,
 -      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));
 -    return res;
 +  packet_size = samples * dec->n_channels * 2;
 +  outbuf = gst_buffer_new_and_alloc (packet_size);
 +  if (!outbuf) {
 +    goto buffer_failed;
    }
  
 -  out_data = (gint16 *) GST_BUFFER_DATA (outbuf);
 +  out_data = (gint16 *) gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE);
  
-   GST_LOG_OBJECT (dec, "decoding %d samples, in size %u", samples, size);
    n = opus_decode (dec->state, data, size, out_data, samples, 0);
 +  gst_buffer_unmap (buf, data, size);
 +  gst_buffer_unmap (outbuf, out_data, out_size);
    if (n < 0) {
      GST_ELEMENT_ERROR (dec, STREAM, DECODE, ("Decoding error: %d", n), (NULL));
      return GST_FLOW_ERROR;
@@@ -330,28 -370,9 +365,13 @@@ memcmp_buffers (GstBuffer * buf1, GstBu
    if (size1 != size2)
      return FALSE;
  
 -  return !memcmp (GST_BUFFER_DATA (buf1), GST_BUFFER_DATA (buf2), size1);
 +  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 gboolean
- gst_opus_dec_is_header (GstBuffer * buf, const char *magic, guint magic_size)
- {
-   guint8 *data;
-   gsize size;
-   gboolean ret;
-   data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
-   if (!data)
-     return FALSE;
-   ret = (size >= magic_size && !memcmp (magic, data, magic_size));
-   gst_buffer_unmap (buf, data, size);
-   return ret;
- }
  static GstFlowReturn
  gst_opus_dec_handle_frame (GstAudioDecoder * adec, GstBuffer * buf)
  {
@@@ -80,8 -86,32 +86,33 @@@ gst_opus_enc_bandwidth_get_type (void
    return id;
  }
  
- #define FORMAT_STR GST_AUDIO_NE(S16)
+ #define GST_OPUS_ENC_TYPE_FRAME_SIZE (gst_opus_enc_frame_size_get_type())
+ static GType
+ gst_opus_enc_frame_size_get_type (void)
+ {
+   static const GEnumValue values[] = {
+     {2, "2.5", "2.5"},
+     {5, "5", "5"},
+     {10, "10", "10"},
+     {20, "20", "20"},
+     {40, "40", "40"},
+     {60, "60", "60"},
+     {0, NULL, NULL}
+   };
+   static volatile GType id = 0;
  
+   if (g_once_init_enter ((gsize *) & id)) {
+     GType _id;
+     _id = g_enum_register_static ("GstOpusEncFrameSize", values);
+     g_once_init_leave ((gsize *) & id, _id);
+   }
+   return id;
+ }
++#define FORMAT_STR GST_AUDIO_NE(S16)
  static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
      GST_PAD_SINK,
      GST_PAD_ALWAYS,
@@@ -224,11 -282,16 +263,18 @@@ gst_opus_enc_class_init (GstOpusEncClas
        PROP_PACKET_LOSS_PERCENT, g_param_spec_int ("packet-loss-percentage",
            "Loss percentage", "Packet loss percentage", 0, 100,
            DEFAULT_PACKET_LOSS_PERCENT,
-           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+           GST_PARAM_MUTABLE_PLAYING));
+   g_object_class_install_property (G_OBJECT_CLASS (klass),
+       PROP_MAX_PAYLOAD_SIZE, g_param_spec_uint ("max-payload-size",
+           "Max payload size", "Maximum payload size in bytes", 2, 1275,
+           DEFAULT_MAX_PAYLOAD_SIZE,
+           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
+           GST_PARAM_MUTABLE_PLAYING));
  
    gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_opus_enc_finalize);
 +
 +  GST_DEBUG_CATEGORY_INIT (opusenc_debug, "opusenc", 0, "Opus encoder");
  }
  
  static void
@@@ -525,47 -519,15 +503,14 @@@ gst_opus_enc_encode (GstOpusEnc * enc, 
  {
    guint8 *bdata, *data, *mdata = NULL;
    gsize bsize, size;
 -  gsize bytes;
 +  gsize bytes = enc->frame_samples * enc->n_channels * 2;
-   gsize bytes_per_packet =
-       (enc->bitrate * enc->frame_samples / enc->sample_rate + 4) / 8;
    gint ret = GST_FLOW_OK;
  
-   if (G_LIKELY (buf)) {
-     bdata = GST_BUFFER_DATA (buf);
-     bsize = GST_BUFFER_SIZE (buf);
-     if (G_UNLIKELY (bsize % bytes)) {
-       GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
-       size = ((bsize / bytes) + 1) * bytes;
-       mdata = g_malloc0 (size);
-       memcpy (mdata, bdata, bsize);
-       bdata = NULL;
-       data = mdata;
-     } else {
-       data = bdata;
-       size = bsize;
-     }
-   } else {
-     GST_DEBUG_OBJECT (enc, "nothing to drain");
-     goto done;
-   }
-   return ret;
- }
- static GstFlowReturn
- gst_opus_enc_encode (GstOpusEnc * enc, GstBuffer * buf)
- {
-   guint8 *bdata, *data, *mdata = NULL;
-   gsize bsize, size;
-   gsize bytes = enc->frame_samples * enc->n_channels * 2;
-   gsize bytes_per_packet =
-       (enc->bitrate * enc->frame_samples / enc->sample_rate + 4) / 8;
-   gint ret = GST_FLOW_OK;
+   g_mutex_lock (enc->property_lock);
  
 -  bytes = enc->frame_samples * enc->n_channels * 2;
    if (G_LIKELY (buf)) {
 -    bdata = GST_BUFFER_DATA (buf);
 -    bsize = GST_BUFFER_SIZE (buf);
 +    bdata = gst_buffer_map (buf, &bsize, NULL, GST_MAP_READ);
 +
      if (G_UNLIKELY (bsize % bytes)) {
        GST_DEBUG_OBJECT (enc, "draining; adding silence samples");
  
      goto done;
    }
  
 -
    while (size) {
 -    gint outsize;
 +    gint encoded_size;
 +    unsigned char *out_data;
 +    gsize out_size;
      GstBuffer *outbuf;
  
-     outbuf = gst_buffer_new_and_alloc (bytes_per_packet);
 -    ret = gst_pad_alloc_buffer_and_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc),
 -        GST_BUFFER_OFFSET_NONE, enc->max_payload_size,
 -        GST_PAD_CAPS (GST_AUDIO_ENCODER_SRC_PAD (enc)), &outbuf);
 -
 -    if (GST_FLOW_OK != ret)
++    outbuf = gst_buffer_new_and_alloc (enc->max_payload_size);
 +    if (!outbuf)
        goto done;
  
-     GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes) to %d bytes",
-         enc->frame_samples, bytes, bytes_per_packet);
+     GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)",
+         enc->frame_samples);
  
 -    outsize =
 +    out_data = gst_buffer_map (outbuf, &out_size, NULL, GST_MAP_WRITE);
 +    encoded_size =
          opus_encode (enc->state, (const gint16 *) data, enc->frame_samples,
-         out_data, bytes_per_packet);
 -        GST_BUFFER_DATA (outbuf), enc->max_payload_size);
++        out_data, enc->max_payload_size);
 +    gst_buffer_unmap (outbuf, out_data, out_size);
  
 -    if (outsize < 0) {
 -      GST_ERROR_OBJECT (enc, "Encoding failed: %d", outsize);
 +    if (encoded_size < 0) {
 +      GST_ERROR_OBJECT (enc, "Encoding failed: %d", encoded_size);
        ret = GST_FLOW_ERROR;
        goto done;
-     } else if (encoded_size != bytes_per_packet) {
 -    } else if (outsize > enc->max_payload_size) {
++    } else if (encoded_size > enc->max_payload_size) {
        GST_WARNING_OBJECT (enc,
-           "Encoded size %d is different from %d bytes per packet", encoded_size,
-           bytes_per_packet);
+           "Encoded size %d is higher than max payload size (%d bytes)",
+           outsize, enc->max_payload_size);
        ret = GST_FLOW_ERROR;
        goto done;
      }
  
  done:
  
 +  if (bdata)
 +    gst_buffer_unmap (buf, bdata, bsize);
+   g_mutex_unlock (enc->property_lock);
    if (mdata)
      g_free (mdata);