mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 16:51:10 +00:00
ext/amrnb/: Further fancyfication.
Original commit message from CVS: * 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.
This commit is contained in:
parent
bc79caeb27
commit
0e71a39449
5 changed files with 60 additions and 26 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
2006-03-02 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* 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 <msmith@fluendo.com>
|
||||
|
||||
* ext/amrnb/amrnbenc.c: (gst_amrnbenc_chain):
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -214,30 +221,32 @@ gst_amrnbenc_chain (GstPad * pad, GstBuffer * buffer)
|
|||
|
||||
/* 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;
|
||||
|
|
|
@ -54,6 +54,7 @@ struct _GstAmrnbEnc {
|
|||
|
||||
/* input settings */
|
||||
gint channels, rate;
|
||||
gint duration;
|
||||
};
|
||||
|
||||
struct _GstAmrnbEncClass {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue