GstSeekType start_type, stop_type;
gint64 start, stop;
GList *walk;
- gint current_pos;
+ GstClockTime current_pos, target_pos;
gint current_sequence;
- gint target_second;
GstM3U8MediaFile *file;
GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK");
file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data);
current_sequence = file->sequence;
current_pos = 0;
- target_second = start / GST_SECOND;
- GST_DEBUG_OBJECT (demux, "Target seek to %d", target_second);
+ target_pos = (GstClockTime) start;
for (walk = demux->client->current->files; walk; walk = walk->next) {
file = walk->data;
current_sequence = file->sequence;
- if (current_pos <= target_second
- && target_second < current_pos + file->duration) {
+ if (current_pos <= target_pos
+ && target_pos < current_pos + file->duration) {
break;
}
current_pos += file->duration;
*/
#include <stdlib.h>
+#include <math.h>
#include <errno.h>
#include <glib.h>
static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data,
gboolean * updated);
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
- gchar * title, gint duration, guint sequence);
+ gchar * title, GstClockTime duration, guint sequence);
static void gst_m3u8_media_file_free (GstM3U8MediaFile * self);
static GstM3U8 *
}
static GstM3U8MediaFile *
-gst_m3u8_media_file_new (gchar * uri, gchar * title, gint duration,
+gst_m3u8_media_file_new (gchar * uri, gchar * title, GstClockTime duration,
guint sequence)
{
GstM3U8MediaFile *file;
}
static gboolean
+double_from_string (gchar * ptr, gchar ** endptr, gdouble * val)
+{
+ gchar *end;
+ gdouble ret;
+
+ g_return_val_if_fail (ptr != NULL, FALSE);
+ g_return_val_if_fail (val != NULL, FALSE);
+
+ errno = 0;
+ ret = strtod (ptr, &end);
+ if ((errno == ERANGE && (ret == HUGE_VAL || ret == -HUGE_VAL))
+ || (errno != 0 && ret == 0)) {
+ GST_WARNING ("%s", g_strerror (errno));
+ return FALSE;
+ }
+
+ if (!isfinite (ret)) {
+ GST_WARNING ("%s", g_strerror (ERANGE));
+ return FALSE;
+ }
+
+ if (endptr)
+ *endptr = end;
+
+ *val = (gint) ret;
+
+ return end != ptr;
+}
+
+static gboolean
parse_attributes (gchar ** ptr, gchar ** a, gchar ** v)
{
gchar *end, *p;
static gboolean
gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
{
- gint val, duration;
+ gint val;
+ GstClockTime duration;
gchar *title, *end;
// gboolean discontinuity;
GstM3U8 *list;
}
list = NULL;
- duration = -1;
+ duration = 0;
title = NULL;
data += 7;
while (TRUE) {
if (data[0] != '#') {
gchar *r;
- if (duration < 0 && list == NULL) {
+ if (duration <= 0 && list == NULL) {
GST_LOG ("%s: got line without EXTINF or EXTSTREAMINF, dropping", data);
goto next_line;
}
file =
gst_m3u8_media_file_new (data, title, duration,
self->mediasequence++);
- duration = -1;
+ duration = 0;
title = NULL;
self->files = g_list_append (self->files, file);
}
}
} else if (g_str_has_prefix (data, "#EXT-X-TARGETDURATION:")) {
if (int_from_string (data + 22, &data, &val))
- self->targetduration = val;
+ self->targetduration = val * GST_SECOND;
} else if (g_str_has_prefix (data, "#EXT-X-MEDIA-SEQUENCE:")) {
if (int_from_string (data + 22, &data, &val))
self->mediasequence = val;
g_free (self->allowcache);
self->allowcache = g_strdup (data + 19);
} else if (g_str_has_prefix (data, "#EXTINF:")) {
- if (!int_from_string (data + 8, &data, &val)) {
+ gdouble fval;
+ if (!double_from_string (data + 8, &data, &fval)) {
GST_WARNING ("Can't read EXTINF duration");
goto next_line;
}
- duration = val;
+ duration = fval * (gdouble) GST_SECOND;
if (duration > self->targetduration)
GST_WARNING ("EXTINF duration > TARGETDURATION");
if (!data || *data != ',')
break;
*timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration;
}
- *timestamp *= GST_SECOND;
}
gboolean
client->sequence = file->sequence + 1;
*uri = file->uri;
- *duration = file->duration * GST_SECOND;
+ *duration = file->duration;
GST_M3U8_CLIENT_UNLOCK (client);
return TRUE;
g_list_foreach (client->current->files, (GFunc) _sum_duration, &duration);
GST_M3U8_CLIENT_UNLOCK (client);
- return duration * GST_SECOND;
+ return duration;
}
GstClockTime
GST_M3U8_CLIENT_LOCK (client);
duration = client->current->targetduration;
GST_M3U8_CLIENT_UNLOCK (client);
- return duration * GST_SECOND;
+ return duration;
}
const gchar *