summaryrefslogtreecommitdiff
path: root/pjmedia/src/pjmedia/vid_stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjmedia/src/pjmedia/vid_stream.c')
-rw-r--r--pjmedia/src/pjmedia/vid_stream.c61
1 files changed, 59 insertions, 2 deletions
diff --git a/pjmedia/src/pjmedia/vid_stream.c b/pjmedia/src/pjmedia/vid_stream.c
index a813758e..af5a08dc 100644
--- a/pjmedia/src/pjmedia/vid_stream.c
+++ b/pjmedia/src/pjmedia/vid_stream.c
@@ -153,8 +153,11 @@ struct pjmedia_vid_stream
#endif
pjmedia_vid_codec *codec; /**< Codec instance being used. */
- pj_uint32_t last_dec_ts; /**< Last decoded timestamp. */
- int last_dec_seq; /**< Last decoded sequence. */
+ pj_uint32_t last_dec_ts; /**< Last decoded timestamp. */
+ int last_dec_seq; /**< Last decoded sequence. */
+
+
+ pj_timestamp ts_freq; /**< Timestamp frequency. */
};
/* Prototypes */
@@ -768,6 +771,8 @@ static pj_status_t put_frame(pjmedia_port *port,
pj_bool_t has_more_data = PJ_FALSE;
pj_size_t total_sent = 0;
pjmedia_vid_encode_opt enc_opt;
+ unsigned pkt_cnt = 0;
+ pj_timestamp initial_time;
#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
/* If the interval since last sending packet is greater than
@@ -826,6 +831,8 @@ static pj_status_t put_frame(pjmedia_port *port,
&rtphdrlen);
return status;
}
+
+ pj_get_timestamp(&initial_time);
/* Loop while we have frame to send */
for (;;) {
@@ -864,6 +871,7 @@ static pj_status_t put_frame(pjmedia_port *port,
pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);
total_sent += frame_out.size;
+ pkt_cnt++;
if (!has_more_data)
break;
@@ -885,8 +893,41 @@ static pj_status_t put_frame(pjmedia_port *port,
/* Ignore this error (?) */
break;
}
+
+ /* Send rate control */
+ if (stream->info.rc_cfg.method==PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING)
+ {
+ pj_timestamp now, next_send_ts, total_send_ts;
+
+ total_send_ts.u64 = total_sent * stream->ts_freq.u64 * 8 /
+ stream->info.rc_cfg.bandwidth;
+ next_send_ts = initial_time;
+ pj_add_timestamp(&next_send_ts, &total_send_ts);
+
+ pj_get_timestamp(&now);
+ if (pj_cmp_timestamp(&now, &next_send_ts) < 0) {
+ unsigned ms_sleep;
+ ms_sleep = pj_elapsed_msec(&now, &next_send_ts);
+
+ if (ms_sleep > 10)
+ ms_sleep = 10;
+
+ pj_thread_sleep(ms_sleep);
+ }
+ }
}
+#if 0
+ /* Trace log for rate control */
+ {
+ pj_timestamp end_time;
+ pj_get_timestamp(&end_time);
+ PJ_LOG(5, (stream->name.ptr, "total pkt=%d size=%d sleep=%d",
+ pkt_cnt, total_sent,
+ pj_elapsed_msec(&initial_time, &end_time)));
+ }
+#endif
+
/* Check if now is the time to transmit RTCP SR/RR report.
* We only do this when stream direction is not "decoding only", because
* when it is, check_tx_rtcp() will be handled by get_frame().
@@ -1413,6 +1454,11 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_create(
stream->frame_ts_len = info->codec_info.clock_rate *
vfd_enc->fps.denum / vfd_enc->fps.num;
+ /* Initialize send rate states */
+ pj_get_timestamp_freq(&stream->ts_freq);
+ if (info->rc_cfg.bandwidth == 0)
+ info->rc_cfg.bandwidth = vfd_enc->max_bps * 150 / 100;
+
/* Override the initial framerate in the decoding direction. This initial
* value will be used by the renderer to configure its clock, and setting
* it to a bit higher value can avoid the possibility of high latency
@@ -1867,4 +1913,15 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_send_rtcp_bye(
}
+/*
+ * Initialize the video stream rate control with default settings.
+ */
+PJ_DEF(void)
+pjmedia_vid_stream_rc_config_default(pjmedia_vid_stream_rc_config *cfg)
+{
+ pj_bzero(cfg, sizeof(*cfg));
+ cfg->method = PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING;
+}
+
+
#endif /* PJMEDIA_HAS_VIDEO */