static gboolean handle_buffer (GstRtpOnvifParse * self, GstBuffer * buf) { GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; guint8 *data; guint16 bits; guint wordlen; guint8 flags; /* guint64 timestamp; guint8 cseq; */ if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp)) { GST_ELEMENT_ERROR (self, STREAM, FAILED, ("Failed to map RTP buffer"), (NULL)); return FALSE; } /* Check if the ONVIF RTP extension is present in the packet */ if (!gst_rtp_buffer_get_extension_data (&rtp, &bits, (gpointer) & data, &wordlen)) goto out; if (bits != EXTENSION_ID || wordlen != EXTENSION_SIZE) goto out; /* timestamp = GST_READ_UINT64_BE (data); TODO */ flags = GST_READ_UINT8 (data + 8); /* cseq = GST_READ_UINT8 (data + 9); TODO */ /* C */ if (flags & (1 << 7)) GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT); else GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); /* E */ /* if (flags & (1 << 6)); TODO */ /* D */ if (flags & (1 << 5)) GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT); else GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); out: gst_rtp_buffer_unmap (&rtp); return TRUE; }
/* Create a copy of @buffer_in having the RTP extension */ static GstBuffer * create_extension_buffer (GstBuffer * buffer_in, gboolean clean_point, gboolean end_contiguous, gboolean discont, guint64 ntp_offset, guint8 cseq) { GstBuffer *buffer_out; GstRTPBuffer rtpbuffer_out = GST_RTP_BUFFER_INIT; guint8 *data; guint8 flags = 0; buffer_out = gst_buffer_copy (buffer_in); fail_unless (gst_rtp_buffer_map (buffer_out, GST_MAP_READWRITE, &rtpbuffer_out)); /* extension */ fail_unless (gst_rtp_buffer_set_extension_data (&rtpbuffer_out, 0xABAC, 3)); fail_unless (gst_rtp_buffer_get_extension (&rtpbuffer_out)); fail_unless (gst_rtp_buffer_get_extension_data (&rtpbuffer_out, NULL, (gpointer) & data, NULL)); /* NTP timestamp */ GST_WRITE_UINT64_BE (data, convert_to_ntp (GST_BUFFER_PTS (buffer_in) + ntp_offset)); /* C E D mbz */ if (clean_point) flags |= (1 << 7); if (end_contiguous) flags |= (1 << 6); if (discont) flags |= (1 << 5); GST_WRITE_UINT8 (data + 8, flags); /* CSeq */ GST_WRITE_UINT8 (data + 9, cseq); memset (data + 10, 0, 4); gst_rtp_buffer_unmap (&rtpbuffer_out); return buffer_out; }
static void do_ntp_time (GstClockTime buffer_time, gint segment_start, gint segment_base) { GstSegment segment; GstBuffer *buffer; GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT; guint8 *data; guint64 expected_ntp_time; guint64 timestamp; /* create a segment that controls the behavior * by changing segment.start and segment.base we affect the stream time and * running time respectively */ gst_segment_init (&segment, GST_FORMAT_TIME); segment.start = segment_start; segment.base = segment_base; gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)); expected_ntp_time = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, buffer_time); expected_ntp_time += NTP_OFFSET; expected_ntp_time = gst_util_uint64_scale (expected_ntp_time, (G_GINT64_CONSTANT (1) << 32), GST_SECOND); buffer = create_rtp_buffer (buffer_time, FALSE); fail_unless_equals_int (gst_pad_push (mysrcpad, buffer), GST_FLOW_OK); fail_unless_equals_int (g_list_length (buffers), 1); buffer = g_list_last (buffers)->data; /* get the extension header */ fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtpbuffer)); fail_unless (gst_rtp_buffer_get_extension_data (&rtpbuffer, NULL, (gpointer) & data, NULL)); /* ...and read the NTP timestamp and verify that it's the expected one */ timestamp = GST_READ_UINT64_BE (data); fail_unless_equals_uint64 (timestamp, expected_ntp_time); gst_rtp_buffer_unmap (&rtpbuffer); gst_check_drop_buffers (); }