From 1643f427db8c3de8cb8dd952eb408c076a4223ee Mon Sep 17 00:00:00 2001 From: =?utf8?q?Olivier=20Cr=C3=AAte?= Date: Thu, 17 Jun 2010 17:34:19 -0400 Subject: [PATCH] rtpsession: Emit signal on incoming RTCP FB packet --- gst/rtpmanager/gstrtpbin-marshal.list | 1 + gst/rtpmanager/rtpsession.c | 57 +++++++++++++++++++++++++++++++++++ gst/rtpmanager/rtpsession.h | 2 ++ 3 files changed, 60 insertions(+) diff --git a/gst/rtpmanager/gstrtpbin-marshal.list b/gst/rtpmanager/gstrtpbin-marshal.list index 0b0d81f..5176b33 100644 --- a/gst/rtpmanager/gstrtpbin-marshal.list +++ b/gst/rtpmanager/gstrtpbin-marshal.list @@ -8,3 +8,4 @@ VOID:UINT,UINT VOID:OBJECT,OBJECT UINT64:BOOL,UINT64 BOOL:POINTER,BOOL +VOID:UINT,UINT,UINT,UINT,POINTER diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index a0ac833..d4bbf08 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -43,6 +43,7 @@ enum SIGNAL_ON_TIMEOUT, SIGNAL_ON_SENDER_TIMEOUT, SIGNAL_ON_SENDING_RTCP, + SIGNAL_ON_FEEDBACK_RTCP, LAST_SIGNAL }; @@ -271,6 +272,27 @@ rtp_session_class_init (RTPSessionClass * klass) accumulate_trues, NULL, gst_rtp_bin_marshal_BOOLEAN__POINTER_BOOLEAN, G_TYPE_BOOLEAN, 2, G_TYPE_POINTER, G_TYPE_BOOLEAN); + /** + * RTPSession::on-feedback-rtcp: + * @session: the object which received the signal + * @type: Type of RTCP packet, will be %GST_RTCP_TYPE_RTPFB or + * %GST_RTCP_TYPE_RTPFB + * @fbtype: The type of RTCP FB packet, probably part of #GstRTCPFBType + * @sender_ssrc: The SSRC of the sender + * @media_ssrc: The SSRC of the media this refers to + * @fci: a #GstBuffer with the FCI data from the FB packet or %NULL if + * there was no FCI + * + * Notify that a RTCP feedback packet has been received + */ + + rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP] = + g_signal_new ("on-feedback-rtcp", G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (RTPSessionClass, on_feedback_rtcp), + NULL, NULL, gst_rtp_bin_marshal_VOID__UINT_UINT_UINT_UINT_POINTER, + G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_UINT, + G_TYPE_POINTER); + 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", @@ -1960,6 +1982,37 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet, GST_DEBUG ("received APP"); } + +static void +rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet, + RTPArrivalStats * arrival) +{ + GstRTCPType type = gst_rtcp_packet_get_type (packet); + GstRTCPFBType fbtype = gst_rtcp_packet_fb_get_type (packet); + guint32 sender_ssrc = gst_rtcp_packet_fb_get_sender_ssrc (packet); + guint32 media_ssrc = gst_rtcp_packet_fb_get_media_ssrc (packet); + guint length = 4 * (gst_rtcp_packet_get_length (packet) - 2); + + GST_DEBUG ("received feedback %d:%d from %08X about %08X" + " with FCI of length %d", type, fbtype, sender_ssrc, media_ssrc, length); + + if (g_signal_has_handler_pending (sess, + rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP], 0, TRUE)) { + GstBuffer *fci = NULL; + + if (length) { + fci = gst_buffer_create_sub (packet->buffer, packet->offset + 72, length); + GST_BUFFER_TIMESTAMP (fci) = arrival->running_time; + } + + g_signal_emit (sess, rtp_session_signals[SIGNAL_ON_FEEDBACK_RTCP], 0, + type, fbtype, sender_ssrc, media_ssrc, fci); + + if (fci) + gst_buffer_unref (fci); + } +} + /** * rtp_session_process_rtcp: * @sess: and #RTPSession @@ -2030,6 +2083,10 @@ rtp_session_process_rtcp (RTPSession * sess, GstBuffer * buffer, case GST_RTCP_TYPE_APP: rtp_session_process_app (sess, &packet, &arrival); break; + case GST_RTCP_TYPE_RTPFB: + case GST_RTCP_TYPE_PSFB: + rtp_session_process_feedback (sess, &packet, &arrival); + break; default: GST_WARNING ("got unknown RTCP packet"); break; diff --git a/gst/rtpmanager/rtpsession.h b/gst/rtpmanager/rtpsession.h index a2d5d57..b63bbcc 100644 --- a/gst/rtpmanager/rtpsession.h +++ b/gst/rtpmanager/rtpsession.h @@ -229,6 +229,8 @@ struct _RTPSessionClass { void (*on_sender_timeout) (RTPSession *sess, RTPSource *source); gboolean (*on_sending_rtcp) (RTPSession *sess, GstBuffer *buffer, gboolean early); + void (*on_feedback_rtcp) (RTPSession *sess, guint type, guint fbtype, + guint sender_ssrc, guint media_ssrc, GstBuffer *fci); }; GType rtp_session_get_type (void); -- 2.7.4