mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +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,
|
static GstFlowReturn gst_ogg_demux_combine_flows (GstOggDemux * ogg,
|
||||||
GstOggPad * pad, GstFlowReturn ret);
|
GstOggPad * pad, GstFlowReturn ret);
|
||||||
|
static void gst_ogg_demux_sync_streams (GstOggDemux * ogg);
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstOggPad, gst_ogg_pad, GST_TYPE_PAD);
|
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->start_time = GST_CLOCK_TIME_NONE;
|
||||||
pad->first_time = GST_CLOCK_TIME_NONE;
|
pad->first_time = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
pad->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
pad->have_type = FALSE;
|
pad->have_type = FALSE;
|
||||||
pad->continued = NULL;
|
pad->continued = NULL;
|
||||||
pad->headers = NULL;
|
pad->headers = NULL;
|
||||||
|
@ -415,6 +418,7 @@ gst_ogg_pad_reset (GstOggPad * pad)
|
||||||
pad->continued = NULL;
|
pad->continued = NULL;
|
||||||
|
|
||||||
pad->last_ret = GST_FLOW_OK;
|
pad->last_ret = GST_FLOW_OK;
|
||||||
|
pad->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the filter function for selecting the elements we can use in
|
/* 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->discont = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pad->last_stop = ogg->segment.last_stop;
|
||||||
|
|
||||||
ret = gst_pad_push (GST_PAD_CAST (pad), buf);
|
ret = gst_pad_push (GST_PAD_CAST (pad), buf);
|
||||||
|
|
||||||
/* combine flows */
|
/* combine flows */
|
||||||
|
@ -1812,6 +1818,10 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
pad->discont = TRUE;
|
pad->discont = TRUE;
|
||||||
pad->last_ret = GST_FLOW_OK;
|
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 */
|
/* activate first */
|
||||||
gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
|
gst_pad_set_active (GST_PAD_CAST (pad), TRUE);
|
||||||
|
|
||||||
|
@ -2918,7 +2928,7 @@ static GstFlowReturn
|
||||||
gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer)
|
gst_ogg_demux_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstOggDemux *ogg;
|
GstOggDemux *ogg;
|
||||||
gint ret;
|
gint ret = 0;
|
||||||
GstFlowReturn result = GST_FLOW_OK;
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
|
||||||
ogg = GST_OGG_DEMUX (GST_OBJECT_PARENT (pad));
|
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);
|
result = gst_ogg_demux_handle_page (ogg, &page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ret == 0 || result == GST_FLOW_OK) {
|
||||||
|
gst_ogg_demux_sync_streams (ogg);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3090,6 +3103,41 @@ done:
|
||||||
return ret;
|
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
|
/* random access code
|
||||||
*
|
*
|
||||||
* - first find all the chains and streams by scanning the file.
|
* - 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)
|
if (ret != GST_FLOW_OK)
|
||||||
goto pause;
|
goto pause;
|
||||||
|
|
||||||
|
gst_ogg_demux_sync_streams (ogg);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
|
|
@ -112,6 +112,10 @@ struct _GstOggPad
|
||||||
gint64 first_granule; /* the granulepos of first page == first sample in next page */
|
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 */
|
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;
|
ogg_stream_state stream;
|
||||||
GList *continued;
|
GList *continued;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue