rtponviftimestamp: implement support for the T flag

https://www.onvif.org/specs/stream/ONVIF-Streaming-Spec.pdf

6.3 RTP header extension
This commit is contained in:
Mathieu Duponchelle 2018-11-05 20:32:03 +01:00 committed by Mathieu Duponchelle
parent f769758e9a
commit 9c3816830c
2 changed files with 32 additions and 3 deletions

View file

@ -35,6 +35,7 @@
#define DEFAULT_NTP_OFFSET GST_CLOCK_TIME_NONE
#define DEFAULT_CSEQ 0
#define DEFAULT_SET_E_BIT FALSE
#define DEFAULT_SET_T_BIT FALSE
GST_DEBUG_CATEGORY_STATIC (rtponviftimestamp_debug);
#define GST_CAT_DEFAULT (rtponviftimestamp_debug)
@ -69,6 +70,7 @@ enum
PROP_NTP_OFFSET,
PROP_CSEQ,
PROP_SET_E_BIT,
PROP_SET_T_BIT,
};
/*static guint gst_rtp_onvif_timestamp_signals[LAST_SIGNAL] = { 0 }; */
@ -91,6 +93,9 @@ gst_rtp_onvif_timestamp_get_property (GObject * object,
case PROP_SET_E_BIT:
g_value_set_boolean (value, self->prop_set_e_bit);
break;
case PROP_SET_T_BIT:
g_value_set_boolean (value, self->prop_set_t_bit);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -113,6 +118,9 @@ gst_rtp_onvif_timestamp_set_property (GObject * object,
case PROP_SET_E_BIT:
self->prop_set_e_bit = g_value_get_boolean (value);
break;
case PROP_SET_T_BIT:
self->prop_set_t_bit = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -191,6 +199,7 @@ gst_rtp_onvif_timestamp_change_state (GstElement * element,
GST_TIME_ARGS (self->ntp_offset));
self->set_d_bit = TRUE;
self->set_e_bit = FALSE;
self->set_t_bit = FALSE;
break;
default:
break;
@ -256,6 +265,12 @@ gst_rtp_onvif_timestamp_class_init (GstRtpOnvifTimestampClass * klass)
"extension. This increases latency by one packet",
DEFAULT_SET_E_BIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_SET_T_BIT,
g_param_spec_boolean ("set-t-bit", "Set 'T' bit",
"If the element should set the 'T' bit as defined in the ONVIF RTP "
"extension. This increases latency by one packet",
DEFAULT_SET_T_BIT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* register pads */
gst_element_class_add_static_pad_template (gstelement_class,
&sink_template_factory);
@ -333,8 +348,11 @@ gst_rtp_onvif_timestamp_sink_event (GstPad * pad, GstObject * parent,
case GST_EVENT_EOS:
{
GstFlowReturn res;
/* Push pending buffers, if any */
self->set_e_bit = TRUE;
if (self->prop_set_t_bit)
self->set_t_bit = TRUE;
res = send_cached_buffer_and_events (self);
if (res != GST_FLOW_OK) {
drop = TRUE;
@ -347,6 +365,7 @@ gst_rtp_onvif_timestamp_sink_event (GstPad * pad, GstObject * parent,
purge_cached_buffer_and_events (self);
self->set_d_bit = TRUE;
self->set_e_bit = FALSE;
self->set_t_bit = FALSE;
gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
break;
default:
@ -418,6 +437,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;
gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);
@ -527,7 +547,7 @@ handle_buffer (GstRtpOnvifTimestamp * self, GstBuffer * buf)
GST_WRITE_UINT64_BE (data, time);
/* The next byte is composed of: C E D mbz (5 bits) */
/* The next byte is composed of: C E D T mbz (4 bits) */
/* Set C if the buffer does *not* have the DELTA_UNIT flag as it means
* that's a key frame (or 'clean point'). */
@ -550,6 +570,13 @@ handle_buffer (GstRtpOnvifTimestamp * self, GstBuffer * buf)
self->set_d_bit = FALSE;
}
/* Set T if we have received EOS */
if (self->set_t_bit) {
GST_DEBUG_OBJECT (self, "set T flag");
field |= (1 << 4);
self->set_t_bit = FALSE;
}
GST_WRITE_UINT8 (data + 8, field);
/* CSeq (low-order byte) */
@ -581,7 +608,7 @@ gst_rtp_onvif_timestamp_chain (GstPad * pad, GstObject * parent,
GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (parent);
GstFlowReturn result = GST_FLOW_OK;
if (!self->prop_set_e_bit) {
if (!self->prop_set_e_bit && !self->prop_set_t_bit) {
/* Modify and push this buffer right away */
return handle_and_push_buffer (self, buf);
}
@ -620,7 +647,7 @@ gst_rtp_onvif_timestamp_chain_list (GstPad * pad, GstObject * parent,
GstRtpOnvifTimestamp *self = GST_RTP_ONVIF_TIMESTAMP (parent);
GstFlowReturn result = GST_FLOW_OK;
if (!self->prop_set_e_bit) {
if (!self->prop_set_e_bit && !self->prop_set_t_bit) {
return handle_and_push_buffer_list (self, list);
}

View file

@ -51,6 +51,7 @@ struct _GstRtpOnvifTimestamp {
GstClockTime prop_ntp_offset;
guint prop_cseq;
gboolean prop_set_e_bit;
gboolean prop_set_t_bit;
/* currently used ntp-offset
*(can be changed runtime with a GstNtpOffset event)
@ -59,6 +60,7 @@ struct _GstRtpOnvifTimestamp {
/* a GstNtpOffset event might mark the stream as discontinued */
gboolean set_d_bit;
gboolean set_e_bit;
gboolean set_t_bit;
GstSegment segment;
/* Buffer waiting to be handled, only used if prop_set_e_bit is TRUE */