matroskademux: additional lock safety

Fixes #619590.
This commit is contained in:
Mark Nauwelaerts 2011-05-04 11:55:21 +02:00
parent 4db6dce2db
commit 8b910885ec

View file

@ -2062,6 +2062,7 @@ gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
GstFormat fmt; GstFormat fmt;
gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL); gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
GST_OBJECT_LOCK (demux);
if (fmt == GST_FORMAT_TIME) { if (fmt == GST_FORMAT_TIME) {
gboolean seekable; gboolean seekable;
@ -2076,6 +2077,7 @@ gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad,
0, demux->segment.duration); 0, demux->segment.duration);
res = TRUE; res = TRUE;
} }
GST_OBJECT_UNLOCK (demux);
break; break;
} }
default: default:
@ -2258,6 +2260,7 @@ gst_matroska_demux_get_seek_track (GstMatroskaDemux * demux,
return track; return track;
} }
/* call with object lock held */
static void static void
gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time, gst_matroska_demux_reset_streams (GstMatroskaDemux * demux, GstClockTime time,
gboolean full) gboolean full)
@ -2483,8 +2486,10 @@ gst_matroska_demux_search_pos (GstMatroskaDemux * demux, GstClockTime time)
demux->state = GST_MATROSKA_DEMUX_STATE_SCANNING; demux->state = GST_MATROSKA_DEMUX_STATE_SCANNING;
/* estimate using start and current position */ /* estimate using start and current position */
GST_OBJECT_LOCK (demux);
opos = demux->offset - demux->ebml_segment_start; opos = demux->offset - demux->ebml_segment_start;
otime = demux->segment.last_stop; otime = demux->segment.last_stop;
GST_OBJECT_UNLOCK (demux);
retry: retry:
GST_LOG_OBJECT (demux, GST_LOG_OBJECT (demux,
@ -2640,8 +2645,6 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
if (pad) if (pad)
track = gst_pad_get_element_private (pad); track = gst_pad_get_element_private (pad);
track = gst_matroska_demux_get_seek_track (demux, track);
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
&stop_type, &stop); &stop_type, &stop);
@ -2665,6 +2668,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
/* check sanity before we start flushing and all that */ /* check sanity before we start flushing and all that */
GST_OBJECT_LOCK (demux); GST_OBJECT_LOCK (demux);
track = gst_matroska_demux_get_seek_track (demux, track);
if ((entry = gst_matroskademux_do_index_seek (demux, track, if ((entry = gst_matroskademux_do_index_seek (demux, track,
seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) == seeksegment.last_stop, &demux->seek_index, &demux->seek_entry)) ==
NULL) { NULL) {
@ -4148,6 +4152,8 @@ gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
{ {
gint stream_nr; gint stream_nr;
GST_OBJECT_LOCK (demux);
GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT, GST_LOG_OBJECT (demux, "Sync to %" GST_TIME_FORMAT,
GST_TIME_ARGS (demux->segment.last_stop)); GST_TIME_ARGS (demux->segment.last_stop));
@ -4173,6 +4179,7 @@ gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
demux->segment.last_stop > demux->segment.start && demux->segment.last_stop > demux->segment.start &&
context->pos + (GST_SECOND / 2) < demux->segment.last_stop) { context->pos + (GST_SECOND / 2) < demux->segment.last_stop) {
gint64 new_start; gint64 new_start;
GstEvent *event;
new_start = demux->segment.last_stop - (GST_SECOND / 2); new_start = demux->segment.last_stop - (GST_SECOND / 2);
if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop)) if (GST_CLOCK_TIME_IS_VALID (demux->segment.stop))
@ -4185,12 +4192,15 @@ gst_matroska_demux_sync_streams (GstMatroskaDemux * demux)
context->pos = new_start; context->pos = new_start;
/* advance stream time */ /* advance stream time */
gst_pad_push_event (context->pad, event = gst_event_new_new_segment (TRUE, demux->segment.rate,
gst_event_new_new_segment (TRUE, demux->segment.rate, demux->segment.format, new_start, demux->segment.stop, new_start);
demux->segment.format, new_start, GST_OBJECT_UNLOCK (demux);
demux->segment.stop, new_start)); gst_pad_push_event (context->pad, event);
GST_OBJECT_LOCK (demux);
} }
} }
GST_OBJECT_UNLOCK (demux);
} }
static GstFlowReturn static GstFlowReturn
@ -5109,9 +5119,11 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
/* handle gaps, e.g. non-zero start-time, or an cue index entry /* handle gaps, e.g. non-zero start-time, or an cue index entry
* that landed us with timestamps not quite intended */ * that landed us with timestamps not quite intended */
GST_OBJECT_LOCK (demux);
if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) && if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop) &&
demux->segment.rate > 0.0) { demux->segment.rate > 0.0) {
GstClockTimeDiff diff; GstClockTimeDiff diff;
GstEvent *event1, *event2;
/* only send newsegments with increasing start times, /* only send newsegments with increasing start times,
* otherwise if these go back and forth downstream (sinks) increase * otherwise if these go back and forth downstream (sinks) increase
@ -5129,15 +5141,17 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
/* send newsegment events such that the gap is not accounted in /* send newsegment events such that the gap is not accounted in
* accum time, hence running_time */ * accum time, hence running_time */
/* close ahead of gap */ /* close ahead of gap */
gst_matroska_demux_send_event (demux, event1 = gst_event_new_new_segment (TRUE, demux->segment.rate,
gst_event_new_new_segment (TRUE, demux->segment.rate, demux->segment.format, demux->segment.last_stop,
demux->segment.format, demux->segment.last_stop, demux->segment.last_stop, demux->segment.last_stop);
demux->segment.last_stop, demux->segment.last_stop));
/* skip gap */ /* skip gap */
gst_matroska_demux_send_event (demux, event2 = gst_event_new_new_segment (FALSE, demux->segment.rate,
gst_event_new_new_segment (FALSE, demux->segment.rate, demux->segment.format, lace_time, demux->segment.stop,
demux->segment.format, lace_time, demux->segment.stop, lace_time);
lace_time)); GST_OBJECT_UNLOCK (demux);
gst_matroska_demux_send_event (demux, event1);
gst_matroska_demux_send_event (demux, event2);
GST_OBJECT_LOCK (demux);
/* align segment view with downstream, /* align segment view with downstream,
* prevents double-counting accum when closing segment */ * prevents double-counting accum when closing segment */
gst_segment_set_newsegment (&demux->segment, FALSE, gst_segment_set_newsegment (&demux->segment, FALSE,
@ -5151,6 +5165,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
|| demux->segment.last_stop < lace_time) { || demux->segment.last_stop < lace_time) {
demux->segment.last_stop = lace_time; demux->segment.last_stop = lace_time;
} }
GST_OBJECT_UNLOCK (demux);
last_stop_end = lace_time; last_stop_end = lace_time;
if (duration) { if (duration) {
@ -5162,13 +5177,17 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
demux->last_stop_end < last_stop_end) demux->last_stop_end < last_stop_end)
demux->last_stop_end = last_stop_end; demux->last_stop_end = last_stop_end;
GST_OBJECT_LOCK (demux);
if (demux->segment.duration == -1 || if (demux->segment.duration == -1 ||
demux->segment.duration < lace_time) { demux->segment.duration < lace_time) {
gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME,
last_stop_end); last_stop_end);
GST_OBJECT_UNLOCK (demux);
gst_element_post_message (GST_ELEMENT_CAST (demux), gst_element_post_message (GST_ELEMENT_CAST (demux),
gst_message_new_duration (GST_OBJECT_CAST (demux), gst_message_new_duration (GST_OBJECT_CAST (demux),
GST_FORMAT_TIME, GST_CLOCK_TIME_NONE)); GST_FORMAT_TIME, GST_CLOCK_TIME_NONE));
} else {
GST_OBJECT_UNLOCK (demux);
} }
} }
@ -6227,6 +6246,7 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
} }
GST_DEBUG_OBJECT (demux, "clearing segment state"); GST_DEBUG_OBJECT (demux, "clearing segment state");
GST_OBJECT_LOCK (demux);
/* clear current segment leftover */ /* clear current segment leftover */
gst_adapter_clear (demux->adapter); gst_adapter_clear (demux->adapter);
/* and some streaming setup */ /* and some streaming setup */
@ -6239,6 +6259,7 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
demux->need_newsegment = TRUE; demux->need_newsegment = TRUE;
/* but keep some of the upstream segment */ /* but keep some of the upstream segment */
demux->segment.rate = rate; demux->segment.rate = rate;
GST_OBJECT_UNLOCK (demux);
exit: exit:
/* chain will send initial newsegment after pads have been added, /* chain will send initial newsegment after pads have been added,
* or otherwise come up with one */ * or otherwise come up with one */
@ -6266,10 +6287,10 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstEvent * event)
gst_adapter_clear (demux->adapter); gst_adapter_clear (demux->adapter);
GST_OBJECT_LOCK (demux); GST_OBJECT_LOCK (demux);
gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE); gst_matroska_demux_reset_streams (demux, GST_CLOCK_TIME_NONE, TRUE);
GST_OBJECT_UNLOCK (demux);
demux->segment.last_stop = GST_CLOCK_TIME_NONE; demux->segment.last_stop = GST_CLOCK_TIME_NONE;
demux->cluster_time = GST_CLOCK_TIME_NONE; demux->cluster_time = GST_CLOCK_TIME_NONE;
demux->cluster_offset = 0; demux->cluster_offset = 0;
GST_OBJECT_UNLOCK (demux);
/* fall-through */ /* fall-through */
} }
default: default: