};
#endif
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT
+#define ABSDIFF(a,b) ((a) < (b) ? (b) - (a) : (a) - (b))
+#endif
+
/* GObject */
static void gst_hls_demux_finalize (GObject * obj);
#ifdef TIZEN_FEATURE_HLSDEMUX_PROPERTY
static void gst_hls_demux_set_current_variant (GstHLSDemux * hlsdemux,
GstHLSVariantStream * variant);
#ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG
-static gboolean gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream,
- GstHLSMedia *media);
+static gboolean gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream * stream,
+ GstHLSMedia * media);
static gboolean gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream * stream,
const gchar * language);
#endif
FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_LIVE_START_TIME,
- g_param_spec_uint64 ("live-start-time", "start time of the first fragment",
- "start time of the first fragment in the current media playlist in case of live", 0, G_MAXUINT64,
- 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ g_param_spec_uint64 ("live-start-time",
+ "start time of the first fragment",
+ "start time of the first fragment in the current media playlist in case of live",
+ 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_LIVE_END_TIME,
g_param_spec_uint64 ("live-end-time", "end time of the last fragment",
- "end time of the last fragment in the current media playlist in case of live", 0, G_MAXUINT64,
- 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+ "end time of the last fragment in the current media playlist in case of live",
+ 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
#endif
element_class->change_state = GST_DEBUG_FUNCPTR (gst_hls_demux_change_state);
/* Snap to segment boundary. Improves seek performance on slow machines. */
snap_nearest =
(flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
- snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
+ snap_after = !!(flags & GST_SEEK_FLAG_SNAP_AFTER);
GST_M3U8_CLIENT_LOCK (hlsdemux->client);
/* FIXME: Here we need proper discont handling */
hlsdemux_stream->do_typefind = TRUE;
hlsdemux_stream->reset_pts = TRUE;
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT
+ hlsdemux_stream->sequence_pos = GST_CLOCK_TIME_NONE;
+ hlsdemux_stream->last_pcr = GST_CLOCK_TIME_NONE;
+#endif
#ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG
if (media) {
return;
}
- for (GList *mlist = hlsdemux->current_variant->media[GST_HLS_MEDIA_TYPE_AUDIO]; mlist; mlist = g_list_next(mlist)) {
+ for (GList * mlist =
+ hlsdemux->current_variant->media[GST_HLS_MEDIA_TYPE_AUDIO]; mlist;
+ mlist = g_list_next (mlist)) {
GstHLSMedia *media = mlist->data;
if (!media->uri && gst_hlsdemux_set_stream_event (stream, media))
return;
hls_stream->pending_pcr_buffer = buffer;
return GST_FLOW_OK;
}
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT
+ if (!stream->discont && GST_CLOCK_TIME_IS_VALID (hls_stream->last_pcr)
+ && GST_CLOCK_TIME_IS_VALID (last_pcr)) {
+ if (G_UNLIKELY (ABSDIFF (hls_stream->last_pcr, last_pcr) > 1 * GST_SECOND)) {
+ GST_DEBUG_OBJECT (stream->pad,
+ "Overwriting fragment timestamp [%" GST_TIME_FORMAT "] to [%"
+ GST_TIME_FORMAT "]", GST_TIME_ARGS (stream->fragment.timestamp),
+ GST_TIME_ARGS (hls_stream->sequence_pos));
+ stream->fragment.timestamp = hls_stream->sequence_pos;
+ stream->discont = TRUE;
+ }
+ }
+
+ if (GST_CLOCK_TIME_IS_VALID (last_pcr))
+ hls_stream->last_pcr = last_pcr;
+#endif
if (tags) {
#ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG
if (stream->discont)
discont = TRUE;
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT
+ hlsdemux_stream->sequence_pos = sequence_pos;
+#endif
/* set up our source for download */
#ifdef TIZEN_FEATURE_AVOID_PAD_SWITCHING
stream->fragment.timestamp = hlsdemux_stream->current_pts = sequence_pos;
#ifdef TIZEN_FEATURE_HLSDEMUX_LANG_TAG
static gboolean
-gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream *stream, GstHLSMedia *media)
+gst_hlsdemux_set_stream_event (GstAdaptiveDemuxStream * stream,
+ GstHLSMedia * media)
{
GstStructure *structure;
GstEvent *event;
if (media->lang)
gst_hlsdemux_set_language_tags (stream, media->lang);
- structure = gst_structure_new ("GstHLSMedia", "mtype", G_TYPE_INT, media->mtype,
- "default", G_TYPE_BOOLEAN, media->is_default,
- "autoselect", G_TYPE_BOOLEAN, media->autoselect,
- "forced", G_TYPE_BOOLEAN, media->forced, NULL);
+ structure =
+ gst_structure_new ("GstHLSMedia", "mtype", G_TYPE_INT, media->mtype,
+ "default", G_TYPE_BOOLEAN, media->is_default, "autoselect",
+ G_TYPE_BOOLEAN, media->autoselect, "forced", G_TYPE_BOOLEAN,
+ media->forced, NULL);
event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, structure);
}
static gboolean
-gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream *stream, const gchar *language)
+gst_hlsdemux_set_language_tags (GstAdaptiveDemuxStream * stream,
+ const gchar * language)
{
GstTagList *lang_tag = NULL;