From 0062c4d6d0b733fe7620aec1091a9113673de2ba Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 29 Apr 2008 14:11:45 +0000 Subject: ext/speex/gstspeexdec.c: Try to preserve input timestamps when we can. Original commit message from CVS: * ext/speex/gstspeexdec.c: (speex_dec_chain_parse_data), (speex_dec_chain): Try to preserve input timestamps when we can. Do beginnings of error concealment. --- ext/speex/gstspeexdec.c | 50 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'ext/speex') diff --git a/ext/speex/gstspeexdec.c b/ext/speex/gstspeexdec.c index 48d16052..01e9d2b3 100644 --- a/ext/speex/gstspeexdec.c +++ b/ext/speex/gstspeexdec.c @@ -106,6 +106,9 @@ static void gst_speex_dec_get_property (GObject * object, guint prop_id, static void gst_speex_dec_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); +static GstFlowReturn speex_dec_chain_parse_data (GstSpeexDec * dec, + GstBuffer * buf, GstClockTime timestamp, GstClockTime duration); + static void gst_speex_dec_base_init (gpointer g_class) { @@ -623,33 +626,49 @@ speex_dec_chain_parse_comments (GstSpeexDec * dec, GstBuffer * buf) } static GstFlowReturn -speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf) +speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf, + GstClockTime timestamp, GstClockTime duration) { GstFlowReturn res = GST_FLOW_OK; gint i, fpp; guint size; guint8 *data; + SpeexBits *bits; + + if (timestamp != -1) { + dec->segment.last_stop = timestamp; + dec->granulepos = -1; + } - data = GST_BUFFER_DATA (buf); - size = GST_BUFFER_SIZE (buf); + if (buf) { + data = GST_BUFFER_DATA (buf); + size = GST_BUFFER_SIZE (buf); - /* send data to the bitstream */ - speex_bits_read_from (&dec->bits, (char *) data, size); + /* send data to the bitstream */ + speex_bits_read_from (&dec->bits, (char *) data, size); - fpp = dec->header->frames_per_packet; + fpp = dec->header->frames_per_packet; + bits = &dec->bits; + + GST_DEBUG_OBJECT (dec, "received buffer of size %u, fpp %d", size, fpp); + + /* copy timestamp */ + } else { + GST_DEBUG_OBJECT (dec, "creating concealment data"); + fpp = dec->header->frames_per_packet; + bits = NULL; + } - GST_DEBUG_OBJECT (dec, "received buffer of size %u, fpp %d", size, fpp); /* now decode each frame */ for (i = 0; i < fpp; i++) { GstBuffer *outbuf; - gint64 timestamp; gint16 *out_data; gint ret, j; GST_LOG_OBJECT (dec, "decoding frame %d/%d", i, fpp); - ret = speex_decode (dec->state, &dec->bits, dec->output); + ret = speex_decode (dec->state, bits, dec->output); if (ret == -1) { /* uh? end of stream */ GST_WARNING_OBJECT (dec, "Unexpected end of stream found"); @@ -659,7 +678,7 @@ speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf) break; } - if (speex_bits_remaining (&dec->bits) < 0) { + if (bits && speex_bits_remaining (bits) < 0) { GST_WARNING_OBJECT (dec, "Decoding overflow: corrupted stream?"); break; } @@ -698,8 +717,10 @@ speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf) GST_DEBUG_OBJECT (dec, "granulepos=%" G_GINT64_FORMAT, dec->granulepos); } - timestamp = gst_util_uint64_scale_int (dec->granulepos, - GST_SECOND, dec->header->rate); + if (timestamp == -1) { + timestamp = gst_util_uint64_scale_int (dec->granulepos, + GST_SECOND, dec->header->rate); + } GST_BUFFER_OFFSET (outbuf) = dec->granulepos; GST_BUFFER_OFFSET_END (outbuf) = dec->granulepos + dec->frame_size; @@ -719,6 +740,7 @@ speex_dec_chain_parse_data (GstSpeexDec * dec, GstBuffer * buf) GST_DEBUG_OBJECT (dec, "flow: %s", gst_flow_get_name (res)); break; } + timestamp = -1; } return res; @@ -740,7 +762,9 @@ speex_dec_chain (GstPad * pad, GstBuffer * buf) res = speex_dec_chain_parse_comments (dec, buf); break; default: - res = speex_dec_chain_parse_data (dec, buf); + res = + speex_dec_chain_parse_data (dec, buf, GST_BUFFER_TIMESTAMP (buf), + GST_BUFFER_DURATION (buf)); break; } -- cgit