diff options
author | Seungha Yang <seungha.yang@navercorp.com> | 2019-10-01 15:36:29 +0900 |
---|---|---|
committer | Seungha Yang <seungha.yang@navercorp.com> | 2019-10-01 17:16:05 +0900 |
commit | d763aeee4b40c69d5d2dc913ac04922a56650369 (patch) | |
tree | d82cd49befba81f00c336f9bc6b20f965b01256e /ext/hls | |
parent | 71ff8236b53094cf6121552f687c383da6d063d2 (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.c | 10 | ||||
-rw-r--r-- | ext/hls/gsthlssink.h | 1 | ||||
-rw-r--r-- | ext/hls/gsthlssink2.c | 11 | ||||
-rw-r--r-- | ext/hls/gsthlssink2.h | 1 | ||||
-rw-r--r-- | ext/hls/gstm3u8playlist.h | 7 |
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, |