"audio");
event = gst_event_new_stream_start (stream_id);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
if (have_group_id (demux))
gst_event_set_group_id (event, demux->group_id);
gst_pad_push_event (demux->audio_pad, event);
static void
gst_flv_demux_push_tags (GstFlvDemux * demux)
{
+ GstEvent *tag_event;
+
gst_flv_demux_add_codec_tag (demux, GST_TAG_AUDIO_CODEC, demux->audio_pad);
gst_flv_demux_add_codec_tag (demux, GST_TAG_VIDEO_CODEC, demux->video_pad);
GST_DEBUG_OBJECT (demux, "pushing %" GST_PTR_FORMAT, demux->taglist);
- gst_flv_demux_push_src_event (demux,
- gst_event_new_tag (gst_tag_list_copy (demux->taglist)));
+ tag_event = gst_event_new_tag (gst_tag_list_copy (demux->taglist));
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (tag_event, demux->segment_seqnum);
+ gst_flv_demux_push_src_event (demux, tag_event);
if (demux->audio_pad) {
GST_DEBUG_OBJECT (demux->audio_pad, "pushing audio %" GST_PTR_FORMAT,
demux->audio_tags);
- gst_pad_push_event (demux->audio_pad,
- gst_event_new_tag (gst_tag_list_copy (demux->audio_tags)));
+ tag_event = gst_event_new_tag (gst_tag_list_copy (demux->audio_tags));
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (tag_event, demux->segment_seqnum);
+ gst_pad_push_event (demux->audio_pad, tag_event);
}
if (demux->video_pad) {
GST_DEBUG_OBJECT (demux->video_pad, "pushing video %" GST_PTR_FORMAT,
demux->video_tags);
- gst_pad_push_event (demux->video_pad,
- gst_event_new_tag (gst_tag_list_copy (demux->video_tags)));
+ tag_event = gst_event_new_tag (gst_tag_list_copy (demux->video_tags));
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (tag_event, demux->segment_seqnum);
+ gst_pad_push_event (demux->video_pad, tag_event);
}
}
demux->last_audio_pts = (stop - demux->audio_time_offset) / GST_MSECOND;
event = gst_event_new_gap (start, stop - start);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
gst_pad_push_event (demux->audio_pad, event);
}
demux->last_video_dts = (stop - demux->video_time_offset) / GST_MSECOND;
event = gst_event_new_gap (start, stop - start);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
gst_pad_push_event (demux->video_pad, event);
}
}
GST_TIME_ARGS (demux->segment.stop));
demux->segment.start = demux->segment.time = demux->segment.position;
demux->new_seg_event = gst_event_new_segment (&demux->segment);
+ gst_event_set_seqnum (demux->new_seg_event, demux->segment_seqnum);
} else {
GST_DEBUG_OBJECT (demux, "pushing pre-generated newsegment event");
}
gst_pad_create_stream_id (demux->video_pad, GST_ELEMENT_CAST (demux),
"video");
event = gst_event_new_stream_start (stream_id);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
g_free (stream_id);
if (have_group_id (demux))
GST_TIME_ARGS (demux->segment.stop));
demux->segment.start = demux->segment.time = demux->segment.position;
demux->new_seg_event = gst_event_new_segment (&demux->segment);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (demux->new_seg_event, demux->segment_seqnum);
} else {
GST_DEBUG_OBJECT (demux, "pushing pre-generated newsegment event");
}
demux->indexed = FALSE;
demux->upstream_seekable = FALSE;
demux->file_size = 0;
+ demux->segment_seqnum = 0;
demux->index_max_pos = 0;
demux->index_max_time = 0;
gst_event_new_seek (1.0, GST_FORMAT_BYTES,
GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET, offset,
GST_SEEK_TYPE_NONE, -1);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
res = gst_pad_push_event (demux->sinkpad, event);
pause:
{
const gchar *reason = gst_flow_get_name (ret);
+ GstMessage *message;
+ GstEvent *event;
GST_LOG_OBJECT (demux, "pausing task, reason %s", reason);
gst_pad_pause_task (pad);
if (demux->segment.rate >= 0) {
GST_LOG_OBJECT (demux, "Sending segment done, at end of segment");
- gst_element_post_message (GST_ELEMENT_CAST (demux),
- gst_message_new_segment_done (GST_OBJECT_CAST (demux),
- GST_FORMAT_TIME, stop));
- gst_flv_demux_push_src_event (demux,
- gst_event_new_segment_done (GST_FORMAT_TIME, stop));
+ message = gst_message_new_segment_done (GST_OBJECT_CAST (demux),
+ GST_FORMAT_TIME, stop);
+ gst_message_set_seqnum (message, demux->segment_seqnum);
+ gst_element_post_message (GST_ELEMENT_CAST (demux), message);
+ event = gst_event_new_segment_done (GST_FORMAT_TIME, stop);
+ gst_event_set_seqnum (event, demux->segment_seqnum);
+ gst_flv_demux_push_src_event (demux, event);
} else { /* Reverse playback */
GST_LOG_OBJECT (demux, "Sending segment done, at beginning of "
"segment");
- gst_element_post_message (GST_ELEMENT_CAST (demux),
- gst_message_new_segment_done (GST_OBJECT_CAST (demux),
- GST_FORMAT_TIME, demux->segment.start));
- gst_flv_demux_push_src_event (demux,
- gst_event_new_segment_done (GST_FORMAT_TIME,
- demux->segment.start));
+ message = gst_message_new_segment_done (GST_OBJECT_CAST (demux),
+ GST_FORMAT_TIME, demux->segment.start);
+ gst_message_set_seqnum (message, demux->segment_seqnum);
+ gst_element_post_message (GST_ELEMENT_CAST (demux), message);
+ event = gst_event_new_segment_done (GST_FORMAT_TIME,
+ demux->segment.start);
+ gst_event_set_seqnum (event, demux->segment_seqnum);
+ gst_flv_demux_push_src_event (demux, event);
}
} else {
/* normal playback, send EOS to all linked pads */
}
GST_LOG_OBJECT (demux, "Sending EOS, at end of stream");
- if (!demux->audio_pad && !demux->video_pad)
+ if (!demux->audio_pad && !demux->video_pad) {
GST_ELEMENT_ERROR (demux, STREAM, FAILED,
("Internal data stream error."), ("Got EOS before any data"));
- else if (!gst_flv_demux_push_src_event (demux, gst_event_new_eos ()))
- GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
+ } else {
+ event = gst_event_new_eos ();
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
+ if (!gst_flv_demux_push_src_event (demux, event))
+ GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
+ }
}
} else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
GST_ELEMENT_FLOW_ERROR (demux, ret);
- gst_flv_demux_push_src_event (demux, gst_event_new_eos ());
+ event = gst_event_new_eos ();
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (event, demux->segment_seqnum);
+ gst_flv_demux_push_src_event (demux, event);
}
gst_object_unref (demux);
return;
GST_DEBUG_OBJECT (demux, "generating an upstream seek at position %"
G_GUINT64_FORMAT, offset);
- ret = gst_pad_push_event (demux->sinkpad,
- gst_event_new_seek (seeksegment.rate, GST_FORMAT_BYTES,
- flags | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
- offset, GST_SEEK_TYPE_NONE, 0));
+ event = gst_event_new_seek (seeksegment.rate, GST_FORMAT_BYTES,
+ flags | GST_SEEK_FLAG_ACCURATE, GST_SEEK_TYPE_SET,
+ offset, GST_SEEK_TYPE_NONE, 0);
+ gst_event_set_seqnum (event, gst_event_get_seqnum (event));
+ ret = gst_pad_push_event (demux->sinkpad, event);
if (G_UNLIKELY (!ret)) {
GST_WARNING_OBJECT (demux, "upstream seek failed");
}
GST_TIME_ARGS (demux->segment.start),
GST_TIME_ARGS (demux->segment.stop));
demux->new_seg_event = gst_event_new_segment (&demux->segment);
+ if (demux->segment_seqnum != GST_SEQNUM_INVALID)
+ gst_event_set_seqnum (demux->new_seg_event, demux->segment_seqnum);
gst_event_unref (event);
} else {
ret = gst_pad_push_event (demux->sinkpad, event);
demux->state = FLV_STATE_SEEK;
/* copy the event */
- if (demux->seek_event)
- gst_event_unref (demux->seek_event);
- demux->seek_event = gst_event_ref (event);
+ gst_event_replace (&demux->seek_event, event);
/* set the building_index flag so that only one thread can setup the
* structures for index seeking. */
gdouble rate;
gboolean update, flush, ret = FALSE;
GstSegment seeksegment;
+ GstEvent *flush_event;
+ GstMessage *message;
+ guint32 seqnum;
gst_event_parse_seek (event, &rate, &format, &flags,
&start_type, &start, &stop_type, &stop);
+ seqnum = gst_event_get_seqnum (event);
if (format != GST_FORMAT_TIME)
goto wrong_format;
if (flush) {
/* Flush start up and downstream to make sure data flow and loops are
idle */
- gst_flv_demux_push_src_event (demux, gst_event_new_flush_start ());
- gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
+ flush_event = gst_event_new_flush_start ();
+ gst_event_set_seqnum (flush_event, seqnum);
+ gst_flv_demux_push_src_event (demux, flush_event);
+
+ flush_event = gst_event_new_flush_start ();
+ gst_event_set_seqnum (flush_event, seqnum);
+ gst_pad_push_event (demux->sinkpad, flush_event);
} else {
/* Pause the pulling task */
gst_pad_pause_task (demux->sinkpad);
/* Take the stream lock */
GST_PAD_STREAM_LOCK (demux->sinkpad);
+ demux->segment_seqnum = seqnum;
if (flush) {
/* Stop flushing upstream we need to pull */
- gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
+ flush_event = gst_event_new_flush_stop (TRUE);
+ gst_event_set_seqnum (flush_event, seqnum);
+ gst_pad_push_event (demux->sinkpad, flush_event);
}
/* Work on a copy until we are sure the seek succeeded. */
" index only up to %" GST_TIME_FORMAT,
GST_TIME_ARGS (demux->index_max_time));
/* stop flushing for now */
- if (flush)
- gst_flv_demux_push_src_event (demux, gst_event_new_flush_stop (TRUE));
+ if (flush) {
+ flush_event = gst_event_new_flush_stop (TRUE);
+ gst_event_set_seqnum (flush_event, seqnum);
+ gst_flv_demux_push_src_event (demux, flush_event);
+ }
/* delegate scanning and index building to task thread to avoid
* occupying main (UI) loop */
if (demux->seek_event)
if (flush) {
/* Stop flushing, the sinks are at time 0 now */
- gst_flv_demux_push_src_event (demux, gst_event_new_flush_stop (TRUE));
+ flush_event = gst_event_new_flush_stop (TRUE);
+ gst_event_set_seqnum (flush_event, seqnum);
+ gst_flv_demux_push_src_event (demux, flush_event);
}
if (ret) {
/* Notify about the start of a new segment */
if (demux->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
- gst_element_post_message (GST_ELEMENT (demux),
- gst_message_new_segment_start (GST_OBJECT (demux),
- demux->segment.format, demux->segment.position));
+ message = gst_message_new_segment_start (GST_OBJECT (demux),
+ demux->segment.format, demux->segment.position);
+ gst_message_set_seqnum (message, seqnum);
+ gst_element_post_message (GST_ELEMENT (demux), message);
}
gst_flow_combiner_reset (demux->flowcombiner);
GST_TIME_ARGS (demux->segment.start),
GST_TIME_ARGS (demux->segment.stop));
demux->new_seg_event = gst_event_new_segment (&demux->segment);
+ gst_event_set_seqnum (demux->new_seg_event, seqnum);
}
exit:
case GST_PAD_MODE_PULL:
if (active) {
demux->random_access = TRUE;
+ demux->segment_seqnum = gst_util_seqnum_next ();
res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flv_demux_loop,
sinkpad, NULL);
} else {
GST_DEBUG_OBJECT (demux, "received new segment");
gst_event_copy_segment (event, &in_segment);
+ demux->segment_seqnum = gst_event_get_seqnum (event);
if (in_segment.format == GST_FORMAT_TIME) {
/* time segment, this is perfect, copy over the values. */