summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/audiorate/gstaudiorate.c41
-rw-r--r--gst/audiorate/gstaudiorate.h1
2 files changed, 39 insertions, 3 deletions
diff --git a/gst/audiorate/gstaudiorate.c b/gst/audiorate/gstaudiorate.c
index fd39b662..2fbd5f8e 100644
--- a/gst/audiorate/gstaudiorate.c
+++ b/gst/audiorate/gstaudiorate.c
@@ -30,8 +30,9 @@
*
* The properties #GstAudioRate:in, #GstAudioRate:out, #GstAudioRate:add
* and #GstAudioRate:drop can be read to obtain information about number of
- * input samples, output samples, dropped samples (i.e. the number of unused input
- * samples) and inserted samples (i.e. the number of samples added to stream).
+ * input samples, output samples, dropped samples (i.e. the number of unused
+ * input samples) and inserted samples (i.e. the number of samples added to
+ * stream).
*
* When the #GstAudioRate:silent property is set to FALSE, a GObject property
* notification will be emitted whenever one of the #GstAudioRate:add or
@@ -40,6 +41,13 @@
* Note that property notification will happen from the streaming thread, so
* applications should be prepared for this.
*
+ * If the #GstAudioRate:tolerance property is non-zero, and an incoming buffer's
+ * timestamp deviates less than the property indicates from what would make a
+ * 'perfect time', then no samples will be added or dropped.
+ * Note that the output is still guaranteed to be a perfect stream, which means
+ * that the incoming data is then simply shifted (by less than the indicated
+ * tolerance) to a perfect time.
+ *
* <refsect2>
* <title>Example pipelines</title>
* |[
@@ -75,7 +83,8 @@ enum
LAST_SIGNAL
};
-#define DEFAULT_SILENT TRUE
+#define DEFAULT_SILENT TRUE
+#define DEFAULT_TOLERANCE 0
enum
{
@@ -85,6 +94,7 @@ enum
ARG_ADD,
ARG_DROP,
ARG_SILENT,
+ ARG_TOLERANCE,
/* FILL ME */
};
@@ -189,6 +199,11 @@ gst_audio_rate_class_init (GstAudioRateClass * klass)
g_param_spec_boolean ("silent", "silent",
"Don't emit notify for dropped and duplicated frames", DEFAULT_SILENT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (object_class, ARG_TOLERANCE,
+ g_param_spec_uint64 ("tolerance", "tolerance",
+ "Only act if timestamp jitter/imperfection exceeds indicated tolerance (ns)",
+ 0, G_MAXUINT64, DEFAULT_TOLERANCE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
element_class->change_state = gst_audio_rate_change_state;
}
@@ -277,6 +292,7 @@ gst_audio_rate_init (GstAudioRate * audiorate)
audiorate->drop = 0;
audiorate->add = 0;
audiorate->silent = DEFAULT_SILENT;
+ audiorate->tolerance = DEFAULT_TOLERANCE;
}
static void
@@ -479,6 +495,7 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
guint64 in_offset, in_offset_end, in_samples;
guint in_size;
GstFlowReturn ret = GST_FLOW_OK;
+ GstClockTimeDiff diff;
audiorate = GST_AUDIO_RATE (gst_pad_get_parent (pad));
@@ -536,6 +553,17 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
GST_TIME_ARGS (GST_FRAMES_TO_CLOCK_TIME (in_samples, audiorate->rate)),
in_size, in_offset, in_offset_end, audiorate->next_offset);
+ diff = in_time - audiorate->next_ts;
+ if (diff <= (GstClockTimeDiff) audiorate->tolerance &&
+ diff >= (GstClockTimeDiff) - audiorate->tolerance) {
+ /* buffer time close enough to expected time,
+ * so produce a perfect stream by simply 'shifting'
+ * it to next ts and offset and sending */
+ GST_LOG_OBJECT (audiorate, "within tolerance %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (audiorate->tolerance));
+ goto send;
+ }
+
/* do we need to insert samples */
if (in_offset > audiorate->next_offset) {
GstBuffer *fill;
@@ -639,6 +667,7 @@ gst_audio_rate_chain (GstPad * pad, GstBuffer * buf)
if (GST_BUFFER_SIZE (buf) == 0)
goto beach;
+send:
/* Now calculate parameters for whichever buffer (either the original
* or truncated one) we're pushing. */
GST_BUFFER_OFFSET (buf) = audiorate->next_offset;
@@ -696,6 +725,9 @@ gst_audio_rate_set_property (GObject * object,
case ARG_SILENT:
audiorate->silent = g_value_get_boolean (value);
break;
+ case ARG_TOLERANCE:
+ audiorate->tolerance = g_value_get_uint64 (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -724,6 +756,9 @@ gst_audio_rate_get_property (GObject * object,
case ARG_SILENT:
g_value_set_boolean (value, audiorate->silent);
break;
+ case ARG_TOLERANCE:
+ g_value_set_uint64 (value, audiorate->tolerance);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
diff --git a/gst/audiorate/gstaudiorate.h b/gst/audiorate/gstaudiorate.h
index 84e3a9a5..bcc087bd 100644
--- a/gst/audiorate/gstaudiorate.h
+++ b/gst/audiorate/gstaudiorate.h
@@ -57,6 +57,7 @@ struct _GstAudioRate
/* stats */
guint64 in, out, add, drop;
gboolean silent;
+ guint64 tolerance;
/* audio state */
guint64 next_offset;