static GstFlowReturn gst_ogg_demux_combine_flows (GstOggDemux * ogg,
GstOggPad * pad, GstFlowReturn ret);
+static void gst_ogg_demux_sync_streams (GstOggDemux * ogg);
G_DEFINE_TYPE (GstOggPad, gst_ogg_pad, GST_TYPE_PAD);
pad->start_time = GST_CLOCK_TIME_NONE;
pad->first_time = GST_CLOCK_TIME_NONE;
+ pad->last_stop = GST_CLOCK_TIME_NONE;
+
pad->have_type = FALSE;
pad->continued = NULL;
pad->headers = NULL;
pad->continued = NULL;
pad->last_ret = GST_FLOW_OK;
+ pad->last_stop = GST_CLOCK_TIME_NONE;
}
/* the filter function for selecting the elements we can use in
pad->discont = FALSE;
}
+ pad->last_stop = ogg->segment.last_stop;
+
ret = gst_pad_push (GST_PAD_CAST (pad), buf);
/* combine flows */
pad->discont = TRUE;
pad->last_ret = GST_FLOW_OK;
+ pad->is_sparse =
+ gst_structure_has_name (gst_caps_get_structure (GST_PAD_CAPS (pad),
+ 0), "application/x-ogm-text");
+
/* activate first */
gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer)
{
GstOggDemux *ogg;
- gint ret;
+ gint ret = 0;
GstFlowReturn result = GST_FLOW_OK;
ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad));
result = gst_ogg_demux_handle_page (ogg, &page);
}
}
+ if (ret == 0 || result == GST_FLOW_OK) {
+ gst_ogg_demux_sync_streams (ogg);
+ }
return result;
}
return ret;
}
+static void
+gst_ogg_demux_sync_streams (GstOggDemux * ogg)
+{
+ GstClockTime cur;
+ GstOggChain *chain;
+ guint i;
+
+ chain = ogg->current_chain;
+ cur = ogg->segment.last_stop;
+ if (chain == NULL || cur == -1)
+ return;
+
+ for (i = 0; i < chain->streams->len; i++) {
+ GstOggPad *stream = g_array_index (chain->streams, GstOggPad *, i);
+
+ /* Theoretically, we should be doing this for all streams, but we're only
+ * doing it for known-to-be-sparse streams at the moment in order not to
+ * break things for wrongly-muxed streams (like we used to produce once) */
+ if (stream->is_sparse && stream->last_stop != GST_CLOCK_TIME_NONE) {
+
+ /* Does this stream lag? Random threshold of 2 seconds */
+ if (GST_CLOCK_DIFF (stream->last_stop, cur) > (2 * GST_SECOND)) {
+ GST_DEBUG_OBJECT (stream, "synchronizing stream with others by "
+ "advancing time from %" GST_TIME_FORMAT " to %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (stream->last_stop), GST_TIME_ARGS (cur));
+ stream->last_stop = cur;
+ /* advance stream time (FIXME: is this right, esp. time_pos?) */
+ gst_pad_push_event (GST_PAD_CAST (stream),
+ gst_event_new_new_segment (TRUE, ogg->segment.rate,
+ GST_FORMAT_TIME, stream->last_stop, -1, stream->last_stop));
+ }
+ }
+ }
+}
+
/* random access code
*
* - first find all the chains and streams by scanning the file.
if (ret != GST_FLOW_OK)
goto pause;
+ gst_ogg_demux_sync_streams (ogg);
return;
/* ERRORS */