diff --git a/gst/flv/gstflvdemux.c b/gst/flv/gstflvdemux.c index 9e098672a9..a0dc9386f2 100644 --- a/gst/flv/gstflvdemux.c +++ b/gst/flv/gstflvdemux.c @@ -105,12 +105,14 @@ static gboolean gst_flv_demux_query (GstPad * pad, GstObject * parent, static gboolean gst_flv_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event); +static GstIndex *gst_flv_demux_get_index (GstElement * element); static void gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts, guint64 pos, gboolean keyframe) { GstIndexAssociation associations[2]; + GstIndex *index; GstIndexEntry *entry; GST_LOG_OBJECT (demux, @@ -121,8 +123,13 @@ gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts, if (!demux->upstream_seekable) return; + index = gst_flv_demux_get_index (GST_ELEMENT (demux)); + + if (!index) + return; + /* entry may already have been added before, avoid adding indefinitely */ - entry = gst_index_get_assoc_entry (demux->index, demux->index_id, + entry = gst_index_get_assoc_entry (index, demux->index_id, GST_INDEX_LOOKUP_EXACT, GST_ASSOCIATION_FLAG_NONE, GST_FORMAT_BYTES, pos); if (entry) { @@ -138,6 +145,7 @@ gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts, if (time != ts || key != ! !keyframe) GST_DEBUG_OBJECT (demux, "metadata mismatch"); #endif + gst_object_unref (index); return; } @@ -146,7 +154,7 @@ gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts, associations[1].format = GST_FORMAT_BYTES; associations[1].value = pos; - gst_index_add_associationv (demux->index, demux->index_id, + gst_index_add_associationv (index, demux->index_id, (keyframe) ? GST_ASSOCIATION_FLAG_KEY_UNIT : GST_ASSOCIATION_FLAG_DELTA_UNIT, 2, (const GstIndexAssociation *) &associations); @@ -155,6 +163,8 @@ gst_flv_demux_parse_and_add_index_entry (GstFlvDemux * demux, GstClockTime ts, demux->index_max_pos = pos; if (ts > demux->index_max_time) demux->index_max_time = ts; + + gst_object_unref (index); } static gchar * @@ -601,7 +611,7 @@ gst_flv_demux_parse_tag_script (GstFlvDemux * demux, GstBuffer * buffer) g_free (function_name); - if (demux->index && demux->times && demux->filepositions) { + if (demux->times && demux->filepositions) { guint num; /* If an index was found, insert associations */ @@ -1020,7 +1030,7 @@ gst_flv_demux_parse_tag_audio (GstFlvDemux * demux, GstBuffer * buffer) /* Only add audio frames to the index if we have no video, * and if the index is not yet complete */ - if (!demux->has_video && demux->index && !demux->indexed) { + if (!demux->has_video && !demux->indexed) { gst_flv_demux_parse_and_add_index_entry (demux, GST_BUFFER_TIMESTAMP (outbuf), demux->cur_tag_offset, TRUE); } @@ -1399,7 +1409,7 @@ gst_flv_demux_parse_tag_video (GstFlvDemux * demux, GstBuffer * buffer) if (!keyframe) GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT); - if (!demux->indexed && demux->index) { + if (!demux->indexed) { gst_flv_demux_parse_and_add_index_entry (demux, GST_BUFFER_TIMESTAMP (outbuf), demux->cur_tag_offset, keyframe); } @@ -1550,7 +1560,7 @@ gst_flv_demux_parse_tag_timestamp (GstFlvDemux * demux, gboolean index, ret = pts * GST_MSECOND; GST_LOG_OBJECT (demux, "pts: %" GST_TIME_FORMAT, GST_TIME_ARGS (ret)); - if (index && demux->index && !demux->indexed && (type == 9 || (type == 8 + if (index && !demux->indexed && (type == 9 || (type == 8 && !demux->has_video))) { gst_flv_demux_parse_and_add_index_entry (demux, ret, demux->offset, keyframe); @@ -2179,6 +2189,7 @@ static GstFlowReturn gst_flv_demux_seek_to_prev_keyframe (GstFlvDemux * demux) { GstFlowReturn ret = GST_FLOW_EOS; + GstIndex *index; GstIndexEntry *entry = NULL; GST_DEBUG_OBJECT (demux, @@ -2197,28 +2208,34 @@ gst_flv_demux_seek_to_prev_keyframe (GstFlvDemux * demux) GST_DEBUG_OBJECT (demux, "locating previous position"); + index = gst_flv_demux_get_index (GST_ELEMENT (demux)); + /* locate index entry before previous start position */ - if (demux->index) - entry = gst_index_get_assoc_entry (demux->index, demux->index_id, + if (index) { + entry = gst_index_get_assoc_entry (index, demux->index_id, GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_BYTES, demux->from_offset - 1); - if (entry) { - gint64 bytes = 0, time = 0; + if (entry) { + gint64 bytes = 0, time = 0; - gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &bytes); - gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time); + gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &bytes); + gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &time); - GST_DEBUG_OBJECT (demux, "found index entry for %" G_GINT64_FORMAT - " at %" GST_TIME_FORMAT ", seeking to %" G_GINT64_FORMAT, - demux->offset - 1, GST_TIME_ARGS (time), bytes); + GST_DEBUG_OBJECT (demux, "found index entry for %" G_GINT64_FORMAT + " at %" GST_TIME_FORMAT ", seeking to %" G_GINT64_FORMAT, + demux->offset - 1, GST_TIME_ARGS (time), bytes); - /* setup for next section */ - demux->to_offset = demux->from_offset; - gst_flv_demux_move_to_offset (demux, bytes, FALSE); - ret = GST_FLOW_OK; + /* setup for next section */ + demux->to_offset = demux->from_offset; + gst_flv_demux_move_to_offset (demux, bytes, FALSE); + ret = GST_FLOW_OK; + } + + gst_object_unref (index); } + done: return ret; } @@ -2474,15 +2491,18 @@ gst_flv_demux_find_offset (GstFlvDemux * demux, GstSegment * segment) { gint64 bytes = 0; gint64 time = 0; + GstIndex *index; GstIndexEntry *entry; g_return_val_if_fail (segment != NULL, 0); time = segment->position; - if (demux->index) { + index = gst_flv_demux_get_index (GST_ELEMENT (demux)); + + if (index) { /* Let's check if we have an index entry for that seek time */ - entry = gst_index_get_assoc_entry (demux->index, demux->index_id, + entry = gst_index_get_assoc_entry (index, demux->index_id, GST_INDEX_LOOKUP_BEFORE, GST_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, time); @@ -2506,6 +2526,8 @@ gst_flv_demux_find_offset (GstFlvDemux * demux, GstSegment * segment) GST_DEBUG_OBJECT (demux, "no index entry found for %" GST_TIME_FORMAT, GST_TIME_ARGS (segment->start)); } + + gst_object_unref (index); } return bytes; @@ -2902,10 +2924,17 @@ gst_flv_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) ret = gst_flv_demux_push_src_event (demux, event); break; case GST_EVENT_EOS: + { + GstIndex *index; + GST_DEBUG_OBJECT (demux, "received EOS"); - if (demux->index) { + + index = gst_flv_demux_get_index (GST_ELEMENT (demux)); + + if (index) { GST_DEBUG_OBJECT (demux, "committing index"); - gst_index_commit (demux->index, demux->index_id); + gst_index_commit (index, demux->index_id); + gst_object_unref (index); } if (!demux->no_more_pads) { gst_element_no_more_pads (GST_ELEMENT (demux)); @@ -2916,6 +2945,7 @@ gst_flv_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) GST_WARNING_OBJECT (demux, "failed pushing EOS on streams"); ret = TRUE; break; + } case GST_EVENT_SEGMENT: { GstSegment in_segment; @@ -3044,6 +3074,7 @@ gst_flv_demux_query (GstPad * pad, GstObject * parent, GstQuery * query) } } res = TRUE; + /* FIXME, check index this way is not thread safe */ if (fmt != GST_FORMAT_TIME || !demux->index) { gst_query_set_seeking (query, fmt, FALSE, -1, -1); } else if (demux->random_access) { @@ -3130,23 +3161,34 @@ static void gst_flv_demux_set_index (GstElement * element, GstIndex * index) { GstFlvDemux *demux = GST_FLV_DEMUX (element); + GstIndex *old_index; GST_OBJECT_LOCK (demux); - if (demux->index) - gst_object_unref (demux->index); + + old_index = demux->index; + if (index) { demux->index = gst_object_ref (index); demux->own_index = FALSE; } else demux->index = NULL; + if (old_index) + gst_object_unref (demux->index); + + gst_object_ref (index); + GST_OBJECT_UNLOCK (demux); + /* object lock might be taken again */ if (index) gst_index_get_writer_id (index, GST_OBJECT (element), &demux->index_id); + GST_DEBUG_OBJECT (demux, "Set index %" GST_PTR_FORMAT, demux->index); + gst_object_unref (index); } +#endif static GstIndex * gst_flv_demux_get_index (GstElement * element) @@ -3162,7 +3204,6 @@ gst_flv_demux_get_index (GstElement * element) return result; } -#endif static void gst_flv_demux_dispose (GObject * object) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 90c99cc0b4..bfe64e1ce0 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -4746,11 +4746,15 @@ gst_matroska_demux_handle_sink_event (GstPad * pad, GstObject * parent, } case GST_EVENT_FLUSH_STOP: { + guint64 dur; + gst_adapter_clear (demux->common.adapter); GST_OBJECT_LOCK (demux); gst_matroska_read_common_reset_streams (&demux->common, GST_CLOCK_TIME_NONE, TRUE); - demux->common.segment.position = GST_CLOCK_TIME_NONE; + dur = demux->common.segment.duration; + gst_segment_init (&demux->common.segment, GST_FORMAT_TIME); + demux->common.segment.duration = dur; demux->cluster_time = GST_CLOCK_TIME_NONE; demux->cluster_offset = 0; GST_OBJECT_UNLOCK (demux);