gst_structure_set ((GstStructure *) s, "session", G_TYPE_UINT,
sess->id, NULL);
}
- GST_RTP_BIN_UNLOCK (rtpbin);
}
GST_BIN_CLASS (parent_class)->handle_message (bin, message);
break;
{
gint percent;
gint min_percent = 100;
- GSList *sessions, *streams, *elements = NULL;
+ GSList *sessions, *streams;
GstRtpBinStream *stream;
gboolean change = FALSE, active = FALSE;
GstClockTime min_out_time;
for (streams = session->streams; streams;
streams = g_slist_next (streams)) {
GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
- GstElement *element = stream->buffer;
GST_DEBUG_OBJECT (bin, "stream %p percent %d", stream,
stream->percent);
/* find min percent */
if (min_percent > stream->percent)
min_percent = stream->percent;
-
- elements = g_slist_prepend (elements, gst_object_ref (element));
}
GST_RTP_SESSION_UNLOCK (session);
}
"running time now %" GST_TIME_FORMAT,
GST_TIME_ARGS (running_time));
+ GST_RTP_BIN_LOCK (rtpbin);
+
/* when we reactivate, calculate the offsets so that all streams have
* an output time that is at least as big as the running_time */
offset = 0;
}
}
+ /* pause all streams */
min_out_time = -1;
- while (G_LIKELY (elements)) {
- GstElement *element = elements->data;
- GstClockTime last_out;
-
- g_signal_emit_by_name (element, "set-active", active, offset,
- &last_out);
-
- if (!active) {
- if (last_out == -1)
- last_out = 0;
- if (last_out < min_out_time)
- min_out_time = last_out;
+ for (sessions = rtpbin->sessions; sessions;
+ sessions = g_slist_next (sessions)) {
+ GstRtpBinSession *session = (GstRtpBinSession *) sessions->data;
+
+ GST_RTP_SESSION_LOCK (session);
+ for (streams = session->streams; streams;
+ streams = g_slist_next (streams)) {
+ GstRtpBinStream *stream = (GstRtpBinStream *) streams->data;
+ GstElement *element = stream->buffer;
+ guint64 last_out;
+
+ g_signal_emit_by_name (element, "set-active", active, offset,
+ &last_out);
+
+ if (!active) {
+ g_object_get (element, "percent", &stream->percent, NULL);
+
+ if (last_out == -1)
+ last_out = 0;
+ if (last_out < min_out_time)
+ min_out_time = last_out;
+ }
+
+ GST_DEBUG_OBJECT (bin,
+ "setting %p to %d, offset %" GST_TIME_FORMAT ", last %"
+ GST_TIME_FORMAT ", percent %d", element, active,
+ GST_TIME_ARGS (offset), GST_TIME_ARGS (last_out),
+ stream->percent);
}
-
- GST_DEBUG_OBJECT (bin,
- "setting %p to %d, offset %" GST_TIME_FORMAT ", last %"
- GST_TIME_FORMAT, element, active, GST_TIME_ARGS (offset),
- GST_TIME_ARGS (last_out));
-
- gst_object_unref (element);
- elements = g_slist_delete_link (elements, elements);
+ GST_RTP_SESSION_UNLOCK (session);
}
GST_DEBUG_OBJECT (bin,
"min out time %" GST_TIME_FORMAT, GST_TIME_ARGS (min_out_time));
/* the buffer_start is the min out time of all paused jitterbuffers */
if (!active)
rtpbin->buffer_start = min_out_time;
+
+ GST_RTP_BIN_UNLOCK (rtpbin);
}
}
GST_BIN_CLASS (parent_class)->handle_message (bin, message);
#define DEFAULT_TS_OFFSET 0
#define DEFAULT_DO_LOST FALSE
#define DEFAULT_MODE RTP_JITTER_BUFFER_MODE_SLAVE
+#define DEFAULT_PERCENT 0
enum
{
PROP_TS_OFFSET,
PROP_DO_LOST,
PROP_MODE,
+ PROP_PERCENT,
PROP_LAST
};
g_param_spec_enum ("mode", "Mode",
"Control the buffering algorithm in use", RTP_TYPE_JITTER_BUFFER_MODE,
DEFAULT_MODE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ /**
+ * GstRtpJitterBuffer::percent:
+ *
+ * The percent of the jitterbuffer that is filled.
+ */
+ g_object_class_install_property (gobject_class, PROP_PERCENT,
+ g_param_spec_int ("percent", "percent",
+ "The buffer filled percent", 0, 100,
+ 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GstRtpJitterBuffer::request-pt-map:
* @buffer: the object which received the signal
priv->active = active;
JBUF_SIGNAL (priv);
}
+ if (!active) {
+ rtp_jitter_buffer_set_buffering (priv->jbuf, TRUE);
+ }
if ((head = rtp_jitter_buffer_peek (priv->jbuf))) {
/* head buffer timestamp and offset gives our output time */
last_out = GST_BUFFER_TIMESTAMP (head) + priv->ts_offset;
g_value_set_enum (value, rtp_jitter_buffer_get_mode (priv->jbuf));
JBUF_UNLOCK (priv);
break;
+ case PROP_PERCENT:
+ {
+ gint percent;
+
+ JBUF_LOCK (priv);
+ if (priv->srcresult != GST_FLOW_OK)
+ percent = 100;
+ else
+ percent = rtp_jitter_buffer_get_percent (priv->jbuf);
+
+ g_value_set_int (value, percent);
+ JBUF_UNLOCK (priv);
+ break;
+ }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
jbuf->high_level = (delay * 90) / 100;
GST_DEBUG ("delay %" GST_TIME_FORMAT ", min %" GST_TIME_FORMAT ", max %"
- GST_TIME_FORMAT, GST_TIME_ARGS (jbuf->level),
+ GST_TIME_FORMAT, GST_TIME_ARGS (jbuf->delay),
GST_TIME_ARGS (jbuf->low_level), GST_TIME_ARGS (jbuf->high_level));
}
}
}
-static void
-update_buffer_level (RTPJitterBuffer * jbuf, gint * percent)
+static guint64
+get_buffer_level (RTPJitterBuffer * jbuf)
{
GstBuffer *high_buf, *low_buf;
- gboolean post = FALSE;
+ guint64 level;
high_buf = g_queue_peek_head (jbuf->packets);
low_buf = g_queue_peek_tail (jbuf->packets);
if (!high_buf || !low_buf || high_buf == low_buf) {
- jbuf->level = 0;
+ level = 0;
} else {
guint64 high_ts, low_ts;
low_ts = GST_BUFFER_TIMESTAMP (low_buf);
if (high_ts > low_ts)
- jbuf->level = high_ts - low_ts;
+ level = high_ts - low_ts;
else
- jbuf->level = 0;
+ level = 0;
}
- GST_DEBUG ("buffer level %" GST_TIME_FORMAT, GST_TIME_ARGS (jbuf->level));
+ return level;
+}
+
+static void
+update_buffer_level (RTPJitterBuffer * jbuf, gint * percent)
+{
+ gboolean post = FALSE;
+ guint64 level;
+
+ level = get_buffer_level (jbuf);
+ GST_DEBUG ("buffer level %" GST_TIME_FORMAT, GST_TIME_ARGS (level));
if (jbuf->buffering) {
post = TRUE;
- if (jbuf->level > jbuf->high_level) {
+ if (level > jbuf->high_level) {
GST_DEBUG ("buffering finished");
jbuf->buffering = FALSE;
}
} else {
- if (jbuf->level < jbuf->low_level) {
+ if (level < jbuf->low_level) {
GST_DEBUG ("buffering started");
jbuf->buffering = TRUE;
post = TRUE;
gint perc;
if (jbuf->buffering) {
- perc = (jbuf->level * 100 / jbuf->high_level);
+ perc = (level * 100 / jbuf->high_level);
perc = MIN (perc, 100);
} else {
perc = 100;
*/
static GstClockTime
calculate_skew (RTPJitterBuffer * jbuf, guint32 rtptime, GstClockTime time,
- guint32 clock_rate, GstClockTime max_delay)
+ guint32 clock_rate)
{
guint64 ext_rtptime;
guint64 send_diff, recv_diff;
return jbuf->buffering;
}
+/**
+ * rtp_jitter_buffer_set_buffering:
+ * @jbuf: an #RTPJitterBuffer
+ * @buffering: the new buffering state
+ *
+ * Forces @jbuf to go into the buffering state.
+ */
+void
+rtp_jitter_buffer_set_buffering (RTPJitterBuffer * jbuf, gboolean buffering)
+{
+ jbuf->buffering = buffering;
+}
+
+/**
+ * rtp_jitter_buffer_get_percent:
+ * @jbuf: an #RTPJitterBuffer
+ *
+ * Get the buffering percent of the jitterbuffer.
+ *
+ * Returns: the buffering percent
+ */
+gint
+rtp_jitter_buffer_get_percent (RTPJitterBuffer * jbuf)
+{
+ gint percent;
+ guint64 level;
+
+ level = get_buffer_level (jbuf);
+ percent = (level * 100 / jbuf->high_level);
+ percent = MIN (percent, 100);
+
+ return percent;
+}
+
/**
* rtp_jitter_buffer_num_packets:
* @jbuf: an #RTPJitterBuffer
/* for buffering */
gboolean buffering;
- guint64 level;
guint64 low_level;
guint64 high_level;
void rtp_jitter_buffer_flush (RTPJitterBuffer *jbuf);
gboolean rtp_jitter_buffer_is_buffering (RTPJitterBuffer * jbuf);
+void rtp_jitter_buffer_set_buffering (RTPJitterBuffer * jbuf, gboolean buffering);
+gint rtp_jitter_buffer_get_percent (RTPJitterBuffer * jbuf);
guint rtp_jitter_buffer_num_packets (RTPJitterBuffer *jbuf);
guint32 rtp_jitter_buffer_get_ts_diff (RTPJitterBuffer *jbuf);