ext/amrnb/: Add newsegment and discont handling. Some code cleanups.

Original commit message from CVS:
* ext/amrnb/amrnbdec.c: (gst_amrnbdec_base_init),
(gst_amrnbdec_event), (gst_amrnbdec_chain),
(gst_amrnbdec_state_change):
* ext/amrnb/amrnbdec.h:
* ext/amrnb/amrnbparse.c: (gst_amrnbparse_base_init),
(gst_amrnbparse_loop):
Add newsegment and discont handling. Some code cleanups.
This commit is contained in:
Stefan Kost 2007-06-25 11:46:24 +00:00
parent 921e4a2ff4
commit f2a1c99445
5 changed files with 66 additions and 5 deletions

View file

@ -1,3 +1,13 @@
2007-06-20 Stefan Kost <ensonic@users.sf.net>
* ext/amrnb/amrnbdec.c: (gst_amrnbdec_base_init),
(gst_amrnbdec_event), (gst_amrnbdec_chain),
(gst_amrnbdec_state_change):
* ext/amrnb/amrnbdec.h:
* ext/amrnb/amrnbparse.c: (gst_amrnbparse_base_init),
(gst_amrnbparse_loop):
Add newsegment and discont handling. Some code cleanups.
2007-06-25 David Schleef <ds@schleef.org>
* ext/dvdread/dvdreadsrc.c: check for an error from

2
common

@ -1 +1 @@
Subproject commit 14c5a68981278f642e4ca5fd5ca08554fc78b348
Subproject commit e6a9941c662289c0743e5d8f4150458a664226f2

View file

@ -17,6 +17,11 @@
* Boston, MA 02111-1307, USA.
*/
/*
* library can be found at http://www.penguin.cz/~utx/amr
* gst-launch filesrc location=./bugdata/Bug24403/Ganga9_21_nb.amr ! amrnbparse ! amrnbdec ! audioresample ! audioconvert ! alsasink
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -179,16 +184,47 @@ gst_amrnbdec_event (GstPad * pad, GstEvent * event)
ret = gst_pad_push_event (amrnbdec->srcpad, event);
break;
case GST_EVENT_NEWSEGMENT:
/* FIXME, store, forward and use for clipping */
{
GstFormat format;
gdouble rate, arate;
gint64 start, stop, time;
gboolean update;
gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
&start, &stop, &time);
/* we need time for now */
if (format != GST_FORMAT_TIME)
goto newseg_wrong_format;
GST_DEBUG_OBJECT (amrnbdec,
"newsegment: update %d, rate %g, arate %g, start %" GST_TIME_FORMAT
", stop %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT,
update, rate, arate, GST_TIME_ARGS (start), GST_TIME_ARGS (stop),
GST_TIME_ARGS (time));
/* now configure the values */
gst_segment_set_newsegment_full (&amrnbdec->segment, update,
rate, arate, format, start, stop, time);
ret = gst_pad_push_event (amrnbdec->srcpad, event);
}
break;
break;
default:
ret = gst_pad_push_event (amrnbdec->srcpad, event);
break;
}
done:
gst_object_unref (amrnbdec);
return ret;
/* ERRORS */
newseg_wrong_format:
{
GST_DEBUG_OBJECT (amrnbdec, "received non TIME newsegment");
goto done;
}
}
static GstFlowReturn
@ -207,6 +243,7 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
gst_adapter_clear (amrnbdec->adapter);
amrnbdec->ts = -1;
amrnbdec->discont = TRUE;
}
/* take latest timestamp, FIXME timestamp is the one of the
@ -223,6 +260,7 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
guint8 *data;
gint block, mode;
/* need to peek data to get the size */
if (gst_adapter_available (amrnbdec->adapter) < 1)
break;
data = (guint8 *) gst_adapter_peek (amrnbdec->adapter, 1);
@ -233,8 +271,9 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
GST_DEBUG_OBJECT (amrnbdec, "mode %d, block %d", mode, block);
if (gst_adapter_available (amrnbdec->adapter) < block)
if (!block || gst_adapter_available (amrnbdec->adapter) < block)
break;
/* the library seems to write into the source data, hence
* the copy. */
data = gst_adapter_take (amrnbdec->adapter, block);
@ -243,8 +282,14 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
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 += amrnbdec->duration;
if (amrnbdec->discont) {
GST_BUFFER_FLAG_SET (out, GST_BUFFER_FLAG_DISCONT);
amrnbdec->discont = FALSE;
}
gst_buffer_set_caps (out, GST_PAD_CAPS (amrnbdec->srcpad));
/* decode */
@ -252,9 +297,10 @@ gst_amrnbdec_chain (GstPad * pad, GstBuffer * buffer)
(short *) GST_BUFFER_DATA (out), 0);
g_free (data);
/* play */
/* send out */
ret = gst_pad_push (amrnbdec->srcpad, out);
}
gst_object_unref (amrnbdec);
return ret;
@ -287,6 +333,8 @@ gst_amrnbdec_state_change (GstElement * element, GstStateChange transition)
amrnbdec->rate = 0;
amrnbdec->channels = 0;
amrnbdec->ts = -1;
amrnbdec->discont = TRUE;
gst_segment_init (&amrnbdec->segment, GST_FORMAT_TIME);
break;
default:
break;

View file

@ -55,6 +55,9 @@ struct _GstAmrnbDec {
/* output settings */
gint channels, rate;
gint duration;
GstSegment segment;
gboolean discont;
};
struct _GstAmrnbDecClass {

View file

@ -385,7 +385,7 @@ gst_amrnbparse_loop (GstPad * pad)
amrnbparse = GST_AMRNBPARSE (GST_PAD_PARENT (pad));
/* init */
if (amrnbparse->need_header) {
if (G_UNLIKELY (amrnbparse->need_header)) {
if (!gst_amrnbparse_pull_header (amrnbparse)) {
GST_ELEMENT_ERROR (amrnbparse, STREAM, WRONG_TYPE, (NULL), (NULL));
GST_LOG_OBJECT (amrnbparse, "could not read header");