#define SCAN_SCR_SZ 12
#define SCAN_PTS_SZ 80
-#define SEGMENT_THRESHOLD (300*GST_MSECOND)
-#define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)
+#define DEFAULT_GAP_THRESHOLD (300*GST_MSECOND)
+#define VIDEO_GAP_THRESHOLD (500*GST_MSECOND)
#define DURATION_SCAN_LIMIT 4 * 1024 * 1024
gchar *name;
GstPsDemuxClass *klass = GST_PS_DEMUX_GET_CLASS (demux);
GstCaps *caps;
- GstClockTime threshold = SEGMENT_THRESHOLD;
+ GstClockTime gap_threshold = DEFAULT_GAP_THRESHOLD;
GstEvent *event;
gchar *stream_id;
"mpegversion", G_TYPE_INT, mpeg_version,
"systemstream", G_TYPE_BOOLEAN, FALSE,
"parsed", G_TYPE_BOOLEAN, FALSE, NULL);
- threshold = VIDEO_SEGMENT_THRESHOLD;
+ gap_threshold = VIDEO_GAP_THRESHOLD;
break;
}
case ST_AUDIO_MPEG1:
name = g_strdup_printf ("video_%02x", id);
caps = gst_caps_new_simple ("video/x-h264",
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
- threshold = VIDEO_SEGMENT_THRESHOLD;
+ gap_threshold = VIDEO_GAP_THRESHOLD;
break;
case ST_VIDEO_H265:
template = klass->video_template;
name = g_strdup_printf ("video_%02x", id);
caps = gst_caps_new_simple ("video/x-h265",
"stream-format", G_TYPE_STRING, "byte-stream", NULL);
- threshold = VIDEO_SEGMENT_THRESHOLD;
+ gap_threshold = VIDEO_GAP_THRESHOLD;
break;
case ST_PS_AUDIO_AC3:
stream->type = stream_type;
stream->pending_tags = NULL;
stream->pad = gst_pad_new_from_template (template, name);
- stream->segment_thresh = threshold;
+ stream->gap_threshold = gap_threshold;
+ stream->nb_out_buffers = 0;
+ stream->gap_ref_buffers = 0;
+ stream->gap_ref_pts = GST_CLOCK_TIME_NONE;
+
gst_pad_set_event_function (stream->pad,
GST_DEBUG_FUNCPTR (gst_ps_demux_src_event));
gst_pad_set_query_function (stream->pad,
gst_ps_demux_send_segment (demux, stream, pts);
+ /* Ignores DTS if PTS < DTS. Maybe additional sanity checking is possible
+ * by comparing 33bits timestap rollover case, but PTS < DTS is already
+ * invalid case */
+ if (GST_CLOCK_TIME_IS_VALID (pts) && GST_CLOCK_TIME_IS_VALID (dts) &&
+ dts > pts) {
+ GST_WARNING_OBJECT (demux, "PTS (%" GST_TIME_FORMAT ") < DTS (%"
+ GST_TIME_FORMAT ")", GST_TIME_ARGS (pts), GST_TIME_ARGS (dts));
+ dts = GST_CLOCK_TIME_NONE;
+ }
+
/* OK, sent new segment now prepare the buffer for sending */
GST_BUFFER_PTS (buf) = pts;
GST_BUFFER_DTS (buf) = dts;
GST_TIME_FORMAT ", size %" G_GSIZE_FORMAT,
stream->id, stream->type, GST_TIME_ARGS (pts), gst_buffer_get_size (buf));
result = gst_pad_push (stream->pad, buf);
+ stream->nb_out_buffers += 1;
+
GST_LOG_OBJECT (demux, "result: %s", gst_flow_get_name (result));
return result;
}
static inline void
-gst_ps_demux_send_gap_updates (GstPsDemux * demux, GstClockTime new_start)
+gst_ps_demux_send_gap_updates (GstPsDemux * demux, GstClockTime time)
{
GstClockTime base_time, stop;
gint i, count = demux->found_count;
GstEvent *event = NULL;
- if (new_start == GST_CLOCK_TIME_NONE)
+ if (time == GST_CLOCK_TIME_NONE)
return;
/* Advance all lagging streams by sending a gap event */
if (stop != GST_CLOCK_TIME_NONE)
stop += base_time;
- if (new_start > stop)
+ if (time > stop)
return;
/* FIXME: Handle reverse playback */
stream->last_ts < demux->src_segment.start + base_time)
stream->last_ts = demux->src_segment.start + base_time;
- if (stream->last_ts + stream->segment_thresh < new_start) {
+ if (stream->last_ts + stream->gap_threshold < time &&
+ stream->nb_out_buffers == stream->gap_ref_buffers &&
+ stream->gap_ref_pts != stream->last_ts) {
/* should send segment info before gap event */
gst_ps_demux_send_segment (demux, stream, GST_CLOCK_TIME_NONE);
GST_LOG_OBJECT (demux,
"Sending gap update to pad %s from time %" GST_TIME_FORMAT " to %"
GST_TIME_FORMAT, GST_PAD_NAME (stream->pad),
- GST_TIME_ARGS (stream->last_ts), GST_TIME_ARGS (new_start));
- event =
- gst_event_new_gap (stream->last_ts, new_start - stream->last_ts);
+ GST_TIME_ARGS (stream->last_ts), GST_TIME_ARGS (time));
+ event = gst_event_new_gap (stream->last_ts, time - stream->last_ts);
gst_pad_push_event (stream->pad, event);
- stream->last_ts = new_start;
+ stream->last_ts = time;
}
+
+ /* Update GAP tracking vars so we don't re-check this stream for a while */
+ stream->gap_ref_pts = time;
+ if (stream->last_ts != GST_CLOCK_TIME_NONE && stream->last_ts > time)
+ stream->gap_ref_pts = stream->last_ts;
}
}
}
if (flush || seeksegment.position != demux->src_segment.position) {
/* Do the actual seeking */
if (!gst_ps_demux_do_seek (demux, &seeksegment)) {
+#ifdef TIZEN_FEATURE_MPEGDEMUX_MODIFICATION
+ goto seek_error;
+#else
return FALSE;
+#endif
}
}
seek_error:
{
GST_WARNING_OBJECT (demux, "couldn't perform seek");
+#ifdef TIZEN_FEATURE_MPEGDEMUX_MODIFICATION
+ GST_PAD_STREAM_UNLOCK (demux->sinkpad);
+#endif
gst_event_unref (event);
return FALSE;
}