summaryrefslogtreecommitdiffstats
path: root/gst/auparse
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2005-11-21 17:18:01 +0000
committerMichael Smith <msmith@xiph.org>2005-11-21 17:18:01 +0000
commit4b379f57270a99df9fff10f79d69dae421634b2e (patch)
treed30c4d919f88d98346f113bf92081d912ba28a41 /gst/auparse
parente48904d47fb016a44729f876d0524f15d328b121 (diff)
gst/auparse/: Partially fix #161712. playbin still doesn't work on these files, (on the bug report, Andy says we aren...
Original commit message from CVS: * gst/auparse/Makefile.am: * gst/auparse/gstauparse.c: (gst_auparse_class_init), (gst_auparse_init), (gst_auparse_dispose), (gst_auparse_chain), (gst_auparse_change_state): * gst/auparse/gstauparse.h: Partially fix #161712. playbin still doesn't work on these files, (on the bug report, Andy says we aren't typefinding it for some reason?) but at least auparse isn't totally busted like it was before.
Diffstat (limited to 'gst/auparse')
-rw-r--r--gst/auparse/gstauparse.c86
1 files changed, 63 insertions, 23 deletions
diff --git a/gst/auparse/gstauparse.c b/gst/auparse/gstauparse.c
index 82abd601..57d0f418 100644
--- a/gst/auparse/gstauparse.c
+++ b/gst/auparse/gstauparse.c
@@ -76,6 +76,7 @@ enum
static void gst_auparse_base_init (gpointer g_class);
static void gst_auparse_class_init (GstAuParseClass * klass);
static void gst_auparse_init (GstAuParse * auparse);
+static void gst_auparse_dispose (GObject * object);
static GstFlowReturn gst_auparse_chain (GstPad * pad, GstBuffer * buf);
@@ -128,12 +129,16 @@ gst_auparse_base_init (gpointer g_class)
static void
gst_auparse_class_init (GstAuParseClass * klass)
{
+ GObjectClass *gobject_class;
GstElementClass *gstelement_class;
+ gobject_class = (GObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ gobject_class->dispose = gst_auparse_dispose;
+
gstelement_class->change_state = gst_auparse_change_state;
}
@@ -152,12 +157,26 @@ gst_auparse_init (GstAuParse * auparse)
gst_element_add_pad (GST_ELEMENT (auparse), auparse->srcpad);
auparse->offset = 0;
+ auparse->buffer_offset = 0;
+ auparse->adapter = gst_adapter_new ();
auparse->size = 0;
auparse->encoding = 0;
auparse->frequency = 0;
auparse->channels = 0;
}
+static void
+gst_auparse_dispose (GObject * object)
+{
+ GstAuParse *au = GST_AUPARSE (object);
+
+ if (au->adapter != NULL) {
+ g_object_unref (au->adapter);
+ au->adapter = NULL;
+ }
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
static GstFlowReturn
gst_auparse_chain (GstPad * pad, GstBuffer * buf)
{
@@ -168,6 +187,8 @@ gst_auparse_chain (GstPad * pad, GstBuffer * buf)
GstCaps *tempcaps;
gint law = 0, depth = 0, ieee = 0;
gchar layout[7];
+ GstBuffer *subbuf;
+ GstEvent *event;
layout[0] = 0;
@@ -181,7 +202,6 @@ gst_auparse_chain (GstPad * pad, GstBuffer * buf)
/* if we haven't seen any data yet... */
if (auparse->size == 0) {
- GstBuffer *newbuf;
guint32 *head = (guint32 *) data;
/* normal format is big endian (au is a Sparc format) */
@@ -316,16 +336,19 @@ Samples :
gst_caps_new_simple ((law == 1) ? "audio/x-mulaw" : "audio/x-alaw",
"rate", G_TYPE_INT, auparse->frequency,
"channels", G_TYPE_INT, auparse->channels, NULL);
+ auparse->sample_size = auparse->channels;
} else if (ieee) {
tempcaps = gst_caps_new_simple ("audio/x-raw-float",
"rate", G_TYPE_INT, auparse->frequency,
"channels", G_TYPE_INT, auparse->channels,
"endianness", G_TYPE_INT,
- auparse->le ? G_LITTLE_ENDIAN : G_BIG_ENDIAN, "width", G_TYPE_INT,
- depth, "buffer-frames", G_TYPE_INT, 0, NULL);
+ auparse->le ? G_LITTLE_ENDIAN : G_BIG_ENDIAN,
+ "width", G_TYPE_INT, depth, NULL);
+ auparse->sample_size = auparse->channels * depth / 8;
} else if (layout[0]) {
tempcaps = gst_caps_new_simple ("audio/x-adpcm",
"layout", G_TYPE_STRING, layout, NULL);
+ auparse->sample_size = 0;
} else {
tempcaps = gst_caps_new_simple ("audio/x-raw-int",
"rate", G_TYPE_INT, auparse->frequency,
@@ -334,44 +357,59 @@ Samples :
auparse->le ? G_LITTLE_ENDIAN : G_BIG_ENDIAN, "depth", G_TYPE_INT,
depth, "width", G_TYPE_INT, depth, "signed", G_TYPE_BOOLEAN, TRUE,
NULL);
+ auparse->sample_size = auparse->channels * depth / 8;
}
gst_pad_set_active (auparse->srcpad, TRUE);
gst_pad_set_caps (auparse->srcpad, tempcaps);
- if ((ret = gst_pad_alloc_buffer (auparse->srcpad, GST_BUFFER_OFFSET_NONE,
- size - (auparse->offset),
- GST_PAD_CAPS (auparse->srcpad), &newbuf)) != GST_FLOW_OK) {
- gst_buffer_unref (buf);
- g_object_unref (auparse);
- return ret;
- }
- ret = GST_FLOW_OK;
+ event = gst_event_new_newsegment (FALSE, 1.0, GST_FORMAT_DEFAULT,
+ 0, GST_CLOCK_TIME_NONE, 0);
+ gst_pad_push_event (auparse->srcpad, event);
- memcpy (GST_BUFFER_DATA (newbuf), data + (auparse->offset),
- size - (auparse->offset));
- GST_BUFFER_SIZE (newbuf) = size - (auparse->offset);
+ subbuf = gst_buffer_create_sub (buf, auparse->offset,
+ size - auparse->offset);
- GstEvent *event;
+ gst_buffer_unref (buf);
- event = NULL;
+ gst_adapter_push (auparse->adapter, subbuf);
+ } else {
+ gst_adapter_push (auparse->adapter, buf);
+ }
- event = gst_event_new_newsegment (FALSE, 1.0, GST_FORMAT_DEFAULT,
- 0, GST_CLOCK_TIME_NONE, 0);
+ if (auparse->sample_size) {
+ /* Ensure we push a buffer that's a multiple of the frame size downstream */
+ int avail = gst_adapter_available (auparse->adapter);
+ avail -= avail % auparse->sample_size;
- gst_pad_push_event (auparse->srcpad, event);
+ if (avail > 0) {
+ const guint8 *data = gst_adapter_peek (auparse->adapter, avail);
+ GstBuffer *newbuf;
- gst_buffer_unref (buf);
- g_object_unref (auparse);
- return gst_pad_push (auparse->srcpad, newbuf);
+ if ((ret = gst_pad_alloc_buffer (auparse->srcpad, auparse->buffer_offset,
+ avail, GST_PAD_CAPS (auparse->srcpad),
+ &newbuf)) == GST_FLOW_OK) {
+
+ memcpy (GST_BUFFER_DATA (newbuf), data, avail);
+ gst_adapter_flush (auparse->adapter, avail);
+ auparse->buffer_offset += avail;
+
+ ret = gst_pad_push (auparse->srcpad, newbuf);
+ }
+ } else
+ ret = GST_FLOW_OK;
+ } else {
+ /* It's something non-trivial (such as ADPCM), we don't understand it, so
+ * just push downstream and assume this will know what to do with it */
+ ret = gst_pad_push (auparse->srcpad, buf);
}
g_object_unref (auparse);
- return gst_pad_push (auparse->srcpad, buf);
+ return ret;
}
static GstStateChangeReturn
@@ -385,6 +423,8 @@ gst_auparse_change_state (GstElement * element, GstStateChange transition)
switch (transition) {
case GST_STATE_CHANGE_READY_TO_NULL:
+ gst_adapter_clear (auparse->adapter);
+ auparse->buffer_offset = 0;
auparse->offset = 0;
auparse->size = 0;
auparse->encoding = 0;