diff options
author | Michael Smith <msmith@xiph.org> | 2005-11-21 17:18:01 +0000 |
---|---|---|
committer | Michael Smith <msmith@xiph.org> | 2005-11-21 17:18:01 +0000 |
commit | 4b379f57270a99df9fff10f79d69dae421634b2e (patch) | |
tree | d30c4d919f88d98346f113bf92081d912ba28a41 | |
parent | e48904d47fb016a44729f876d0524f15d328b121 (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.
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | gst/auparse/gstauparse.c | 86 |
2 files changed, 74 insertions, 23 deletions
@@ -1,3 +1,14 @@ +2005-11-21 Michael Smith <msmith@fluendo.com> + + * 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. + 2005-11-21 Andy Wingo <wingo@pobox.com> * *.h: 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; |