mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
hlsdemux: Report the correct timestamp for live streams
Buffers would always start with timestamp 0 and we'd start streaming from the first buffer, but live streams always start streaming from the last fragment - 3 fragments in the playlist, which makes its timestamp, as returned by get_next_fragment, be whatever position they had in the playlist. This makes sure the position correctly reports the position of the buffer in the playlist, and added a shifting variable to allow seeking in the middle of fragments.
This commit is contained in:
parent
894ac8f493
commit
55e4206159
4 changed files with 35 additions and 7 deletions
|
@ -410,7 +410,8 @@ gst_hls_demux_src_event (GstPad * pad, GstEvent * event)
|
|||
GST_M3U8_CLIENT_LOCK (demux->client);
|
||||
GST_DEBUG_OBJECT (demux, "seeking to sequence %d", current_sequence);
|
||||
demux->client->sequence = current_sequence;
|
||||
demux->position = start;
|
||||
gst_m3u8_client_get_current_position (demux->client, &demux->position);
|
||||
demux->position_shift = start - demux->position;
|
||||
demux->need_segment = TRUE;
|
||||
GST_M3U8_CLIENT_UNLOCK (demux->client);
|
||||
|
||||
|
@ -751,13 +752,15 @@ gst_hls_demux_loop (GstHLSDemux * demux)
|
|||
demux->need_segment = TRUE;
|
||||
}
|
||||
if (demux->need_segment) {
|
||||
GstClockTime start = demux->position + demux->position_shift;
|
||||
/* And send a newsegment */
|
||||
GST_DEBUG_OBJECT (demux, "Sending new-segment. Segment start:%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (demux->position));
|
||||
GST_DEBUG_OBJECT (demux, "Sending new-segment. segment start:%"
|
||||
GST_TIME_FORMAT, GST_TIME_ARGS (start));
|
||||
gst_pad_push_event (demux->srcpad,
|
||||
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, demux->position,
|
||||
GST_CLOCK_TIME_NONE, demux->position));
|
||||
gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
|
||||
start, GST_CLOCK_TIME_NONE, start));
|
||||
demux->need_segment = FALSE;
|
||||
demux->position_shift = 0;
|
||||
}
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buf)))
|
||||
|
@ -886,6 +889,7 @@ gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose)
|
|||
g_queue_clear (demux->queue);
|
||||
|
||||
demux->position = 0;
|
||||
demux->position_shift = 0;
|
||||
demux->need_segment = TRUE;
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1041,7 @@ gst_hls_demux_cache_fragments (GstHLSDemux * demux)
|
|||
demux->client->sequence -= demux->fragments_cache;
|
||||
else
|
||||
demux->client->sequence = 0;
|
||||
gst_m3u8_client_get_current_position (demux->client, &demux->position);
|
||||
GST_M3U8_CLIENT_UNLOCK (demux->client);
|
||||
} else {
|
||||
GstClockTime duration = gst_m3u8_client_get_duration (demux->client);
|
||||
|
|
|
@ -89,6 +89,7 @@ struct _GstHLSDemux
|
|||
|
||||
/* Position in the stream */
|
||||
GstClockTime position;
|
||||
GstClockTime position_shift;
|
||||
gboolean need_segment;
|
||||
};
|
||||
|
||||
|
|
|
@ -468,13 +468,31 @@ _find_next (GstM3U8MediaFile * file, GstM3U8Client * client)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
gst_m3u8_client_get_current_position (GstM3U8Client * client,
|
||||
GstClockTime * timestamp)
|
||||
{
|
||||
GList *l;
|
||||
GList *walk;
|
||||
|
||||
l = g_list_find_custom (client->current->files, client,
|
||||
(GCompareFunc) _find_next);
|
||||
|
||||
*timestamp = 0;
|
||||
for (walk = client->current->files; walk; walk = walk->next) {
|
||||
if (walk == l)
|
||||
break;
|
||||
*timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration;
|
||||
}
|
||||
*timestamp *= GST_SECOND;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
|
||||
gboolean * discontinuity, const gchar ** uri, GstClockTime * duration,
|
||||
GstClockTime * timestamp)
|
||||
{
|
||||
GList *l;
|
||||
GList *walk;
|
||||
GList *l, *walk;
|
||||
GstM3U8MediaFile *file;
|
||||
|
||||
g_return_val_if_fail (client != NULL, FALSE);
|
||||
|
@ -490,6 +508,8 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gst_m3u8_client_get_current_position (client, timestamp);
|
||||
|
||||
file = GST_M3U8_MEDIA_FILE (l->data);
|
||||
|
||||
*discontinuity = client->sequence != file->sequence;
|
||||
|
|
|
@ -84,6 +84,8 @@ void gst_m3u8_client_set_current (GstM3U8Client * client, GstM3U8 * m3u8);
|
|||
gboolean gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
|
||||
gboolean * discontinuity, const gchar ** uri, GstClockTime * duration,
|
||||
GstClockTime * timestamp);
|
||||
void gst_m3u8_client_get_current_position (GstM3U8Client * client,
|
||||
GstClockTime * timestamp);
|
||||
GstClockTime gst_m3u8_client_get_duration (GstM3U8Client * client);
|
||||
GstClockTime gst_m3u8_client_get_target_duration (GstM3U8Client * client);
|
||||
const gchar *gst_m3u8_client_get_uri(GstM3U8Client * client);
|
||||
|
|
Loading…
Reference in a new issue