summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Smith <msmith@xiph.org>2007-03-15 10:52:21 +0000
committerMichael Smith <msmith@xiph.org>2007-03-15 10:52:21 +0000
commit03ab530205fa1194a2deb1c38886f5b5978399a2 (patch)
tree42f91790ef526603cb7c1f90bca10d0a966e6047
parente3ef9cd15d1f0fc55702c29cfb60338325b54065 (diff)
downloadgst-plugins-bad-03ab530205fa1194a2deb1c38886f5b5978399a2.tar.gz
gst-plugins-bad-03ab530205fa1194a2deb1c38886f5b5978399a2.tar.bz2
gst-plugins-bad-03ab530205fa1194a2deb1c38886f5b5978399a2.zip
gst/audioresample/gstaudioresample.c: Don't trigger discontinuities for very small imperfections; a filter flush will...
Original commit message from CVS: * gst/audioresample/gstaudioresample.c: (audioresample_check_discont), (audioresample_transform): Don't trigger discontinuities for very small imperfections; a filter flush will sound bad, and many plugins have rounding errors leading to these.
-rw-r--r--gst/audioresample/gstaudioresample.c50
1 files changed, 34 insertions, 16 deletions
diff --git a/gst/audioresample/gstaudioresample.c b/gst/audioresample/gstaudioresample.c
index 8e9e7682..98f08d80 100644
--- a/gst/audioresample/gstaudioresample.c
+++ b/gst/audioresample/gstaudioresample.c
@@ -575,6 +575,33 @@ audioresample_do_output (GstAudioresample * audioresample, GstBuffer * outbuf)
return GST_FLOW_OK;
}
+/* llabs() is C99, so we might not have it; just use a simple macro... */
+#define LLABS(x) ((x>0)?x:-x)
+static gboolean
+audioresample_check_discont (GstAudioresample * audioresample,
+ GstClockTime timestamp)
+{
+ if (timestamp != GST_CLOCK_TIME_NONE &&
+ audioresample->prev_ts != GST_CLOCK_TIME_NONE &&
+ audioresample->prev_duration != GST_CLOCK_TIME_NONE &&
+ timestamp != audioresample->prev_ts + audioresample->prev_duration) {
+ /* Potentially a discontinuous buffer. However, it turns out that many
+ * elements generate imperfect streams due to rounding errors, so we permit
+ * a small error (up to one sample) without triggering a filter
+ * flush/restart (if triggered incorrectly, this will be audible) */
+ GstClockTimeDiff diff = timestamp -
+ (audioresample->prev_ts + audioresample->prev_duration);
+
+ if (LLABS (diff) > GST_SECOND / audioresample->i_rate) {
+ GST_WARNING_OBJECT (audioresample,
+ "encountered timestamp discontinuity of %" G_GINT64_FORMAT, diff);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
static GstFlowReturn
audioresample_transform (GstBaseTransform * base, GstBuffer * inbuf,
GstBuffer * outbuf)
@@ -600,22 +627,13 @@ audioresample_transform (GstBaseTransform * base, GstBuffer * inbuf,
GST_BUFFER_OFFSET (inbuf), GST_BUFFER_OFFSET_END (inbuf));
/* check for timestamp discontinuities and flush/reset if needed */
- if (GST_CLOCK_TIME_IS_VALID (audioresample->prev_ts) &&
- GST_CLOCK_TIME_IS_VALID (audioresample->prev_duration)) {
- GstClockTime ts_expected = audioresample->prev_ts +
- audioresample->prev_duration;
- GstClockTimeDiff ts_diff = GST_CLOCK_DIFF (ts_expected, timestamp);
-
- if (G_UNLIKELY (ts_diff != 0)) {
- GST_WARNING_OBJECT (audioresample,
- "encountered timestamp discontinuity of %" G_GINT64_FORMAT, ts_diff);
- /* Flush internal samples */
- audioresample_pushthrough (audioresample);
- /* Inform downstream element about discontinuity */
- audioresample->need_discont = TRUE;
- /* We want to recalculate the offset */
- audioresample->ts_offset = -1;
- }
+ if (G_UNLIKELY (audioresample_check_discont (audioresample, timestamp))) {
+ /* Flush internal samples */
+ audioresample_pushthrough (audioresample);
+ /* Inform downstream element about discontinuity */
+ audioresample->need_discont = TRUE;
+ /* We want to recalculate the offset */
+ audioresample->ts_offset = -1;
}
if (audioresample->ts_offset == -1) {