ext/amrnb/amrnbdec.*: Fix amrnbdec, handle events, take copy from adapter since the decoder apparently writes in the ...

Original commit message from CVS:
* ext/amrnb/amrnbdec.c: (gst_amrnbdec_init),
(gst_amrnbdec_setcaps), (gst_amrnbdec_event), (gst_amrnbdec_chain),
(gst_amrnbdec_state_change):
* ext/amrnb/amrnbdec.h:
Fix amrnbdec, handle events, take copy from adapter since the decoder
apparently writes in the source data.
Use some _scale_int, and precalc duration.
Fix some leaks, post ERROR messages.
This commit is contained in:
Wim Taymans 2006-02-06 15:55:28 +00:00
parent 2dcf1494c2
commit b34a106764
4 changed files with 79 additions and 14 deletions

View file

@ -1,3 +1,14 @@
2006-02-06 Wim Taymans <wim@fluendo.com>
* ext/amrnb/amrnbdec.c: (gst_amrnbdec_init),
(gst_amrnbdec_setcaps), (gst_amrnbdec_event), (gst_amrnbdec_chain),
(gst_amrnbdec_state_change):
* ext/amrnb/amrnbdec.h:
Fix amrnbdec, handle events, take copy from adapter since the decoder
apparently writes in the source data.
Use some _scale_int, and precalc duration.
Fix some leaks, post ERROR messages.
2006-02-04 Tim-Philipp Müller <tim at centricular dot net> 2006-02-04 Tim-Philipp Müller <tim at centricular dot net>
* gst/realmedia/rmdemux.c: (gst_rmdemux_add_stream): * gst/realmedia/rmdemux.c: (gst_rmdemux_add_stream):

2
common

@ -1 +1 @@
Subproject commit 79d67fe009b6120b82d51df860c78e8361f02aea Subproject commit 58567e5519f2d00a4592491db1a6e8302993279e

View file

@ -48,6 +48,7 @@ static void gst_amrnbdec_base_init (GstAmrnbDecClass * klass);
static void gst_amrnbdec_class_init (GstAmrnbDecClass * klass); static void gst_amrnbdec_class_init (GstAmrnbDecClass * klass);
static void gst_amrnbdec_init (GstAmrnbDec * amrnbdec); static void gst_amrnbdec_init (GstAmrnbDec * amrnbdec);
static gboolean gst_amrnbdec_event (GstPad * pad, GstEvent * event);
static GstFlowReturn gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer);
static gboolean gst_amrnbdec_setcaps (GstPad * pad, GstCaps * caps); static gboolean gst_amrnbdec_setcaps (GstPad * pad, GstCaps * caps);
static GstStateChangeReturn gst_amrnbdec_state_change (GstElement * element, static GstStateChangeReturn gst_amrnbdec_state_change (GstElement * element,
@ -117,6 +118,7 @@ gst_amrnbdec_init (GstAmrnbDec * amrnbdec)
gst_pad_new_from_template (gst_static_pad_template_get (&sink_template), gst_pad_new_from_template (gst_static_pad_template_get (&sink_template),
"sink"); "sink");
gst_pad_set_setcaps_function (amrnbdec->sinkpad, gst_amrnbdec_setcaps); gst_pad_set_setcaps_function (amrnbdec->sinkpad, gst_amrnbdec_setcaps);
gst_pad_set_event_function (amrnbdec->sinkpad, gst_amrnbdec_event);
gst_pad_set_chain_function (amrnbdec->sinkpad, gst_amrnbdec_chain); gst_pad_set_chain_function (amrnbdec->sinkpad, gst_amrnbdec_chain);
gst_element_add_pad (GST_ELEMENT (amrnbdec), amrnbdec->sinkpad); gst_element_add_pad (GST_ELEMENT (amrnbdec), amrnbdec->sinkpad);
@ -133,7 +135,8 @@ gst_amrnbdec_init (GstAmrnbDec * amrnbdec)
amrnbdec->handle = NULL; amrnbdec->handle = NULL;
amrnbdec->channels = 0; amrnbdec->channels = 0;
amrnbdec->rate = 0; amrnbdec->rate = 0;
amrnbdec->ts = 0; amrnbdec->duration = 0;
amrnbdec->ts = -1;
} }
static gboolean static gboolean
@ -143,7 +146,7 @@ gst_amrnbdec_setcaps (GstPad * pad, GstCaps * caps)
GstAmrnbDec *amrnbdec; GstAmrnbDec *amrnbdec;
GstCaps *copy; GstCaps *copy;
amrnbdec = GST_AMRNBDEC (GST_PAD_PARENT (pad)); amrnbdec = GST_AMRNBDEC (gst_pad_get_parent (pad));
structure = gst_caps_get_structure (caps, 0); structure = gst_caps_get_structure (caps, 0);
@ -159,19 +162,54 @@ gst_amrnbdec_setcaps (GstPad * pad, GstCaps * caps)
"endianness", G_TYPE_INT, G_BYTE_ORDER, "endianness", G_TYPE_INT, G_BYTE_ORDER,
"rate", G_TYPE_INT, amrnbdec->rate, "signed", G_TYPE_BOOLEAN, TRUE, NULL); "rate", G_TYPE_INT, amrnbdec->rate, "signed", G_TYPE_BOOLEAN, TRUE, NULL);
amrnbdec->duration = gst_util_uint64_scale_int (GST_SECOND, 160,
amrnbdec->rate * amrnbdec->channels);
gst_pad_set_caps (amrnbdec->srcpad, copy); gst_pad_set_caps (amrnbdec->srcpad, copy);
gst_caps_unref (copy); gst_caps_unref (copy);
gst_object_unref (amrnbdec);
return TRUE; return TRUE;
} }
static gboolean
gst_amrnbdec_event (GstPad * pad, GstEvent * event)
{
GstAmrnbDec *amrnbdec;
gboolean ret = TRUE;
amrnbdec = GST_AMRNBDEC (gst_pad_get_parent (pad));
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
ret = gst_pad_push_event (amrnbdec->srcpad, event);
break;
case GST_EVENT_FLUSH_STOP:
ret = gst_pad_push_event (amrnbdec->srcpad, event);
gst_adapter_clear (amrnbdec->adapter);
amrnbdec->ts = -1;
break;
case GST_EVENT_EOS:
gst_adapter_clear (amrnbdec->adapter);
ret = gst_pad_push_event (amrnbdec->srcpad, event);
break;
default:
ret = gst_pad_push_event (amrnbdec->srcpad, event);
break;
}
gst_object_unref (amrnbdec);
return ret;
}
static GstFlowReturn static GstFlowReturn
gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer) gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
{ {
GstAmrnbDec *amrnbdec; GstAmrnbDec *amrnbdec;
GstFlowReturn ret; GstFlowReturn ret;
amrnbdec = GST_AMRNBDEC (GST_PAD_PARENT (pad)); amrnbdec = GST_AMRNBDEC (gst_pad_get_parent (pad));
if (amrnbdec->rate == 0 || amrnbdec->channels == 0) if (amrnbdec->rate == 0 || amrnbdec->channels == 0)
goto not_negotiated; goto not_negotiated;
@ -198,30 +236,35 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
if (gst_adapter_available (amrnbdec->adapter) < block) if (gst_adapter_available (amrnbdec->adapter) < block)
break; break;
data = (guint8 *) gst_adapter_peek (amrnbdec->adapter, block); data = (guint8 *) gst_adapter_take (amrnbdec->adapter, block);
/* get output */ /* get output */
out = gst_buffer_new_and_alloc (160 * 2); out = gst_buffer_new_and_alloc (160 * 2);
GST_BUFFER_DURATION (out) = GST_SECOND * 160 / GST_BUFFER_DURATION (out) = amrnbdec->duration;
(amrnbdec->rate * amrnbdec->channels);
GST_BUFFER_TIMESTAMP (out) = amrnbdec->ts; GST_BUFFER_TIMESTAMP (out) = amrnbdec->ts;
if (amrnbdec->ts != -1)
amrnbdec->ts += GST_BUFFER_DURATION (out); amrnbdec->ts += GST_BUFFER_DURATION (out);
gst_buffer_set_caps (out, gst_pad_get_caps (amrnbdec->srcpad)); gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbdec->srcpad));
/* decode */ /* decode, the library seems to write into the source data, hence
* the copy. */
Decoder_Interface_Decode (amrnbdec->handle, data, Decoder_Interface_Decode (amrnbdec->handle, data,
(short *) GST_BUFFER_DATA (out), 0); (short *) GST_BUFFER_DATA (out), 0);
g_free (data);
gst_adapter_flush (amrnbdec->adapter, block);
/* play */ /* play */
ret = gst_pad_push (amrnbdec->srcpad, out); ret = gst_pad_push (amrnbdec->srcpad, out);
} }
gst_object_unref (amrnbdec);
return ret; return ret;
/* ERRORS */
not_negotiated: not_negotiated:
{ {
GST_ELEMENT_ERROR (amrnbdec, STREAM, TYPE_NOT_FOUND, (NULL),
("Decoder is not initialized"));
gst_object_unref (amrnbdec);
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
} }
} }
@ -237,11 +280,13 @@ gst_amrnbdec_state_change (GstElement * element, GstStateChange transition)
switch (transition) { switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY: case GST_STATE_CHANGE_NULL_TO_READY:
if (!(amrnbdec->handle = Decoder_Interface_init ())) if (!(amrnbdec->handle = Decoder_Interface_init ()))
return GST_STATE_CHANGE_FAILURE; goto init_failed;
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_adapter_clear (amrnbdec->adapter); gst_adapter_clear (amrnbdec->adapter);
amrnbdec->ts = 0; amrnbdec->rate = 0;
amrnbdec->channels = 0;
amrnbdec->ts = -1;
break; break;
default: default:
break; break;
@ -258,4 +303,12 @@ gst_amrnbdec_state_change (GstElement * element, GstStateChange transition)
} }
return ret; return ret;
/* ERRORS */
init_failed:
{
GST_ELEMENT_ERROR (amrnbdec, LIBRARY, INIT, (NULL),
("Failed to open AMR Decoder"));
return GST_STATE_CHANGE_FAILURE;
}
} }

View file

@ -54,6 +54,7 @@ struct _GstAmrnbDec {
/* output settings */ /* output settings */
gint channels, rate; gint channels, rate;
gint duration;
}; };
struct _GstAmrnbDecClass { struct _GstAmrnbDecClass {