mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-09 08:55:33 +00:00
hlsdemux2: Remove enable-llhls property
This was only used for testing purposes Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
parent
854683c871
commit
0639f117cb
9 changed files with 53 additions and 148 deletions
|
@ -49,7 +49,6 @@ enum _PlaylistLoaderState
|
||||||
struct _GstHLSDemuxPlaylistLoaderPrivate
|
struct _GstHLSDemuxPlaylistLoaderPrivate
|
||||||
{
|
{
|
||||||
GstAdaptiveDemux *demux;
|
GstAdaptiveDemux *demux;
|
||||||
gboolean llhls_enabled;
|
|
||||||
|
|
||||||
GstHLSDemuxPlaylistLoaderSuccessCallback success_cb;
|
GstHLSDemuxPlaylistLoaderSuccessCallback success_cb;
|
||||||
GstHLSDemuxPlaylistLoaderErrorCallback error_cb;
|
GstHLSDemuxPlaylistLoaderErrorCallback error_cb;
|
||||||
|
@ -89,14 +88,13 @@ static void start_playlist_download (GstHLSDemuxPlaylistLoader * pl,
|
||||||
/* Takes ownership of the loop ref */
|
/* Takes ownership of the loop ref */
|
||||||
GstHLSDemuxPlaylistLoader *
|
GstHLSDemuxPlaylistLoader *
|
||||||
gst_hls_demux_playlist_loader_new (GstAdaptiveDemux * demux,
|
gst_hls_demux_playlist_loader_new (GstAdaptiveDemux * demux,
|
||||||
DownloadHelper * download_helper, gboolean llhls_enabled)
|
DownloadHelper * download_helper)
|
||||||
{
|
{
|
||||||
GstHLSDemuxPlaylistLoader *pl =
|
GstHLSDemuxPlaylistLoader *pl =
|
||||||
g_object_new (GST_TYPE_HLS_DEMUX_PLAYLIST_LOADER, NULL);
|
g_object_new (GST_TYPE_HLS_DEMUX_PLAYLIST_LOADER, NULL);
|
||||||
GstHLSDemuxPlaylistLoaderPrivate *priv = pl->priv;
|
GstHLSDemuxPlaylistLoaderPrivate *priv = pl->priv;
|
||||||
|
|
||||||
priv->demux = demux;
|
priv->demux = demux;
|
||||||
priv->llhls_enabled = llhls_enabled;
|
|
||||||
priv->scheduler_task = gst_adaptive_demux_get_loop (demux);
|
priv->scheduler_task = gst_adaptive_demux_get_loop (demux);
|
||||||
priv->download_helper = download_helper;
|
priv->download_helper = download_helper;
|
||||||
|
|
||||||
|
@ -428,7 +426,7 @@ get_playlist_reload_interval (GstHLSDemuxPlaylistLoader * pl,
|
||||||
GstM3U8MediaSegment *last_seg =
|
GstM3U8MediaSegment *last_seg =
|
||||||
g_ptr_array_index (playlist->segments, playlist->segments->len - 1);
|
g_ptr_array_index (playlist->segments, playlist->segments->len - 1);
|
||||||
|
|
||||||
if (priv->llhls_enabled && last_seg->partial_segments) {
|
if (last_seg->partial_segments) {
|
||||||
GstM3U8PartialSegment *last_part =
|
GstM3U8PartialSegment *last_part =
|
||||||
g_ptr_array_index (last_seg->partial_segments,
|
g_ptr_array_index (last_seg->partial_segments,
|
||||||
last_seg->partial_segments->len - 1);
|
last_seg->partial_segments->len - 1);
|
||||||
|
@ -443,8 +441,7 @@ get_playlist_reload_interval (GstHLSDemuxPlaylistLoader * pl,
|
||||||
target_duration = last_seg->duration;
|
target_duration = last_seg->duration;
|
||||||
min_reload_interval = target_duration / 2;
|
min_reload_interval = target_duration / 2;
|
||||||
}
|
}
|
||||||
} else if (priv->llhls_enabled
|
} else if (GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)) {
|
||||||
&& GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)) {
|
|
||||||
target_duration = playlist->partial_targetduration;
|
target_duration = playlist->partial_targetduration;
|
||||||
min_reload_interval = target_duration / 2;
|
min_reload_interval = target_duration / 2;
|
||||||
} else if (playlist->version > 5) {
|
} else if (playlist->version > 5) {
|
||||||
|
@ -740,7 +737,7 @@ start_playlist_download (GstHLSDemuxPlaylistLoader * pl,
|
||||||
} else {
|
} else {
|
||||||
/* Get the next MSN (and/or possibly part number) for the request params */
|
/* Get the next MSN (and/or possibly part number) for the request params */
|
||||||
gst_hls_media_playlist_get_next_msn_and_part (current_playlist,
|
gst_hls_media_playlist_get_next_msn_and_part (current_playlist,
|
||||||
priv->llhls_enabled, &dl_params.next_msn, &dl_params.next_part);
|
&dl_params.next_msn, &dl_params.next_part);
|
||||||
dl_params.flags |= PLAYLIST_DOWNLOAD_FLAG_BLOCKING_REQUEST;
|
dl_params.flags |= PLAYLIST_DOWNLOAD_FLAG_BLOCKING_REQUEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct _GstHLSDemuxPlaylistLoader
|
||||||
GType gst_hls_demux_playlist_loader_get_type(void);
|
GType gst_hls_demux_playlist_loader_get_type(void);
|
||||||
|
|
||||||
GstHLSDemuxPlaylistLoader *gst_hls_demux_playlist_loader_new(GstAdaptiveDemux *demux,
|
GstHLSDemuxPlaylistLoader *gst_hls_demux_playlist_loader_new(GstAdaptiveDemux *demux,
|
||||||
DownloadHelper *download_helper, gboolean llhls_enabled);
|
DownloadHelper *download_helper);
|
||||||
|
|
||||||
void gst_hls_demux_playlist_loader_set_callbacks (GstHLSDemuxPlaylistLoader *pl,
|
void gst_hls_demux_playlist_loader_set_callbacks (GstHLSDemuxPlaylistLoader *pl,
|
||||||
GstHLSDemuxPlaylistLoaderSuccessCallback success_cb,
|
GstHLSDemuxPlaylistLoaderSuccessCallback success_cb,
|
||||||
|
|
|
@ -44,15 +44,6 @@
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_hls_demux2_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_hls_demux2_debug);
|
||||||
#define GST_CAT_DEFAULT gst_hls_demux2_debug
|
#define GST_CAT_DEFAULT gst_hls_demux2_debug
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PROP_0,
|
|
||||||
|
|
||||||
PROP_LLHLS_ENABLED,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DEFAULT_LLHLS_ENABLED TRUE
|
|
||||||
|
|
||||||
/* Maximum values for mpeg-ts DTS values */
|
/* Maximum values for mpeg-ts DTS values */
|
||||||
#define MPEG_TS_MAX_PTS (((((guint64)1) << 33) * (guint64)100000) / 9)
|
#define MPEG_TS_MAX_PTS (((((guint64)1) << 33) * (guint64)100000) / 9)
|
||||||
|
|
||||||
|
@ -94,38 +85,6 @@ static void gst_hls_demux_stream_finalize (GObject * object);
|
||||||
G_DEFINE_TYPE (GstHLSDemuxStream, gst_hls_demux_stream,
|
G_DEFINE_TYPE (GstHLSDemuxStream, gst_hls_demux_stream,
|
||||||
GST_TYPE_ADAPTIVE_DEMUX2_STREAM);
|
GST_TYPE_ADAPTIVE_DEMUX2_STREAM);
|
||||||
|
|
||||||
static void
|
|
||||||
gst_hls_demux_stream_set_property (GObject * object, guint prop_id,
|
|
||||||
const GValue * value, GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
GstHLSDemuxStream *stream = GST_HLS_DEMUX_STREAM (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_LLHLS_ENABLED:
|
|
||||||
stream->llhls_enabled = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_hls_demux_stream_get_property (GObject * object, guint prop_id,
|
|
||||||
GValue * value, GParamSpec * pspec)
|
|
||||||
{
|
|
||||||
GstHLSDemuxStream *stream = GST_HLS_DEMUX_STREAM (object);
|
|
||||||
|
|
||||||
switch (prop_id) {
|
|
||||||
case PROP_LLHLS_ENABLED:
|
|
||||||
g_value_set_boolean (value, stream->llhls_enabled);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_hls_demux_stream_class_init (GstHLSDemuxStreamClass * klass)
|
gst_hls_demux_stream_class_init (GstHLSDemuxStreamClass * klass)
|
||||||
{
|
{
|
||||||
|
@ -133,8 +92,6 @@ gst_hls_demux_stream_class_init (GstHLSDemuxStreamClass * klass)
|
||||||
GstAdaptiveDemux2StreamClass *adaptivedemux2stream_class =
|
GstAdaptiveDemux2StreamClass *adaptivedemux2stream_class =
|
||||||
GST_ADAPTIVE_DEMUX2_STREAM_CLASS (klass);
|
GST_ADAPTIVE_DEMUX2_STREAM_CLASS (klass);
|
||||||
|
|
||||||
gobject_class->set_property = gst_hls_demux_stream_set_property;
|
|
||||||
gobject_class->get_property = gst_hls_demux_stream_get_property;
|
|
||||||
gobject_class->finalize = gst_hls_demux_stream_finalize;
|
gobject_class->finalize = gst_hls_demux_stream_finalize;
|
||||||
|
|
||||||
adaptivedemux2stream_class->update_fragment_info =
|
adaptivedemux2stream_class->update_fragment_info =
|
||||||
|
@ -162,10 +119,6 @@ gst_hls_demux_stream_class_init (GstHLSDemuxStreamClass * klass)
|
||||||
adaptivedemux2stream_class->get_presentation_offset =
|
adaptivedemux2stream_class->get_presentation_offset =
|
||||||
gst_hls_demux_stream_get_presentation_offset;
|
gst_hls_demux_stream_get_presentation_offset;
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_LLHLS_ENABLED,
|
|
||||||
g_param_spec_boolean ("llhls-enabled", "Enable LL-HLS support",
|
|
||||||
"Enable support for LL-HLS (Low Latency HLS) downloads",
|
|
||||||
DEFAULT_LLHLS_ENABLED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -176,7 +129,6 @@ gst_hls_demux_stream_init (GstHLSDemuxStream * stream)
|
||||||
stream->reset_pts = TRUE;
|
stream->reset_pts = TRUE;
|
||||||
stream->presentation_offset = 60 * GST_SECOND;
|
stream->presentation_offset = 60 * GST_SECOND;
|
||||||
stream->pdt_tag_sent = FALSE;
|
stream->pdt_tag_sent = FALSE;
|
||||||
stream->llhls_enabled = DEFAULT_LLHLS_ENABLED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -216,8 +168,7 @@ gst_hls_demux_stream_seek (GstAdaptiveDemux2Stream * stream, gboolean forward,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow jumping to partial segments in the last 2 segments in LL-HLS */
|
/* Allow jumping to partial segments in the last 2 segments in LL-HLS */
|
||||||
if (hls_stream->llhls_enabled
|
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (hls_stream->playlist))
|
||||||
&& GST_HLS_MEDIA_PLAYLIST_IS_LIVE (hls_stream->playlist))
|
|
||||||
flags |= GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL;
|
flags |= GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL;
|
||||||
|
|
||||||
GstM3U8SeekResult seek_result;
|
GstM3U8SeekResult seek_result;
|
||||||
|
@ -1207,8 +1158,7 @@ gst_hls_demux_stream_advance_fragment (GstAdaptiveDemux2Stream * stream)
|
||||||
|
|
||||||
new_segment =
|
new_segment =
|
||||||
gst_hls_media_playlist_advance_fragment (hlsdemux_stream->playlist,
|
gst_hls_media_playlist_advance_fragment (hlsdemux_stream->playlist,
|
||||||
hlsdemux_stream->current_segment, stream->demux->segment.rate > 0,
|
hlsdemux_stream->current_segment, stream->demux->segment.rate > 0);
|
||||||
hlsdemux_stream->llhls_enabled);
|
|
||||||
|
|
||||||
if (new_segment) {
|
if (new_segment) {
|
||||||
hlsdemux_stream->reset_pts = FALSE;
|
hlsdemux_stream->reset_pts = FALSE;
|
||||||
|
@ -1220,8 +1170,7 @@ gst_hls_demux_stream_advance_fragment (GstAdaptiveDemux2Stream * stream)
|
||||||
hlsdemux_stream->current_segment = new_segment;
|
hlsdemux_stream->current_segment = new_segment;
|
||||||
|
|
||||||
/* In LL-HLS, handle advancing into the partial-only segment */
|
/* In LL-HLS, handle advancing into the partial-only segment */
|
||||||
if (hlsdemux_stream->llhls_enabled
|
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (hlsdemux_stream->playlist)
|
||||||
&& GST_HLS_MEDIA_PLAYLIST_IS_LIVE (hlsdemux_stream->playlist)
|
|
||||||
&& new_segment->partial_only) {
|
&& new_segment->partial_only) {
|
||||||
hlsdemux_stream->in_partial_segments = TRUE;
|
hlsdemux_stream->in_partial_segments = TRUE;
|
||||||
hlsdemux_stream->part_idx = 0;
|
hlsdemux_stream->part_idx = 0;
|
||||||
|
@ -1261,8 +1210,7 @@ static void
|
||||||
gst_hls_demux_stream_update_preloads (GstHLSDemuxStream * hlsdemux_stream)
|
gst_hls_demux_stream_update_preloads (GstHLSDemuxStream * hlsdemux_stream)
|
||||||
{
|
{
|
||||||
GstHLSMediaPlaylist *playlist = hlsdemux_stream->playlist;
|
GstHLSMediaPlaylist *playlist = hlsdemux_stream->playlist;
|
||||||
gboolean preloads_allowed = hlsdemux_stream->llhls_enabled
|
gboolean preloads_allowed = GST_HLS_MEDIA_PLAYLIST_IS_LIVE (playlist);
|
||||||
&& GST_HLS_MEDIA_PLAYLIST_IS_LIVE (playlist);
|
|
||||||
|
|
||||||
if (playlist->preload_hints == NULL || !preloads_allowed) {
|
if (playlist->preload_hints == NULL || !preloads_allowed) {
|
||||||
if (hlsdemux_stream->preloader != NULL) {
|
if (hlsdemux_stream->preloader != NULL) {
|
||||||
|
@ -1532,8 +1480,7 @@ gst_hls_demux_stream_get_playlist_loader (GstHLSDemuxStream * hls_stream)
|
||||||
GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX2_STREAM_CAST (hls_stream)->demux;
|
GstAdaptiveDemux *demux = GST_ADAPTIVE_DEMUX2_STREAM_CAST (hls_stream)->demux;
|
||||||
if (hls_stream->playlistloader == NULL) {
|
if (hls_stream->playlistloader == NULL) {
|
||||||
hls_stream->playlistloader =
|
hls_stream->playlistloader =
|
||||||
gst_hls_demux_playlist_loader_new (demux, demux->download_helper,
|
gst_hls_demux_playlist_loader_new (demux, demux->download_helper);
|
||||||
hls_stream->llhls_enabled);
|
|
||||||
gst_hls_demux_playlist_loader_set_callbacks (hls_stream->playlistloader,
|
gst_hls_demux_playlist_loader_set_callbacks (hls_stream->playlistloader,
|
||||||
on_playlist_update_success, on_playlist_update_error, hls_stream);
|
on_playlist_update_success, on_playlist_update_error, hls_stream);
|
||||||
}
|
}
|
||||||
|
@ -1638,8 +1585,7 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream)
|
||||||
GST_DEBUG_OBJECT (stream, "Setting up initial segment");
|
GST_DEBUG_OBJECT (stream, "Setting up initial segment");
|
||||||
|
|
||||||
if (gst_hls_media_playlist_get_starting_segment
|
if (gst_hls_media_playlist_get_starting_segment
|
||||||
(hlsdemux_stream->playlist, hlsdemux_stream->llhls_enabled,
|
(hlsdemux_stream->playlist, &seek_result)) {
|
||||||
&seek_result)) {
|
|
||||||
hlsdemux_stream->current_segment = seek_result.segment;
|
hlsdemux_stream->current_segment = seek_result.segment;
|
||||||
hlsdemux_stream->in_partial_segments =
|
hlsdemux_stream->in_partial_segments =
|
||||||
seek_result.found_partial_segment;
|
seek_result.found_partial_segment;
|
||||||
|
@ -1797,7 +1743,7 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream)
|
||||||
|
|
||||||
stream->recommended_buffering_threshold =
|
stream->recommended_buffering_threshold =
|
||||||
gst_hls_media_playlist_recommended_buffering_threshold
|
gst_hls_media_playlist_recommended_buffering_threshold
|
||||||
(hlsdemux_stream->playlist, hlsdemux_stream->llhls_enabled);
|
(hlsdemux_stream->playlist);
|
||||||
|
|
||||||
if (discont)
|
if (discont)
|
||||||
stream->discont = TRUE;
|
stream->discont = TRUE;
|
||||||
|
|
|
@ -69,11 +69,6 @@ struct _GstHLSDemuxStream
|
||||||
/* A stream either variants or renditions */
|
/* A stream either variants or renditions */
|
||||||
gboolean is_variant;
|
gboolean is_variant;
|
||||||
|
|
||||||
/* A copy of the demuxer flag, stored when the
|
|
||||||
* stream is created, so it can't change after
|
|
||||||
* the stream starts downloading things */
|
|
||||||
gboolean llhls_enabled;
|
|
||||||
|
|
||||||
/* Rendition-specific fields */
|
/* Rendition-specific fields */
|
||||||
GstStreamType rendition_type; /* FIXME: Also used by variant streams */
|
GstStreamType rendition_type; /* FIXME: Also used by variant streams */
|
||||||
gchar *lang;
|
gchar *lang;
|
||||||
|
|
|
@ -72,11 +72,9 @@ enum
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
PROP_START_BITRATE,
|
PROP_START_BITRATE,
|
||||||
PROP_LLHLS_ENABLED,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEFAULT_START_BITRATE 0
|
#define DEFAULT_START_BITRATE 0
|
||||||
#define DEFAULT_LLHLS_ENABLED TRUE
|
|
||||||
|
|
||||||
/* GObject */
|
/* GObject */
|
||||||
static void gst_hls_demux_finalize (GObject * obj);
|
static void gst_hls_demux_finalize (GObject * obj);
|
||||||
|
@ -141,9 +139,6 @@ gst_hls_demux_set_property (GObject * object, guint prop_id,
|
||||||
case PROP_START_BITRATE:
|
case PROP_START_BITRATE:
|
||||||
demux->start_bitrate = g_value_get_uint (value);
|
demux->start_bitrate = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
case PROP_LLHLS_ENABLED:
|
|
||||||
demux->llhls_enabled = g_value_get_boolean (value);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -160,9 +155,6 @@ gst_hls_demux_get_property (GObject * object, guint prop_id,
|
||||||
case PROP_START_BITRATE:
|
case PROP_START_BITRATE:
|
||||||
g_value_set_uint (value, demux->start_bitrate);
|
g_value_set_uint (value, demux->start_bitrate);
|
||||||
break;
|
break;
|
||||||
case PROP_LLHLS_ENABLED:
|
|
||||||
g_value_set_boolean (value, demux->llhls_enabled);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -201,11 +193,6 @@ gst_hls_demux2_class_init (GstHLSDemux2Class * klass)
|
||||||
0, G_MAXUINT, DEFAULT_START_BITRATE,
|
0, G_MAXUINT, DEFAULT_START_BITRATE,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, PROP_LLHLS_ENABLED,
|
|
||||||
g_param_spec_boolean ("llhls-enabled", "Enable LL-HLS support",
|
|
||||||
"Enable support for LL-HLS (Low Latency HLS) downloads",
|
|
||||||
DEFAULT_LLHLS_ENABLED, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
||||||
|
|
||||||
element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state);
|
element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state);
|
||||||
|
|
||||||
gst_element_class_add_static_pad_template (element_class, &sinktemplate);
|
gst_element_class_add_static_pad_template (element_class, &sinktemplate);
|
||||||
|
@ -232,7 +219,6 @@ gst_hls_demux2_class_init (GstHLSDemux2Class * klass)
|
||||||
static void
|
static void
|
||||||
gst_hls_demux2_init (GstHLSDemux * demux)
|
gst_hls_demux2_init (GstHLSDemux * demux)
|
||||||
{
|
{
|
||||||
demux->llhls_enabled = DEFAULT_LLHLS_ENABLED;
|
|
||||||
demux->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
demux->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
|
||||||
g_mutex_init (&demux->keys_lock);
|
g_mutex_init (&demux->keys_lock);
|
||||||
}
|
}
|
||||||
|
@ -438,8 +424,7 @@ create_common_hls_stream (GstHLSDemux * demux, const gchar * name)
|
||||||
{
|
{
|
||||||
GstAdaptiveDemux2Stream *stream;
|
GstAdaptiveDemux2Stream *stream;
|
||||||
|
|
||||||
stream = g_object_new (GST_TYPE_HLS_DEMUX_STREAM, "name", name,
|
stream = g_object_new (GST_TYPE_HLS_DEMUX_STREAM, "name", name, NULL);
|
||||||
"llhls-enabled", demux->llhls_enabled, NULL);
|
|
||||||
|
|
||||||
gst_adaptive_demux2_add_stream ((GstAdaptiveDemux *) demux, stream);
|
gst_adaptive_demux2_add_stream ((GstAdaptiveDemux *) demux, stream);
|
||||||
|
|
||||||
|
@ -760,7 +745,7 @@ gst_hls_demux_process_initial_manifest (GstAdaptiveDemux * demux,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_hls_media_playlist_get_starting_segment (simple_media_playlist,
|
if (!gst_hls_media_playlist_get_starting_segment (simple_media_playlist,
|
||||||
hlsdemux->main_stream->llhls_enabled, &seek_result)) {
|
&seek_result)) {
|
||||||
GST_DEBUG_OBJECT (hlsdemux->main_stream,
|
GST_DEBUG_OBJECT (hlsdemux->main_stream,
|
||||||
"Failed to find a segment to start at");
|
"Failed to find a segment to start at");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1231,7 +1216,7 @@ gst_hls_demux_reset_for_lost_sync (GstHLSDemux * hlsdemux)
|
||||||
/* Resynchronize the variant stream */
|
/* Resynchronize the variant stream */
|
||||||
g_assert (stream->current_position != GST_CLOCK_STIME_NONE);
|
g_assert (stream->current_position != GST_CLOCK_STIME_NONE);
|
||||||
if (gst_hls_media_playlist_get_starting_segment (hls_stream->playlist,
|
if (gst_hls_media_playlist_get_starting_segment (hls_stream->playlist,
|
||||||
hls_stream->llhls_enabled, &seek_result)) {
|
&seek_result)) {
|
||||||
hls_stream->current_segment = seek_result.segment;
|
hls_stream->current_segment = seek_result.segment;
|
||||||
hls_stream->in_partial_segments = seek_result.found_partial_segment;
|
hls_stream->in_partial_segments = seek_result.found_partial_segment;
|
||||||
hls_stream->part_idx = seek_result.part_idx;
|
hls_stream->part_idx = seek_result.part_idx;
|
||||||
|
@ -1371,8 +1356,8 @@ gst_hls_demux_get_live_seek_range (GstAdaptiveDemux * demux, gint64 * start,
|
||||||
|
|
||||||
if (hlsdemux->main_playlist) {
|
if (hlsdemux->main_playlist) {
|
||||||
ret =
|
ret =
|
||||||
gst_hls_media_playlist_get_seek_range (hlsdemux->main_playlist,
|
gst_hls_media_playlist_get_seek_range (hlsdemux->main_playlist, start,
|
||||||
hlsdemux->llhls_enabled, start, stop);
|
stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -81,9 +81,6 @@ struct _GstHLSDemux2
|
||||||
/* Initial bitrate to use before any bandwidth measurement */
|
/* Initial bitrate to use before any bandwidth measurement */
|
||||||
guint start_bitrate;
|
guint start_bitrate;
|
||||||
|
|
||||||
/* Whether LL-HLS (Low Latency HLS) features are enabled */
|
|
||||||
gboolean llhls_enabled;
|
|
||||||
|
|
||||||
/* Decryption key cache: url => GstHLSKey */
|
/* Decryption key cache: url => GstHLSKey */
|
||||||
GHashTable *keys;
|
GHashTable *keys;
|
||||||
GMutex keys_lock;
|
GMutex keys_lock;
|
||||||
|
|
|
@ -2087,11 +2087,11 @@ gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * playlist,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist * self,
|
gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist * self,
|
||||||
gboolean allow_low_latency, GstM3U8SeekResult * seek_result)
|
GstM3U8SeekResult * seek_result)
|
||||||
{
|
{
|
||||||
GstM3U8MediaSegment *res = NULL;
|
GstM3U8MediaSegment *res = NULL;
|
||||||
|
|
||||||
GST_DEBUG ("allow_low_latency:%d playlist %s", allow_low_latency, self->uri);
|
GST_DEBUG ("playlist %s", self->uri);
|
||||||
|
|
||||||
if (!GST_HLS_MEDIA_PLAYLIST_IS_LIVE (self)) {
|
if (!GST_HLS_MEDIA_PLAYLIST_IS_LIVE (self)) {
|
||||||
/* For non-live, we just grab the first one */
|
/* For non-live, we just grab the first one */
|
||||||
|
@ -2100,14 +2100,13 @@ gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist * self,
|
||||||
GstClockTime hold_back = GST_CLOCK_TIME_NONE;
|
GstClockTime hold_back = GST_CLOCK_TIME_NONE;
|
||||||
/* Live playlist. If low-latency, use the PART-HOLD-BACK specified distance
|
/* Live playlist. If low-latency, use the PART-HOLD-BACK specified distance
|
||||||
* from the end, otherwise HOLD-BACK distance */
|
* from the end, otherwise HOLD-BACK distance */
|
||||||
if (allow_low_latency) {
|
if (GST_CLOCK_TIME_IS_VALID (self->part_hold_back))
|
||||||
if (GST_CLOCK_TIME_IS_VALID (self->part_hold_back))
|
hold_back = self->part_hold_back;
|
||||||
hold_back = self->part_hold_back;
|
else if (GST_CLOCK_TIME_IS_VALID (self->partial_targetduration))
|
||||||
else if (GST_CLOCK_TIME_IS_VALID (self->partial_targetduration))
|
hold_back = 3 * self->partial_targetduration;
|
||||||
hold_back = 3 * self->partial_targetduration;
|
else if (GST_CLOCK_TIME_IS_VALID (self->hold_back))
|
||||||
else if (GST_CLOCK_TIME_IS_VALID (self->hold_back))
|
hold_back = self->hold_back;
|
||||||
hold_back = self->hold_back;
|
|
||||||
}
|
|
||||||
if (hold_back == GST_CLOCK_TIME_NONE) {
|
if (hold_back == GST_CLOCK_TIME_NONE) {
|
||||||
/* If low-latency is not enabled, or none of the above were present,
|
/* If low-latency is not enabled, or none of the above were present,
|
||||||
* fallback to the standard behaviour:
|
* fallback to the standard behaviour:
|
||||||
|
@ -2125,7 +2124,9 @@ gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist * self,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (hold_back)) {
|
if (GST_CLOCK_TIME_IS_VALID (hold_back)) {
|
||||||
GstSeekFlags flags = GST_SEEK_FLAG_SNAP_BEFORE | GST_SEEK_FLAG_KEY_UNIT;
|
GstSeekFlags flags =
|
||||||
|
GST_SEEK_FLAG_SNAP_BEFORE | GST_SEEK_FLAG_KEY_UNIT |
|
||||||
|
GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL;
|
||||||
GstM3U8MediaSegment *last_seg =
|
GstM3U8MediaSegment *last_seg =
|
||||||
g_ptr_array_index (self->segments, self->segments->len - 1);
|
g_ptr_array_index (self->segments, self->segments->len - 1);
|
||||||
GstClockTime playlist_duration =
|
GstClockTime playlist_duration =
|
||||||
|
@ -2142,9 +2143,6 @@ gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist * self,
|
||||||
" Looking for a segment before %" GST_TIME_FORMAT,
|
" Looking for a segment before %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (hold_back), GST_TIME_ARGS (target_ts));
|
GST_TIME_ARGS (hold_back), GST_TIME_ARGS (target_ts));
|
||||||
|
|
||||||
if (allow_low_latency)
|
|
||||||
flags |= GST_HLS_M3U8_SEEK_FLAG_ALLOW_PARTIAL;
|
|
||||||
|
|
||||||
if (gst_hls_media_playlist_seek (self, TRUE, flags, target_ts,
|
if (gst_hls_media_playlist_seek (self, TRUE, flags, target_ts,
|
||||||
seek_result)) {
|
seek_result)) {
|
||||||
#ifndef GST_DISABLE_GST_DEBUG
|
#ifndef GST_DISABLE_GST_DEBUG
|
||||||
|
@ -2297,8 +2295,7 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8,
|
||||||
|
|
||||||
GstM3U8MediaSegment *
|
GstM3U8MediaSegment *
|
||||||
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
|
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
|
||||||
GstM3U8MediaSegment * current, gboolean forward,
|
GstM3U8MediaSegment * current, gboolean forward)
|
||||||
gboolean allow_partial_only_segment)
|
|
||||||
{
|
{
|
||||||
GstM3U8MediaSegment *file = NULL;
|
GstM3U8MediaSegment *file = NULL;
|
||||||
guint idx;
|
guint idx;
|
||||||
|
@ -2330,13 +2327,6 @@ gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
|
||||||
idx - 1));
|
idx - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file && file->partial_only && !allow_partial_only_segment) {
|
|
||||||
GST_LOG
|
|
||||||
("Ignoring segment with only partials as full segment was requested");
|
|
||||||
gst_m3u8_media_segment_unref (file);
|
|
||||||
file = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
GST_DEBUG ("Advanced to segment sn:%" G_GINT64_FORMAT " dsn:%"
|
GST_DEBUG ("Advanced to segment sn:%" G_GINT64_FORMAT " dsn:%"
|
||||||
G_GINT64_FORMAT, file->sequence, file->discont_sequence);
|
G_GINT64_FORMAT, file->sequence, file->discont_sequence);
|
||||||
|
@ -2394,7 +2384,7 @@ gst_hls_media_playlist_get_duration (GstHLSMediaPlaylist * m3u8)
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_hls_media_playlist_get_next_msn_and_part (GstHLSMediaPlaylist * m3u8,
|
gst_hls_media_playlist_get_next_msn_and_part (GstHLSMediaPlaylist * m3u8,
|
||||||
gboolean low_latency, gint64 * next_msn, gint64 * next_part)
|
gint64 * next_msn, gint64 * next_part)
|
||||||
{
|
{
|
||||||
/* Return the MSN and part number that are 1 past the end of the current playlist */
|
/* Return the MSN and part number that are 1 past the end of the current playlist */
|
||||||
if (m3u8->segments->len == 0) {
|
if (m3u8->segments->len == 0) {
|
||||||
|
@ -2408,7 +2398,7 @@ gst_hls_media_playlist_get_next_msn_and_part (GstHLSMediaPlaylist * m3u8,
|
||||||
|
|
||||||
/* If low_latency mode and the last segment contains partial segments, the next playlist update is
|
/* If low_latency mode and the last segment contains partial segments, the next playlist update is
|
||||||
* when one extra partial segment gets added */
|
* when one extra partial segment gets added */
|
||||||
if (low_latency && last->partial_segments != NULL) {
|
if (last->partial_segments != NULL) {
|
||||||
*next_msn = last->sequence;
|
*next_msn = last->sequence;
|
||||||
*next_part = last->partial_segments->len;
|
*next_part = last->partial_segments->len;
|
||||||
return;
|
return;
|
||||||
|
@ -2525,7 +2515,7 @@ gst_hls_media_playlist_has_lost_sync (GstHLSMediaPlaylist * m3u8,
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
|
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
|
||||||
gboolean low_latency, gint64 * start, gint64 * stop)
|
gint64 * start, gint64 * stop)
|
||||||
{
|
{
|
||||||
GstM3U8MediaSegment *first, *last;
|
GstM3U8MediaSegment *first, *last;
|
||||||
|
|
||||||
|
@ -2546,8 +2536,7 @@ gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
|
||||||
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (m3u8)) {
|
if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (m3u8)) {
|
||||||
GstM3U8SeekResult seek_result;
|
GstM3U8SeekResult seek_result;
|
||||||
|
|
||||||
if (gst_hls_media_playlist_get_starting_segment (m3u8, low_latency,
|
if (gst_hls_media_playlist_get_starting_segment (m3u8, &seek_result)) {
|
||||||
&seek_result)) {
|
|
||||||
if (seek_result.found_partial_segment) {
|
if (seek_result.found_partial_segment) {
|
||||||
GstM3U8PartialSegment *part =
|
GstM3U8PartialSegment *part =
|
||||||
g_ptr_array_index (seek_result.segment->partial_segments,
|
g_ptr_array_index (seek_result.segment->partial_segments,
|
||||||
|
@ -2567,7 +2556,7 @@ gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
|
||||||
|
|
||||||
GstClockTime
|
GstClockTime
|
||||||
gst_hls_media_playlist_recommended_buffering_threshold (GstHLSMediaPlaylist *
|
gst_hls_media_playlist_recommended_buffering_threshold (GstHLSMediaPlaylist *
|
||||||
playlist, gboolean low_latency)
|
playlist)
|
||||||
{
|
{
|
||||||
if (!playlist->duration || !GST_CLOCK_TIME_IS_VALID (playlist->duration)
|
if (!playlist->duration || !GST_CLOCK_TIME_IS_VALID (playlist->duration)
|
||||||
|| playlist->segments->len == 0)
|
|| playlist->segments->len == 0)
|
||||||
|
@ -2588,14 +2577,12 @@ gst_hls_media_playlist_recommended_buffering_threshold (GstHLSMediaPlaylist *
|
||||||
&& threshold > 3 * playlist->targetduration)
|
&& threshold > 3 * playlist->targetduration)
|
||||||
threshold = 3 * playlist->targetduration;
|
threshold = 3 * playlist->targetduration;
|
||||||
|
|
||||||
if (low_latency) {
|
if (GST_CLOCK_TIME_IS_VALID (playlist->part_hold_back)
|
||||||
if (GST_CLOCK_TIME_IS_VALID (playlist->part_hold_back)
|
&& threshold > playlist->part_hold_back)
|
||||||
&& threshold > playlist->part_hold_back)
|
threshold = playlist->part_hold_back;
|
||||||
threshold = playlist->part_hold_back;
|
else if (GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)
|
||||||
else if (GST_CLOCK_TIME_IS_VALID (playlist->partial_targetduration)
|
&& threshold > 3 * playlist->partial_targetduration)
|
||||||
&& threshold > 3 * playlist->partial_targetduration)
|
threshold = 3 * playlist->partial_targetduration;
|
||||||
threshold = 3 * playlist->partial_targetduration;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return threshold;
|
return threshold;
|
||||||
|
|
|
@ -312,12 +312,11 @@ gst_hls_media_playlist_has_next_fragment (GstHLSMediaPlaylist * m3u8,
|
||||||
GstM3U8MediaSegment *
|
GstM3U8MediaSegment *
|
||||||
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
|
gst_hls_media_playlist_advance_fragment (GstHLSMediaPlaylist * m3u8,
|
||||||
GstM3U8MediaSegment * current,
|
GstM3U8MediaSegment * current,
|
||||||
gboolean forward,
|
gboolean forward);
|
||||||
gboolean allow_partial_only_segment);
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self, gboolean low_latency,
|
gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self,
|
||||||
GstM3U8SeekResult *seek_result);
|
GstM3U8SeekResult *seek_result);
|
||||||
|
|
||||||
GstClockTime
|
GstClockTime
|
||||||
gst_hls_media_playlist_get_end_stream_time (GstHLSMediaPlaylist * m3u8);
|
gst_hls_media_playlist_get_end_stream_time (GstHLSMediaPlaylist * m3u8);
|
||||||
|
@ -326,8 +325,9 @@ GstClockTime
|
||||||
gst_hls_media_playlist_get_duration (GstHLSMediaPlaylist * m3u8);
|
gst_hls_media_playlist_get_duration (GstHLSMediaPlaylist * m3u8);
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_hls_media_playlist_get_next_msn_and_part (GstHLSMediaPlaylist * m3u8, gboolean low_latency,
|
gst_hls_media_playlist_get_next_msn_and_part (GstHLSMediaPlaylist * m3u8,
|
||||||
gint64 *next_msn, gint64 *next_part);
|
gint64 *next_msn,
|
||||||
|
gint64 *next_part);
|
||||||
|
|
||||||
gchar *
|
gchar *
|
||||||
gst_hls_media_playlist_get_uri (GstHLSMediaPlaylist * m3u8);
|
gst_hls_media_playlist_get_uri (GstHLSMediaPlaylist * m3u8);
|
||||||
|
@ -336,7 +336,7 @@ gboolean
|
||||||
gst_hls_media_playlist_is_live (GstHLSMediaPlaylist * m3u8);
|
gst_hls_media_playlist_is_live (GstHLSMediaPlaylist * m3u8);
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8, gboolean low_latency,
|
gst_hls_media_playlist_get_seek_range (GstHLSMediaPlaylist * m3u8,
|
||||||
gint64 * start,
|
gint64 * start,
|
||||||
gint64 * stop);
|
gint64 * stop);
|
||||||
|
|
||||||
|
@ -360,8 +360,7 @@ void
|
||||||
gst_hls_media_playlist_dump (GstHLSMediaPlaylist* self);
|
gst_hls_media_playlist_dump (GstHLSMediaPlaylist* self);
|
||||||
|
|
||||||
GstClockTime
|
GstClockTime
|
||||||
gst_hls_media_playlist_recommended_buffering_threshold (GstHLSMediaPlaylist *
|
gst_hls_media_playlist_recommended_buffering_threshold (GstHLSMediaPlaylist * playlist);
|
||||||
playlist, gboolean low_latency);
|
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -524,8 +524,7 @@ GST_START_TEST (test_playlist_with_doubles_duration)
|
||||||
assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
|
assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
|
||||||
file = GST_M3U8_MEDIA_SEGMENT (g_ptr_array_index (pl->segments, 3));
|
file = GST_M3U8_MEDIA_SEGMENT (g_ptr_array_index (pl->segments, 3));
|
||||||
assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
|
assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
|
||||||
fail_unless (gst_hls_media_playlist_get_seek_range (pl, FALSE, &start,
|
fail_unless (gst_hls_media_playlist_get_seek_range (pl, &start, &stop));
|
||||||
&stop));
|
|
||||||
assert_equals_int64 (start, 0);
|
assert_equals_int64 (start, 0);
|
||||||
assert_equals_float (stop / (double) GST_SECOND,
|
assert_equals_float (stop / (double) GST_SECOND,
|
||||||
10.321 + 9.6789 + 10.2344 + 9.92);
|
10.321 + 9.6789 + 10.2344 + 9.92);
|
||||||
|
@ -705,7 +704,7 @@ GST_START_TEST (test_advance_fragment)
|
||||||
pl = load_m3u8 (BYTE_RANGES_PLAYLIST);
|
pl = load_m3u8 (BYTE_RANGES_PLAYLIST);
|
||||||
|
|
||||||
/* Check the next fragment */
|
/* Check the next fragment */
|
||||||
fail_unless (gst_hls_media_playlist_get_starting_segment (pl, FALSE,
|
fail_unless (gst_hls_media_playlist_get_starting_segment (pl,
|
||||||
&seek_result) == TRUE);
|
&seek_result) == TRUE);
|
||||||
|
|
||||||
mf = seek_result.segment;
|
mf = seek_result.segment;
|
||||||
|
@ -719,7 +718,7 @@ GST_START_TEST (test_advance_fragment)
|
||||||
gst_m3u8_media_segment_unref (mf);
|
gst_m3u8_media_segment_unref (mf);
|
||||||
|
|
||||||
/* Check next media segments */
|
/* Check next media segments */
|
||||||
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE, FALSE);
|
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE);
|
||||||
fail_unless (mf != NULL);
|
fail_unless (mf != NULL);
|
||||||
assert_equals_int (mf->discont, FALSE);
|
assert_equals_int (mf->discont, FALSE);
|
||||||
assert_equals_string (mf->uri, "http://media.example.com/all.ts");
|
assert_equals_string (mf->uri, "http://media.example.com/all.ts");
|
||||||
|
@ -730,7 +729,7 @@ GST_START_TEST (test_advance_fragment)
|
||||||
gst_m3u8_media_segment_unref (mf);
|
gst_m3u8_media_segment_unref (mf);
|
||||||
|
|
||||||
/* Check next media segments */
|
/* Check next media segments */
|
||||||
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE, FALSE);
|
mf = gst_hls_media_playlist_advance_fragment (pl, mf, TRUE);
|
||||||
assert_equals_int (mf->discont, FALSE);
|
assert_equals_int (mf->discont, FALSE);
|
||||||
assert_equals_string (mf->uri, "http://media.example.com/all.ts");
|
assert_equals_string (mf->uri, "http://media.example.com/all.ts");
|
||||||
assert_equals_uint64 (mf->stream_time, 20 * GST_SECOND);
|
assert_equals_uint64 (mf->stream_time, 20 * GST_SECOND);
|
||||||
|
|
Loading…
Reference in a new issue