#define DEFAULT_DISCONT_WAIT (1 * GST_SECOND)
#define DEFAULT_CHANNELS (GST_DECKLINK_AUDIO_CHANNELS_2)
+#ifndef ABSDIFF
+#define ABSDIFF(x, y) ( (x) > (y) ? ((x) - (y)) : ((y) - (x)) )
+#endif
+
enum
{
PROP_0,
self->info.rate) - timestamp;
}
+ // Detect gaps in stream time
+ self->processed += sample_count;
+
+ if (p.stream_timestamp != GST_CLOCK_TIME_NONE) {
+ GstClockTime start_stream_time, end_stream_time;
+
+ start_stream_time = p.stream_timestamp;
+
+ start_offset =
+ gst_util_uint64_scale (start_stream_time, self->info.rate, GST_SECOND);
+
+ end_offset = start_offset + sample_count;
+ end_stream_time = gst_util_uint64_scale_int (end_offset, GST_SECOND,
+ self->info.rate);
+
+ if (self->expected_stream_time != GST_CLOCK_TIME_NONE &&
+ ABSDIFF (self->expected_stream_time, p.stream_timestamp) >
+ gst_util_uint64_scale (2, GST_SECOND, self->info.rate)) {
+ GstMessage *msg;
+ GstClockTime running_time;
+
+ self->dropped +=
+ gst_util_uint64_scale (ABSDIFF (self->expected_stream_time,
+ p.stream_timestamp), self->info.rate, GST_SECOND);
+ running_time =
+ gst_segment_to_running_time (&GST_BASE_SRC (self)->segment,
+ GST_FORMAT_TIME, timestamp);
+
+ msg =
+ gst_message_new_qos (GST_OBJECT (self), TRUE, running_time, p.stream_timestamp,
+ timestamp, duration);
+ gst_message_set_qos_stats (msg, GST_FORMAT_DEFAULT, self->processed,
+ self->dropped);
+ gst_element_post_message (GST_ELEMENT (self), msg);
+ }
+ self->expected_stream_time = end_stream_time;
+ }
+
if (p.no_signal)
GST_BUFFER_FLAG_SET (*buffer, GST_BUFFER_FLAG_GAP);
GST_BUFFER_TIMESTAMP (*buffer) = timestamp;
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
+ self->processed = 0;
+ self->dropped = 0;
+ self->expected_stream_time = GST_CLOCK_TIME_NONE;
if (!gst_decklink_audio_src_open (self)) {
ret = GST_STATE_CHANGE_FAILURE;
goto out;
#define DEFAULT_SKIP_FIRST_TIME (0)
#define DEFAULT_DROP_NO_SIGNAL_FRAMES (FALSE)
+#ifndef ABSDIFF
+#define ABSDIFF(x, y) ( (x) > (y) ? ((x) - (y)) : ((y) - (x)) )
+#endif
+
enum
{
PROP_0,
}
}
+ if (self->expected_stream_time != GST_CLOCK_TIME_NONE &&
+ ABSDIFF (self->expected_stream_time, f.stream_timestamp) > 1) {
+ GstMessage *msg;
+ GstClockTime running_time;
+
+ self->dropped += f.stream_timestamp - self->expected_stream_time;
+ running_time = gst_segment_to_running_time (&GST_BASE_SRC (self)->segment,
+ GST_FORMAT_TIME, f.timestamp);
+
+ msg = gst_message_new_qos (GST_OBJECT (self), TRUE, running_time, f.stream_timestamp,
+ f.timestamp, f.duration);
+ gst_message_set_qos_stats (msg, GST_FORMAT_TIME, self->processed,
+ self->dropped);
+ gst_element_post_message (GST_ELEMENT (self), msg);
+ }
+ if (self->first_stream_time == GST_CLOCK_TIME_NONE)
+ self->first_stream_time = f.stream_timestamp;
+ self->processed = f.stream_timestamp - self->dropped - self->first_stream_time;
+ self->expected_stream_time = f.stream_timestamp + f.stream_duration;
+
g_mutex_unlock (&self->lock);
if (caps_changed) {
caps = gst_decklink_mode_get_caps (f.mode, f.format, TRUE);
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
+ self->processed = 0;
+ self->dropped = 0;
+ self->expected_stream_time = GST_CLOCK_TIME_NONE;
+ self->first_stream_time = GST_CLOCK_TIME_NONE;
if (!gst_decklink_video_src_open (self)) {
ret = GST_STATE_CHANGE_FAILURE;
goto out;