GstClockTime eos_time;
- /* number of microseconds we alow timestamps or clock slaving to drift
- gboolean do_time_offset;
+ /* number of microseconds we allow clock slaving to drift
* before resyncing */
guint64 drift_tolerance;
+
+ /* number of nanoseconds we allow timestamps to drift
+ * before resyncing */
+ GstClockTime alignment_threshold;
+
+ /* time of the previous detected discont candidate */
+ GstClockTime discont_time;
+
+ /* number of nanoseconds to wait until creating a discontinuity */
+ GstClockTime discont_wait;
};
/* BaseAudioSink signals and args */
gint64 samples_done = segdone * ringbuf->samples_per_seg;
gint64 headroom = sample_offset - samples_done;
gboolean allow_align = TRUE;
+ gboolean discont = FALSE;
+ gint rate;
/* now try to align the sample to the previous one, first see how big the
* difference is. */
if (sample_offset >= sink->next_sample)
- diff = sample_offset - sink->next_sample;
+ sample_diff = sample_offset - sink->next_sample;
else
- diff = sink->next_sample - sample_offset;
+ sample_diff = sink->next_sample - sample_offset;
- /* calculate the max allowed drift in units of samples. By default this is
- * 20ms and should be anough to compensate for timestamp rounding errors. */
- maxdrift = (rate * sink->priv->drift_tolerance) / GST_MSECOND;
+ rate = GST_AUDIO_INFO_RATE (&ringbuf->spec.info);
+
- ringbuf->spec.rate, GST_SECOND);
+ /* calculate the max allowed drift in units of samples. */
+ max_sample_diff = gst_util_uint64_scale_int (sink->priv->alignment_threshold,
++ rate, GST_SECOND);
/* calc align with previous sample */
align = sink->next_sample - sample_offset;
/* don't align if it means writing behind the read-segment */
- if (diff > headroom && align < 0)
+ if (sample_diff > headroom && align < 0)
allow_align = FALSE;
- if (G_LIKELY (diff < maxdrift && allow_align)) {
+ if (G_UNLIKELY (sample_diff >= max_sample_diff)) {
+ /* wait before deciding to make a discontinuity */
+ if (sink->priv->discont_wait > 0) {
+ GstClockTime time = gst_util_uint64_scale_int (sample_offset,
- GST_SECOND, ringbuf->spec.rate);
++ GST_SECOND, rate);
+ if (sink->priv->discont_time == -1) {
+ /* discont candidate */
+ sink->priv->discont_time = time;
+ } else if (time - sink->priv->discont_time >= sink->priv->discont_wait) {
+ /* discont_wait expired, discontinuity detected */
+ discont = TRUE;
+ sink->priv->discont_time = -1;
+ }
+ } else {
+ discont = TRUE;
+ }
+ } else if (G_UNLIKELY (sink->priv->discont_time != -1)) {
+ /* we have had a discont, but are now back on track! */
+ sink->priv->discont_time = -1;
+ }
+
+ if (G_LIKELY (!discont && allow_align)) {
GST_DEBUG_OBJECT (sink,
"align with prev sample, ABS (%" G_GINT64_FORMAT ") < %"
- G_GINT64_FORMAT, align, maxdrift);
+ G_GINT64_FORMAT, align, max_sample_diff);
} else {
gint64 diff_s G_GNUC_UNUSED;
/* calculate sample diff in seconds for error message */
- diff_s = gst_util_uint64_scale_int (diff, GST_SECOND, rate);
- diff_s =
- gst_util_uint64_scale_int (sample_diff, GST_SECOND, ringbuf->spec.rate);
++ diff_s = gst_util_uint64_scale_int (sample_diff, GST_SECOND, rate);
/* timestamps drifted apart from previous samples too much, we need to
* resync. We log this as an element warning. */
gstsubtitleoverlay.c \
gstplaysinkvideoconvert.c \
gstplaysinkaudioconvert.c \
+ gstplaysinkconvertbin.c \
gststreamsynchronizer.c
-nodist_libgstplaybin_la_SOURCES = $(built_sources)
-libgstplaybin_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(csp_cflags)
-libgstplaybin_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstplaybin_la_LIBADD = \
+nodist_libgstplayback_la_SOURCES = $(built_sources)
+libgstplayback_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) $(csp_cflags)
+libgstplayback_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstplayback_la_LIBADD = \
$(top_builddir)/gst-libs/gst/pbutils/libgstpbutils-@GST_MAJORMINOR@.la \
$(top_builddir)/gst-libs/gst/interfaces/libgstinterfaces-@GST_MAJORMINOR@.la \
$(top_builddir)/gst-libs/gst/video/libgstvideo-@GST_MAJORMINOR@.la \
if (peer) {
parent = gst_pad_get_parent_element (peer);
if (parent == sink) {
- caps = gst_pad_get_negotiated_caps (pad);
+ caps = gst_pad_get_current_caps (pad);
+ if (srcpad) {
+ gst_object_ref (pad);
+ *srcpad = pad;
+ }
done = TRUE;
}
elem = delem->element;
delem_next = l->next->data;
elem_next = delem_next->element;
+ srcpad = NULL;
- caps = _gst_element_get_linked_caps (elem_next, elem);
+ caps = _gst_element_get_linked_caps (elem_next, elem, &srcpad);
if (caps) {
- s = gst_structure_id_empty_new (topology_structure_name);
+ s = gst_structure_new_id_empty (topology_structure_name);
gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
gst_caps_unref (caps);
topology_caps = g_quark_from_static_string ("caps");
topology_next = g_quark_from_static_string ("next");
topology_pad = g_quark_from_static_string ("pad");
+ topology_element_srcpad = g_quark_from_static_string ("element-srcpad");
- return gst_element_register (plugin, "decodebin2", GST_RANK_NONE,
+ return gst_element_register (plugin, "decodebin", GST_RANK_NONE,
GST_TYPE_DECODE_BIN);
}