summaryrefslogtreecommitdiffstats
path: root/ext/speex
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2008-04-29 14:11:45 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-04-29 14:11:45 +0000
commit0062c4d6d0b733fe7620aec1091a9113673de2ba (patch)
treed05d19312ade8da63fae01dc73dd19b1c35982ab /ext/speex
parentd76f39be0e944fe46d4aab93be7491d2db7ff0f0 (diff)
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.
Diffstat (limited to 'ext/speex')
-rw-r--r--ext/speex/gstspeexdec.c50
1 files changed, 37 insertions, 13 deletions
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;
}