mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-30 13:41:48 +00:00
asfdemux: fixes/enhancements for streaming mode
* Do not rock the boat by reacting to FLUSH_START. * Try to handle TIME seeking by seeking upstream in BYTES. * Handle SEEKING query.
This commit is contained in:
parent
95ddda57e2
commit
2bd14c7153
1 changed files with 101 additions and 6 deletions
|
@ -337,7 +337,6 @@ gst_asf_demux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GST_EVENT_FLUSH_START:
|
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
GST_OBJECT_LOCK (demux);
|
GST_OBJECT_LOCK (demux);
|
||||||
gst_asf_demux_reset_stream_state_after_discont (demux);
|
gst_asf_demux_reset_stream_state_after_discont (demux);
|
||||||
|
@ -424,6 +423,52 @@ gst_asf_demux_reset_stream_state_after_discont (GstASFDemux * demux)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* do a seek in push based mode */
|
||||||
|
static gboolean
|
||||||
|
gst_asf_demux_handle_seek_push (GstASFDemux * demux, GstEvent * event)
|
||||||
|
{
|
||||||
|
gdouble rate;
|
||||||
|
GstFormat format;
|
||||||
|
GstSeekFlags flags;
|
||||||
|
GstSeekType cur_type, stop_type;
|
||||||
|
gint64 cur, stop;
|
||||||
|
guint packet;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
|
||||||
|
&stop_type, &stop);
|
||||||
|
|
||||||
|
stop_type = GST_SEEK_TYPE_NONE;
|
||||||
|
stop = -1;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS (cur));
|
||||||
|
|
||||||
|
/* determine packet, by index or by estimation */
|
||||||
|
if (!gst_asf_demux_seek_index_lookup (demux, &packet, cur, NULL)) {
|
||||||
|
packet = (guint) gst_util_uint64_scale (demux->num_packets,
|
||||||
|
cur, demux->play_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (packet > demux->num_packets) {
|
||||||
|
GST_DEBUG_OBJECT (demux, "could not determine packet to seek to, "
|
||||||
|
"seek aborted.");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "seeking to packet %d", packet);
|
||||||
|
|
||||||
|
cur = demux->data_offset + (packet * demux->packet_size);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (demux, "Pushing BYTE seek rate %g, "
|
||||||
|
"start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, cur, stop);
|
||||||
|
/* BYTE seek event */
|
||||||
|
event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, cur,
|
||||||
|
stop_type, stop);
|
||||||
|
res = gst_pad_push_event (demux->sinkpad, event);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
|
gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
@ -447,6 +492,11 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!demux->activated_streams) {
|
||||||
|
GST_LOG_OBJECT (demux, "streams not yet activated, ignoring seek");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
@ -465,8 +515,23 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
|
||||||
keyunit_sync = ((flags & GST_SEEK_FLAG_KEY_UNIT) == GST_SEEK_FLAG_KEY_UNIT);
|
keyunit_sync = ((flags & GST_SEEK_FLAG_KEY_UNIT) == GST_SEEK_FLAG_KEY_UNIT);
|
||||||
|
|
||||||
if (demux->streaming) {
|
if (demux->streaming) {
|
||||||
|
/* support it safely needs more segment handling, e.g. closing etc */
|
||||||
|
if (!flush) {
|
||||||
|
GST_LOG_OBJECT (demux, "streaming; non-flushing seek not supported");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* we can (re)construct the start later on, but not the end */
|
||||||
|
if (stop_type != GST_SEEK_TYPE_NONE) {
|
||||||
|
GST_LOG_OBJECT (demux, "streaming; end type must be NONE");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
gst_event_ref (event);
|
gst_event_ref (event);
|
||||||
return gst_pad_push_event (demux->sinkpad, event);
|
/* upstream might handle TIME seek, e.g. mms or rtsp,
|
||||||
|
* or not, e.g. http, then we give it a hand */
|
||||||
|
if (!gst_pad_push_event (demux->sinkpad, event))
|
||||||
|
return gst_asf_demux_handle_seek_push (demux, event);
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unlock the streaming thread */
|
/* unlock the streaming thread */
|
||||||
|
@ -3315,10 +3380,40 @@ gst_asf_demux_handle_src_query (GstPad * pad, GstQuery * query)
|
||||||
duration = demux->segment.duration;
|
duration = demux->segment.duration;
|
||||||
GST_OBJECT_UNLOCK (demux);
|
GST_OBJECT_UNLOCK (demux);
|
||||||
|
|
||||||
gst_query_set_seeking (query, GST_FORMAT_TIME, demux->seekable,
|
if (!demux->streaming || !demux->seekable) {
|
||||||
0, duration);
|
gst_query_set_seeking (query, GST_FORMAT_TIME, demux->seekable, 0,
|
||||||
res = TRUE;
|
duration);
|
||||||
}
|
res = TRUE;
|
||||||
|
} else {
|
||||||
|
GstFormat fmt;
|
||||||
|
gboolean seekable;
|
||||||
|
|
||||||
|
/* try downstream first in TIME */
|
||||||
|
res = gst_pad_query_default (pad, query);
|
||||||
|
|
||||||
|
gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
|
||||||
|
GST_LOG_OBJECT (demux, "upstream %s seekable %d",
|
||||||
|
GST_STR_NULL (gst_format_get_name (fmt)), seekable);
|
||||||
|
/* if no luck, maybe in BYTES */
|
||||||
|
if (!seekable || fmt != GST_FORMAT_TIME) {
|
||||||
|
GstQuery *q;
|
||||||
|
|
||||||
|
q = gst_query_new_seeking (GST_FORMAT_BYTES);
|
||||||
|
if ((res = gst_pad_peer_query (demux->sinkpad, q))) {
|
||||||
|
gst_query_parse_seeking (q, &fmt, &seekable, NULL, NULL);
|
||||||
|
GST_LOG_OBJECT (demux, "upstream %s seekable %d",
|
||||||
|
GST_STR_NULL (gst_format_get_name (fmt)), seekable);
|
||||||
|
if (fmt != GST_FORMAT_BYTES)
|
||||||
|
seekable = FALSE;
|
||||||
|
}
|
||||||
|
gst_query_unref (q);
|
||||||
|
gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0,
|
||||||
|
duration);
|
||||||
|
res = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
GST_LOG_OBJECT (demux, "only support seeking in TIME format");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue