mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 20:59:44 +00:00
mssdemux: implement snap seeking
Implement snap seek flags handling in stream_seek to allow the parent class to handle it for us https://bugzilla.gnome.org/show_bug.cgi?id=759158
This commit is contained in:
parent
c01d266238
commit
ac2734f5cb
3 changed files with 58 additions and 39 deletions
|
@ -310,7 +310,8 @@ gst_mss_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
|
|||
{
|
||||
GstMssDemuxStream *mssstream = (GstMssDemuxStream *) stream;
|
||||
|
||||
gst_mss_stream_seek (mssstream->manifest_stream, flags, ts, final_ts);
|
||||
gst_mss_stream_seek (mssstream->manifest_stream, forward, flags, ts,
|
||||
final_ts);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1089,26 +1089,32 @@ gst_mss_stream_type_name (GstMssStreamType streamtype)
|
|||
/**
|
||||
* Seeks all streams to the fragment that contains the set time
|
||||
*
|
||||
* @forward: if this is forward playback
|
||||
* @time: time in nanoseconds
|
||||
*/
|
||||
void
|
||||
gst_mss_manifest_seek (GstMssManifest * manifest, guint64 time)
|
||||
gst_mss_manifest_seek (GstMssManifest * manifest, gboolean forward,
|
||||
guint64 time)
|
||||
{
|
||||
GSList *iter;
|
||||
|
||||
for (iter = manifest->streams; iter; iter = g_slist_next (iter)) {
|
||||
gst_mss_stream_seek (iter->data, 0, time, NULL);
|
||||
gst_mss_stream_seek (iter->data, forward, 0, time, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#define SNAP_AFTER(forward,flags) \
|
||||
((forward && (flags & GST_SEEK_FLAG_SNAP_AFTER)) || \
|
||||
(!forward && (flags & GST_SEEK_FLAG_SNAP_BEFORE)))
|
||||
|
||||
/**
|
||||
* Seeks this stream to the fragment that contains the sample at time
|
||||
*
|
||||
* @time: time in nanoseconds
|
||||
*/
|
||||
void
|
||||
gst_mss_stream_seek (GstMssStream * stream, GstSeekFlags flags, guint64 time,
|
||||
guint64 * final_time)
|
||||
gst_mss_stream_seek (GstMssStream * stream, gboolean forward,
|
||||
GstSeekFlags flags, guint64 time, guint64 * final_time)
|
||||
{
|
||||
GList *iter;
|
||||
guint64 timescale;
|
||||
|
@ -1118,48 +1124,58 @@ gst_mss_stream_seek (GstMssStream * stream, GstSeekFlags flags, guint64 time,
|
|||
time = gst_util_uint64_scale_round (time, timescale, GST_SECOND);
|
||||
|
||||
GST_DEBUG ("Stream %s seeking to %" G_GUINT64_FORMAT, stream->url, time);
|
||||
|
||||
for (iter = stream->fragments; iter; iter = g_list_next (iter)) {
|
||||
GList *next = g_list_next (iter);
|
||||
if (next) {
|
||||
fragment = next->data;
|
||||
fragment = iter->data;
|
||||
if (fragment->time + fragment->repetitions * fragment->duration > time) {
|
||||
stream->current_fragment = iter;
|
||||
stream->fragment_repetition_index =
|
||||
(time - fragment->time) / fragment->duration;
|
||||
if (((time - fragment->time) % fragment->duration) == 0) {
|
||||
|
||||
if (fragment->time > time) {
|
||||
stream->current_fragment = iter;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
fragment = iter->data;
|
||||
if (fragment->time + fragment->repetitions * fragment->duration > time) {
|
||||
stream->current_fragment = iter;
|
||||
} else {
|
||||
stream->current_fragment = NULL; /* EOS */
|
||||
/* for reverse playback, start from the previous fragment when we are
|
||||
* exactly at a limit */
|
||||
if (!forward)
|
||||
stream->fragment_repetition_index--;
|
||||
} else if (SNAP_AFTER (forward, flags))
|
||||
stream->fragment_repetition_index++;
|
||||
|
||||
if (stream->fragment_repetition_index == fragment->repetitions) {
|
||||
/* move to the next one */
|
||||
stream->fragment_repetition_index = 0;
|
||||
stream->current_fragment = g_list_next (iter);
|
||||
fragment =
|
||||
stream->current_fragment ? stream->current_fragment->data : NULL;
|
||||
|
||||
} else if (stream->fragment_repetition_index == -1) {
|
||||
if (g_list_previous (iter)) {
|
||||
stream->current_fragment = g_list_previous (iter);
|
||||
fragment =
|
||||
stream->current_fragment ? stream->current_fragment->data : NULL;
|
||||
stream->fragment_repetition_index = fragment->repetitions - 1;
|
||||
} else {
|
||||
stream->fragment_repetition_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* position inside the repetitions */
|
||||
if (stream->current_fragment) {
|
||||
fragment = stream->current_fragment->data;
|
||||
stream->fragment_repetition_index =
|
||||
(time - fragment->time) / fragment->duration;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Stream %s seeked to fragment time %" G_GUINT64_FORMAT
|
||||
" repetition %u", stream->url, fragment->time,
|
||||
" repetition %u", stream->url,
|
||||
fragment ? fragment->time : GST_CLOCK_TIME_NONE,
|
||||
stream->fragment_repetition_index);
|
||||
if (final_time) {
|
||||
if (fragment)
|
||||
*final_time =
|
||||
fragment->time +
|
||||
stream->fragment_repetition_index * fragment->duration;
|
||||
else {
|
||||
/* always stops on the last one */
|
||||
GstMssStreamFragment *last_fragment = iter->data;
|
||||
*final_time =
|
||||
last_fragment->time +
|
||||
last_fragment->repetitions * last_fragment->duration;
|
||||
if (fragment) {
|
||||
*final_time = gst_util_uint64_scale_round (fragment->time +
|
||||
stream->fragment_repetition_index * fragment->duration,
|
||||
GST_SECOND, timescale);
|
||||
} else {
|
||||
GstMssStreamFragment *last_fragment = g_list_last (iter)->data;
|
||||
*final_time = gst_util_uint64_scale_round (last_fragment->time +
|
||||
last_fragment->repetitions * last_fragment->duration,
|
||||
GST_SECOND, timescale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1214,7 +1230,9 @@ gst_mss_stream_reload_fragments (GstMssStream * stream, xmlNodePtr streamIndex)
|
|||
g_list_free_full (stream->fragments, g_free);
|
||||
stream->fragments = g_list_reverse (builder.fragments);
|
||||
stream->current_fragment = stream->fragments;
|
||||
gst_mss_stream_seek (stream, 0, current_gst_time, NULL);
|
||||
/* TODO Verify how repositioning here works for reverse
|
||||
* playback - it might start from the wrong fragment */
|
||||
gst_mss_stream_seek (stream, TRUE, 0, current_gst_time, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ GSList * gst_mss_manifest_get_streams (GstMssManifest * manifest);
|
|||
guint64 gst_mss_manifest_get_timescale (GstMssManifest * manifest);
|
||||
guint64 gst_mss_manifest_get_duration (GstMssManifest * manifest);
|
||||
GstClockTime gst_mss_manifest_get_gst_duration (GstMssManifest * manifest);
|
||||
void gst_mss_manifest_seek (GstMssManifest * manifest, guint64 time);
|
||||
void gst_mss_manifest_seek (GstMssManifest * manifest, gboolean forward, guint64 time);
|
||||
gboolean gst_mss_manifest_change_bitrate (GstMssManifest *manifest, guint64 bitrate);
|
||||
guint64 gst_mss_manifest_get_current_bitrate (GstMssManifest * manifest);
|
||||
gboolean gst_mss_manifest_is_live (GstMssManifest * manifest);
|
||||
|
@ -67,7 +67,7 @@ GstClockTime gst_mss_stream_get_fragment_gst_duration (GstMssStream * stream);
|
|||
gboolean gst_mss_stream_has_next_fragment (GstMssStream * stream);
|
||||
GstFlowReturn gst_mss_stream_advance_fragment (GstMssStream * stream);
|
||||
GstFlowReturn gst_mss_stream_regress_fragment (GstMssStream * stream);
|
||||
void gst_mss_stream_seek (GstMssStream * stream, GstSeekFlags flags, guint64 time, guint64 * final_time);
|
||||
void gst_mss_stream_seek (GstMssStream * stream, gboolean forward, GstSeekFlags flags, guint64 time, guint64 * final_time);
|
||||
const gchar * gst_mss_stream_get_lang (GstMssStream * stream);
|
||||
|
||||
const gchar * gst_mss_stream_type_name (GstMssStreamType streamtype);
|
||||
|
|
Loading…
Reference in a new issue