mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 04:52:28 +00:00
hlsdemux: add floating point segment duration support
This commit is contained in:
parent
1188120eba
commit
fd92f8d6a2
3 changed files with 51 additions and 21 deletions
|
@ -341,9 +341,8 @@ gst_hls_demux_src_event (GstPad * pad, GstEvent * event)
|
||||||
GstSeekType start_type, stop_type;
|
GstSeekType start_type, stop_type;
|
||||||
gint64 start, stop;
|
gint64 start, stop;
|
||||||
GList *walk;
|
GList *walk;
|
||||||
gint current_pos;
|
GstClockTime current_pos, target_pos;
|
||||||
gint current_sequence;
|
gint current_sequence;
|
||||||
gint target_second;
|
|
||||||
GstM3U8MediaFile *file;
|
GstM3U8MediaFile *file;
|
||||||
|
|
||||||
GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK");
|
GST_INFO_OBJECT (demux, "Received GST_EVENT_SEEK");
|
||||||
|
@ -367,14 +366,13 @@ gst_hls_demux_src_event (GstPad * pad, GstEvent * event)
|
||||||
file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data);
|
file = GST_M3U8_MEDIA_FILE (demux->client->current->files->data);
|
||||||
current_sequence = file->sequence;
|
current_sequence = file->sequence;
|
||||||
current_pos = 0;
|
current_pos = 0;
|
||||||
target_second = start / GST_SECOND;
|
target_pos = (GstClockTime) start;
|
||||||
GST_DEBUG_OBJECT (demux, "Target seek to %d", target_second);
|
|
||||||
for (walk = demux->client->current->files; walk; walk = walk->next) {
|
for (walk = demux->client->current->files; walk; walk = walk->next) {
|
||||||
file = walk->data;
|
file = walk->data;
|
||||||
|
|
||||||
current_sequence = file->sequence;
|
current_sequence = file->sequence;
|
||||||
if (current_pos <= target_second
|
if (current_pos <= target_pos
|
||||||
&& target_second < current_pos + file->duration) {
|
&& target_pos < current_pos + file->duration) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
current_pos += file->duration;
|
current_pos += file->duration;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ static void gst_m3u8_free (GstM3U8 * m3u8);
|
||||||
static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data,
|
static gboolean gst_m3u8_update (GstM3U8 * m3u8, gchar * data,
|
||||||
gboolean * updated);
|
gboolean * updated);
|
||||||
static GstM3U8MediaFile *gst_m3u8_media_file_new (gchar * uri,
|
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 void gst_m3u8_media_file_free (GstM3U8MediaFile * self);
|
||||||
|
|
||||||
static GstM3U8 *
|
static GstM3U8 *
|
||||||
|
@ -77,7 +78,7 @@ gst_m3u8_free (GstM3U8 * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstM3U8MediaFile *
|
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)
|
guint sequence)
|
||||||
{
|
{
|
||||||
GstM3U8MediaFile *file;
|
GstM3U8MediaFile *file;
|
||||||
|
@ -131,6 +132,36 @@ int_from_string (gchar * ptr, gchar ** endptr, gint * val)
|
||||||
return end != ptr;
|
return end != ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
static gboolean
|
||||||
parse_attributes (gchar ** ptr, gchar ** a, gchar ** v)
|
parse_attributes (gchar ** ptr, gchar ** a, gchar ** v)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +217,8 @@ gst_m3u8_compare_playlist_by_bitrate (gconstpointer a, gconstpointer b)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
{
|
{
|
||||||
gint val, duration;
|
gint val;
|
||||||
|
GstClockTime duration;
|
||||||
gchar *title, *end;
|
gchar *title, *end;
|
||||||
// gboolean discontinuity;
|
// gboolean discontinuity;
|
||||||
GstM3U8 *list;
|
GstM3U8 *list;
|
||||||
|
@ -222,7 +254,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
}
|
}
|
||||||
|
|
||||||
list = NULL;
|
list = NULL;
|
||||||
duration = -1;
|
duration = 0;
|
||||||
title = NULL;
|
title = NULL;
|
||||||
data += 7;
|
data += 7;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
|
@ -233,7 +265,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
if (data[0] != '#') {
|
if (data[0] != '#') {
|
||||||
gchar *r;
|
gchar *r;
|
||||||
|
|
||||||
if (duration < 0 && list == NULL) {
|
if (duration <= 0 && list == NULL) {
|
||||||
GST_LOG ("%s: got line without EXTINF or EXTSTREAMINF, dropping", data);
|
GST_LOG ("%s: got line without EXTINF or EXTSTREAMINF, dropping", data);
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
|
@ -277,7 +309,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
file =
|
file =
|
||||||
gst_m3u8_media_file_new (data, title, duration,
|
gst_m3u8_media_file_new (data, title, duration,
|
||||||
self->mediasequence++);
|
self->mediasequence++);
|
||||||
duration = -1;
|
duration = 0;
|
||||||
title = NULL;
|
title = NULL;
|
||||||
self->files = g_list_append (self->files, file);
|
self->files = g_list_append (self->files, file);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +353,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
}
|
}
|
||||||
} else if (g_str_has_prefix (data, "#EXT-X-TARGETDURATION:")) {
|
} else if (g_str_has_prefix (data, "#EXT-X-TARGETDURATION:")) {
|
||||||
if (int_from_string (data + 22, &data, &val))
|
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:")) {
|
} else if (g_str_has_prefix (data, "#EXT-X-MEDIA-SEQUENCE:")) {
|
||||||
if (int_from_string (data + 22, &data, &val))
|
if (int_from_string (data + 22, &data, &val))
|
||||||
self->mediasequence = val;
|
self->mediasequence = val;
|
||||||
|
@ -334,11 +366,12 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
|
||||||
g_free (self->allowcache);
|
g_free (self->allowcache);
|
||||||
self->allowcache = g_strdup (data + 19);
|
self->allowcache = g_strdup (data + 19);
|
||||||
} else if (g_str_has_prefix (data, "#EXTINF:")) {
|
} 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");
|
GST_WARNING ("Can't read EXTINF duration");
|
||||||
goto next_line;
|
goto next_line;
|
||||||
}
|
}
|
||||||
duration = val;
|
duration = fval * (gdouble) GST_SECOND;
|
||||||
if (duration > self->targetduration)
|
if (duration > self->targetduration)
|
||||||
GST_WARNING ("EXTINF duration > TARGETDURATION");
|
GST_WARNING ("EXTINF duration > TARGETDURATION");
|
||||||
if (!data || *data != ',')
|
if (!data || *data != ',')
|
||||||
|
@ -485,7 +518,6 @@ gst_m3u8_client_get_current_position (GstM3U8Client * client,
|
||||||
break;
|
break;
|
||||||
*timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration;
|
*timestamp += GST_M3U8_MEDIA_FILE (walk->data)->duration;
|
||||||
}
|
}
|
||||||
*timestamp *= GST_SECOND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -517,7 +549,7 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
|
||||||
client->sequence = file->sequence + 1;
|
client->sequence = file->sequence + 1;
|
||||||
|
|
||||||
*uri = file->uri;
|
*uri = file->uri;
|
||||||
*duration = file->duration * GST_SECOND;
|
*duration = file->duration;
|
||||||
|
|
||||||
GST_M3U8_CLIENT_UNLOCK (client);
|
GST_M3U8_CLIENT_UNLOCK (client);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -545,7 +577,7 @@ gst_m3u8_client_get_duration (GstM3U8Client * client)
|
||||||
|
|
||||||
g_list_foreach (client->current->files, (GFunc) _sum_duration, &duration);
|
g_list_foreach (client->current->files, (GFunc) _sum_duration, &duration);
|
||||||
GST_M3U8_CLIENT_UNLOCK (client);
|
GST_M3U8_CLIENT_UNLOCK (client);
|
||||||
return duration * GST_SECOND;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstClockTime
|
GstClockTime
|
||||||
|
@ -558,7 +590,7 @@ gst_m3u8_client_get_target_duration (GstM3U8Client * client)
|
||||||
GST_M3U8_CLIENT_LOCK (client);
|
GST_M3U8_CLIENT_LOCK (client);
|
||||||
duration = client->current->targetduration;
|
duration = client->current->targetduration;
|
||||||
GST_M3U8_CLIENT_UNLOCK (client);
|
GST_M3U8_CLIENT_UNLOCK (client);
|
||||||
return duration * GST_SECOND;
|
return duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar *
|
const gchar *
|
||||||
|
|
|
@ -41,7 +41,7 @@ struct _GstM3U8
|
||||||
|
|
||||||
gboolean endlist; /* if ENDLIST has been reached */
|
gboolean endlist; /* if ENDLIST has been reached */
|
||||||
gint version; /* last EXT-X-VERSION */
|
gint version; /* last EXT-X-VERSION */
|
||||||
gint targetduration; /* last EXT-X-TARGETDURATION */
|
GstClockTime targetduration; /* last EXT-X-TARGETDURATION */
|
||||||
gchar *allowcache; /* last EXT-X-ALLOWCACHE */
|
gchar *allowcache; /* last EXT-X-ALLOWCACHE */
|
||||||
|
|
||||||
gint bandwidth;
|
gint bandwidth;
|
||||||
|
@ -62,7 +62,7 @@ struct _GstM3U8
|
||||||
struct _GstM3U8MediaFile
|
struct _GstM3U8MediaFile
|
||||||
{
|
{
|
||||||
gchar *title;
|
gchar *title;
|
||||||
gint duration;
|
GstClockTime duration;
|
||||||
gchar *uri;
|
gchar *uri;
|
||||||
guint sequence; /* the sequence nb of this file */
|
guint sequence; /* the sequence nb of this file */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue