mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 15:18:21 +00:00
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.
This commit is contained in:
parent
1ef3186243
commit
aea20f207d
3 changed files with 33 additions and 10 deletions
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue