From eb86865a62b01688fcfdbcb2c0d374e36d37ec3f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 28 Aug 2007 20:30:16 +0000 Subject: [PATCH] gst/rtpmanager/gstrtpbin.c: Add some more advanced example pipelines. Original commit message from CVS: * gst/rtpmanager/gstrtpbin.c: (gst_rtp_bin_clear_pt_map): Add some more advanced example pipelines. * gst/rtpmanager/gstrtpsession.c: (rtcp_thread), (stop_rtcp_thread), (gst_rtp_session_send_rtcp): Add some debug and FIXME. Release LOCK when performing session cleanup. * gst/rtpmanager/rtpsession.c: (session_report_blocks): Add some debug. * gst/rtpmanager/rtpsource.c: (calculate_jitter), (rtp_source_send_rtp): Make sure we always send RTP packets with the session SSRC. --- gst/rtpmanager/gstrtpbin.c | 48 +++++++++++++++++++++++++++++++++++++++++- gst/rtpmanager/gstrtpsession.c | 9 +++++--- gst/rtpmanager/rtpsession.c | 1 + gst/rtpmanager/rtpsource.c | 17 ++++++++++++--- 4 files changed, 68 insertions(+), 7 deletions(-) diff --git a/gst/rtpmanager/gstrtpbin.c b/gst/rtpmanager/gstrtpbin.c index 7f92b8c..cb2a9f0 100644 --- a/gst/rtpmanager/gstrtpbin.c +++ b/gst/rtpmanager/gstrtpbin.c @@ -75,9 +75,54 @@ * * Receive RTP data from port 5000 and send to the session 0 in gstrtpbin. * + * + * + * gst-launch gstrtpbin name=rtpbin \ + * v4l2src ! ffmpegcolorspace ! ffenc_h263 ! rtph263ppay ! rtpbin.send_rtp_sink_0 \ + * rtpbin.send_rtp_src_0 ! udpsink port=5000 \ + * rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false \ + * udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0 \ + * audiotestsrc ! amrnbenc ! rtpamrpay ! rtpbin.send_rtp_sink_1 \ + * rtpbin.send_rtp_src_1 ! udpsink port=5002 \ + * rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false \ + * udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1 + * + * Encode and payload H263 video captured from a v4l2src. Encode and payload AMR + * audio generated from audiotestsrc. The video is sent to session 0 in rtpbin + * and the audio is sent to session 1. Video packets are sent on UDP port 5000 + * and audio packets on port 5002. The video RTCP packets for session 0 are sent + * on port 5001 and the audio RTCP packets for session 0 are sent on port 5003. + * RTCP packets for session 0 are received on port 5005 and RTCP for session 1 + * is received on port 5007. Since RTCP packets from the sender should be sent + * as soon as possible, sync=false is configured on udpsink. + * + * + * + * gst-launch -v gstrtpbin name=rtpbin \ + * udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \ + * port=5000 ! rtpbin.recv_rtp_sink_0 \ + * rtpbin. ! rtph263pdepay ! ffdec_h263 ! xvimagesink \ + * udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0 \ + * rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false \ + * udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \ + * port=5002 ! rtpbin.recv_rtp_sink_1 \ + * rtpbin. ! rtpamrdepay ! amrnbdec ! alsasink \ + * udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1 \ + * rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false + * + * Receive H263 on port 5000, send it through rtpbin in session 0, depayload, + * decode and display the video. + * Receive AMR on port 5002, send it through rtpbin in session 1, depayload, + * decode and play the audio. + * Receive server RTCP packets for session 0 on port 5001 and RTCP packets for + * session 1 on port 5003. These packets will be used for session management and + * synchronisation. + * Send RTCP reports for session 0 on port 5005 and RTCP reports for session 1 + * on port 5007. + * * * - * Last reviewed on 2007-05-28 (0.10.5) + * Last reviewed on 2007-08-28 (0.10.6) */ #ifdef HAVE_CONFIG_H @@ -452,6 +497,7 @@ gst_rtp_bin_clear_pt_map (GstRtpBin * bin) GSList *walk; GST_RTP_BIN_LOCK (bin); + GST_DEBUG_OBJECT (bin, "clearing pt map"); for (walk = bin->sessions; walk; walk = g_slist_next (walk)) { GstRtpBinSession *session = (GstRtpBinSession *) walk->data; diff --git a/gst/rtpmanager/gstrtpsession.c b/gst/rtpmanager/gstrtpsession.c index 1b63024..7f5782b 100644 --- a/gst/rtpmanager/gstrtpsession.c +++ b/gst/rtpmanager/gstrtpsession.c @@ -583,8 +583,10 @@ rtcp_thread (GstRtpSession * rtpsession) GST_DEBUG_OBJECT (rtpsession, "unlocked %d, current %" GST_TIME_FORMAT, res, GST_TIME_ARGS (current_time)); - /* perform actions, we ignore result. */ + /* perform actions, we ignore result. Release lock because it might push. */ + GST_RTP_SESSION_UNLOCK (rtpsession); rtp_session_on_timeout (rtpsession->priv->session, current_time); + GST_RTP_SESSION_LOCK (rtpsession); } GST_RTP_SESSION_UNLOCK (rtpsession); @@ -637,6 +639,7 @@ stop_rtcp_thread (GstRtpSession * rtpsession) gst_clock_id_unschedule (rtpsession->priv->id); GST_RTP_SESSION_UNLOCK (rtpsession); + /* FIXME, can deadlock because the thread might be blocked in a push */ g_thread_join (rtpsession->priv->thread); } @@ -753,11 +756,11 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src, rtpsession = GST_RTP_SESSION (user_data); priv = rtpsession->priv; - GST_DEBUG_OBJECT (rtpsession, "sending RTCP"); - if (rtpsession->send_rtcp_src) { + GST_DEBUG_OBJECT (rtpsession, "sending RTCP"); result = gst_pad_push (rtpsession->send_rtcp_src, buffer); } else { + GST_DEBUG_OBJECT (rtpsession, "not sending RTCP, no output pad"); gst_buffer_unref (buffer); result = GST_FLOW_OK; } diff --git a/gst/rtpmanager/rtpsession.c b/gst/rtpmanager/rtpsession.c index 9ab3b4a..6fa478c 100644 --- a/gst/rtpmanager/rtpsession.c +++ b/gst/rtpmanager/rtpsession.c @@ -1659,6 +1659,7 @@ session_report_blocks (const gchar * key, RTPSource * source, ReportData * data) DLSR = gst_util_uint64_scale_int (diff, 65536, GST_SECOND); } else { /* No valid SR received, LSR/DLSR are set to 0 then */ + GST_DEBUG ("no valid SR received"); LSR = 0; DLSR = 0; } diff --git a/gst/rtpmanager/rtpsource.c b/gst/rtpmanager/rtpsource.c index 8007d54..1a98951 100644 --- a/gst/rtpmanager/rtpsource.c +++ b/gst/rtpmanager/rtpsource.c @@ -266,8 +266,8 @@ calculate_jitter (RTPSource * src, GstBuffer * buffer, src->stats.prev_rtptime = src->stats.last_rtptime; src->stats.last_rtptime = rtparrival; - GST_DEBUG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %u", - rtparrival, rtptime, clock_rate, diff, src->stats.jitter); + GST_DEBUG ("rtparrival %u, rtptime %u, clock-rate %d, diff %d, jitter: %f", + rtparrival, rtptime, clock_rate, diff, (src->stats.jitter) / 16.0); return; @@ -446,6 +446,8 @@ rtp_source_process_bye (RTPSource * src, const gchar * reason) * @buffer: an RTP buffer * * Send an RTP @buffer originating from @src. This will make @src a sender. + * This function takes ownership of @buffer and modifies the SSRC in the RTP + * packet to that of @src. * * Returns: a #GstFlowReturn. */ @@ -467,9 +469,18 @@ rtp_source_send_rtp (RTPSource * src, GstBuffer * buffer) src->stats.packets_sent++; src->stats.octets_sent += len; - /* push packet */ if (src->callbacks.push_rtp) { + guint32 ssrc; + + ssrc = gst_rtp_buffer_get_ssrc (buffer); + if (ssrc != src->ssrc) { + GST_DEBUG ("updating SSRC from %u to %u", ssrc, src->ssrc); + buffer = gst_buffer_make_writable (buffer); + + gst_rtp_buffer_set_ssrc (buffer, src->ssrc); + } + GST_DEBUG ("pushing RTP packet %" G_GUINT64_FORMAT, src->stats.packets_sent); result = src->callbacks.push_rtp (src, buffer, src->user_data); -- 2.7.4