RTPSource * src, GstBuffer * buffer, gboolean eos, gpointer user_data);
static GstFlowReturn gst_rtp_session_sync_rtcp (RTPSession * sess,
GstBuffer * buffer, gpointer user_data);
-static gint gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
+static GstCaps *gst_rtp_session_caps (RTPSession * sess, guint8 payload,
gpointer user_data);
static void gst_rtp_session_reconsider (RTPSession * sess, gpointer user_data);
static void gst_rtp_session_request_key_unit (RTPSession * sess, guint32 ssrc,
gst_rtp_session_send_rtp,
gst_rtp_session_sync_rtcp,
gst_rtp_session_send_rtcp,
- gst_rtp_session_clock_rate,
+ gst_rtp_session_caps,
gst_rtp_session_reconsider,
gst_rtp_session_request_key_unit,
gst_rtp_session_request_time,
}
/* called when the session manager needs the clock rate */
-static gint
-gst_rtp_session_clock_rate (RTPSession * sess, guint8 payload,
- gpointer user_data)
+static GstCaps *
+gst_rtp_session_caps (RTPSession * sess, guint8 payload, gpointer user_data)
{
- gint result = -1;
- GstRtpSession *rtpsession;
- GstCaps *caps;
- const GstStructure *s;
-
- rtpsession = GST_RTP_SESSION_CAST (user_data);
-
- caps = gst_rtp_session_get_caps_for_pt (rtpsession, payload);
-
- if (!caps)
- goto done;
-
- s = gst_caps_get_structure (caps, 0);
- if (!gst_structure_get_int (s, "clock-rate", &result))
- goto no_clock_rate;
+ GstRtpSession *rtpsession = GST_RTP_SESSION_CAST (user_data);
- gst_caps_unref (caps);
-
- GST_DEBUG_OBJECT (rtpsession, "parsed clock-rate %d", result);
-
-done:
-
- return result;
-
- /* ERRORS */
-no_clock_rate:
- {
- gst_caps_unref (caps);
- GST_DEBUG_OBJECT (rtpsession, "No clock-rate in caps!");
- goto done;
- }
+ return gst_rtp_session_get_caps_for_pt (rtpsession, payload);
}
/* called when the session manager asks us to reconsider the timeout */
sess->callbacks.sync_rtcp = callbacks->sync_rtcp;
sess->sync_rtcp_user_data = user_data;
}
- if (callbacks->clock_rate) {
- sess->callbacks.clock_rate = callbacks->clock_rate;
- sess->clock_rate_user_data = user_data;
+ if (callbacks->caps) {
+ sess->callbacks.caps = callbacks->caps;
+ sess->caps_user_data = user_data;
}
if (callbacks->reconsider) {
sess->callbacks.reconsider = callbacks->reconsider;
}
/**
- * rtp_session_set_clock_rate_callback:
+ * rtp_session_set_caps_callback:
* @sess: an #RTPSession
* @callback: callback to set
* @user_data: user data passed in the callback
* Configure only the clock_rate callback to be notified of the clock_rate action.
*/
void
-rtp_session_set_clock_rate_callback (RTPSession * sess,
- RTPSessionClockRate callback, gpointer user_data)
+rtp_session_set_caps_callback (RTPSession * sess,
+ RTPSessionCaps callback, gpointer user_data)
{
g_return_if_fail (RTP_IS_SESSION (sess));
- sess->callbacks.clock_rate = callback;
- sess->clock_rate_user_data = user_data;
+ sess->callbacks.caps = callback;
+ sess->caps_user_data = user_data;
}
/**
return result;
}
-static gint
-source_clock_rate (RTPSource * source, guint8 pt, RTPSession * session)
+static GstCaps *
+source_caps (RTPSource * source, guint8 pt, RTPSession * session)
{
- gint result;
+ GstCaps *result = NULL;
RTP_SESSION_UNLOCK (session);
- if (session->callbacks.clock_rate)
- result =
- session->callbacks.clock_rate (session, pt,
- session->clock_rate_user_data);
- else
- result = -1;
+ if (session->callbacks.caps)
+ result = session->callbacks.caps (session, pt, session->caps_user_data);
RTP_SESSION_LOCK (session);
- GST_DEBUG ("got clock-rate %d for pt %d", result, pt);
+ GST_DEBUG ("got caps %" GST_PTR_FORMAT " for pt %d", result, pt);
return result;
}
static RTPSourceCallbacks callbacks = {
(RTPSourcePushRTP) source_push_rtp,
- (RTPSourceClockRate) source_clock_rate,
+ (RTPSourceCaps) source_caps,
};
source->validated = TRUE;
source->internal = TRUE;
- source->probation = FALSE;
+ source->probation = 0;
+ source->curr_probation = 0;
rtp_source_set_sdes_struct (source, gst_structure_copy (sess->sdes));
rtp_source_set_callbacks (source, &callbacks, sess);
typedef GstFlowReturn (*RTPSessionSyncRTCP) (RTPSession *sess, GstBuffer *buffer, gpointer user_data);
/**
- * RTPSessionClockRate:
+ * RTPSessionCaps:
* @sess: an #RTPSession
* @payload: the payload
* @user_data: user data specified when registering
*
- * This callback will be called when @sess needs the clock-rate of @payload.
+ * This callback will be called when @sess needs the caps of @payload.
*
- * Returns: the clock-rate of @pt.
+ * Returns: the caps of @pt.
*/
-typedef gint (*RTPSessionClockRate) (RTPSession *sess, guint8 payload, gpointer user_data);
+typedef GstCaps * (*RTPSessionCaps) (RTPSession *sess, guint8 payload, gpointer user_data);
/**
* RTPSessionReconsider:
RTPSessionSendRTP send_rtp;
RTPSessionSyncRTCP sync_rtcp;
RTPSessionSendRTCP send_rtcp;
- RTPSessionClockRate clock_rate;
+ RTPSessionCaps caps;
RTPSessionReconsider reconsider;
RTPSessionRequestKeyUnit request_key_unit;
RTPSessionRequestTime request_time;
gpointer send_rtp_user_data;
gpointer send_rtcp_user_data;
gpointer sync_rtcp_user_data;
- gpointer clock_rate_user_data;
+ gpointer caps_user_data;
gpointer reconsider_user_data;
gpointer request_key_unit_user_data;
gpointer request_time_user_data;
void rtp_session_set_sync_rtcp_callback (RTPSession * sess,
RTPSessionSyncRTCP callback,
gpointer user_data);
-void rtp_session_set_clock_rate_callback (RTPSession * sess,
- RTPSessionClockRate callback,
+void rtp_session_set_caps_callback (RTPSession * sess,
+ RTPSessionCaps callback,
gpointer user_data);
void rtp_session_set_reconsider_callback (RTPSession * sess,
RTPSessionReconsider callback,
g_free (src->bye_reason);
- gst_caps_replace (&src->send_caps, NULL);
+ gst_caps_replace (&src->caps, NULL);
g_list_free_full (src->conflicting_addresses,
(GDestroyNotify) rtp_conflicting_address_free);
g_return_if_fail (RTP_IS_SOURCE (src));
src->callbacks.push_rtp = cb->push_rtp;
- src->callbacks.clock_rate = cb->clock_rate;
+ src->callbacks.caps = cb->caps;
src->user_data = user_data;
}
gboolean rtx;
/* nothing changed, return */
- if (caps == NULL || src->send_caps == caps)
+ if (caps == NULL || src->caps == caps)
return;
s = gst_caps_get_structure (caps, 0);
GST_DEBUG ("got %sseqnum-offset %" G_GINT32_FORMAT, rtx ? "rtx " : "",
src->seqnum_offset);
- gst_caps_replace (&src->send_caps, caps);
+ gst_caps_replace (&src->caps, caps);
if (rtx) {
src->media_ssrc = ssrc;
}
static void
-fetch_clock_rate_from_payload (RTPSource * src, guint8 payload)
+fetch_caps_for_payload (RTPSource * src, guint8 payload)
{
if (src->payload == -1) {
/* first payload received, nothing was in the caps, lock on to this payload */
src->stats.transit = -1;
}
- if (src->clock_rate == -1) {
- gint clock_rate = -1;
+ if (src->clock_rate == -1 || !src->caps) {
+ GstCaps *caps = NULL;
- if (src->callbacks.clock_rate)
- clock_rate = src->callbacks.clock_rate (src, payload, src->user_data);
+ if (src->callbacks.caps) {
+ caps = src->callbacks.caps (src, payload, src->user_data);
+ }
+
+ GST_DEBUG ("got caps %" GST_PTR_FORMAT, caps);
+
+ if (caps) {
+ const GstStructure *s;
+ gint clock_rate = -1;
+ const gchar *encoding_name;
- GST_DEBUG ("got clock-rate %d", clock_rate);
+ s = gst_caps_get_structure (caps, 0);
+
+ if (gst_structure_get_int (s, "clock-rate", &clock_rate)) {
+ src->clock_rate = clock_rate;
+ gst_rtp_packet_rate_ctx_reset (&src->packet_rate_ctx, clock_rate);
+ } else {
+ GST_DEBUG ("No clock-rate in caps!");
+ }
+
+ encoding_name = gst_structure_get_string (s, "encoding-name");
+ /* Disable probation for RTX sources as packets will arrive very
+ * irregularly and waiting for a second packet usually exceeds the
+ * deadline of the retransmission */
+ if (g_strcmp0 (encoding_name, "rtx") == 0) {
+ src->probation = src->curr_probation = 0;
+ }
+ }
- src->clock_rate = clock_rate;
- gst_rtp_packet_rate_ctx_reset (&src->packet_rate_ctx, clock_rate);
+ gst_caps_replace (&src->caps, caps);
+ gst_clear_caps (&caps);
}
}
g_return_val_if_fail (RTP_IS_SOURCE (src), GST_FLOW_ERROR);
g_return_val_if_fail (pinfo != NULL, GST_FLOW_ERROR);
- fetch_clock_rate_from_payload (src, pinfo->pt);
+ fetch_caps_for_payload (src, pinfo->pt);
if (!update_receiver_stats (src, pinfo, TRUE))
return GST_FLOW_OK;
if (src->clock_rate == -1 && src->pt_set) {
GST_INFO ("no clock-rate, getting for pt %u and SSRC %u", src->pt,
src->ssrc);
- fetch_clock_rate_from_payload (src, src->pt);
+ fetch_caps_for_payload (src, src->pt);
}
if (src->clock_rate != -1) {
gpointer user_data);
/**
- * RTPSourceClockRate:
+ * RTPSourceCaps:
* @src: an #RTPSource
* @payload: a payload type
* @user_data: user data specified when registering
*
- * This callback will be called when @src needs the clock-rate of the
+ * This callback will be called when @src needs the caps of the
* @payload.
*
- * Returns: a clock-rate for @payload.
+ * Returns: a caps for @payload.
*/
-typedef gint (*RTPSourceClockRate) (RTPSource *src, guint8 payload, gpointer user_data);
+typedef GstCaps * (*RTPSourceCaps) (RTPSource *src, guint8 payload, gpointer user_data);
/**
* RTPSourceCallbacks:
* @push_rtp: a packet becomes available for handling
- * @clock_rate: a clock-rate is requested
+ * @caps: a caps is requested
* @get_time: the current clock time is requested
*
* Callbacks performed by #RTPSource when actions need to be performed.
*/
typedef struct {
RTPSourcePushRTP push_rtp;
- RTPSourceClockRate clock_rate;
+ RTPSourceCaps caps;
} RTPSourceCallbacks;
/**
GSocketAddress *rtcp_from;
gint payload;
- GstCaps *send_caps;
+ GstCaps *caps;
gint clock_rate;
gint32 seqnum_offset;