hlsdemux: cache current file position in the list

Avoids iterating the list everytime to look for the next segment
to be used (or to advance to the next one).
This commit is contained in:
Thiago Santos 2015-01-08 16:24:29 -03:00
parent 308b2e5aaf
commit d310c0c460
2 changed files with 50 additions and 19 deletions

View file

@ -419,6 +419,7 @@ gst_m3u8_update (GstM3U8Client * client, GstM3U8 * self, gchar * data,
g_free (self->last_data); g_free (self->last_data);
self->last_data = data; self->last_data = data;
client->current_file = NULL;
if (self->files) { if (self->files) {
g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL); g_list_foreach (self->files, (GFunc) gst_m3u8_media_file_free, NULL);
g_list_free (self->files); g_list_free (self->files);
@ -777,6 +778,7 @@ gst_m3u8_client_new (const gchar * uri, const gchar * base_uri)
client = g_new0 (GstM3U8Client, 1); client = g_new0 (GstM3U8Client, 1);
client->main = gst_m3u8_new (); client->main = gst_m3u8_new ();
client->current = NULL; client->current = NULL;
client->current_file = NULL;
client->sequence = -1; client->sequence = -1;
client->sequence_position = 0; client->sequence_position = 0;
client->update_failed_count = 0; client->update_failed_count = 0;
@ -808,6 +810,7 @@ gst_m3u8_client_set_current (GstM3U8Client * self, GstM3U8 * m3u8)
self->current = m3u8; self->current = m3u8;
self->update_failed_count = 0; self->update_failed_count = 0;
self->duration = GST_CLOCK_TIME_NONE; self->duration = GST_CLOCK_TIME_NONE;
self->current_file = NULL;
} }
GST_M3U8_CLIENT_UNLOCK (self); GST_M3U8_CLIENT_UNLOCK (self);
} }
@ -847,8 +850,8 @@ gst_m3u8_client_update (GstM3U8Client * self, gchar * data)
} }
if (m3u8->files && self->sequence == -1) { if (m3u8->files && self->sequence == -1) {
self->sequence = self->current_file = g_list_first (m3u8->files);
GST_M3U8_MEDIA_FILE (g_list_first (m3u8->files)->data)->sequence; self->sequence = GST_M3U8_MEDIA_FILE (self->current_file->data)->sequence;
self->sequence_position = 0; self->sequence_position = 0;
GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence); GST_DEBUG ("Setting first sequence at %u", (guint) self->sequence);
} }
@ -999,7 +1002,6 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
GstClockTime * timestamp, gint64 * range_start, gint64 * range_end, GstClockTime * timestamp, gint64 * range_start, gint64 * range_end,
gchar ** key, guint8 ** iv, gboolean forward) gchar ** key, guint8 ** iv, gboolean forward)
{ {
GList *l;
GstM3U8MediaFile *file; GstM3U8MediaFile *file;
g_return_val_if_fail (client != NULL, FALSE); g_return_val_if_fail (client != NULL, FALSE);
@ -1011,13 +1013,17 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
GST_M3U8_CLIENT_UNLOCK (client); GST_M3U8_CLIENT_UNLOCK (client);
return FALSE; return FALSE;
} }
l = find_next_fragment (client, client->current->files, forward); if (!client->current_file) {
if (!l) { client->current_file =
find_next_fragment (client, client->current->files, forward);
}
if (!client->current_file) {
GST_M3U8_CLIENT_UNLOCK (client); GST_M3U8_CLIENT_UNLOCK (client);
return FALSE; return FALSE;
} }
file = GST_M3U8_MEDIA_FILE (l->data); file = GST_M3U8_MEDIA_FILE (client->current_file->data);
GST_DEBUG ("Got fragment with sequence %u (client sequence %u)", GST_DEBUG ("Got fragment with sequence %u (client sequence %u)",
(guint) file->sequence, (guint) client->sequence); (guint) file->sequence, (guint) client->sequence);
@ -1057,8 +1063,14 @@ gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward)
GST_M3U8_CLIENT_LOCK (client); GST_M3U8_CLIENT_LOCK (client);
GST_DEBUG ("Checking if has next fragment %" G_GINT64_FORMAT, GST_DEBUG ("Checking if has next fragment %" G_GINT64_FORMAT,
client->sequence + 1); client->sequence + (forward ? 1 : -1));
ret = has_next_fragment (client, client->current->files, forward); if (client->current_file) {
ret =
(forward ? client->current_file->next : client->current_file->prev) !=
NULL;
} else {
ret = has_next_fragment (client, client->current->files, forward);
}
GST_M3U8_CLIENT_UNLOCK (client); GST_M3U8_CLIENT_UNLOCK (client);
return ret; return ret;
} }
@ -1066,29 +1078,47 @@ gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward)
void void
gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward) gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
{ {
GList *l;
GstM3U8MediaFile *file; GstM3U8MediaFile *file;
g_return_if_fail (client != NULL); g_return_if_fail (client != NULL);
g_return_if_fail (client->current != NULL); g_return_if_fail (client->current != NULL);
GST_M3U8_CLIENT_LOCK (client); GST_M3U8_CLIENT_LOCK (client);
GST_DEBUG ("Looking for fragment %" G_GINT64_FORMAT, client->sequence); if (!client->current_file) {
l = g_list_find_custom (client->current->files, client, GList *l;
(GCompareFunc) _find_current);
if (l == NULL) { GST_DEBUG ("Looking for fragment %" G_GINT64_FORMAT, client->sequence);
GST_ERROR ("Could not find current fragment"); l = g_list_find_custom (client->current->files, client,
GST_M3U8_CLIENT_UNLOCK (client); (GCompareFunc) _find_current);
return; if (l == NULL) {
GST_ERROR ("Could not find current fragment");
GST_M3U8_CLIENT_UNLOCK (client);
return;
}
client->current_file = l;
} }
file = GST_M3U8_MEDIA_FILE (l->data); file = GST_M3U8_MEDIA_FILE (client->current_file->data);
GST_DEBUG ("Advancing from sequence %u", (guint) file->sequence); GST_DEBUG ("Advancing from sequence %u", (guint) file->sequence);
if (forward) { if (forward) {
client->sequence = file->sequence + 1; client->current_file = client->current_file->next;
if (client->current_file) {
client->sequence =
GST_M3U8_MEDIA_FILE (client->current_file->data)->sequence;
} else {
client->sequence = file->sequence + 1;
}
client->sequence_position += file->duration; client->sequence_position += file->duration;
} else { } else {
client->sequence = file->sequence - 1; client->current_file = client->current_file->prev;
if (client->current_file) {
client->sequence =
GST_M3U8_MEDIA_FILE (client->current_file->data)->sequence;
} else {
client->sequence = file->sequence - 1;
}
if (client->sequence_position > file->duration) if (client->sequence_position > file->duration)
client->sequence_position -= file->duration; client->sequence_position -= file->duration;
else else

View file

@ -89,6 +89,7 @@ struct _GstM3U8Client
GstM3U8 *main; /* main playlist */ GstM3U8 *main; /* main playlist */
GstM3U8 *current; GstM3U8 *current;
guint update_failed_count; guint update_failed_count;
GList *current_file;
gint64 sequence; /* the next sequence for this client */ gint64 sequence; /* the next sequence for this client */
GstClockTime sequence_position; /* position of this sequence */ GstClockTime sequence_position; /* position of this sequence */
gint64 highest_sequence_number; /* largest seen sequence number */ gint64 highest_sequence_number; /* largest seen sequence number */