mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 10:10:32 +00:00
oggdemux: Better handling of sparse streams by sending segment updates
Fixes bug #397419.
This commit is contained in:
parent
7a3797f332
commit
3a38a0958e
2 changed files with 54 additions and 1 deletions
|
@ -127,6 +127,7 @@ static GstClockTime gst_annodex_granule_to_time (gint64 granulepos,
|
|||
|
||||
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);
|
||||
|
||||
|
@ -161,6 +162,8 @@ gst_ogg_pad_init (GstOggPad * 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;
|
||||
|
@ -415,6 +418,7 @@ gst_ogg_pad_reset (GstOggPad * pad)
|
|||
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
|
||||
|
@ -874,6 +878,8 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet)
|
|||
pad->discont = FALSE;
|
||||
}
|
||||
|
||||
pad->last_stop = ogg->segment.last_stop;
|
||||
|
||||
ret = gst_pad_push (GST_PAD_CAST (pad), buf);
|
||||
|
||||
/* combine flows */
|
||||
|
@ -1812,6 +1818,10 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
|||
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);
|
||||
|
||||
|
@ -2918,7 +2928,7 @@ static GstFlowReturn
|
|||
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));
|
||||
|
@ -2940,6 +2950,9 @@ gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer)
|
|||
result = gst_ogg_demux_handle_page (ogg, &page);
|
||||
}
|
||||
}
|
||||
if (ret == 0 || result == GST_FLOW_OK) {
|
||||
gst_ogg_demux_sync_streams (ogg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3090,6 +3103,41 @@ done:
|
|||
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.
|
||||
|
@ -3140,6 +3188,7 @@ gst_ogg_demux_loop (GstOggPad * pad)
|
|||
if (ret != GST_FLOW_OK)
|
||||
goto pause;
|
||||
|
||||
gst_ogg_demux_sync_streams (ogg);
|
||||
return;
|
||||
|
||||
/* ERRORS */
|
||||
|
|
|
@ -112,6 +112,10 @@ struct _GstOggPad
|
|||
gint64 first_granule; /* the granulepos of first page == first sample in next page */
|
||||
GstClockTime first_time; /* the timestamp of the second page or granuletime of first page */
|
||||
|
||||
gboolean is_sparse; /* TRUE if this is a subtitle pad or some other sparse stream */
|
||||
GstClockTime last_stop; /* last_stop when last push occured; used to detect when we
|
||||
* need to send a newsegment update event for sparse streams */
|
||||
|
||||
ogg_stream_state stream;
|
||||
GList *continued;
|
||||
|
||||
|
|
Loading…
Reference in a new issue