diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2012-10-29 17:19:50 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2013-03-27 22:21:17 +0000 |
commit | beaeeafb4dbe2ce6493dd489a1374153e1cb067d (patch) | |
tree | f53b318ef3d2d3e4588ecb9633396bec89590ff4 /ext/sbc | |
parent | 32154c5ae696aa5368bab37eee1f7dbcd0788e94 (diff) | |
download | gstreamer-plugins-bad-beaeeafb4dbe2ce6493dd489a1374153e1cb067d.tar.gz |
sbc: sbcdec: handle DISCONT and timestamps
Reset state on discont.
Interpollate timestamps.
Diffstat (limited to 'ext/sbc')
-rw-r--r-- | ext/sbc/gstsbcdec.c | 55 | ||||
-rw-r--r-- | ext/sbc/gstsbcdec.h | 1 |
2 files changed, 50 insertions, 6 deletions
diff --git a/ext/sbc/gstsbcdec.c b/ext/sbc/gstsbcdec.c index 12df308a3..180c1379a 100644 --- a/ext/sbc/gstsbcdec.c +++ b/ext/sbc/gstsbcdec.c @@ -61,9 +61,18 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer) GstFlowReturn res = GST_FLOW_OK; guint size, codesize, offset = 0; guint8 *data; + GstClockTime timestamp; codesize = sbc_get_codesize (&dec->sbc); + if (GST_BUFFER_IS_DISCONT (buffer)) { + /* reset previous buffer */ + gst_buffer_unref (dec->buffer); + dec->buffer = NULL; + /* we need a new timestamp to lock onto */ + dec->next_sample = -1; + } + if (dec->buffer) { GstBuffer *temp = buffer; buffer = gst_buffer_span (dec->buffer, 0, buffer, @@ -76,11 +85,16 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer) data = GST_BUFFER_DATA (buffer); size = GST_BUFFER_SIZE (buffer); + timestamp = GST_BUFFER_TIMESTAMP (buffer); + + while (offset < size) { GstBuffer *output; GstPadTemplate *template; GstCaps *caps; int consumed; + GstClockTime duration; + gint rate, channels; res = gst_pad_alloc_buffer_and_set_caps (dec->srcpad, GST_BUFFER_OFFSET_NONE, codesize, NULL, &output); @@ -90,16 +104,46 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer) consumed = sbc_decode (&dec->sbc, data + offset, size - offset, GST_BUFFER_DATA (output), codesize, NULL); + GST_INFO_OBJECT (dec, "consumed %d bytes", consumed); + if (consumed <= 0) break; + rate = gst_sbc_parse_rate_from_sbc (dec->sbc.frequency); + channels = gst_sbc_get_channel_number (dec->sbc.mode); + + if (GST_CLOCK_TIME_IS_VALID (timestamp)) { + /* lock onto timestamp when we have one */ + dec->next_sample = gst_util_uint64_scale_int (timestamp, + rate, GST_SECOND); + } + if (dec->next_sample != (guint64) - 1) { + /* reconstruct timestamp from our sample counter otherwise */ + timestamp = gst_util_uint64_scale_int (dec->next_sample, + GST_SECOND, rate); + } + GST_BUFFER_TIMESTAMP (output) = timestamp; + + /* calculate the next sample */ + if (dec->next_sample != (guint64) - 1) { + /* we ave a valid sample, counter, increment it. */ + dec->next_sample += codesize / (2 * channels); + duration = gst_util_uint64_scale_int (dec->next_sample, + GST_SECOND, rate) - timestamp; + } else { + /* otherwise calculate duration based on output size */ + duration = gst_util_uint64_scale_int (codesize / (2 * channels), + GST_SECOND, rate) - timestamp; + } + GST_BUFFER_DURATION (output) = duration; + + /* reset timestamp for next round */ + timestamp = GST_CLOCK_TIME_NONE; + /* we will reuse the same caps object */ if (dec->outcaps == NULL) { caps = gst_caps_new_simple ("audio/x-raw-int", - "rate", G_TYPE_INT, - gst_sbc_parse_rate_from_sbc (dec->sbc.frequency), - "channels", G_TYPE_INT, - gst_sbc_get_channel_number (dec->sbc.mode), NULL); + "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, channels, NULL); template = gst_static_pad_template_get (&sbc_dec_src_factory); @@ -112,8 +156,6 @@ sbc_dec_chain (GstPad * pad, GstBuffer * buffer) gst_buffer_set_caps (output, dec->outcaps); - gst_buffer_copy_metadata (output, buffer, GST_BUFFER_COPY_TIMESTAMPS); - res = gst_pad_push (dec->srcpad, output); if (res != GST_FLOW_OK) goto done; @@ -146,6 +188,7 @@ sbc_dec_change_state (GstElement * element, GstStateChange transition) } sbc_init (&dec->sbc, 0); dec->outcaps = NULL; + dec->next_sample = -1; break; default: break; diff --git a/ext/sbc/gstsbcdec.h b/ext/sbc/gstsbcdec.h index c77feaed3..a62e61b2f 100644 --- a/ext/sbc/gstsbcdec.h +++ b/ext/sbc/gstsbcdec.h @@ -53,6 +53,7 @@ struct _GstSbcDec { GstCaps *outcaps; sbc_t sbc; + guint64 next_sample; }; struct _GstSbcDecClass { |