rtpbin: pipeline gets an EOS when any rtpsources byes

Instead of sending EOS when a source byes we have to wait for
all the sources to be gone, which means they already sent BYE and
were removed from the session. We now handle the EOS in the rtcp
loop checking the amount of sources in the session.

https://bugzilla.gnome.org/show_bug.cgi?id=773218
This commit is contained in:
Alejandro G. Castro 2016-10-26 13:21:29 +02:00 committed by Sebastian Dröge
parent cd71e3a8e8
commit eeea2a7fe8
3 changed files with 21 additions and 17 deletions

View file

@ -293,7 +293,7 @@ static GstFlowReturn gst_rtp_session_process_rtp (RTPSession * sess,
static GstFlowReturn gst_rtp_session_send_rtp (RTPSession * sess, static GstFlowReturn gst_rtp_session_send_rtp (RTPSession * sess,
RTPSource * src, gpointer data, gpointer user_data); RTPSource * src, gpointer data, gpointer user_data);
static GstFlowReturn gst_rtp_session_send_rtcp (RTPSession * sess, static GstFlowReturn gst_rtp_session_send_rtcp (RTPSession * sess,
RTPSource * src, GstBuffer * buffer, gboolean eos, gpointer user_data); RTPSource * src, GstBuffer * buffer, gpointer user_data);
static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess, static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
GstBuffer * buffer, gpointer user_data); GstBuffer * buffer, gpointer user_data);
static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload, static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
@ -1156,6 +1156,22 @@ rtcp_thread (GstRtpSession * rtpsession)
GST_RTP_SESSION_UNLOCK (rtpsession); GST_RTP_SESSION_UNLOCK (rtpsession);
rtp_session_on_timeout (session, current_time, ntpnstime, running_time); rtp_session_on_timeout (session, current_time, ntpnstime, running_time);
GST_RTP_SESSION_LOCK (rtpsession); GST_RTP_SESSION_LOCK (rtpsession);
if (!rtp_session_get_num_sources (session)) {
/* when no sources left in the session, all of the them have went
* BYE at some point and removed, we can send EOS to the
* pipeline. */
GstPad *rtcp_src = rtpsession->send_rtcp_src;
if (rtcp_src) {
gst_object_ref (rtcp_src);
GST_LOG_OBJECT (rtpsession, "sending EOS");
GST_RTP_SESSION_UNLOCK (rtpsession);
gst_pad_push_event (rtpsession->send_rtcp_src, gst_event_new_eos ());
GST_RTP_SESSION_LOCK (rtpsession);
gst_object_unref (rtcp_src);
}
}
} }
/* mark the thread as stopped now */ /* mark the thread as stopped now */
rtpsession->priv->thread_stopped = TRUE; rtpsession->priv->thread_stopped = TRUE;
@ -1413,11 +1429,10 @@ do_rtcp_events (GstRtpSession * rtpsession, GstPad * srcpad)
} }
/* called when the session manager has an RTCP packet ready for further /* called when the session manager has an RTCP packet ready for further
* sending. The eos flag is set when an EOS event should be sent downstream as * sending. */
* well. */
static GstFlowReturn static GstFlowReturn
gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src, gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
GstBuffer * buffer, gboolean eos, gpointer user_data) GstBuffer * buffer, gpointer user_data)
{ {
GstFlowReturn result; GstFlowReturn result;
GstRtpSession *rtpsession; GstRtpSession *rtpsession;
@ -1440,11 +1455,6 @@ gst_rtp_session_send_rtcp (RTPSession * sess, RTPSource * src,
GST_LOG_OBJECT (rtpsession, "sending RTCP"); GST_LOG_OBJECT (rtpsession, "sending RTCP");
result = gst_pad_push (rtcp_src, buffer); result = gst_pad_push (rtcp_src, buffer);
/* we have to send EOS after this packet */
if (eos) {
GST_LOG_OBJECT (rtpsession, "sending EOS");
gst_pad_push_event (rtcp_src, gst_event_new_eos ());
}
gst_object_unref (rtcp_src); gst_object_unref (rtcp_src);
} else { } else {
GST_RTP_SESSION_UNLOCK (rtpsession); GST_RTP_SESSION_UNLOCK (rtpsession);
@ -2056,7 +2066,6 @@ gst_rtp_session_event_send_rtcp_src (GstPad * pad, GstObject * parent,
return ret; return ret;
} }
static gboolean static gboolean
gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent, gst_rtp_session_event_send_rtp_sink (GstPad * pad, GstObject * parent,
GstEvent * event) GstEvent * event)

View file

@ -3263,7 +3263,6 @@ early_exit:
typedef struct typedef struct
{ {
RTPSource *source; RTPSource *source;
gboolean is_bye;
GstBuffer *buffer; GstBuffer *buffer;
} ReportOutput; } ReportOutput;
@ -3874,7 +3873,6 @@ static void
generate_rtcp (const gchar * key, RTPSource * source, ReportData * data) generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
{ {
RTPSession *sess = data->sess; RTPSession *sess = data->sess;
gboolean is_bye = FALSE;
ReportOutput *output; ReportOutput *output;
/* only generate RTCP for active internal sources */ /* only generate RTCP for active internal sources */
@ -3893,7 +3891,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
if (source->marked_bye) { if (source->marked_bye) {
/* send BYE */ /* send BYE */
make_source_bye (sess, source, data); make_source_bye (sess, source, data);
is_bye = TRUE;
} else if (!data->is_early) { } else if (!data->is_early) {
/* loop over all known sources and add report blocks. If we are early, we /* loop over all known sources and add report blocks. If we are early, we
* just make a minimal RTCP packet and skip this step */ * just make a minimal RTCP packet and skip this step */
@ -3918,7 +3915,6 @@ generate_rtcp (const gchar * key, RTPSource * source, ReportData * data)
output = g_slice_new (ReportOutput); output = g_slice_new (ReportOutput);
output->source = g_object_ref (source); output->source = g_object_ref (source);
output->is_bye = is_bye;
output->buffer = data->rtcp; output->buffer = data->rtcp;
/* queue the RTCP packet to push later */ /* queue the RTCP packet to push later */
g_queue_push_tail (&data->output, output); g_queue_push_tail (&data->output, output);
@ -4098,7 +4094,7 @@ done:
GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats, GST_DEBUG ("%p, sending RTCP packet, avg size %u, %u", &sess->stats,
sess->stats.avg_rtcp_packet_size, packet_size); sess->stats.avg_rtcp_packet_size, packet_size);
result = result =
sess->callbacks.send_rtcp (sess, source, buffer, output->is_bye, sess->callbacks.send_rtcp (sess, source, buffer,
sess->send_rtcp_user_data); sess->send_rtcp_user_data);
RTP_SESSION_LOCK (sess); RTP_SESSION_LOCK (sess);

View file

@ -71,7 +71,6 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
* @sess: an #RTPSession * @sess: an #RTPSession
* @src: the #RTPSource * @src: the #RTPSource
* @buffer: the RTCP buffer ready for sending * @buffer: the RTCP buffer ready for sending
* @eos: if an EOS event should be pushed
* @user_data: user data specified when registering * @user_data: user data specified when registering
* *
* This callback will be called when @sess has @buffer ready for sending to * This callback will be called when @sess has @buffer ready for sending to
@ -80,7 +79,7 @@ typedef GstFlowReturn (*RTPSessionSendRTP) (RTPSession *sess, RTPSource *src, gp
* Returns: a #GstFlowReturn. * Returns: a #GstFlowReturn.
*/ */
typedef GstFlowReturn (*RTPSessionSendRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer, typedef GstFlowReturn (*RTPSessionSendRTCP) (RTPSession *sess, RTPSource *src, GstBuffer *buffer,
gboolean eos, gpointer user_data); gpointer user_data);
/** /**
* RTPSessionSyncRTCP: * RTPSessionSyncRTCP: