rtpbuffer: add gst_rtp_buffer_get_payload_bytes

The function gst_rtp_buffer_get_payload can not be used in Python
because it lacks necessary length parameter. This patch adds a new
function, gst_rtp_buffer_get_payload_bytes, to use from Python
bindings. The new function has the advisory "Rename to:" annotation
so it can replace the gst_rtp_buffer_get_payload whan creating
bindings.

The function gst_rtp_buffer_get_extension_bytes is also added. It wraps
gst_rtp_buffer_get_extension_data which doesn't work in Python due to
incomplete annotation and because it returns the length as number of
32-bit words.

https://bugzilla.gnome.org/show_bug.cgi?id=698562
This commit is contained in:
Branko Subasic 2013-06-16 22:39:30 +02:00 committed by Sebastian Dröge
parent f240d34c7e
commit 4dd5c5b808
3 changed files with 193 additions and 2 deletions

View file

@ -651,7 +651,7 @@ gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
} }
/** /**
* gst_rtp_buffer_get_extension_data: * gst_rtp_buffer_get_extension_data: (skip)
* @rtp: the RTP packet * @rtp: the RTP packet
* @bits: (out): location for result bits * @bits: (out): location for result bits
* @data: (out) (array) (element-type guint8) (transfer none): location for data * @data: (out) (array) (element-type guint8) (transfer none): location for data
@ -688,6 +688,47 @@ gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
return TRUE; return TRUE;
} }
/**
* gst_rtp_buffer_get_extension_bytes:
* @rtp: the RTP packet
* @bits: (out): location for header bits
*
* Similar to gst_rtp_buffer_get_extension_data, but more suitable for language
* bindings usage. @bits will contain the extension 16 bits of custom data and
* the extension data (not including the extension header) is placed in a new
* #GBytes structure.
*
* If @rtp did not contain an extension, this function will return %NULL, with
* @bits unchanged. If there is an extension header but no extension data then
* an empty #GBytes will be returned.
*
* Returns: (transfer full): A new #GBytes if an extension header was present
* and %NULL otherwise.
*
* Rename to: gst_rtp_buffer_get_extension_data
*
* Since: 1.2
*/
GBytes *
gst_rtp_buffer_get_extension_bytes (GstRTPBuffer * rtp, guint16 * bits)
{
gpointer buf_data = NULL;
guint buf_len;
g_return_val_if_fail (rtp != NULL, FALSE);
if (!gst_rtp_buffer_get_extension_data (rtp, bits, &buf_data, &buf_len))
return NULL;
if (buf_len == 0) {
/* if no extension data is present return an empty GBytes */
buf_data = NULL;
}
/* multiply length with 4 to get length in bytes */
return g_bytes_new (buf_data, 4 * buf_len);
}
/* ensure header, payload and padding are in separate buffers */ /* ensure header, payload and padding are in separate buffers */
static void static void
ensure_buffers (GstRTPBuffer * rtp) ensure_buffers (GstRTPBuffer * rtp)
@ -1057,7 +1098,7 @@ gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
} }
/** /**
* gst_rtp_buffer_get_payload: * gst_rtp_buffer_get_payload: (skip)
* @rtp: the RTP packet * @rtp: the RTP packet
* *
* Get a pointer to the payload data in @buffer. This pointer is valid as long * Get a pointer to the payload data in @buffer. This pointer is valid as long
@ -1092,6 +1133,34 @@ gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
return rtp->data[2]; return rtp->data[2];
} }
/**
* gst_rtp_buffer_get_payload_bytes:
* @rtp: the RTP packet
*
* Similar to gst_rtp_buffer_get_payload, but more suitable for language
* bindings usage. The return value is a pointer to a #GBytes structure
* containing the payload data in @rtp.
*
* Returns: (transfer full): A new #GBytes containing the payload data in @rtp.
*
* Rename to: gst_rtp_buffer_get_payload
*
* Since: 1.2
*/
GBytes *
gst_rtp_buffer_get_payload_bytes (GstRTPBuffer * rtp)
{
gpointer data;
g_return_val_if_fail (rtp != NULL, NULL);
data = gst_rtp_buffer_get_payload (rtp);
if (data == NULL)
return NULL;
return g_bytes_new (data, gst_rtp_buffer_get_payload_len (rtp));
}
/** /**
* gst_rtp_buffer_default_clock_rate: * gst_rtp_buffer_default_clock_rate:
* @payload_type: the static payload type * @payload_type: the static payload type

View file

@ -94,6 +94,7 @@ gboolean gst_rtp_buffer_get_extension (GstRTPBuffer *rtp);
void gst_rtp_buffer_set_extension (GstRTPBuffer *rtp, gboolean extension); void gst_rtp_buffer_set_extension (GstRTPBuffer *rtp, gboolean extension);
gboolean gst_rtp_buffer_get_extension_data (GstRTPBuffer *rtp, guint16 *bits, gboolean gst_rtp_buffer_get_extension_data (GstRTPBuffer *rtp, guint16 *bits,
gpointer *data, guint *wordlen); gpointer *data, guint *wordlen);
GBytes* gst_rtp_buffer_get_extension_bytes (GstRTPBuffer *rtp, guint16 *bits);
gboolean gst_rtp_buffer_set_extension_data (GstRTPBuffer *rtp, guint16 bits, guint16 length); gboolean gst_rtp_buffer_set_extension_data (GstRTPBuffer *rtp, guint16 bits, guint16 length);
guint32 gst_rtp_buffer_get_ssrc (GstRTPBuffer *rtp); guint32 gst_rtp_buffer_get_ssrc (GstRTPBuffer *rtp);
@ -120,6 +121,7 @@ GstBuffer* gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer *rtp, guint o
guint gst_rtp_buffer_get_payload_len (GstRTPBuffer *rtp); guint gst_rtp_buffer_get_payload_len (GstRTPBuffer *rtp);
gpointer gst_rtp_buffer_get_payload (GstRTPBuffer *rtp); gpointer gst_rtp_buffer_get_payload (GstRTPBuffer *rtp);
GBytes* gst_rtp_buffer_get_payload_bytes (GstRTPBuffer *rtp);
/* some helpers */ /* some helpers */
guint32 gst_rtp_buffer_default_clock_rate (guint8 payload_type); guint32 gst_rtp_buffer_default_clock_rate (guint8 payload_type);

View file

@ -838,6 +838,123 @@ GST_START_TEST (test_rtp_ntp56_extension)
GST_END_TEST; GST_END_TEST;
GST_START_TEST (test_rtp_buffer_get_extension_bytes)
{
GstBuffer *buf;
guint16 bits;
guint size;
guint8 misc_data[4] = { 1, 2, 3, 4 };
gpointer pointer;
GstRTPBuffer rtp = { NULL, };
GBytes *gb;
gsize gb_size;
/* create RTP buffer without extension header */
buf = gst_rtp_buffer_new_allocate (4, 0, 0);
gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
fail_if (gst_rtp_buffer_get_extension (&rtp));
/* verify that obtaining extension data returns NULL and bits are unchanged */
bits = 0xabcd;
gb = gst_rtp_buffer_get_extension_bytes (&rtp, &bits);
fail_unless (gb == NULL);
fail_unless (bits == 0xabcd);
g_bytes_unref (gb);
/* add extension header without data and verify that
* an empty GBytes is returned */
fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 270, 0));
fail_unless (gst_rtp_buffer_get_extension (&rtp));
gb = gst_rtp_buffer_get_extension_bytes (&rtp, &bits);
fail_unless (gb != NULL);
fail_unless_equals_int (g_bytes_get_size (gb), 0);
g_bytes_unref (gb);
gst_rtp_buffer_unmap (&rtp);
gst_buffer_unref (buf);
/* create RTP buffer with extension header and extension data */
buf = gst_rtp_buffer_new_allocate (4, 0, 0);
gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
fail_unless (gst_rtp_buffer_add_extension_onebyte_header (&rtp, 5,
misc_data, 2));
fail_unless (gst_rtp_buffer_get_extension (&rtp));
/* verify that gst_rtp_buffer_get_extension_bytes returns the same
* header bits and data as does gst_rtp_buffer_get_extension_data */
fail_unless (gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer,
&size));
fail_unless (bits == 0xBEDE);
fail_unless (size == 1);
gb = gst_rtp_buffer_get_extension_bytes (&rtp, &bits);
fail_unless (gb != NULL);
fail_unless (bits == 0xBEDE);
fail_unless_equals_int (g_bytes_get_size (gb), size * 4);
fail_unless (memcmp (pointer, g_bytes_get_data (gb, &gb_size),
size * 4) == 0);
fail_unless_equals_int (gb_size, size * 4);
g_bytes_unref (gb);
gst_rtp_buffer_unmap (&rtp);
gst_buffer_unref (buf);
}
GST_END_TEST;
GST_START_TEST (test_rtp_buffer_get_payload_bytes)
{
guint8 rtppacket[] = {
0x80, 0xe0, 0xdf, 0xd7, 0xef, 0x84, 0xbe, 0xed, 0x9b, 0xc5, 0x29, 0x14,
'H', 'e', 'l', 'l', 'o', '\0'
};
GstBuffer *buf;
GstMapInfo map;
gconstpointer data;
gsize size;
GstRTPBuffer rtp = { NULL, };
GBytes *gb;
/* create empty RTP buffer, i.e. no payload */
buf = gst_rtp_buffer_new_allocate (0, 4, 0);
fail_unless (buf != NULL);
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
fail_unless_equals_int (map.size, RTP_HEADER_LEN + 4);
fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp));
/* verify that requesting payload data returns an empty GBytes */
gb = gst_rtp_buffer_get_payload_bytes (&rtp);
fail_unless (gb != NULL);
fail_unless_equals_int (g_bytes_get_size (gb), 0);
gst_rtp_buffer_unmap (&rtp);
gst_buffer_unmap (buf, &map);
gst_buffer_unref (buf);
/* create RTP buffer containing RTP packet */
buf = gst_buffer_new_and_alloc (sizeof (rtppacket));
fail_unless (buf != NULL);
gst_buffer_fill (buf, 0, rtppacket, sizeof (rtppacket));
gst_buffer_map (buf, &map, GST_MAP_READWRITE);
fail_unless_equals_int (map.size, sizeof (rtppacket));
fail_unless (gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp));
/* verify that the returned GBytes contains the correct payload data */
gb = gst_rtp_buffer_get_payload_bytes (&rtp);
fail_unless (gb != NULL);
data = g_bytes_get_data (gb, &size);
fail_unless (data != NULL);
fail_unless (size == (sizeof (rtppacket) - RTP_HEADER_LEN));
fail_unless_equals_string ("Hello", data);
gst_rtp_buffer_unmap (&rtp);
gst_buffer_unmap (buf, &map);
gst_buffer_unref (buf);
}
GST_END_TEST;
static Suite * static Suite *
rtp_suite (void) rtp_suite (void)
{ {
@ -855,6 +972,9 @@ rtp_suite (void)
tcase_add_test (tc_chain, test_rtp_ntp64_extension); tcase_add_test (tc_chain, test_rtp_ntp64_extension);
tcase_add_test (tc_chain, test_rtp_ntp56_extension); tcase_add_test (tc_chain, test_rtp_ntp56_extension);
tcase_add_test (tc_chain, test_rtp_buffer_get_payload_bytes);
tcase_add_test (tc_chain, test_rtp_buffer_get_extension_bytes);
//tcase_add_test (tc_chain, test_rtp_buffer_list); //tcase_add_test (tc_chain, test_rtp_buffer_list);
return s; return s;