summaryrefslogtreecommitdiff
path: root/gst/onvif
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2019-07-26 03:27:22 +0200
committerMathieu Duponchelle <mduponchelle1@gmail.com>2019-08-06 22:49:25 +0000
commitaea20f207db7a4203bafab92c0e800c811c1ec48 (patch)
tree952cdbb91bc0e1f65daff08db16665381634e9a0 /gst/onvif
parent1ef3186243e5b2c6108a43d08914c86911ee8542 (diff)
downloadgstreamer-plugins-bad-aea20f207db7a4203bafab92c0e800c811c1ec48.tar.gz
rtponviftimestamp: add opt-out "drop-out-of-segment" property
The default behaviour of rtponviftimestamp is to drop buffers outside the segment. This creates obvious problems for reverse playback. The ONVIF specification unfortunately doesn't describe how to handle that specific use case, but we can expose a property to let the user disable the dropping behaviour, and forward these buffers with a G_MAXUINT64 ONVIF timestamp. Also modify rtponvifparse to handle such timestamps appropriately.
Diffstat (limited to 'gst/onvif')
-rw-r--r--gst/onvif/gstrtponvifparse.c9
-rw-r--r--gst/onvif/gstrtponviftimestamp.c33
-rw-r--r--gst/onvif/gstrtponviftimestamp.h1
3 files changed, 33 insertions, 10 deletions
diff --git a/gst/onvif/gstrtponvifparse.c b/gst/onvif/gstrtponvifparse.c
index f32c4a1e6..8fa0d8591 100644
--- a/gst/onvif/gstrtponvifparse.c
+++ b/gst/onvif/gstrtponvifparse.c
@@ -118,8 +118,13 @@ handle_buffer (GstRtpOnvifParse * self, GstBuffer * buf, gboolean * send_eos)
timestamp_fraction = GST_READ_UINT32_BE (data + 4);
timestamp_nseconds =
(timestamp_fraction * G_GINT64_CONSTANT (1000000000)) >> 32;
- GST_BUFFER_PTS (buf) =
- timestamp_seconds * GST_SECOND + timestamp_nseconds * GST_NSECOND;
+
+ if (timestamp_seconds == G_MAXUINT32 && timestamp_fraction == G_MAXUINT32) {
+ GST_BUFFER_PTS (buf) = GST_CLOCK_TIME_NONE;
+ } else {
+ GST_BUFFER_PTS (buf) =
+ timestamp_seconds * GST_SECOND + timestamp_nseconds * GST_NSECOND;
+ }
flags = GST_READ_UINT8 (data + 8);
/* cseq = GST_READ_UINT8 (data + 9); TODO */
diff --git a/gst/onvif/gstrtponviftimestamp.c b/gst/onvif/gstrtponviftimestamp.c
index 4991e426f..55aad02f2 100644
--- a/gst/onvif/gstrtponviftimestamp.c
+++ b/gst/onvif/gstrtponviftimestamp.c
@@ -36,6 +36,7 @@
#define DEFAULT_CSEQ 0
#define DEFAULT_SET_E_BIT FALSE
#define DEFAULT_SET_T_BIT FALSE
+#define DEFAULT_DROP_OUT_OF_SEGMENT TRUE
GST_DEBUG_CATEGORY_STATIC (rtponviftimestamp_debug);
#define GST_CAT_DEFAULT (rtponviftimestamp_debug)
@@ -71,6 +72,7 @@ enum
PROP_CSEQ,
PROP_SET_E_BIT,
PROP_SET_T_BIT,
+ PROP_DROP_OUT_OF_SEGMENT
};
/*static guint gst_rtp_onvif_timestamp_signals[LAST_SIGNAL] = { 0 }; */
@@ -96,6 +98,8 @@ gst_rtp_onvif_timestamp_get_property (GObject * object,
case PROP_SET_T_BIT:
g_value_set_boolean (value, self->prop_set_t_bit);
break;
+ case PROP_DROP_OUT_OF_SEGMENT:
+ g_value_set_boolean (value, self->prop_drop_out_of_segment);
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -121,6 +125,9 @@ gst_rtp_onvif_timestamp_set_property (GObject * object,
case PROP_SET_T_BIT:
self->prop_set_t_bit = g_value_get_boolean (value);
break;
+ case PROP_DROP_OUT_OF_SEGMENT:
+ self->prop_drop_out_of_segment = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -271,6 +278,13 @@ gst_rtp_onvif_timestamp_class_init (GstRtpOnvifTimestampClass * klass)
"extension. This increases latency by one packet",
DEFAULT_SET_T_BIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_DROP_OUT_OF_SEGMENT,
+ g_param_spec_boolean ("drop-out-of-segment", "Drop out of segment",
+ "Whether the element should drop buffers that fall outside the segment, "
+ "not part of the specification but allows full reverse playback.",
+ DEFAULT_DROP_OUT_OF_SEGMENT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/* register pads */
gst_element_class_add_static_pad_template (gstelement_class,
&sink_template_factory);
@@ -438,6 +452,7 @@ gst_rtp_onvif_timestamp_init (GstRtpOnvifTimestamp * self)
self->prop_ntp_offset = DEFAULT_NTP_OFFSET;
self->prop_set_e_bit = DEFAULT_SET_E_BIT;
self->prop_set_t_bit = DEFAULT_SET_T_BIT;
+ self->prop_drop_out_of_segment = DEFAULT_DROP_OUT_OF_SEGMENT;
gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
@@ -530,18 +545,20 @@ handle_buffer (GstRtpOnvifTimestamp * self, GstBuffer * buf)
goto done;
}
- if (time == GST_CLOCK_TIME_NONE) {
+ if (self->prop_drop_out_of_segment && time == GST_CLOCK_TIME_NONE) {
GST_ERROR_OBJECT (self, "Failed to get stream time");
- goto done;
+ gst_rtp_buffer_unmap (&rtp);
+ return FALSE;
}
/* add the offset (in seconds) */
- time += self->ntp_offset;
-
- /* convert to NTP time. upper 32 bits should contain the seconds
- * and the lower 32 bits, the fractions of a second. */
- time = gst_util_uint64_scale (time, (G_GINT64_CONSTANT (1) << 32),
- GST_SECOND);
+ if (time != GST_CLOCK_TIME_NONE) {
+ time += self->ntp_offset;
+ /* convert to NTP time. upper 32 bits should contain the seconds
+ * and the lower 32 bits, the fractions of a second. */
+ time = gst_util_uint64_scale (time, (G_GINT64_CONSTANT (1) << 32),
+ GST_SECOND);
+ }
GST_DEBUG_OBJECT (self, "timestamp: %" G_GUINT64_FORMAT, time);
diff --git a/gst/onvif/gstrtponviftimestamp.h b/gst/onvif/gstrtponviftimestamp.h
index 21a0f6560..f093f0edf 100644
--- a/gst/onvif/gstrtponviftimestamp.h
+++ b/gst/onvif/gstrtponviftimestamp.h
@@ -52,6 +52,7 @@ struct _GstRtpOnvifTimestamp {
guint prop_cseq;
gboolean prop_set_e_bit;
gboolean prop_set_t_bit;
+ gboolean prop_drop_out_of_segment;
/* currently used ntp-offset
*(can be changed runtime with a GstNtpOffset event)