mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
rtpsession: Add new signal 'on-app-rtcp'
Similar to the 'on-feedback-rtcp' signal, but emitted for RTCP APP packets. https://bugzilla.gnome.org/show_bug.cgi?id=762217
This commit is contained in:
parent
eb13a1d607
commit
4c0e509328
3 changed files with 130 additions and 0 deletions
|
@ -47,6 +47,7 @@ enum
|
||||||
SIGNAL_ON_TIMEOUT,
|
SIGNAL_ON_TIMEOUT,
|
||||||
SIGNAL_ON_SENDER_TIMEOUT,
|
SIGNAL_ON_SENDER_TIMEOUT,
|
||||||
SIGNAL_ON_SENDING_RTCP,
|
SIGNAL_ON_SENDING_RTCP,
|
||||||
|
SIGNAL_ON_APP_RTCP,
|
||||||
SIGNAL_ON_FEEDBACK_RTCP,
|
SIGNAL_ON_FEEDBACK_RTCP,
|
||||||
SIGNAL_SEND_RTCP,
|
SIGNAL_SEND_RTCP,
|
||||||
SIGNAL_SEND_RTCP_FULL,
|
SIGNAL_SEND_RTCP_FULL,
|
||||||
|
@ -296,6 +297,23 @@ rtp_session_class_init (RTPSessionClass * klass)
|
||||||
accumulate_trues, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2,
|
accumulate_trues, NULL, g_cclosure_marshal_generic, G_TYPE_BOOLEAN, 2,
|
||||||
GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_BOOLEAN);
|
GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_BOOLEAN);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RTPSession::on-app-rtcp:
|
||||||
|
* @session: the object which received the signal
|
||||||
|
* @subtype: The subtype of the packet
|
||||||
|
* @ssrc: The SSRC/CSRC of the packet
|
||||||
|
* @name: The name of the packet
|
||||||
|
* @data: a #GstBuffer with the application-dependant data or %NULL if
|
||||||
|
* there was no data
|
||||||
|
*
|
||||||
|
* Notify that a RTCP APP packet has been received
|
||||||
|
*/
|
||||||
|
rtp_session_signals[SIGNAL_ON_APP_RTCP] =
|
||||||
|
g_signal_new ("on-app-rtcp", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_app_rtcp),
|
||||||
|
NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 4,
|
||||||
|
G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, GST_TYPE_BUFFER);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RTPSession::on-feedback-rtcp:
|
* RTPSession::on-feedback-rtcp:
|
||||||
* @session: the object which received the signal
|
* @session: the object which received the signal
|
||||||
|
@ -2517,6 +2535,33 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet,
|
||||||
RTPPacketInfo * pinfo)
|
RTPPacketInfo * pinfo)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("received APP");
|
GST_DEBUG ("received APP");
|
||||||
|
|
||||||
|
if (g_signal_has_handler_pending (sess,
|
||||||
|
rtp_session_signals[SIGNAL_ON_APP_RTCP], 0, TRUE)) {
|
||||||
|
GstBuffer *data_buffer = NULL;
|
||||||
|
guint16 data_length;
|
||||||
|
gchar name[5];
|
||||||
|
|
||||||
|
data_length = gst_rtcp_packet_app_get_data_length (packet) * 4;
|
||||||
|
if (data_length > 0) {
|
||||||
|
guint8 *data = gst_rtcp_packet_app_get_data (packet);
|
||||||
|
data_buffer = gst_buffer_copy_region (packet->rtcp->buffer,
|
||||||
|
GST_BUFFER_COPY_MEMORY, data - packet->rtcp->map.data, data_length);
|
||||||
|
GST_BUFFER_PTS (data_buffer) = pinfo->running_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy (name, gst_rtcp_packet_app_get_name (packet), 4);
|
||||||
|
name[4] = '\0';
|
||||||
|
|
||||||
|
RTP_SESSION_UNLOCK (sess);
|
||||||
|
g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_APP_RTCP], 0,
|
||||||
|
gst_rtcp_packet_app_get_subtype (packet),
|
||||||
|
gst_rtcp_packet_app_get_ssrc (packet), name, data_buffer);
|
||||||
|
RTP_SESSION_LOCK (sess);
|
||||||
|
|
||||||
|
if (data_buffer)
|
||||||
|
gst_buffer_unref (data_buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
|
|
|
@ -309,6 +309,8 @@ struct _RTPSessionClass {
|
||||||
void (*on_sender_timeout) (RTPSession *sess, RTPSource *source);
|
void (*on_sender_timeout) (RTPSession *sess, RTPSource *source);
|
||||||
gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer,
|
gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer,
|
||||||
gboolean early);
|
gboolean early);
|
||||||
|
void (*on_app_rtcp) (RTPSession *sess, guint subtype, guint ssrc,
|
||||||
|
const gchar *name, GstBuffer *data);
|
||||||
void (*on_feedback_rtcp) (RTPSession *sess, guint type, guint fbtype,
|
void (*on_feedback_rtcp) (RTPSession *sess, guint type, guint fbtype,
|
||||||
guint sender_ssrc, guint media_ssrc, GstBuffer *fci);
|
guint sender_ssrc, guint media_ssrc, GstBuffer *fci);
|
||||||
gboolean (*send_rtcp) (RTPSession *sess, GstClockTime max_delay);
|
gboolean (*send_rtcp) (RTPSession *sess, GstClockTime max_delay);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
* Boston, MA 02110-1301, USA.
|
* Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <gst/check/gstharness.h>
|
||||||
#include <gst/check/gstcheck.h>
|
#include <gst/check/gstcheck.h>
|
||||||
#include <gst/check/gsttestclock.h>
|
#include <gst/check/gsttestclock.h>
|
||||||
|
|
||||||
|
@ -576,6 +577,87 @@ GST_START_TEST (test_internal_sources_timeout)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
guint8 subtype;
|
||||||
|
guint32 ssrc;
|
||||||
|
gchar *name;
|
||||||
|
GstBuffer *data;
|
||||||
|
} RTCPAppResult;
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_app_rtcp_cb (GObject * session, guint subtype, guint ssrc,
|
||||||
|
const gchar * name, GstBuffer * data, RTCPAppResult * result)
|
||||||
|
{
|
||||||
|
result->subtype = subtype;
|
||||||
|
result->ssrc = ssrc;
|
||||||
|
result->name = g_strdup (name);
|
||||||
|
result->data = data ? gst_buffer_ref (data) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_receive_rtcp_app_packet)
|
||||||
|
{
|
||||||
|
GstHarness *h;
|
||||||
|
GstBuffer *buffer;
|
||||||
|
GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
|
||||||
|
GstRTCPPacket packet;
|
||||||
|
RTCPAppResult result = { 0 };
|
||||||
|
GstElement *internal_session;
|
||||||
|
guint8 data[] = { 0x11, 0x22, 0x33, 0x44 };
|
||||||
|
|
||||||
|
h = gst_harness_new_with_padnames ("rtpsession", "recv_rtcp_sink", NULL);
|
||||||
|
g_object_get (h->element, "internal-session", &internal_session, NULL);
|
||||||
|
|
||||||
|
g_signal_connect (internal_session, "on-app-rtcp",
|
||||||
|
G_CALLBACK (on_app_rtcp_cb), &result);
|
||||||
|
|
||||||
|
/* Push APP buffer with no data */
|
||||||
|
buffer = gst_rtcp_buffer_new (1000);
|
||||||
|
fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
|
||||||
|
fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
|
||||||
|
gst_rtcp_packet_app_set_subtype (&packet, 21);
|
||||||
|
gst_rtcp_packet_app_set_ssrc (&packet, 0x11111111);
|
||||||
|
gst_rtcp_packet_app_set_name (&packet, "Test");
|
||||||
|
gst_rtcp_buffer_unmap (&rtcp);
|
||||||
|
|
||||||
|
gst_harness_set_src_caps_str (h, "application/x-rtcp");
|
||||||
|
fail_unless_equals_int (gst_harness_push (h, buffer), GST_FLOW_OK);
|
||||||
|
|
||||||
|
fail_unless_equals_int (result.subtype, 21);
|
||||||
|
fail_unless_equals_int (result.ssrc, 0x11111111);
|
||||||
|
fail_unless_equals_string (result.name, "Test");
|
||||||
|
fail_unless_equals_pointer (result.data, NULL);
|
||||||
|
|
||||||
|
g_free (result.name);
|
||||||
|
|
||||||
|
/* Push APP buffer with data */
|
||||||
|
memset (&result, 0, sizeof (result));
|
||||||
|
buffer = gst_rtcp_buffer_new (1000);
|
||||||
|
fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
|
||||||
|
fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
|
||||||
|
gst_rtcp_packet_app_set_subtype (&packet, 22);
|
||||||
|
gst_rtcp_packet_app_set_ssrc (&packet, 0x22222222);
|
||||||
|
gst_rtcp_packet_app_set_name (&packet, "Test");
|
||||||
|
gst_rtcp_packet_app_set_data_length (&packet, sizeof (data) / 4);
|
||||||
|
memcpy (gst_rtcp_packet_app_get_data (&packet), data, sizeof (data));
|
||||||
|
gst_rtcp_buffer_unmap (&rtcp);
|
||||||
|
|
||||||
|
fail_unless_equals_int (gst_harness_push (h, buffer), GST_FLOW_OK);
|
||||||
|
|
||||||
|
fail_unless_equals_int (result.subtype, 22);
|
||||||
|
fail_unless_equals_int (result.ssrc, 0x22222222);
|
||||||
|
fail_unless_equals_string (result.name, "Test");
|
||||||
|
fail_unless (gst_buffer_memcmp (result.data, 0, data, sizeof (data)) == 0);
|
||||||
|
|
||||||
|
g_free (result.name);
|
||||||
|
gst_buffer_unref (result.data);
|
||||||
|
|
||||||
|
gst_object_unref (internal_session);
|
||||||
|
gst_harness_teardown (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
rtpsession_suite (void)
|
rtpsession_suite (void)
|
||||||
{
|
{
|
||||||
|
@ -586,6 +668,7 @@ rtpsession_suite (void)
|
||||||
tcase_add_test (tc_chain, test_multiple_ssrc_rr);
|
tcase_add_test (tc_chain, test_multiple_ssrc_rr);
|
||||||
tcase_add_test (tc_chain, test_multiple_senders_roundrobin_rbs);
|
tcase_add_test (tc_chain, test_multiple_senders_roundrobin_rbs);
|
||||||
tcase_add_test (tc_chain, test_internal_sources_timeout);
|
tcase_add_test (tc_chain, test_internal_sources_timeout);
|
||||||
|
tcase_add_test (tc_chain, test_receive_rtcp_app_packet);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue