ext/wavpack/: Don't play audioconvert. As wavpack wants/outputs all samples with...
authorSebastian Dröge <slomo@circular-chaos.org>
Fri, 30 Mar 2007 04:50:11 +0000 (04:50 +0000)
committerSebastian Dröge <slomo@circular-chaos.org>
Fri, 30 Mar 2007 04:50:11 +0000 (04:50 +0000)
Original commit message from CVS:
* ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_reset),
(gst_wavpack_dec_init), (gst_wavpack_dec_sink_set_caps),
(gst_wavpack_dec_clip_outgoing_buffer),
(gst_wavpack_dec_post_tags), (gst_wavpack_dec_chain):
* ext/wavpack/gstwavpackdec.h:
* ext/wavpack/gstwavpackenc.c: (gst_wavpack_enc_reset),
(gst_wavpack_enc_sink_set_caps), (gst_wavpack_enc_set_wp_config),
(gst_wavpack_enc_chain):
* ext/wavpack/gstwavpackenc.h:
* ext/wavpack/gstwavpackparse.c:
Don't play audioconvert. As wavpack wants/outputs all samples with
width==32 and depth=[1,32] accept this and let audioconvert convert
to accepted formats instead of doing it in the element for n*8 depths.
This also adds support for non-n*8 depths and prevents some useless
memory allocations. Fixes #421598
Also add a workaround for bug #421542 in wavpackenc for now...
* tests/check/elements/wavpackdec.c: (GST_START_TEST):
* tests/check/elements/wavpackenc.c: (GST_START_TEST):
* tests/check/elements/wavpackparse.c: (GST_START_TEST):
Consider the change above in the unit tests and test if the correct
caps are accepted and set. Also check for GST_BUFFER_OFFSET_END in
the wavpackparse unit test.
* ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_init),
(gst_wavpack_dec_sink_set_caps):
Set caps on the src pad as soon as possible.
* ext/wavpack/gstwavpackdec.h:
* ext/wavpack/gstwavpackcommon.h:
* ext/wavpack/gstwavpackenc.h:
* ext/wavpack/gstwavpackparse.h:
Fix indention. gst-indent is now called by cicl.

ChangeLog
ext/wavpack/gstwavpackcommon.h
ext/wavpack/gstwavpackdec.c
ext/wavpack/gstwavpackdec.h
ext/wavpack/gstwavpackenc.c
ext/wavpack/gstwavpackenc.h
ext/wavpack/gstwavpackparse.c
ext/wavpack/gstwavpackparse.h
tests/check/elements/wavpackdec.c
tests/check/elements/wavpackenc.c
tests/check/elements/wavpackparse.c

index f5d5405..c6e4d54 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,38 @@
+2007-03-30  Sebastian Dröge  <slomo@circular-chaos.org>
+
+       * ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_reset),
+       (gst_wavpack_dec_init), (gst_wavpack_dec_sink_set_caps),
+       (gst_wavpack_dec_clip_outgoing_buffer),
+       (gst_wavpack_dec_post_tags), (gst_wavpack_dec_chain):
+       * ext/wavpack/gstwavpackdec.h:
+       * ext/wavpack/gstwavpackenc.c: (gst_wavpack_enc_reset),
+       (gst_wavpack_enc_sink_set_caps), (gst_wavpack_enc_set_wp_config),
+       (gst_wavpack_enc_chain):
+       * ext/wavpack/gstwavpackenc.h:
+       * ext/wavpack/gstwavpackparse.c:
+       Don't play audioconvert. As wavpack wants/outputs all samples with
+       width==32 and depth=[1,32] accept this and let audioconvert convert
+       to accepted formats instead of doing it in the element for n*8 depths.
+       This also adds support for non-n*8 depths and prevents some useless
+       memory allocations. Fixes #421598
+       Also add a workaround for bug #421542 in wavpackenc for now...
+       * tests/check/elements/wavpackdec.c: (GST_START_TEST):
+       * tests/check/elements/wavpackenc.c: (GST_START_TEST):
+       * tests/check/elements/wavpackparse.c: (GST_START_TEST):
+       Consider the change above in the unit tests and test if the correct
+       caps are accepted and set. Also check for GST_BUFFER_OFFSET_END in
+       the wavpackparse unit test.
+
+       * ext/wavpack/gstwavpackdec.c: (gst_wavpack_dec_init),
+       (gst_wavpack_dec_sink_set_caps):
+       Set caps on the src pad as soon as possible.
+
+       * ext/wavpack/gstwavpackdec.h:
+       * ext/wavpack/gstwavpackcommon.h:
+       * ext/wavpack/gstwavpackenc.h:
+       * ext/wavpack/gstwavpackparse.h:
+       Fix indention. gst-indent is now called by cicl.
+
 2007-03-28  Edward Hervey  <edward@fluendo.com>
 
        * gst/qtdemux/qtdemux.c: (gst_qtdemux_prepare_current_sample),
index cc654a8..3cf6e56 100644 (file)
@@ -28,9 +28,9 @@
 
 typedef struct
 {
-  guint32  byte_length;
-  guint8  *data;
-  guint8   id;
+  guint32 byte_length;
+  guint8 *data;
+  guint8 id;
 } GstWavpackMetadata;
 
 #define ID_UNIQUE               0x3f
index 1917117..8e46e61 100644 (file)
@@ -61,7 +61,7 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/x-wavpack, "
-        "width = (int) { 8, 16, 24, 32 }, "
+        "width = (int) [ 1, 32 ], "
         "channels = (int) [ 1, 2 ], "
         "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true")
     );
@@ -70,19 +70,21 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/x-raw-int, "
-        "width = (int) { 8, 16, 32 }, "
-        "depth = (int) [ 8, 32 ], "
+        "width = (int) 32, "
+        "depth = (int) [ 1, 32 ], "
         "channels = (int) [ 1, 2 ], "
         "rate = (int) [ 6000, 192000 ], "
         "endianness = (int) BYTE_ORDER, " "signed = (boolean) true")
     );
 
 static GstFlowReturn gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buffer);
+static gboolean gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps);
 static gboolean gst_wavpack_dec_sink_event (GstPad * pad, GstEvent * event);
 static void gst_wavpack_dec_finalize (GObject * object);
 static GstStateChangeReturn gst_wavpack_dec_change_state (GstElement * element,
     GstStateChange transition);
 static gboolean gst_wavpack_dec_sink_event (GstPad * pad, GstEvent * event);
+static void gst_wavpack_dec_post_tags (GstWavpackDec * dec);
 
 GST_BOILERPLATE (GstWavpackDec, gst_wavpack_dec, GstElement, GST_TYPE_ELEMENT);
 
@@ -125,7 +127,6 @@ gst_wavpack_dec_reset (GstWavpackDec * dec)
 
   dec->channels = 0;
   dec->sample_rate = 0;
-  dec->width = 0;
   dec->depth = 0;
 
   gst_segment_init (&dec->segment, GST_FORMAT_UNDEFINED);
@@ -137,6 +138,8 @@ gst_wavpack_dec_init (GstWavpackDec * dec, GstWavpackDecClass * gklass)
   dec->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
   gst_pad_set_chain_function (dec->sinkpad,
       GST_DEBUG_FUNCPTR (gst_wavpack_dec_chain));
+  gst_pad_set_setcaps_function (dec->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_wavpack_dec_sink_set_caps));
   gst_pad_set_event_function (dec->sinkpad,
       GST_DEBUG_FUNCPTR (gst_wavpack_dec_sink_event));
   gst_element_add_pad (GST_ELEMENT (dec), dec->sinkpad);
@@ -162,43 +165,40 @@ gst_wavpack_dec_finalize (GObject * object)
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
-static void
-gst_wavpack_dec_format_samples (GstWavpackDec * dec, guint8 * out_buffer,
-    int32_t * samples, guint num_samples)
+static gboolean
+gst_wavpack_dec_sink_set_caps (GstPad * pad, GstCaps * caps)
 {
-  switch (dec->width) {
-    case 8:{
-      gint8 *dst = (gint8 *) out_buffer;
-      gint8 *end = dst + (num_samples * dec->channels);
+  GstWavpackDec *dec = GST_WAVPACK_DEC (gst_pad_get_parent (pad));
+  GstStructure *structure = gst_caps_get_structure (caps, 0);
 
-      while (dst < end) {
-        *dst++ = (gint8) * samples++;
-      }
-      break;
-    }
-    case 16:{
-      gint16 *dst = (gint16 *) out_buffer;
-      gint16 *end = dst + (num_samples * dec->channels);
+  /* Check if we can set the caps here already */
+  if (gst_structure_get_int (structure, "channels", &dec->channels) &&
+      gst_structure_get_int (structure, "rate", &dec->sample_rate) &&
+      gst_structure_get_int (structure, "width", &dec->depth)) {
+    GstCaps *caps;
 
-      while (dst < end) {
-        *dst++ = (gint16) * samples++;
-      }
-      break;
-    }
-    case 24:
-    case 32:{
-      gint32 *dst = (gint32 *) out_buffer;
-      gint32 *end = dst + (num_samples * dec->channels);
+    caps = gst_caps_new_simple ("audio/x-raw-int",
+        "rate", G_TYPE_INT, dec->sample_rate,
+        "channels", G_TYPE_INT, dec->channels,
+        "depth", G_TYPE_INT, dec->depth,
+        "width", G_TYPE_INT, 32,
+        "endianness", G_TYPE_INT, G_BYTE_ORDER,
+        "signed", G_TYPE_BOOLEAN, TRUE, NULL);
 
-      while (dst < end) {
-        *dst++ = *samples++;
-      }
-      break;
-    }
-    default:
-      g_return_if_reached ();
-      break;
+    GST_DEBUG_OBJECT (dec, "setting caps %" GST_PTR_FORMAT, caps);
+
+    /* should always succeed */
+    gst_pad_set_caps (dec->srcpad, caps);
+    gst_caps_unref (caps);
+
+    /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something
+     * is decoded or after the format has changed */
+    gst_wavpack_dec_post_tags (dec);
   }
+
+  gst_object_unref (dec);
+
+  return TRUE;
 }
 
 static gboolean
@@ -220,7 +220,7 @@ gst_wavpack_dec_clip_outgoing_buffer (GstWavpackDec * dec, GstBuffer * buf)
       GST_BUFFER_TIMESTAMP (buf) = cstart;
       GST_BUFFER_DURATION (buf) -= diff;
 
-      diff = (dec->width / 8) * dec->channels
+      diff = 4 * dec->channels
           * GST_CLOCK_TIME_TO_FRAMES (diff, dec->sample_rate);
       GST_BUFFER_DATA (buf) += diff;
       GST_BUFFER_SIZE (buf) -= diff;
@@ -230,7 +230,7 @@ gst_wavpack_dec_clip_outgoing_buffer (GstWavpackDec * dec, GstBuffer * buf)
     if (diff > 0) {
       GST_BUFFER_DURATION (buf) -= diff;
 
-      diff = (dec->width / 8) * dec->channels
+      diff = 4 * dec->channels
           * GST_CLOCK_TIME_TO_FRAMES (diff, dec->sample_rate);
       GST_BUFFER_SIZE (buf) -= diff;
     }
@@ -243,7 +243,7 @@ gst_wavpack_dec_clip_outgoing_buffer (GstWavpackDec * dec, GstBuffer * buf)
 }
 
 static void
-gst_wavpack_dec_post_tags (GstWavpackDec * dec, WavpackHeader * wph)
+gst_wavpack_dec_post_tags (GstWavpackDec * dec)
 {
   GstTagList *list;
   GstFormat format_time = GST_FORMAT_TIME, format_bytes = GST_FORMAT_BYTES;
@@ -276,7 +276,6 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf)
   GstBuffer *outbuf;
   GstFlowReturn ret = GST_FLOW_OK;
   WavpackHeader wph;
-  int32_t *unpack_buf = NULL;
   int32_t decoded, unpacked_size;
   gboolean format_changed;
 
@@ -331,14 +330,12 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf)
     dec->sample_rate = WavpackGetSampleRate (dec->context);
     dec->channels = WavpackGetNumChannels (dec->context);
     dec->depth = WavpackGetBitsPerSample (dec->context);
-    dec->width =
-        (GST_ROUND_UP_8 (dec->depth) == 24) ? 32 : GST_ROUND_UP_8 (dec->depth);
 
     caps = gst_caps_new_simple ("audio/x-raw-int",
         "rate", G_TYPE_INT, dec->sample_rate,
         "channels", G_TYPE_INT, dec->channels,
         "depth", G_TYPE_INT, dec->depth,
-        "width", G_TYPE_INT, dec->width,
+        "width", G_TYPE_INT, 32,
         "endianness", G_TYPE_INT, G_BYTE_ORDER,
         "signed", G_TYPE_BOOLEAN, TRUE, NULL);
 
@@ -350,27 +347,25 @@ gst_wavpack_dec_chain (GstPad * pad, GstBuffer * buf)
 
     /* send GST_TAG_AUDIO_CODEC and GST_TAG_BITRATE tags before something
      * is decoded or after the format has changed */
-    gst_wavpack_dec_post_tags (dec, &wph);
+    gst_wavpack_dec_post_tags (dec);
   }
 
-  /* decode */
-  unpack_buf = g_new (int32_t, wph.block_samples * dec->channels);
-  decoded = WavpackUnpackSamples (dec->context, unpack_buf, wph.block_samples);
-  if (decoded != wph.block_samples)
-    goto decode_error;
-
   /* alloc output buffer */
-  unpacked_size = wph.block_samples * (dec->width / 8) * dec->channels;
+  unpacked_size = 4 * wph.block_samples * dec->channels;
   ret = gst_pad_alloc_buffer (dec->srcpad, GST_BUFFER_OFFSET (buf),
       unpacked_size, GST_PAD_CAPS (dec->srcpad), &outbuf);
+
   if (ret != GST_FLOW_OK)
     goto out;
 
-  /* put samples into the output buffer */
-  gst_wavpack_dec_format_samples (dec, GST_BUFFER_DATA (outbuf),
-      unpack_buf, wph.block_samples);
   gst_buffer_stamp (outbuf, buf);
 
+  /* decode */
+  decoded = WavpackUnpackSamples (dec->context,
+      (int32_t *) GST_BUFFER_DATA (outbuf), wph.block_samples);
+  if (decoded != wph.block_samples)
+    goto decode_error;
+
   if (gst_wavpack_dec_clip_outgoing_buffer (dec, outbuf)) {
     GST_LOG_OBJECT (dec, "pushing buffer with time %" GST_TIME_FORMAT,
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
@@ -385,7 +380,6 @@ out:
     GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (ret));
   }
 
-  g_free (unpack_buf);
   gst_buffer_unref (buf);
 
   return ret;
@@ -407,7 +401,7 @@ decode_error:
   {
     GST_ELEMENT_ERROR (dec, STREAM, DECODE, (NULL),
         ("Failed to decode wavpack stream"));
-    g_free (unpack_buf);
+    gst_buffer_unref (outbuf);
     gst_buffer_unref (buf);
     return GST_FLOW_ERROR;
   }
index dcae0a8..68380ca 100644 (file)
@@ -30,7 +30,6 @@
 #include "gstwavpackstreamreader.h"
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_WAVPACK_DEC \
   (gst_wavpack_dec_get_type())
 #define GST_WAVPACK_DEC(obj) \
@@ -48,23 +47,22 @@ struct _GstWavpackDec
 {
   GstElement element;
 
-  /*< private >*/
-  GstPad              *sinkpad;
-  GstPad              *srcpad;
+  /*< private > */
+  GstPad *sinkpad;
+  GstPad *srcpad;
 
-  WavpackContext      *context;
+  WavpackContext *context;
   WavpackStreamReader *stream_reader;
 
-  read_id              wv_id;
+  read_id wv_id;
 
-  GstSegment           segment; /* used for clipping, TIME format */
+  GstSegment segment;           /* used for clipping, TIME format */
 
-  guint                sample_rate;
-  guint                width;
-  guint                depth;
-  guint                channels;
+  gint sample_rate;
+  gint depth;
+  gint channels;
 
-  gint                 error_count;
+  gint error_count;
 };
 
 struct _GstWavpackDecClass
index 5761013..c1d2596 100644 (file)
@@ -108,26 +108,8 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/x-raw-int, "
         "width = (int) 32, "
-        "depth = (int) 32, "
-        "endianness = (int) LITTLE_ENDIAN, "
-        "channels = (int) [ 1, 2 ], "
-        "rate = (int) [ 6000, 192000 ]," "signed = (boolean) TRUE;"
-        "audio/x-raw-int, "
-        "width = (int) 24, "
-        "depth = (int) 24, "
-        "endianness = (int) LITTLE_ENDIAN, "
-        "channels = (int) [ 1, 2 ], "
-        "rate = (int) [ 6000, 192000 ]," "signed = (boolean) TRUE;"
-        "audio/x-raw-int, "
-        "width = (int) 16, "
-        "depth = (int) 16, "
-        "endianness = (int) LITTLE_ENDIAN, "
-        "channels = (int) [ 1, 2 ], "
-        "rate = (int) [ 6000, 192000 ]," "signed = (boolean) TRUE;"
-        "audio/x-raw-int, "
-        "width = (int) 8, "
-        "depth = (int) 8, "
-        "endianness = (int) LITTLE_ENDIAN, "
+        "depth = (int) [ 1, 32], "
+        "endianness = (int) BYTE_ORDER, "
         "channels = (int) [ 1, 2 ], "
         "rate = (int) [ 6000, 192000 ]," "signed = (boolean) TRUE")
     );
@@ -136,7 +118,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS ("audio/x-wavpack, "
-        "width = (int) { 8, 16, 24, 32 }, "
+        "width = (int) [ 1, 32 ], "
         "channels = (int) [ 1, 2 ], "
         "rate = (int) [ 6000, 192000 ], " "framed = (boolean) TRUE")
     );
@@ -343,7 +325,7 @@ gst_wavpack_enc_reset (GstWavpackEnc * enc)
 
   /* reset stream information */
   enc->samplerate = 0;
-  enc->width = 0;
+  enc->depth = 0;
   enc->channels = 0;
 }
 
@@ -389,14 +371,13 @@ gst_wavpack_enc_sink_set_caps (GstPad * pad, GstCaps * caps)
 {
   GstWavpackEnc *enc = GST_WAVPACK_ENC (gst_pad_get_parent (pad));
   GstStructure *structure = gst_caps_get_structure (caps, 0);
-  int depth = 0;
 
+  /* FIXME: Workaround for bug #421543: calls gst_pad_accept_caps() */
   /* check caps and put relevant parts into our object attributes */
-  if (!gst_structure_get_int (structure, "channels", &enc->channels) ||
+  if (!gst_pad_accept_caps (pad, caps) ||
+      !gst_structure_get_int (structure, "channels", &enc->channels) ||
       !gst_structure_get_int (structure, "rate", &enc->samplerate) ||
-      !gst_structure_get_int (structure, "width", &enc->width) ||
-      !(gst_structure_get_int (structure, "depth", &depth) ||
-          depth != enc->width)) {
+      !gst_structure_get_int (structure, "depth", &enc->depth)) {
     GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL),
         ("got invalid caps: %" GST_PTR_FORMAT, caps));
     gst_object_unref (enc);
@@ -407,7 +388,7 @@ gst_wavpack_enc_sink_set_caps (GstPad * pad, GstCaps * caps)
   caps = gst_caps_new_simple ("audio/x-wavpack",
       "channels", G_TYPE_INT, enc->channels,
       "rate", G_TYPE_INT, enc->samplerate,
-      "width", G_TYPE_INT, enc->width, "framed", G_TYPE_BOOLEAN, TRUE, NULL);
+      "width", G_TYPE_INT, enc->depth, "framed", G_TYPE_BOOLEAN, TRUE, NULL);
 
   if (!gst_pad_set_caps (enc->srcpad, caps)) {
     GST_ELEMENT_ERROR (enc, LIBRARY, INIT, (NULL),
@@ -428,8 +409,8 @@ gst_wavpack_enc_set_wp_config (GstWavpackEnc * enc)
 {
   enc->wp_config = g_new0 (WavpackConfig, 1);
   /* set general stream informations in the WavpackConfig */
-  enc->wp_config->bytes_per_sample = (enc->width + 7) >> 3;
-  enc->wp_config->bits_per_sample = enc->width;
+  enc->wp_config->bytes_per_sample = GST_ROUND_UP_8 (enc->depth) / 8;
+  enc->wp_config->bits_per_sample = enc->depth;
   enc->wp_config->num_channels = enc->channels;
 
   /* TODO: handle more than 2 channels correctly! */
@@ -540,46 +521,6 @@ gst_wavpack_enc_set_wp_config (GstWavpackEnc * enc)
   }
 }
 
-static int32_t *
-gst_wavpack_enc_format_samples (const uchar * src_data, uint32_t sample_count,
-    guint width)
-{
-  int32_t *data = g_new0 (int32_t, sample_count);
-
-  /* put all samples into an int32_t*, no matter what
-   * width we have and convert them from little endian
-   * to host byte order */
-
-  switch (width) {
-      int i;
-
-    case 8:
-      for (i = 0; i < sample_count; i++)
-        data[i] = (int32_t) (int8_t) src_data[i];
-      break;
-    case 16:
-      for (i = 0; i < sample_count; i++)
-        data[i] = (int32_t) src_data[2 * i]
-            | ((int32_t) (int8_t) src_data[2 * i + 1] << 8);
-      break;
-    case 24:
-      for (i = 0; i < sample_count; i++)
-        data[i] = (int32_t) src_data[3 * i]
-            | ((int32_t) src_data[3 * i + 1] << 8)
-            | ((int32_t) (int8_t) src_data[3 * i + 2] << 16);
-      break;
-    case 32:
-      for (i = 0; i < sample_count; i++)
-        data[i] = (int32_t) src_data[4 * i]
-            | ((int32_t) src_data[4 * i + 1] << 8)
-            | ((int32_t) src_data[4 * i + 2] << 16)
-            | ((int32_t) (int8_t) src_data[4 * i + 3] << 24);
-      break;
-  }
-
-  return data;
-}
-
 static int
 gst_wavpack_enc_push_block (void *id, void *data, int32_t count)
 {
@@ -663,8 +604,7 @@ static GstFlowReturn
 gst_wavpack_enc_chain (GstPad * pad, GstBuffer * buf)
 {
   GstWavpackEnc *enc = GST_WAVPACK_ENC (gst_pad_get_parent (pad));
-  uint32_t sample_count = GST_BUFFER_SIZE (buf) / ((enc->width + 7) >> 3);
-  int32_t *data;
+  uint32_t sample_count = GST_BUFFER_SIZE (buf) / 4;
   GstFlowReturn ret;
 
   /* reset the last returns to GST_FLOW_OK. This is only set to something else
@@ -712,17 +652,9 @@ gst_wavpack_enc_chain (GstPad * pad, GstBuffer * buf)
     MD5Update (enc->md5_context, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
   }
 
-  /* put all samples into an int32_t*, no matter what
-   * width we have and convert them from little endian
-   * to host byte order */
-  data =
-      gst_wavpack_enc_format_samples (GST_BUFFER_DATA (buf), sample_count,
-      enc->width);
-
-  gst_buffer_unref (buf);
-
   /* encode and handle return values from encoding */
-  if (WavpackPackSamples (enc->wp_context, data, sample_count / enc->channels)) {
+  if (WavpackPackSamples (enc->wp_context, (int32_t *) GST_BUFFER_DATA (buf),
+          sample_count / enc->channels)) {
     GST_DEBUG ("encoding samples successful");
     ret = GST_FLOW_OK;
   } else {
@@ -745,7 +677,7 @@ gst_wavpack_enc_chain (GstPad * pad, GstBuffer * buf)
     }
   }
 
-  g_free (data);
+  gst_buffer_unref (buf);
   gst_object_unref (enc);
   return ret;
 }
index 35d796f..617a2f6 100644 (file)
@@ -28,7 +28,6 @@
 #include "md5.h"
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_WAVPACK_ENC \
   (gst_wavpack_enc_get_type())
 #define GST_WAVPACK_ENC(obj) \
@@ -39,7 +38,6 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAVPACK_ENC))
 #define GST_IS_WAVPACK_ENC_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAVPACK_ENC))
-
 typedef struct _GstWavpackEnc GstWavpackEnc;
 typedef struct _GstWavpackEncClass GstWavpackEncClass;
 
@@ -54,7 +52,7 @@ struct _GstWavpackEnc
 {
   GstElement element;
 
-  /*< private >*/
+  /*< private > */
   GstPad *sinkpad, *srcpad;
   GstPad *wvcsrcpad;
 
@@ -66,7 +64,7 @@ struct _GstWavpackEnc
 
   gint samplerate;
   gint channels;
-  gint width;
+  gint depth;
 
   GstWavpackEncWriteID wv_id;
   GstWavpackEncWriteID wvc_id;
@@ -93,5 +91,4 @@ GType gst_wavpack_enc_get_type (void);
 gboolean gst_wavpack_enc_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-
 #endif /* __GST_WAVPACK_ENC_H__ */
index c484a10..70d5407 100644 (file)
@@ -65,7 +65,7 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS ("audio/x-wavpack, "
-        "width = (int) { 8, 16, 24, 32 }, "
+        "width = (int) [ 1, 32 ], "
         "channels = (int) [ 1, 2 ], "
         "rate = (int) [ 6000, 192000 ], " "framed = (boolean) true")
     );
index ed7db73..7729c0f 100644 (file)
@@ -26,7 +26,6 @@
 #include <gst/base/gstadapter.h>
 
 G_BEGIN_DECLS
-
 #define GST_TYPE_WAVPACK_PARSE \
   (gst_wavpack_parse_get_type())
 #define GST_WAVPACK_PARSE(obj) \
@@ -37,58 +36,57 @@ G_BEGIN_DECLS
   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAVPACK_PARSE))
 #define GST_IS_WAVPACK_PARSE_CLASS(klass) \
   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAVPACK_PARSE))
-
-typedef struct _GstWavpackParse           GstWavpackParse;
-typedef struct _GstWavpackParseClass      GstWavpackParseClass;
+typedef struct _GstWavpackParse GstWavpackParse;
+typedef struct _GstWavpackParseClass GstWavpackParseClass;
 typedef struct _GstWavpackParseIndexEntry GstWavpackParseIndexEntry;
 
-struct _GstWavpackParseIndexEntry {
-  gint64 byte_offset;          /* byte offset of this chunk  */
-  gint64 sample_offset;        /* first sample in this chunk */
-  gint64 sample_offset_end;    /* first sample in next chunk  */
+struct _GstWavpackParseIndexEntry
+{
+  gint64 byte_offset;           /* byte offset of this chunk  */
+  gint64 sample_offset;         /* first sample in this chunk */
+  gint64 sample_offset_end;     /* first sample in next chunk  */
 };
 
 struct _GstWavpackParse
 {
-  GstElement     element;
+  GstElement element;
 
-  /*< private >*/
-  GstPad        *sinkpad;
-  GstPad        *srcpad;
-  
-  guint          samplerate;
-  guint          channels;
-  guint          total_samples;
+  /*< private > */
+  GstPad *sinkpad;
+  GstPad *srcpad;
 
-  gboolean       need_newsegment;
+  guint samplerate;
+  guint channels;
+  guint total_samples;
 
-  gint64         current_offset;   /* byte offset on sink pad */
-  gint64         upstream_length;  /* length of file in bytes */
+  gboolean need_newsegment;
 
-  GstSegment     segment;     /* the currently configured segment, in
-                               * samples/audio frames (DEFAULT format) */
+  gint64 current_offset;        /* byte offset on sink pad */
+  gint64 upstream_length;       /* length of file in bytes */
 
-  GstAdapter    *adapter;     /* when operating chain-based, otherwise NULL */
+  GstSegment segment;           /* the currently configured segment, in
+                                 * samples/audio frames (DEFAULT format) */
+
+  GstAdapter *adapter;          /* when operating chain-based, otherwise NULL */
 
   /* Array of GstWavpackParseIndexEntry structs, mapping known
    * sample offsets to byte offsets. Is kept increasing without
    * gaps (ie. append only and consecutive entries must always
    * map to consecutive chunks in the file). */
-  GArray        *entries;
+  GArray *entries;
 
   /* Queued events (e.g. tag events we receive before we create the src pad) */
-  GList         *queued_events;  /* STREAM_LOCK */
+  GList *queued_events;         /* STREAM_LOCK */
 };
 
-struct _GstWavpackParseClass 
+struct _GstWavpackParseClass
 {
   GstElementClass parent;
 };
 
 GType gst_wavpack_parse_get_type (void);
 
-gboolean gst_wavpack_parse_plugin_init (GstPlugin *plugin);
+gboolean gst_wavpack_parse_plugin_init (GstPlugin * plugin);
 
 G_END_DECLS
-
 #endif /* __GST_WAVPACK_PARSE_H__ */
index b058a5e..812944c 100644 (file)
@@ -51,7 +51,13 @@ guint8 test_frame[] = {
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
+    GST_STATIC_CAPS ("audio/x-raw-int, "
+        "width = (int) 32, "
+        "depth = (int) 16, "
+        "channels = (int) 1, "
+        "rate = (int) 44100, "
+        "endianness = (int) BYTE_ORDER, " "signed = (boolean) true")
+    );
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -117,11 +123,11 @@ GST_START_TEST (test_decode_frame)
   outbuffer = GST_BUFFER (buffers->data);
 
   fail_if (outbuffer == NULL);
-  /* uncompressed data should be 51200 bytes */
-  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), 51200);
+  /* uncompressed data should be 102400 bytes */
+  fail_unless_equals_int (GST_BUFFER_SIZE (outbuffer), 102400);
 
-  /* and all 51200 bytes must be 0, i.e. silence */
-  for (i = 0; i < 51200; i++)
+  /* and all 102400 bytes must be 0, i.e. silence */
+  for (i = 0; i < 102400; i++)
     fail_unless_equals_int (GST_BUFFER_DATA (outbuffer)[i], 0);
 
   ASSERT_BUFFER_REFCOUNT (outbuffer, "outbuffer", 1);
index 3ac3ea3..a22d2ac 100644 (file)
@@ -31,7 +31,7 @@ static GstPad *mysrcpad, *mysinkpad;
 static GstBus *bus;
 
 #define RAW_CAPS_STRING "audio/x-raw-int, " \
-                        "width = (int) 16, " \
+                        "width = (int) 32, " \
                         "depth = (int) 16, " \
                         "channels = (int) 1, " \
                         "rate = (int) 44100, " \
@@ -47,11 +47,20 @@ static GstBus *bus;
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
+    GST_STATIC_CAPS ("audio/x-wavpack, "
+        "width = (int) 16, "
+        "channels = (int) 1, "
+        "rate = (int) 44100, " "framed = (boolean) true"));
+
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
+    GST_STATIC_CAPS ("audio/x-raw-int, "
+        "width = (int) 32, "
+        "depth = (int) 16, "
+        "channels = (int) 1, "
+        "rate = (int) 44100, "
+        "endianness = (int) BYTE_ORDER, " "signed = (boolean) true"));
 
 GstElement *
 setup_wavpackenc ()
@@ -126,8 +135,8 @@ GST_START_TEST (test_encode_silence)
 
   fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 0);
   fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 0);
-  fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 11337868);
-  fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 500);
+  fail_unless_equals_int (GST_BUFFER_DURATION (outbuffer), 5668934);
+  fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 250);
 
   fail_unless (memcmp (GST_BUFFER_DATA (outbuffer), "wvpk", 4) == 0,
       "Failed to encode to valid Wavpack frames");
index 80cef39..7a3b8cc 100644 (file)
@@ -59,7 +59,11 @@ guint8 test_file[] = {
 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
     GST_PAD_SINK,
     GST_PAD_ALWAYS,
-    GST_STATIC_CAPS_ANY);
+    GST_STATIC_CAPS ("audio/x-wavpack, "
+        "width = (int) 16, "
+        "channels = (int) 1, "
+        "rate = (int) 44100, " "framed = (boolean) TRUE"));
+
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -175,11 +179,13 @@ GST_START_TEST (test_parsing_valid_frames)
       case 0:{
         fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 0);
         fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 0);
+        fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 25600);
         break;
       }
       case 1:{
         fail_unless_equals_int (GST_BUFFER_TIMESTAMP (outbuffer), 580498866);
         fail_unless_equals_int (GST_BUFFER_OFFSET (outbuffer), 25600);
+        fail_unless_equals_int (GST_BUFFER_OFFSET_END (outbuffer), 51200);
         break;
       }
     }