diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list index 01b530be41..0b0d81ff3a 100644 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ b/gst/rtpmanager/gstrtpbin-marshal.list @@ -7,3 +7,4 @@ VOID:UINT VOID:UINT,UINT VOID:OBJECT,OBJECT UINT64:BOOL,UINT64 +BOOL:POINTER,BOOL diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 176a86f498..4b1513d180 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -42,6 +42,7 @@ enum SIGNAL_ON_BYE_TIMEOUT, SIGNAL_ON_TIMEOUT, SIGNAL_ON_SENDER_TIMEOUT, + SIGNAL_ON_SENDING_RTCP, LAST_SIGNAL }; @@ -107,6 +108,16 @@ static GstFlowReturn rtp_session_schedule_bye_locked (RTPSession * sess, static GstClockTime calculate_rtcp_interval (RTPSession * sess, gboolean deterministic, gboolean first); +static gboolean +accumulate_trues (GSignalInvocationHint * ihint, GValue * return_accu, + const GValue * handler_return, gpointer data) +{ + if (g_value_get_boolean (handler_return)) + g_value_set_boolean (return_accu, TRUE); + + return TRUE; +} + static void rtp_session_class_init (RTPSessionClass * klass) { @@ -240,6 +251,24 @@ rtp_session_class_init (RTPSessionClass * klass) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, RTP_TYPE_SOURCE); + /** + * RTPSession::on-sending-rtcp + * @session: the object which received the signal + * @buffer: the #GstBuffer containing the RTCP packet about to be sent + * @early: %TRUE if the packet is early, %FALSE if it is regular + * + * This signal is emitted before sending an RTCP packet, it can be used + * to add extra RTCP Packets. + * + * Returns: %TRUE if the RTCP buffer should NOT be suppressed, %FALSE + * if suppressing it is acceptable + */ + rtp_session_signals[SIGNAL_ON_SENDING_RTCP] = + g_signal_new ("on-sending-rtcp", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_sending_rtcp), + accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__POINTER_BOOLEAN, + G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); + g_object_class_install_property (gobject_class, PROP_INTERNAL_SSRC, g_param_spec_uint ("internal-ssrc", "Internal SSRC", "The internal SSRC used for the session", @@ -2704,6 +2733,10 @@ rtp_session_on_timeout (RTPSession * sess, GstClockTime current_time, /* push out the RTCP packet */ if (data.rtcp) { + /* Give the user a change to add its own packet */ + g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_SENDING_RTCP], 0, + data.rtcp, FALSE, NULL); + /* close the RTCP packet */ gst_rtcp_buffer_end (data.rtcp); diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index 3fc9874675..0f86856cd7 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -224,6 +224,8 @@ struct _RTPSessionClass { void (*on_bye_timeout) (RTPSession *sess, RTPSource *source); void (*on_timeout) (RTPSession *sess, RTPSource *source); void (*on_sender_timeout) (RTPSession *sess, RTPSource *source); + gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer, + gboolean early); }; GType rtp_session_get_type (void);