mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 09:55:36 +00:00
rtpsession: relate received FIRs and PLIs to source
This is needed in order to: - Avoid ignoring requests for different media sources. - Add SSRC field in the GstForceKeyUnit event. https://bugzilla.gnome.org/show_bug.cgi?id=778013
This commit is contained in:
parent
19c9600ea6
commit
3aa69ca0bb
5 changed files with 26 additions and 24 deletions
|
@ -299,7 +299,7 @@ static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
|
||||||
static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
|
static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data);
|
static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data);
|
||||||
static void gst_rtp_session_request_key_unit (RTPSession * sess,
|
static void gst_rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc,
|
||||||
gboolean all_headers, gpointer user_data);
|
gboolean all_headers, gpointer user_data);
|
||||||
static GstClockTime gst_rtp_session_request_time (RTPSession * session,
|
static GstClockTime gst_rtp_session_request_time (RTPSession * session,
|
||||||
gpointer user_data);
|
gpointer user_data);
|
||||||
|
@ -2647,7 +2647,7 @@ wrong_pad:
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_session_request_key_unit (RTPSession * sess,
|
gst_rtp_session_request_key_unit (RTPSession * sess,
|
||||||
gboolean all_headers, gpointer user_data)
|
guint32 ssrc, gboolean all_headers, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstRtpSession *rtpsession = GST_RTP_SESSION (user_data);
|
GstRtpSession *rtpsession = GST_RTP_SESSION (user_data);
|
||||||
GstEvent *event;
|
GstEvent *event;
|
||||||
|
@ -2660,7 +2660,7 @@ gst_rtp_session_request_key_unit (RTPSession * sess,
|
||||||
|
|
||||||
if (send_rtp_sink) {
|
if (send_rtp_sink) {
|
||||||
event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
|
event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
|
||||||
gst_structure_new ("GstForceKeyUnit",
|
gst_structure_new ("GstForceKeyUnit", "ssrc", G_TYPE_UINT, ssrc,
|
||||||
"all-headers", G_TYPE_BOOLEAN, all_headers, NULL));
|
"all-headers", G_TYPE_BOOLEAN, all_headers, NULL));
|
||||||
gst_pad_push_event (send_rtp_sink, event);
|
gst_pad_push_event (send_rtp_sink, event);
|
||||||
gst_object_unref (send_rtp_sink);
|
gst_object_unref (send_rtp_sink);
|
||||||
|
|
|
@ -662,8 +662,6 @@ rtp_session_init (RTPSession * sess)
|
||||||
sess->rtp_profile = DEFAULT_RTP_PROFILE;
|
sess->rtp_profile = DEFAULT_RTP_PROFILE;
|
||||||
sess->reduced_size_rtcp = DEFAULT_RTCP_REDUCED_SIZE;
|
sess->reduced_size_rtcp = DEFAULT_RTCP_REDUCED_SIZE;
|
||||||
|
|
||||||
sess->last_keyframe_request = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
sess->is_doing_ptp = TRUE;
|
sess->is_doing_ptp = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2565,13 +2563,13 @@ rtp_session_process_app (RTPSession * sess, GstRTCPPacket * packet,
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
|
rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
|
||||||
gboolean fir, GstClockTime current_time)
|
guint32 media_ssrc, gboolean fir, GstClockTime current_time)
|
||||||
{
|
{
|
||||||
guint32 round_trip = 0;
|
guint32 round_trip = 0;
|
||||||
|
|
||||||
rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, &round_trip);
|
rtp_source_get_last_rb (src, NULL, NULL, NULL, NULL, NULL, NULL, &round_trip);
|
||||||
|
|
||||||
if (sess->last_keyframe_request != GST_CLOCK_TIME_NONE && round_trip) {
|
if (src->last_keyframe_request != GST_CLOCK_TIME_NONE && round_trip) {
|
||||||
GstClockTime round_trip_in_ns = gst_util_uint64_scale (round_trip,
|
GstClockTime round_trip_in_ns = gst_util_uint64_scale (round_trip,
|
||||||
GST_SECOND, 65536);
|
GST_SECOND, 65536);
|
||||||
|
|
||||||
|
@ -2580,24 +2578,24 @@ rtp_session_request_local_key_unit (RTPSession * sess, RTPSource * src,
|
||||||
if (round_trip_in_ns > 5 * GST_SECOND)
|
if (round_trip_in_ns > 5 * GST_SECOND)
|
||||||
round_trip_in_ns = GST_SECOND / 2;
|
round_trip_in_ns = GST_SECOND / 2;
|
||||||
|
|
||||||
if (current_time - sess->last_keyframe_request < 2 * round_trip_in_ns) {
|
if (current_time - src->last_keyframe_request < 2 * round_trip_in_ns) {
|
||||||
GST_DEBUG ("Ignoring %s request because one was send without one "
|
GST_DEBUG ("Ignoring %s request from %X because one was send without one "
|
||||||
"RTT (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")",
|
"RTT (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")",
|
||||||
fir ? "FIR" : "PLI",
|
fir ? "FIR" : "PLI", rtp_source_get_ssrc (src),
|
||||||
GST_TIME_ARGS (current_time - sess->last_keyframe_request),
|
GST_TIME_ARGS (current_time - src->last_keyframe_request),
|
||||||
GST_TIME_ARGS (round_trip_in_ns));
|
GST_TIME_ARGS (round_trip_in_ns));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sess->last_keyframe_request = current_time;
|
src->last_keyframe_request = current_time;
|
||||||
|
|
||||||
GST_LOG ("received %s request from %X %p(%p)", fir ? "FIR" : "PLI",
|
GST_LOG ("received %s request from %X about %X %p(%p)", fir ? "FIR" : "PLI",
|
||||||
rtp_source_get_ssrc (src), sess->callbacks.process_rtp,
|
rtp_source_get_ssrc (src), media_ssrc, sess->callbacks.process_rtp,
|
||||||
sess->callbacks.request_key_unit);
|
sess->callbacks.request_key_unit);
|
||||||
|
|
||||||
RTP_SESSION_UNLOCK (sess);
|
RTP_SESSION_UNLOCK (sess);
|
||||||
sess->callbacks.request_key_unit (sess, fir,
|
sess->callbacks.request_key_unit (sess, media_ssrc, fir,
|
||||||
sess->request_key_unit_user_data);
|
sess->request_key_unit_user_data);
|
||||||
RTP_SESSION_LOCK (sess);
|
RTP_SESSION_LOCK (sess);
|
||||||
|
|
||||||
|
@ -2617,12 +2615,14 @@ rtp_session_process_pli (RTPSession * sess, guint32 sender_ssrc,
|
||||||
if (src == NULL)
|
if (src == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rtp_session_request_local_key_unit (sess, src, FALSE, current_time);
|
rtp_session_request_local_key_unit (sess, src, media_ssrc, FALSE,
|
||||||
|
current_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
||||||
guint8 * fci_data, guint fci_length, GstClockTime current_time)
|
guint32 media_ssrc, guint8 * fci_data, guint fci_length,
|
||||||
|
GstClockTime current_time)
|
||||||
{
|
{
|
||||||
RTPSource *src;
|
RTPSource *src;
|
||||||
guint32 ssrc;
|
guint32 ssrc;
|
||||||
|
@ -2673,7 +2673,8 @@ rtp_session_process_fir (RTPSession * sess, guint32 sender_ssrc,
|
||||||
if (!our_request)
|
if (!our_request)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rtp_session_request_local_key_unit (sess, src, TRUE, current_time);
|
rtp_session_request_local_key_unit (sess, src, media_ssrc, TRUE,
|
||||||
|
current_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2764,8 +2765,8 @@ rtp_session_process_feedback (RTPSession * sess, GstRTCPPacket * packet,
|
||||||
case GST_RTCP_PSFB_TYPE_FIR:
|
case GST_RTCP_PSFB_TYPE_FIR:
|
||||||
if (src)
|
if (src)
|
||||||
src->stats.recv_fir_count++;
|
src->stats.recv_fir_count++;
|
||||||
rtp_session_process_fir (sess, sender_ssrc, fci_data, fci_length,
|
rtp_session_process_fir (sess, sender_ssrc, media_ssrc, fci_data,
|
||||||
current_time);
|
fci_length, current_time);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -120,6 +120,7 @@ typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data);
|
||||||
/**
|
/**
|
||||||
* RTPSessionRequestKeyUnit:
|
* RTPSessionRequestKeyUnit:
|
||||||
* @sess: an #RTPSession
|
* @sess: an #RTPSession
|
||||||
|
* @ssrc: SSRC of the source related to the key unit request
|
||||||
* @all_headers: %TRUE if "all-headers" property should be set on the key unit
|
* @all_headers: %TRUE if "all-headers" property should be set on the key unit
|
||||||
* request
|
* request
|
||||||
* @user_data: user data specified when registering
|
* @user_data: user data specified when registering
|
||||||
|
@ -127,7 +128,7 @@ typedef void (*RTPSessionReconsider) (RTPSession *sess, gpointer user_data);
|
||||||
* Asks the encoder to produce a key unit as soon as possibly within the
|
* Asks the encoder to produce a key unit as soon as possibly within the
|
||||||
* bandwidth constraints
|
* bandwidth constraints
|
||||||
*/
|
*/
|
||||||
typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess,
|
typedef void (*RTPSessionRequestKeyUnit) (RTPSession *sess, guint32 ssrc,
|
||||||
gboolean all_headers, gpointer user_data);
|
gboolean all_headers, gpointer user_data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,9 +276,6 @@ struct _RTPSession {
|
||||||
GstClockTime rtcp_feedback_retention_window;
|
GstClockTime rtcp_feedback_retention_window;
|
||||||
guint rtcp_immediate_feedback_threshold;
|
guint rtcp_immediate_feedback_threshold;
|
||||||
|
|
||||||
GstClockTime last_keyframe_request;
|
|
||||||
gboolean last_keyframe_all_headers;
|
|
||||||
|
|
||||||
gboolean is_doing_ptp;
|
gboolean is_doing_ptp;
|
||||||
|
|
||||||
GList *conflicting_addresses;
|
GList *conflicting_addresses;
|
||||||
|
|
|
@ -301,6 +301,8 @@ rtp_source_init (RTPSource * src)
|
||||||
|
|
||||||
src->reported_in_sr_of = g_hash_table_new (g_direct_hash, g_direct_equal);
|
src->reported_in_sr_of = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
|
src->last_keyframe_request = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
rtp_source_reset (src);
|
rtp_source_reset (src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@ struct _RTPSource {
|
||||||
gboolean send_fir;
|
gboolean send_fir;
|
||||||
guint8 current_send_fir_seqnum;
|
guint8 current_send_fir_seqnum;
|
||||||
gint last_fir_count;
|
gint last_fir_count;
|
||||||
|
GstClockTime last_keyframe_request;
|
||||||
|
|
||||||
gboolean send_nack;
|
gboolean send_nack;
|
||||||
GArray *nacks;
|
GArray *nacks;
|
||||||
|
|
Loading…
Reference in a new issue