gpointer g_class);
static void gst_base_rtp_depayload_push (GstBaseRTPDepayload * filter,
- GstRTPBuffer * rtp_buf);
+ GstBuffer * rtp_buf);
GType
gst_base_rtp_depayload_get_type (void)
static GstElementStateReturn gst_base_rtp_depayload_change_state (GstElement *
element);
static GstFlowReturn gst_base_rtp_depayload_add_to_queue (GstBaseRTPDepayload *
- filter, GstRTPBuffer * in);
+ filter, GstBuffer * in);
static void gst_base_rtp_depayload_set_gst_timestamp
(GstBaseRTPDepayload * filter, guint32 timestamp, GstBuffer * buf);
g_return_val_if_fail (filter->clock_rate > 0, GST_FLOW_ERROR);
- // must supply RTPBuffers here
- g_return_val_if_fail (GST_IS_RTPBUFFER (in), GST_FLOW_ERROR);
-
GstBaseRTPDepayloadClass *bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
if (filter->process_only) {
GST_DEBUG ("Pushing directly!");
- gst_base_rtp_depayload_push (filter, GST_RTPBUFFER (in));
+ gst_base_rtp_depayload_push (filter, in);
} else {
if (bclass->add_to_queue)
- ret = bclass->add_to_queue (filter, GST_RTPBUFFER (in));
+ ret = bclass->add_to_queue (filter, in);
}
return ret;
}
static GstFlowReturn
gst_base_rtp_depayload_add_to_queue (GstBaseRTPDepayload * filter,
- GstRTPBuffer * in)
+ GstBuffer * in)
{
GQueue *queue = filter->queue;
QUEUE_LOCK (filter);
if (g_queue_is_empty (queue)) {
g_queue_push_tail (queue, in);
- } else
+ } else {
+ guint16 seqnum, queueseq;
+ guint32 timestamp;
+
+ seqnum = gst_rtpbuffer_get_seq (in);
+ queueseq = gst_rtpbuffer_get_seq (GST_BUFFER (g_queue_peek_head (queue)));
+
// not our first packet
- {
// let us make sure it is not very late
- if (in->seqnum < GST_RTPBUFFER (g_queue_peek_head (queue))->seqnum) {
- // we need to drop this one
- GST_DEBUG ("Packet arrived to late, dropping");
- return GST_FLOW_OK;
- }
+ if (seqnum < queueseq)
+ goto too_late;
+
// look for right place to insert it
int i = 0;
- while (in->seqnum < GST_RTPBUFFER (g_queue_peek_nth (queue, i))->seqnum)
+ while (seqnum < queueseq) {
i++;
+ queueseq =
+ gst_rtpbuffer_get_seq (GST_BUFFER (g_queue_peek_nth (queue, i)));
+ }
+
// now insert it at that place
g_queue_push_nth (queue, in, i);
- GST_DEBUG ("Packet added to queue %d at pos %d timestamp %u sn %d",
- g_queue_get_length (queue), i, in->timestamp, in->seqnum);
+ timestamp = gst_rtpbuffer_get_timestamp (in);
+
+ GST_DEBUG ("Packet added to queue %d at pos %d timestamp %u sn %d",
+ g_queue_get_length (queue), i, timestamp, seqnum);
}
QUEUE_UNLOCK (filter);
return GST_FLOW_OK;
+
+too_late:
+ {
+ QUEUE_UNLOCK (filter);
+ // we need to drop this one
+ GST_DEBUG ("Packet arrived to late, dropping");
+ return GST_FLOW_OK;
+ }
}
static void
-gst_base_rtp_depayload_push (GstBaseRTPDepayload * filter,
- GstRTPBuffer * rtp_buf)
+gst_base_rtp_depayload_push (GstBaseRTPDepayload * filter, GstBuffer * rtp_buf)
{
GstBaseRTPDepayloadClass *bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
GstBuffer *out_buf;
// let's send it out to processing
- out_buf = bclass->process (filter, GST_RTPBUFFER (rtp_buf));
+ out_buf = bclass->process (filter, rtp_buf);
if (out_buf) {
// set the caps
gst_buffer_set_caps (GST_BUFFER (out_buf),
gst_base_rtp_depayload_queue_release (GstBaseRTPDepayload * filter)
{
GQueue *queue = filter->queue;
+ guint32 headts, tailts;
+ GstBaseRTPDepayloadClass *bclass;
if (g_queue_is_empty (queue))
return;
guint maxtsunits = (gfloat) filter->clock_rate * q_size_secs;
//GST_DEBUG("maxtsunit is %u", maxtsunits);
- //GST_DEBUG("ts %d %d %d", GST_RTPBUFFER(g_queue_peek_head (queue))->timestamp, GST_RTPBUFFER(g_queue_peek_tail (queue))->timestamp);
+ //GST_DEBUG("ts %d %d %d", GST_BUFFER(g_queue_peek_head (queue))->timestamp, GST_BUFFER(g_queue_peek_tail (queue))->timestamp);
QUEUE_LOCK (filter);
- while (GST_RTPBUFFER (g_queue_peek_head (queue))->timestamp -
- GST_RTPBUFFER (g_queue_peek_tail (queue))->timestamp > maxtsunits) {
+ headts = gst_rtpbuffer_get_timestamp (GST_BUFFER (g_queue_peek_head (queue)));
+ tailts = gst_rtpbuffer_get_timestamp (GST_BUFFER (g_queue_peek_tail (queue)));
+
+ bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
+
+ while (headts - tailts > maxtsunits) {
//GST_DEBUG("Poping packet from queue");
- GstBaseRTPDepayloadClass *bclass =
- GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
if (bclass->process) {
- GstRTPBuffer *in = g_queue_pop_tail (queue);
+ GstBuffer *in = g_queue_pop_tail (queue);
- gst_base_rtp_depayload_push (filter, GST_RTPBUFFER (in));
+ gst_base_rtp_depayload_push (filter, in);
}
+ tailts =
+ gst_rtpbuffer_get_timestamp (GST_BUFFER (g_queue_peek_tail (queue)));
}
QUEUE_UNLOCK (filter);
}
#include "gstrtpbuffer.h"
-static void gst_rtpbuffer_init (GTypeInstance * instance, gpointer g_class);
-static void gst_rtpbuffer_class_init (gpointer g_class, gpointer class_data);
-static void gst_rtpbuffer_finalize (GstRTPBuffer * nbuf);
-static GstRTPBuffer *gst_rtpbuffer_copy (GstRTPBuffer * nbuf);
-
-static GstBufferClass *parent_class;
-
-GType
-gst_rtpbuffer_get_type (void)
-{
- static GType _gst_rtpbuffer_type = 0;
-
- if (G_UNLIKELY (_gst_rtpbuffer_type == 0)) {
- static const GTypeInfo rtpbuffer_info = {
- sizeof (GstRTPBufferClass),
- NULL,
- NULL,
- gst_rtpbuffer_class_init,
- NULL,
- NULL,
- sizeof (GstRTPBuffer),
- 0,
- gst_rtpbuffer_init,
- NULL
- };
-
- _gst_rtpbuffer_type = g_type_register_static (GST_TYPE_BUFFER,
- "GstRTPBuffer", &rtpbuffer_info, 0);
+#define GST_RTP_HEADER_LEN 12
+
+typedef struct _GstRTPHeader
+{
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ unsigned int csrc_count:4; /* CSRC count */
+ unsigned int extension:1; /* header extension flag */
+ unsigned int padding:1; /* padding flag */
+ unsigned int version:2; /* protocol version */
+ unsigned int payload_type:7; /* payload type */
+ unsigned int marker:1; /* marker bit */
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+ unsigned int version:2; /* protocol version */
+ unsigned int padding:1; /* padding flag */
+ unsigned int extension:1; /* header extension flag */
+ unsigned int csrc_count:4; /* CSRC count */
+ unsigned int marker:1; /* marker bit */
+ unsigned int payload_type:7; /* payload type */
+#else
+#error "G_BYTE_ORDER should be big or little endian."
+#endif
+ guint16 seq; /* sequence number */
+ guint32 timestamp; /* timestamp */
+ guint32 ssrc; /* synchronization source */
+ guint32 csrc[1]; /* optional CSRC list */
+} GstRTPHeader;
+
+#define GST_RTP_HEADER_VERSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version)
+#define GST_RTP_HEADER_PADDING(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding)
+#define GST_RTP_HEADER_EXTENSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension)
+#define GST_RTP_HEADER_CSRC_COUNT(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count)
+#define GST_RTP_HEADER_MARKER(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker)
+#define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type)
+#define GST_RTP_HEADER_SEQ(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq)
+#define GST_RTP_HEADER_TIMESTAMP(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp)
+#define GST_RTP_HEADER_SSRC(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc)
+#define GST_RTP_HEADER_CSRC(buf,i) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc[i])
+
+#define GST_RTP_HEADER_CSRC_SIZE(buf) (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32))
+
+void
+gst_rtpbuffer_allocate_data (GstBuffer * buffer, guint payload_len,
+ guint8 pad_len, guint8 csrc_count)
+{
+ guint len;
+
+ g_return_if_fail (csrc_count <= 15);
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+
+ len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
+ + payload_len + pad_len;
+
+ GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len);
+ GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
+ GST_BUFFER_SIZE (buffer) = len;
+
+ /* fill in defaults */
+ GST_RTP_HEADER_VERSION (buffer) = GST_RTP_VERSION;
+ GST_RTP_HEADER_PADDING (buffer) = FALSE;
+ GST_RTP_HEADER_EXTENSION (buffer) = FALSE;
+ GST_RTP_HEADER_CSRC_COUNT (buffer) = 0;
+ GST_RTP_HEADER_MARKER (buffer) = FALSE;
+ GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0;
+ GST_RTP_HEADER_SEQ (buffer) = 0;
+ GST_RTP_HEADER_TIMESTAMP (buffer) = 0;
+ GST_RTP_HEADER_SSRC (buffer) = 0;
+}
+
+GstBuffer *
+gst_rtpbuffer_new_take_data (gpointer data, guint len)
+{
+ GstBuffer *result;
+
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+
+ result = gst_buffer_new ();
+
+ GST_BUFFER_MALLOCDATA (result) = data;
+ GST_BUFFER_DATA (result) = data;
+ GST_BUFFER_SIZE (result) = len;
+
+ return result;
+}
+
+GstBuffer *
+gst_rtpbuffer_new_copy_data (gpointer data, guint len)
+{
+ return gst_rtpbuffer_new_take_data (g_memdup (data, len), len);
+}
+
+GstBuffer *
+gst_rtpbuffer_new_allocate (guint payload_len, guint8 pad_len,
+ guint8 csrc_count)
+{
+ GstBuffer *result;
+
+ g_return_val_if_fail (csrc_count <= 15, NULL);
+
+ result = gst_buffer_new ();
+ gst_rtpbuffer_allocate_data (result, payload_len, pad_len, csrc_count);
+
+ return result;
+}
+
+GstBuffer *
+gst_rtpbuffer_new_allocate_len (guint packet_len, guint8 pad_len,
+ guint8 csrc_count)
+{
+ guint len;
+
+ g_return_val_if_fail (csrc_count <= 15, NULL);
+
+ len = gst_rtpbuffer_calc_payload_len (packet_len, pad_len, csrc_count);
+
+ return gst_rtpbuffer_new_allocate (len, pad_len, csrc_count);
+}
+
+guint
+gst_rtpbuffer_calc_header_len (guint8 csrc_count)
+{
+ g_return_val_if_fail (csrc_count <= 15, 0);
+
+ return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
+}
+
+guint
+gst_rtpbuffer_calc_packet_len (guint payload_len, guint8 pad_len,
+ guint8 csrc_count)
+{
+ g_return_val_if_fail (csrc_count <= 15, 0);
+
+ return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
+ + pad_len;
+}
+
+guint
+gst_rtpbuffer_calc_payload_len (guint packet_len, guint8 pad_len,
+ guint8 csrc_count)
+{
+ g_return_val_if_fail (csrc_count <= 15, 0);
+
+ return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
+ - pad_len;
+}
+
+gboolean
+gst_rtpbuffer_validate_data (guint8 * data, guint len)
+{
+ guint8 padding;
+ guint8 csrc_count;
+ guint header_len;
+ guint8 version;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ header_len = GST_RTP_HEADER_LEN;
+ if (len < header_len) {
+ GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len);
+ return FALSE;
+ }
+
+ /* check version */
+ version = (data[0] & 0xc0) >> 6;
+ if (version != GST_RTP_VERSION) {
+ GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
+ return FALSE;
+ }
+
+ /* calc header length with csrc */
+ csrc_count = (data[0] & 0x0f);
+ header_len += csrc_count * sizeof (guint32);
+
+ /* check for padding */
+ if (data[0] & 0x40)
+ padding = data[len - 1];
+ else
+ padding = 0;
+
+ /* check if padding not bigger than packet and header */
+ if (len - header_len <= padding) {
+ GST_DEBUG ("padding check failed (%d - %d <= %d)",
+ len, header_len, padding);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+gst_rtpbuffer_validate (GstBuffer * buffer)
+{
+ guint8 *data;
+ guint len;
+
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+
+ data = GST_BUFFER_DATA (buffer);
+ len = GST_BUFFER_SIZE (buffer);
+
+ return gst_rtpbuffer_validate_data (data, len);
+}
+
+
+void
+gst_rtpbuffer_set_packet_len (GstBuffer * buffer, guint len)
+{
+ guint oldlen;
+
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+
+ oldlen = GST_BUFFER_SIZE (buffer);
+
+ if (oldlen < len) {
+ guint8 *newdata;
+
+ newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
+ GST_BUFFER_MALLOCDATA (buffer) = newdata;
+ GST_BUFFER_DATA (buffer) = newdata;
}
- return _gst_rtpbuffer_type;
+ GST_BUFFER_SIZE (buffer) = len;
+
+ /* remove any padding */
+ GST_RTP_HEADER_PADDING (buffer) = FALSE;
+
+}
+
+guint
+gst_rtpbuffer_get_packet_len (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+
+ return GST_BUFFER_SIZE (buffer);
+}
+
+guint8
+gst_rtpbuffer_get_version (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ return GST_RTP_HEADER_VERSION (buffer);
+}
+
+void
+gst_rtpbuffer_set_version (GstBuffer * buffer, guint8 version)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (version < 0x04);
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_VERSION (buffer) = version;
+}
+
+
+gboolean
+gst_rtpbuffer_get_padding (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
+
+ return GST_RTP_HEADER_PADDING (buffer);
+}
+
+void
+gst_rtpbuffer_set_padding (GstBuffer * buffer, gboolean padding)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_PADDING (buffer) = padding;
+}
+
+void
+gst_rtpbuffer_pad_to (GstBuffer * buffer, guint len)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ if (len > 0)
+ GST_RTP_HEADER_PADDING (buffer) = TRUE;
+ else
+ GST_RTP_HEADER_PADDING (buffer) = FALSE;
+}
+
+
+gboolean
+gst_rtpbuffer_get_extension (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
+
+ return GST_RTP_HEADER_EXTENSION (buffer);
+}
+
+void
+gst_rtpbuffer_set_extension (GstBuffer * buffer, gboolean extension)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_EXTENSION (buffer) = extension;
+}
+
+guint32
+gst_rtpbuffer_get_ssrc (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ return g_ntohl (GST_RTP_HEADER_SSRC (buffer));
+}
+
+void
+gst_rtpbuffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_SSRC (buffer) = g_htonl (ssrc);
+}
+
+guint8
+gst_rtpbuffer_get_csrc_count (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ return GST_RTP_HEADER_CSRC_COUNT (buffer);
+}
+
+guint32
+gst_rtpbuffer_get_csrc (GstBuffer * buffer, guint8 idx)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+ g_return_val_if_fail (GST_RTP_HEADER_CSRC_COUNT (buffer) < idx, 0);
+
+ return g_ntohl (GST_RTP_HEADER_CSRC (buffer, idx));
+}
+
+void
+gst_rtpbuffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ g_return_if_fail (GST_RTP_HEADER_CSRC_COUNT (buffer) < idx);
+
+ GST_RTP_HEADER_CSRC (buffer, idx) = g_htonl (csrc);
+}
+
+gboolean
+gst_rtpbuffer_get_marker (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
+
+ return GST_RTP_HEADER_MARKER (buffer);
+}
+
+void
+gst_rtpbuffer_set_marker (GstBuffer * buffer, gboolean marker)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_MARKER (buffer) = marker;
}
-static void
-gst_rtpbuffer_class_init (gpointer g_class, gpointer class_data)
+
+guint8
+gst_rtpbuffer_get_payload_type (GstBuffer * buffer)
{
- GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (g_class);
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ return GST_RTP_HEADER_PAYLOAD_TYPE (buffer);
+}
- parent_class = g_type_class_ref (GST_TYPE_BUFFER);
+void
+gst_rtpbuffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ g_return_if_fail (payload_type < 0x80);
- mo_class->copy = (GstMiniObjectCopyFunction) gst_rtpbuffer_copy;
- mo_class->finalize = (GstMiniObjectFinalizeFunction) gst_rtpbuffer_finalize;
+ GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type;
}
-static void
-gst_rtpbuffer_init (GTypeInstance * instance, gpointer g_class)
+
+guint16
+gst_rtpbuffer_get_seq (GstBuffer * buffer)
{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ return g_ntohs (GST_RTP_HEADER_SEQ (buffer));
}
-static void
-gst_rtpbuffer_finalize (GstRTPBuffer * nbuf)
+void
+gst_rtpbuffer_set_seq (GstBuffer * buffer, guint16 seq)
{
- GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (nbuf));
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+
+ GST_RTP_HEADER_SEQ (buffer) = g_htons (seq);
}
-static GstRTPBuffer *
-gst_rtpbuffer_copy (GstRTPBuffer * nbuf)
+
+guint32
+gst_rtpbuffer_get_timestamp (GstBuffer * buffer)
{
- GstRTPBuffer *copy;
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
- copy =
- (GstRTPBuffer *) GST_MINI_OBJECT_CLASS (parent_class)->
- copy (GST_MINI_OBJECT (nbuf));
+ return g_ntohl (GST_RTP_HEADER_TIMESTAMP (buffer));
+}
- copy->pt = nbuf->pt;
- copy->seqnum = nbuf->seqnum;
- copy->timestamp = nbuf->timestamp;
- copy->timestampinc = nbuf->timestampinc;
- copy->mark = nbuf->mark;
+void
+gst_rtpbuffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
+{
+ g_return_if_fail (GST_IS_BUFFER (buffer));
+ g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
- return copy;
+ GST_RTP_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp);
}
-GstRTPBuffer *
-gst_rtpbuffer_new (void)
+
+guint
+gst_rtpbuffer_get_payload_len (GstBuffer * buffer)
{
- GstRTPBuffer *buf;
+ guint len;
+
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+
+ len = GST_BUFFER_SIZE (buffer)
+ - GST_RTP_HEADER_LEN - GST_RTP_HEADER_CSRC_SIZE (buffer);
- buf = (GstRTPBuffer *) gst_mini_object_new (GST_TYPE_RTPBUFFER);
+ if (GST_RTP_HEADER_PADDING (buffer))
+ len -= ((guint8 *) GST_BUFFER_DATA (buffer))[GST_BUFFER_SIZE (buffer) - 1];
+
+ return len;
+}
+
+gpointer
+gst_rtpbuffer_get_payload (GstBuffer * buffer)
+{
+ g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+ g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
- return buf;
+ return GST_BUFFER_DATA (buffer) + GST_RTP_HEADER_LEN
+ + GST_RTP_HEADER_CSRC_SIZE (buffer);
}
/* GStreamer
* Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
+ * <2005> Wim Taymans <wim@fluendo.com>
+ *
+ * gstrtpbuffer.h: various helper functions to manipulate buffers
+ * with RTP payload.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
G_BEGIN_DECLS
-typedef struct _GstRTPBuffer GstRTPBuffer;
-typedef struct _GstRTPBufferClass GstRTPBufferClass;
+#define GST_RTP_VERSION 2
+
+typedef enum
+{
+ /* Audio: */
+ GST_RTP_PAYLOAD_PCMU = 0, /* ITU-T G.711. mu-law audio (RFC 3551) */
+ GST_RTP_PAYLOAD_GSM = 3,
+ GST_RTP_PAYLOAD_PCMA = 8, /* ITU-T G.711 A-law audio (RFC 3551) */
+ GST_RTP_PAYLOAD_L16_STEREO = 10,
+ GST_RTP_PAYLOAD_L16_MONO = 11,
+ GST_RTP_PAYLOAD_MPA = 14, /* Audio MPEG 1-3 */
+ GST_RTP_PAYLOAD_G723_63 = 16, /* Not standard */
+ GST_RTP_PAYLOAD_G723_53 = 17, /* Not standard */
+ GST_RTP_PAYLOAD_TS48 = 18, /* Not standard */
+ GST_RTP_PAYLOAD_TS41 = 19, /* Not standard */
+ GST_RTP_PAYLOAD_G728 = 20, /* Not standard */
+ GST_RTP_PAYLOAD_G729 = 21, /* Not standard */
+
+ /* Video: */
+ GST_RTP_PAYLOAD_MPV = 32, /* Video MPEG 1 & 2 */
+
+ /* BOTH */
+ GST_RTP_PAYLOAD_BMPEG = 34 /* Not Standard */
+} GstRTPPayload;
-#define GST_TYPE_RTPBUFFER (gst_rtpbuffer_get_type())
-#define GST_IS_RTPBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTPBUFFER))
-#define GST_IS_RTPBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTPBUFFER))
-#define GST_RTPBUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_RTPBUFFER, GstRTPBufferClass))
-#define GST_RTPBUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_RTPBUFFER, GstRTPBuffer))
-#define GST_RTPBUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_RTPBUFFER, GstRTPBufferClass))
+/* creating buffers */
+GstBuffer* gst_rtpbuffer_new (void);
+void gst_rtpbuffer_allocate_data (GstBuffer *buffer, guint payload_len,
+ guint8 pad_len, guint8 csrc_count);
-/* buffer for use rtp packets
- *
- * It contains the payload type, timestamp, timestamp increment
- * and mark of the rtp packet
- */
+GstBuffer* gst_rtpbuffer_new_take_data (gpointer data, guint len);
+GstBuffer* gst_rtpbuffer_new_copy_data (gpointer data, guint len);
+GstBuffer* gst_rtpbuffer_new_allocate (guint payload_len, guint8 pad_len, guint8 csrc_count);
+GstBuffer* gst_rtpbuffer_new_allocate_len (guint packet_len, guint8 pad_len, guint8 csrc_count);
-struct _GstRTPBuffer {
- GstBuffer buffer;
+guint gst_rtpbuffer_calc_header_len (guint8 csrc_count);
+guint gst_rtpbuffer_calc_packet_len (guint payload_len, guint8 pad_len, guint8 csrc_count);
+guint gst_rtpbuffer_calc_payload_len (guint packet_len, guint8 pad_len, guint8 csrc_count);
- guint8 pt;
- guint16 seqnum;
- guint32 timestamp;
- guint32 timestampinc;
- gboolean mark;
+gboolean gst_rtpbuffer_validate_data (guint8 *data, guint len);
+gboolean gst_rtpbuffer_validate (GstBuffer *buffer);
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
+void gst_rtpbuffer_set_packet_len (GstBuffer *buffer, guint len);
+guint gst_rtpbuffer_get_packet_len (GstBuffer *buffer);
-struct _GstRTPBufferClass {
- GstBufferClass buffer_class;
+guint8 gst_rtpbuffer_get_version (GstBuffer *buffer);
+void gst_rtpbuffer_set_version (GstBuffer *buffer, guint8 version);
- /*< private >*/
- gpointer _gst_reserved[GST_PADDING];
-};
+gboolean gst_rtpbuffer_get_padding (GstBuffer *buffer);
+void gst_rtpbuffer_set_padding (GstBuffer *buffer, gboolean padding);
+void gst_rtpbuffer_pad_to (GstBuffer *buffer, guint len);
-/* creating buffers */
-GType gst_rtpbuffer_get_type (void);
+gboolean gst_rtpbuffer_get_extension (GstBuffer *buffer);
+void gst_rtpbuffer_set_extension (GstBuffer *buffer, gboolean extension);
+
+guint32 gst_rtpbuffer_get_ssrc (GstBuffer *buffer);
+void gst_rtpbuffer_set_ssrc (GstBuffer *buffer, guint32 ssrc);
+
+guint8 gst_rtpbuffer_get_csrc_count (GstBuffer *buffer);
+guint32 gst_rtpbuffer_get_csrc (GstBuffer *buffer, guint8 idx);
+void gst_rtpbuffer_set_csrc (GstBuffer *buffer, guint8 idx, guint32 csrc);
+
+gboolean gst_rtpbuffer_get_marker (GstBuffer *buffer);
+void gst_rtpbuffer_set_marker (GstBuffer *buffer, gboolean marker);
+
+guint8 gst_rtpbuffer_get_payload_type (GstBuffer *buffer);
+void gst_rtpbuffer_set_payload_type (GstBuffer *buffer, guint8 payload_type);
+
+guint16 gst_rtpbuffer_get_seq (GstBuffer *buffer);
+void gst_rtpbuffer_set_seq (GstBuffer *buffer, guint16 seq);
+
+guint32 gst_rtpbuffer_get_timestamp (GstBuffer *buffer);
+void gst_rtpbuffer_set_timestamp (GstBuffer *buffer, guint32 timestamp);
-GstRTPBuffer* gst_rtpbuffer_new (void);
+guint gst_rtpbuffer_get_payload_len (GstBuffer *buffer);
+gpointer gst_rtpbuffer_get_payload (GstBuffer *buffer);
G_END_DECLS