diff --git a/ChangeLog b/ChangeLog index 74a4eef6c9..e4bb883e54 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2006-03-02 Wim Taymans + + * ext/amrnb/amrnbdec.c: (gst_amrnbdec_init), + (gst_amrnbdec_setcaps), (gst_amrnbdec_chain), + (gst_amrnbdec_state_change): + * ext/amrnb/amrnbenc.c: (gst_amrnbenc_init), + (gst_amrnbenc_setcaps), (gst_amrnbenc_chain), + (gst_amrnbenc_state_change): + * ext/amrnb/amrnbenc.h: + * ext/amrnb/amrnbparse.c: (gst_amrnbparse_init), + (gst_amrnbparse_query): + Further fancyfication. + Use _take to get writable data from the adapter. + Precalc packet duration. + Handle disconts. + Forward _push to upstream. + Post error messages when something goes wrong. + Remove old code in amrnbparse. + Don't ignore query results from upstream. + 2006-03-02 Michael Smith * ext/amrnb/amrnbenc.c: (gst_amrnbenc_chain): diff --git a/ext/amrnb/amrnbdec.c b/ext/amrnb/amrnbdec.c index 131c97edfb..0749b7c4a7 100644 --- a/ext/amrnb/amrnbdec.c +++ b/ext/amrnb/amrnbdec.c @@ -133,10 +133,6 @@ gst_amrnbdec_init (GstAmrnbDec * amrnbdec) /* init rest */ amrnbdec->handle = NULL; - amrnbdec->channels = 0; - amrnbdec->rate = 0; - amrnbdec->duration = 0; - amrnbdec->ts = -1; } static gboolean @@ -214,6 +210,15 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer) if (amrnbdec->rate == 0 || amrnbdec->channels == 0) goto not_negotiated; + /* discontinuity, don't combine samples before and after the + * DISCONT */ + if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { + gst_adapter_clear (amrnbdec->adapter); + amrnbdec->ts = -1; + } + + /* take latest timestamp, FIXME timestamp is the one of the + * first buffer in the adapter. */ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) amrnbdec->ts = GST_BUFFER_TIMESTAMP (buffer); @@ -238,14 +243,14 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer) break; /* the library seems to write into the source data, hence * the copy. */ - data = (guint8 *) gst_adapter_take (amrnbdec->adapter, block); + data = gst_adapter_take (amrnbdec->adapter, block); /* get output */ out = gst_buffer_new_and_alloc (160 * 2); GST_BUFFER_DURATION (out) = amrnbdec->duration; GST_BUFFER_TIMESTAMP (out) = amrnbdec->ts; if (amrnbdec->ts != -1) - amrnbdec->ts += GST_BUFFER_DURATION (out); + amrnbdec->ts += amrnbdec->duration; gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbdec->srcpad)); /* decode */ diff --git a/ext/amrnb/amrnbenc.c b/ext/amrnb/amrnbenc.c index ad7d14fda3..4518d3a4a8 100644 --- a/ext/amrnb/amrnbenc.c +++ b/ext/amrnb/amrnbenc.c @@ -132,9 +132,6 @@ gst_amrnbenc_init (GstAmrnbEnc * amrnbenc) /* init rest */ amrnbenc->handle = NULL; - amrnbenc->channels = 0; - amrnbenc->rate = 0; - amrnbenc->ts = 0; } static void @@ -178,6 +175,10 @@ gst_amrnbenc_setcaps (GstPad * pad, GstCaps * caps) "channels", G_TYPE_INT, amrnbenc->channels, "rate", G_TYPE_INT, amrnbenc->rate, NULL); + /* precalc duration as it's constant now */ + amrnbenc->duration = gst_util_uint64_scale_int (160, GST_SECOND, + amrnbenc->rate * amrnbenc->channels); + gst_pad_set_caps (amrnbenc->srcpad, copy); gst_caps_unref (copy); @@ -197,12 +198,18 @@ gst_amrnbenc_chain (GstPad * pad, GstBuffer * buffer) if (amrnbenc->rate == 0 || amrnbenc->channels == 0) goto not_negotiated; + /* discontinuity clears adapter, FIXME, maybe we can set some + * encoder flag to mask the discont. */ + if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { + gst_adapter_clear (amrnbenc->adapter); + amrnbenc->ts = 0; + } + + /* take latest timestamp, FIXME timestamp is the one of the + * first buffer in the adapter. */ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) amrnbenc->ts = GST_BUFFER_TIMESTAMP (buffer); - /* The AMR encoder actually writes into the source data buffers it gets */ - buffer = gst_buffer_make_writable (buffer); - ret = GST_FLOW_OK; gst_adapter_push (amrnbenc->adapter, buffer); @@ -212,32 +219,34 @@ gst_amrnbenc_chain (GstPad * pad, GstBuffer * buffer) guint8 *data; gint outsize; - /* get output, max size is 32 */ + /* get output, max size is 32 */ out = gst_buffer_new_and_alloc (32); - GST_BUFFER_DURATION (out) = GST_SECOND * 160 / - (amrnbenc->rate * amrnbenc->channels); + GST_BUFFER_DURATION (out) = amrnbenc->duration; GST_BUFFER_TIMESTAMP (out) = amrnbenc->ts; - amrnbenc->ts += GST_BUFFER_DURATION (out); - gst_buffer_set_caps (out, gst_pad_get_caps (amrnbenc->srcpad)); + if (amrnbenc->ts != -1) + amrnbenc->ts += amrnbenc->duration; + gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbenc->srcpad)); - data = (guint8 *) gst_adapter_peek (amrnbenc->adapter, 320); + /* The AMR encoder actually writes into the source data buffers it gets */ + data = gst_adapter_take (amrnbenc->adapter, 320); /* encode */ outsize = Encoder_Interface_Encode (amrnbenc->handle, MR122, (short *) data, (guint8 *) GST_BUFFER_DATA (out), 0); - gst_adapter_flush (amrnbenc->adapter, 320); - GST_BUFFER_SIZE (out) = outsize; /* play */ - ret = gst_pad_push (amrnbenc->srcpad, out); + if ((ret = gst_pad_push (amrnbenc->srcpad, out)) != GST_FLOW_OK) + break; } - return ret; + /* ERRORS */ not_negotiated: { + GST_ELEMENT_ERROR (amrnbenc, STREAM, TYPE_NOT_FOUND, + (NULL), ("unknown type")); return GST_FLOW_NOT_NEGOTIATED; } } @@ -256,6 +265,8 @@ gst_amrnbenc_state_change (GstElement * element, GstStateChange transition) return GST_STATE_CHANGE_FAILURE; break; case GST_STATE_CHANGE_READY_TO_PAUSED: + amrnbenc->rate = 0; + amrnbenc->channels = 0; amrnbenc->ts = 0; gst_adapter_clear (amrnbenc->adapter); break; diff --git a/ext/amrnb/amrnbenc.h b/ext/amrnb/amrnbenc.h index 60fdf59b5d..be602a205f 100644 --- a/ext/amrnb/amrnbenc.h +++ b/ext/amrnb/amrnbenc.h @@ -54,6 +54,7 @@ struct _GstAmrnbEnc { /* input settings */ gint channels, rate; + gint duration; }; struct _GstAmrnbEncClass { diff --git a/ext/amrnb/amrnbparse.c b/ext/amrnb/amrnbparse.c index 6106d23d56..6bf5de0b0a 100644 --- a/ext/amrnb/amrnbparse.c +++ b/ext/amrnb/amrnbparse.c @@ -129,9 +129,6 @@ gst_amrnbparse_init (GstAmrnbParse * amrnbparse) GST_DEBUG_FUNCPTR (gst_amrnbparse_chain)); gst_pad_set_event_function (amrnbparse->sinkpad, GST_DEBUG_FUNCPTR (gst_amrnbparse_event)); -/* gst_pad_set_loop_function (amrnbparse->sinkpad, - GST_DEBUG_FUNCPTR (gst_amrnbparse_loop)); -*/ gst_pad_set_activate_function (amrnbparse->sinkpad, gst_amrnbparse_sink_activate); gst_element_add_pad (GST_ELEMENT (amrnbparse), amrnbparse->sinkpad); @@ -225,7 +222,7 @@ gst_amrnbparse_query (GstPad * pad, GstQuery * query) pformat = GST_FORMAT_BYTES; res = gst_pad_query_position (peer, &pformat, &pcur); - res = gst_pad_query_duration (peer, &pformat, &ptot); + res &= gst_pad_query_duration (peer, &pformat, &ptot); gst_object_unref (GST_OBJECT (peer)); if (res) { tot = amrnbparse->ts * ((gdouble) ptot / pcur);