summaryrefslogtreecommitdiff
path: root/ext/hls
diff options
context:
space:
mode:
authorSeungha Yang <seungha.yang@navercorp.com>2019-10-01 15:36:29 +0900
committerSeungha Yang <seungha.yang@navercorp.com>2019-10-01 17:16:05 +0900
commitd763aeee4b40c69d5d2dc913ac04922a56650369 (patch)
treed82cd49befba81f00c336f9bc6b20f965b01256e /ext/hls
parent71ff8236b53094cf6121552f687c383da6d063d2 (diff)
hlssink,hlssink2: Ensure writing ENDLIST tag at the end
hlssink* elements could be finalized without EOS event, and in that case the final playlist might not include the EXT-X-ENDLIST tag. Since missing ENDLIST tag means it's live stream, but we did't intend it, hlssink* elements should put the tag at the end.
Diffstat (limited to 'ext/hls')
-rw-r--r--ext/hls/gsthlssink.c10
-rw-r--r--ext/hls/gsthlssink.h1
-rw-r--r--ext/hls/gsthlssink2.c11
-rw-r--r--ext/hls/gsthlssink2.h1
-rw-r--r--ext/hls/gstm3u8playlist.h7
5 files changed, 30 insertions, 0 deletions
diff --git a/ext/hls/gsthlssink.c b/ext/hls/gsthlssink.c
index bcb2555f1..78f8df1e6 100644
--- a/ext/hls/gsthlssink.c
+++ b/ext/hls/gsthlssink.c
@@ -209,6 +209,8 @@ gst_hls_sink_reset (GstHlsSink * sink)
sink->playlist =
gst_m3u8_playlist_new (GST_M3U8_PLAYLIST_VERSION, sink->playlist_length,
FALSE);
+
+ sink->state = GST_M3U8_PLAYLIST_RENDER_INIT;
}
static gboolean
@@ -304,6 +306,7 @@ gst_hls_sink_handle_message (GstBin * bin, GstMessage * message)
g_free (entry_location);
gst_hls_sink_write_playlist (sink);
+ sink->state |= GST_M3U8_PLAYLIST_RENDER_STARTED;
/* multifilesink is starting a new file. It means that upstream sent a key
* unit and we can schedule the next key unit now.
@@ -321,6 +324,7 @@ gst_hls_sink_handle_message (GstBin * bin, GstMessage * message)
case GST_MESSAGE_EOS:{
sink->playlist->end_list = TRUE;
gst_hls_sink_write_playlist (sink);
+ sink->state |= GST_M3U8_PLAYLIST_RENDER_ENDED;
break;
}
default:
@@ -355,6 +359,12 @@ gst_hls_sink_change_state (GstElement * element, GstStateChange trans)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ /* drain playlist with #EXT-X-ENDLIST */
+ if (sink->playlist && (sink->state & GST_M3U8_PLAYLIST_RENDER_STARTED) &&
+ !(sink->state & GST_M3U8_PLAYLIST_RENDER_ENDED)) {
+ sink->playlist->end_list = TRUE;
+ gst_hls_sink_write_playlist (sink);
+ }
gst_hls_sink_reset (sink);
break;
case GST_STATE_CHANGE_READY_TO_NULL:
diff --git a/ext/hls/gsthlssink.h b/ext/hls/gsthlssink.h
index 6660c9510..b76c39887 100644
--- a/ext/hls/gsthlssink.h
+++ b/ext/hls/gsthlssink.h
@@ -54,6 +54,7 @@ struct _GstHlsSink
GstSegment segment;
gboolean waiting_fku;
GstClockTime last_running_time;
+ GstM3U8PlaylistRenderState state;
};
struct _GstHlsSinkClass
diff --git a/ext/hls/gsthlssink2.c b/ext/hls/gsthlssink2.c
index 2c416b5cd..275e41ccc 100644
--- a/ext/hls/gsthlssink2.c
+++ b/ext/hls/gsthlssink2.c
@@ -227,6 +227,8 @@ gst_hls_sink2_reset (GstHlsSink2 * sink)
g_queue_foreach (&sink->old_locations, (GFunc) g_free, NULL);
g_queue_clear (&sink->old_locations);
+
+ sink->state = GST_M3U8_PLAYLIST_RENDER_INIT;
}
static void
@@ -288,6 +290,7 @@ gst_hls_sink2_handle_message (GstBin * bin, GstMessage * message)
g_free (entry_location);
gst_hls_sink2_write_playlist (sink);
+ sink->state |= GST_M3U8_PLAYLIST_RENDER_STARTED;
g_queue_push_tail (&sink->old_locations,
g_strdup (sink->current_location));
@@ -305,6 +308,7 @@ gst_hls_sink2_handle_message (GstBin * bin, GstMessage * message)
case GST_MESSAGE_EOS:{
sink->playlist->end_list = TRUE;
gst_hls_sink2_write_playlist (sink);
+ sink->state |= GST_M3U8_PLAYLIST_RENDER_ENDED;
break;
}
default:
@@ -397,6 +401,13 @@ gst_hls_sink2_change_state (GstElement * element, GstStateChange trans)
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ /* drain playlist with #EXT-X-ENDLIST */
+ if (sink->playlist && (sink->state & GST_M3U8_PLAYLIST_RENDER_STARTED) &&
+ !(sink->state & GST_M3U8_PLAYLIST_RENDER_ENDED)) {
+ sink->playlist->end_list = TRUE;
+ gst_hls_sink2_write_playlist (sink);
+ }
+ /* fall-through */
case GST_STATE_CHANGE_READY_TO_NULL:
gst_hls_sink2_reset (sink);
break;
diff --git a/ext/hls/gsthlssink2.h b/ext/hls/gsthlssink2.h
index 70539cb04..ebba33a70 100644
--- a/ext/hls/gsthlssink2.h
+++ b/ext/hls/gsthlssink2.h
@@ -55,6 +55,7 @@ struct _GstHlsSink2
gchar *current_location;
GstClockTime current_running_time_start;
GQueue old_locations;
+ GstM3U8PlaylistRenderState state;
};
struct _GstHlsSink2Class
diff --git a/ext/hls/gstm3u8playlist.h b/ext/hls/gstm3u8playlist.h
index 7d80435db..aae449946 100644
--- a/ext/hls/gstm3u8playlist.h
+++ b/ext/hls/gstm3u8playlist.h
@@ -41,6 +41,13 @@ struct _GstM3U8Playlist
GQueue *entries;
};
+typedef enum
+{
+ GST_M3U8_PLAYLIST_RENDER_INIT = (1 << 0),
+ GST_M3U8_PLAYLIST_RENDER_STARTED = (1 << 1),
+ GST_M3U8_PLAYLIST_RENDER_ENDED = (1 << 2),
+} GstM3U8PlaylistRenderState;
+
GstM3U8Playlist * gst_m3u8_playlist_new (guint version,
guint window_size,