mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #257, support 0.1s+ latency. 2.0.70
This commit is contained in:
parent
68ade0a267
commit
10297fab51
19 changed files with 179 additions and 30 deletions
|
@ -453,6 +453,7 @@ Supported operating systems and hardware:
|
||||||
[CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_SrsLibrtmp#publish-audio-raw-stream),
|
[CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_SrsLibrtmp#publish-audio-raw-stream),
|
||||||
[EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_SrsLibrtmp#publish-audio-raw-stream)
|
[EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_SrsLibrtmp#publish-audio-raw-stream)
|
||||||
) by srs-librtmp.
|
) by srs-librtmp.
|
||||||
|
1. Support 0.1s+ latency, read [#257](https://github.com/winlinvip/simple-rtmp-server/issues/257).
|
||||||
1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
|
1. [no-plan] Support <500ms latency, FRSC(Fast RTMP-compatible Stream Channel tech).
|
||||||
1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
|
1. [no-plan] Support RTMP 302 redirect [#92](https://github.com/winlinvip/simple-rtmp-server/issues/92).
|
||||||
1. [no-plan] Support multiple processes, for both origin and edge
|
1. [no-plan] Support multiple processes, for both origin and edge
|
||||||
|
@ -486,6 +487,7 @@ Supported operating systems and hardware:
|
||||||
* 2013-10-17, Created.<br/>
|
* 2013-10-17, Created.<br/>
|
||||||
|
|
||||||
## History
|
## History
|
||||||
|
* v2.0, 2014-12-12, fix [#257](https://github.com/winlinvip/simple-rtmp-server/issues/257), support 0.1s+ latency. 2.0.70
|
||||||
* v2.0, 2014-12-08, update wiki for mr([EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_LowLatency#merged-read), [CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_LowLatency#merged-read)) and mw([EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_LowLatency#merged-write), [CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_LowLatency#merged-write)).
|
* v2.0, 2014-12-08, update wiki for mr([EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_LowLatency#merged-read), [CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_LowLatency#merged-read)) and mw([EN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_EN_LowLatency#merged-write), [CN](https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_LowLatency#merged-write)).
|
||||||
* v2.0, 2014-12-07, fix [#251](https://github.com/winlinvip/simple-rtmp-server/issues/251), 10k+ clients, use queue cond wait and fast vector. 2.0.67
|
* v2.0, 2014-12-07, fix [#251](https://github.com/winlinvip/simple-rtmp-server/issues/251), 10k+ clients, use queue cond wait and fast vector. 2.0.67
|
||||||
* v2.0, 2014-12-05, fix [#251](https://github.com/winlinvip/simple-rtmp-server/issues/251), 9k+ clients, use fast cache for msgs queue. 2.0.57
|
* v2.0, 2014-12-05, fix [#251](https://github.com/winlinvip/simple-rtmp-server/issues/251), 9k+ clients, use fast cache for msgs queue. 2.0.57
|
||||||
|
|
|
@ -145,6 +145,13 @@ vhost __defaultVhost__ {
|
||||||
# the MR(merged-read) setting for publisher.
|
# the MR(merged-read) setting for publisher.
|
||||||
# the MW(merged-write) settings for player.
|
# the MW(merged-write) settings for player.
|
||||||
vhost mrw.srs.com {
|
vhost mrw.srs.com {
|
||||||
|
# whether enable min delay mode for vhost.
|
||||||
|
# for min latence mode:
|
||||||
|
# 1. disable the mr for vhost.
|
||||||
|
# 2. use timeout for cond wait for consumer queue.
|
||||||
|
# @see https://github.com/winlinvip/simple-rtmp-server/issues/257
|
||||||
|
# default: on
|
||||||
|
min_latency off;
|
||||||
# about MR, read https://github.com/winlinvip/simple-rtmp-server/issues/241
|
# about MR, read https://github.com/winlinvip/simple-rtmp-server/issues/241
|
||||||
mr {
|
mr {
|
||||||
# whether enable the MR(merged-read)
|
# whether enable the MR(merged-read)
|
||||||
|
@ -440,6 +447,12 @@ vhost debug.srs.com {
|
||||||
|
|
||||||
# the vhost for min delay, donot cache any stream.
|
# the vhost for min delay, donot cache any stream.
|
||||||
vhost min.delay.com {
|
vhost min.delay.com {
|
||||||
|
# @see vhost mrw.srs.com for detail.
|
||||||
|
min_latency on;
|
||||||
|
mr {
|
||||||
|
enabled off;
|
||||||
|
}
|
||||||
|
mw_latency 100;
|
||||||
# whether cache the last gop.
|
# whether cache the last gop.
|
||||||
# if on, cache the last gop and dispatch to client,
|
# if on, cache the last gop and dispatch to client,
|
||||||
# to enabled fast startup for client, client play immediately.
|
# to enabled fast startup for client, client play immediately.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# the config for srs to delivery realtime RTMP stream
|
# the config for srs to delivery realtime RTMP stream
|
||||||
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v1_CN_SampleRealtime
|
# @see https://github.com/winlinvip/simple-rtmp-server/wiki/v2_CN_SampleRealtime
|
||||||
# @see full.conf for detail config.
|
# @see full.conf for detail config.
|
||||||
|
|
||||||
listen 1935;
|
listen 1935;
|
||||||
|
@ -7,6 +7,7 @@ max_connections 1000;
|
||||||
vhost __defaultVhost__ {
|
vhost __defaultVhost__ {
|
||||||
gop_cache off;
|
gop_cache off;
|
||||||
queue_length 10;
|
queue_length 10;
|
||||||
|
min_latency on;
|
||||||
mr {
|
mr {
|
||||||
enabled off;
|
enabled off;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ function SrsPlayer(container, width, height, private_object) {
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.id = SrsPlayer.__id++;
|
this.id = SrsPlayer.__id++;
|
||||||
this.stream_url = null;
|
this.stream_url = null;
|
||||||
this.buffer_time = 0.8; // default to 0.8
|
this.buffer_time = 0.3; // default to 0.3
|
||||||
this.volume = 1.0; // default to 100%
|
this.volume = 1.0; // default to 100%
|
||||||
this.callbackObj = null;
|
this.callbackObj = null;
|
||||||
|
|
||||||
|
|
14
trunk/research/players/srs_player.html
Normal file → Executable file
14
trunk/research/players/srs_player.html
Normal file → Executable file
|
@ -96,7 +96,7 @@
|
||||||
|
|
||||||
srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());
|
srs_player = new SrsPlayer("player_id", srs_get_player_width(), srs_get_player_height());
|
||||||
srs_player.on_player_ready = function() {
|
srs_player.on_player_ready = function() {
|
||||||
select_buffer_time("#btn_bt_0_8", 0.8);
|
select_buffer_time("#btn_bt_0_1", 0.1);
|
||||||
this.play(url);
|
this.play(url);
|
||||||
};
|
};
|
||||||
srs_player.on_player_metadata = function(metadata) {
|
srs_player.on_player_metadata = function(metadata) {
|
||||||
|
@ -231,6 +231,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
|
$("#btn_bt_0_1").click(function(){
|
||||||
|
select_buffer_time("#btn_bt_0_1", 0.1);
|
||||||
|
});
|
||||||
|
$("#btn_bt_0_2").click(function(){
|
||||||
|
select_buffer_time("#btn_bt_0_2", 0.2);
|
||||||
|
});
|
||||||
|
$("#btn_bt_0_3").click(function(){
|
||||||
|
select_buffer_time("#btn_bt_0_3", 0.3);
|
||||||
|
});
|
||||||
$("#btn_bt_0_5").click(function(){
|
$("#btn_bt_0_5").click(function(){
|
||||||
select_buffer_time("#btn_bt_0_5", 0.5);
|
select_buffer_time("#btn_bt_0_5", 0.5);
|
||||||
});
|
});
|
||||||
|
@ -504,6 +513,9 @@
|
||||||
<div class="btn-group dropup">
|
<div class="btn-group dropup">
|
||||||
<button class="btn dropdown-toggle" data-toggle="dropdown">缓冲区<span class="caret"></span></button>
|
<button class="btn dropdown-toggle" data-toggle="dropdown">缓冲区<span class="caret"></span></button>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
|
<li><a id="btn_bt_0_1" href="#">0.1秒(实时)</a></li>
|
||||||
|
<li><a id="btn_bt_0_2" href="#">0.2秒(实时)</a></li>
|
||||||
|
<li><a id="btn_bt_0_3" href="#">0.3秒(实时)</a></li>
|
||||||
<li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li>
|
<li><a id="btn_bt_0_5" href="#">0.5秒(实时)</a></li>
|
||||||
<li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li>
|
<li><a id="btn_bt_0_8" href="#">0.8秒(会议)</a></li>
|
||||||
<li><a id="btn_bt_1" href="#">1秒(低延迟)</a></li>
|
<li><a id="btn_bt_1" href="#">1秒(低延迟)</a></li>
|
||||||
|
|
|
@ -852,6 +852,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
|
||||||
}
|
}
|
||||||
srs_trace("vhost %s reload mw success.", vhost.c_str());
|
srs_trace("vhost %s reload mw success.", vhost.c_str());
|
||||||
}
|
}
|
||||||
|
// min_latency, only one per vhost
|
||||||
|
if (!srs_directive_equals(new_vhost->get("min_latency"), old_vhost->get("min_latency"))) {
|
||||||
|
for (it = subscribes.begin(); it != subscribes.end(); ++it) {
|
||||||
|
ISrsReloadHandler* subscribe = *it;
|
||||||
|
if ((ret = subscribe->on_reload_vhost_realtime(vhost)) != ERROR_SUCCESS) {
|
||||||
|
srs_error("vhost %s notify subscribes min_latency failed. ret=%d", vhost.c_str(), ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
srs_trace("vhost %s reload min_latency success.", vhost.c_str());
|
||||||
|
}
|
||||||
// http, only one per vhost.
|
// http, only one per vhost.
|
||||||
if (!srs_directive_equals(new_vhost->get("http"), old_vhost->get("http"))) {
|
if (!srs_directive_equals(new_vhost->get("http"), old_vhost->get("http"))) {
|
||||||
for (it = subscribes.begin(); it != subscribes.end(); ++it) {
|
for (it = subscribes.begin(); it != subscribes.end(); ++it) {
|
||||||
|
@ -1350,7 +1361,7 @@ int SrsConfig::check_config()
|
||||||
&& n != "time_jitter"
|
&& n != "time_jitter"
|
||||||
&& n != "atc" && n != "atc_auto"
|
&& n != "atc" && n != "atc_auto"
|
||||||
&& n != "debug_srs_upnode"
|
&& n != "debug_srs_upnode"
|
||||||
&& n != "mr" && n != "mw_latency"
|
&& n != "mr" && n != "mw_latency" && n != "min_latency"
|
||||||
) {
|
) {
|
||||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||||
srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret);
|
srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret);
|
||||||
|
@ -2125,7 +2136,6 @@ int SrsConfig::get_chunk_size(string vhost)
|
||||||
|
|
||||||
bool SrsConfig::get_mr_enabled(string vhost)
|
bool SrsConfig::get_mr_enabled(string vhost)
|
||||||
{
|
{
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
|
@ -2147,7 +2157,6 @@ bool SrsConfig::get_mr_enabled(string vhost)
|
||||||
|
|
||||||
int SrsConfig::get_mr_sleep_ms(string vhost)
|
int SrsConfig::get_mr_sleep_ms(string vhost)
|
||||||
{
|
{
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
|
@ -2169,7 +2178,6 @@ int SrsConfig::get_mr_sleep_ms(string vhost)
|
||||||
|
|
||||||
int SrsConfig::get_mw_sleep_ms(string vhost)
|
int SrsConfig::get_mw_sleep_ms(string vhost)
|
||||||
{
|
{
|
||||||
|
|
||||||
SrsConfDirective* conf = get_vhost(vhost);
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
if (!conf) {
|
if (!conf) {
|
||||||
|
@ -2184,6 +2192,22 @@ int SrsConfig::get_mw_sleep_ms(string vhost)
|
||||||
return ::atoi(conf->arg0().c_str());
|
return ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SrsConfig::get_realtime_enabled(string vhost)
|
||||||
|
{
|
||||||
|
SrsConfDirective* conf = get_vhost(vhost);
|
||||||
|
|
||||||
|
if (!conf) {
|
||||||
|
return SRS_PERF_MIN_LATENCY_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
conf = conf->get("min_latency");
|
||||||
|
if (!conf || conf->arg0() != "off") {
|
||||||
|
return SRS_PERF_MIN_LATENCY_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int SrsConfig::get_global_chunk_size()
|
int SrsConfig::get_global_chunk_size()
|
||||||
{
|
{
|
||||||
SrsConfDirective* conf = root->get("chunk_size");
|
SrsConfDirective* conf = root->get("chunk_size");
|
||||||
|
|
|
@ -545,6 +545,12 @@ public:
|
||||||
*/
|
*/
|
||||||
// TODO: FIXME: add utest for mw config.
|
// TODO: FIXME: add utest for mw config.
|
||||||
virtual int get_mw_sleep_ms(std::string vhost);
|
virtual int get_mw_sleep_ms(std::string vhost);
|
||||||
|
/**
|
||||||
|
* whether min latency mode enabled.
|
||||||
|
* @param vhost, the vhost to get the min_latency.
|
||||||
|
*/
|
||||||
|
// TODO: FIXME: add utest for min_latency.
|
||||||
|
virtual bool get_realtime_enabled(std::string vhost);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* get the global chunk size.
|
* get the global chunk size.
|
||||||
|
|
|
@ -251,6 +251,8 @@ SrsPublishRecvThread::SrsPublishRecvThread(
|
||||||
mr = _srs_config->get_mr_enabled(req->vhost);
|
mr = _srs_config->get_mr_enabled(req->vhost);
|
||||||
mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost);
|
mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost);
|
||||||
|
|
||||||
|
realtime = _srs_config->get_realtime_enabled(req->vhost);
|
||||||
|
|
||||||
_srs_config->subscribe(this);
|
_srs_config->subscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,6 +342,10 @@ int SrsPublishRecvThread::handle(SrsCommonMessage* msg)
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
_nb_msgs++;
|
_nb_msgs++;
|
||||||
|
|
||||||
|
// log to show the time of recv thread.
|
||||||
|
srs_verbose("recv thread now=%"PRId64"us, got msg time=%"PRId64"ms, size=%d",
|
||||||
|
srs_update_system_time_ms(), msg->header.timestamp, msg->size);
|
||||||
|
|
||||||
// the rtmp connection will handle this message
|
// the rtmp connection will handle this message
|
||||||
ret = _conn->handle_publish_message(_source, msg, _is_fmle, _is_edge);
|
ret = _conn->handle_publish_message(_source, msg, _is_fmle, _is_edge);
|
||||||
|
@ -363,7 +369,7 @@ void SrsPublishRecvThread::on_recv_error(int ret)
|
||||||
#ifdef SRS_PERF_MERGED_READ
|
#ifdef SRS_PERF_MERGED_READ
|
||||||
void SrsPublishRecvThread::on_read(ssize_t nread)
|
void SrsPublishRecvThread::on_read(ssize_t nread)
|
||||||
{
|
{
|
||||||
if (!mr) {
|
if (!mr || realtime) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,6 +392,10 @@ void SrsPublishRecvThread::on_read(ssize_t nread)
|
||||||
int SrsPublishRecvThread::on_reload_vhost_mr(string vhost)
|
int SrsPublishRecvThread::on_reload_vhost_mr(string vhost)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (req->vhost != vhost) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// the mr settings,
|
// the mr settings,
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/241
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/241
|
||||||
|
@ -419,6 +429,21 @@ int SrsPublishRecvThread::on_reload_vhost_mr(string vhost)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SrsPublishRecvThread::on_reload_vhost_realtime(string vhost)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (req->vhost != vhost) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool realtime_enabled = _srs_config->get_realtime_enabled(req->vhost);
|
||||||
|
srs_trace("realtime changed %d=>%d", realtime, realtime_enabled);
|
||||||
|
realtime = realtime_enabled;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
|
void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
|
||||||
{
|
{
|
||||||
// the bytes:
|
// the bytes:
|
||||||
|
@ -446,8 +471,9 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms)
|
||||||
}
|
}
|
||||||
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size);
|
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size);
|
||||||
|
|
||||||
srs_trace("mr change sleep %d=>%d, erbuf=%d, rbuf %d=>%d, sbytes=%d",
|
srs_trace("mr change sleep %d=>%d, erbuf=%d, rbuf %d=>%d, sbytes=%d, realtime=%d",
|
||||||
mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf, SRS_MR_SMALL_BYTES);
|
mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf,
|
||||||
|
SRS_MR_SMALL_BYTES, realtime);
|
||||||
|
|
||||||
rtmp->set_recv_buffer(nb_rbuf);
|
rtmp->set_recv_buffer(nb_rbuf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,9 @@ private:
|
||||||
bool mr;
|
bool mr;
|
||||||
int mr_fd;
|
int mr_fd;
|
||||||
int mr_sleep;
|
int mr_sleep;
|
||||||
|
// for realtime
|
||||||
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/257
|
||||||
|
bool realtime;
|
||||||
// the recv thread error code.
|
// the recv thread error code.
|
||||||
int recv_error_code;
|
int recv_error_code;
|
||||||
SrsRtmpConn* _conn;
|
SrsRtmpConn* _conn;
|
||||||
|
@ -193,6 +196,7 @@ public:
|
||||||
// interface ISrsReloadHandler
|
// interface ISrsReloadHandler
|
||||||
public:
|
public:
|
||||||
virtual int on_reload_vhost_mr(std::string vhost);
|
virtual int on_reload_vhost_mr(std::string vhost);
|
||||||
|
virtual int on_reload_vhost_realtime(std::string vhost);
|
||||||
private:
|
private:
|
||||||
virtual void set_socket_buffer(int sleep_ms);
|
virtual void set_socket_buffer(int sleep_ms);
|
||||||
};
|
};
|
||||||
|
|
|
@ -150,6 +150,11 @@ int ISrsReloadHandler::on_reload_vhost_mw(string /*vhost*/)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ISrsReloadHandler::on_reload_vhost_realtime(string /*vhost*/)
|
||||||
|
{
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int ISrsReloadHandler::on_reload_vhost_chunk_size(string /*vhost*/)
|
int ISrsReloadHandler::on_reload_vhost_chunk_size(string /*vhost*/)
|
||||||
{
|
{
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
virtual int on_reload_vhost_dvr(std::string vhost);
|
virtual int on_reload_vhost_dvr(std::string vhost);
|
||||||
virtual int on_reload_vhost_mr(std::string vhost);
|
virtual int on_reload_vhost_mr(std::string vhost);
|
||||||
virtual int on_reload_vhost_mw(std::string vhost);
|
virtual int on_reload_vhost_mw(std::string vhost);
|
||||||
|
virtual int on_reload_vhost_realtime(std::string vhost);
|
||||||
virtual int on_reload_vhost_chunk_size(std::string vhost);
|
virtual int on_reload_vhost_chunk_size(std::string vhost);
|
||||||
virtual int on_reload_vhost_transcode(std::string vhost);
|
virtual int on_reload_vhost_transcode(std::string vhost);
|
||||||
virtual int on_reload_ingest_removed(std::string vhost, std::string ingest_id);
|
virtual int on_reload_ingest_removed(std::string vhost, std::string ingest_id);
|
||||||
|
|
|
@ -50,6 +50,7 @@ using namespace std;
|
||||||
#include <srs_protocol_amf0.hpp>
|
#include <srs_protocol_amf0.hpp>
|
||||||
#include <srs_app_recv_thread.hpp>
|
#include <srs_app_recv_thread.hpp>
|
||||||
#include <srs_core_performance.hpp>
|
#include <srs_core_performance.hpp>
|
||||||
|
#include <srs_kernel_utility.hpp>
|
||||||
|
|
||||||
// when stream is busy, for example, streaming is already
|
// when stream is busy, for example, streaming is already
|
||||||
// publishing, when a new client to request to publish,
|
// publishing, when a new client to request to publish,
|
||||||
|
@ -86,6 +87,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd)
|
||||||
|
|
||||||
mw_sleep = SRS_PERF_MW_SLEEP;
|
mw_sleep = SRS_PERF_MW_SLEEP;
|
||||||
mw_enabled = false;
|
mw_enabled = false;
|
||||||
|
realtime = SRS_PERF_MIN_LATENCY_ENABLED;
|
||||||
|
|
||||||
_srs_config->subscribe(this);
|
_srs_config->subscribe(this);
|
||||||
}
|
}
|
||||||
|
@ -212,14 +214,35 @@ int SrsRtmpConn::on_reload_vhost_removed(string vhost)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsRtmpConn::on_reload_vhost_mw(string /*vhost*/)
|
int SrsRtmpConn::on_reload_vhost_mw(string vhost)
|
||||||
{
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (req->vhost != vhost) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int sleep_ms = _srs_config->get_mw_sleep_ms(req->vhost);
|
int sleep_ms = _srs_config->get_mw_sleep_ms(req->vhost);
|
||||||
|
|
||||||
// when mw_sleep changed, resize the socket send buffer.
|
// when mw_sleep changed, resize the socket send buffer.
|
||||||
change_mw_sleep(sleep_ms);
|
change_mw_sleep(sleep_ms);
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SrsRtmpConn::on_reload_vhost_realtime(string vhost)
|
||||||
|
{
|
||||||
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
if (req->vhost != vhost) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool realtime_enabled = _srs_config->get_realtime_enabled(req->vhost);
|
||||||
|
srs_trace("realtime changed %d=>%d", realtime, realtime_enabled);
|
||||||
|
realtime = realtime_enabled;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsRtmpConn::get_send_bytes_delta()
|
int64_t SrsRtmpConn::get_send_bytes_delta()
|
||||||
|
@ -570,6 +593,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
|
||||||
// when mw_sleep changed, resize the socket send buffer.
|
// when mw_sleep changed, resize the socket send buffer.
|
||||||
mw_enabled = true;
|
mw_enabled = true;
|
||||||
change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
|
change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost));
|
||||||
|
realtime = _srs_config->get_realtime_enabled(req->vhost);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// to use isolate thread to recv, can improve about 33% performance.
|
// to use isolate thread to recv, can improve about 33% performance.
|
||||||
|
@ -599,9 +623,15 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
|
||||||
pithy_print.elapse();
|
pithy_print.elapse();
|
||||||
|
|
||||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||||
|
// for send wait time debug
|
||||||
|
srs_verbose("send thread now=%"PRId64"us, wait %dms", srs_update_system_time_ms(), mw_sleep);
|
||||||
|
|
||||||
// wait for message to incoming.
|
// wait for message to incoming.
|
||||||
// @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/251
|
||||||
consumer->wait(SRS_PERF_MW_MIN_MSGS, mw_sleep);
|
consumer->wait(SRS_PERF_MW_MIN_MSGS, mw_sleep, realtime);
|
||||||
|
|
||||||
|
// for send wait time debug
|
||||||
|
srs_verbose("send thread now=%"PRId64"us wakeup", srs_update_system_time_ms());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// get messages from consumer.
|
// get messages from consumer.
|
||||||
|
@ -613,10 +643,12 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsQueueRecvThread* trd)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||||
// we use wait to get messages, so the count must be positive.
|
// we use wait timeout to get messages,
|
||||||
srs_assert(count > 0);
|
// for min latency event no message incoming,
|
||||||
srs_info("mw wait %dms and got %d msgs %"PRId64"-%"PRId64"ms",
|
// so the count maybe zero.
|
||||||
mw_sleep, count, msgs.msgs[0]->timestamp, msgs.msgs[count - 1]->timestamp);
|
srs_verbose("mw wait %dms and got %d msgs %"PRId64"-%"PRId64"ms", mw_sleep, count,
|
||||||
|
(count > 0? msgs.msgs[0]->timestamp : 0),
|
||||||
|
(count > 0? msgs.msgs[count - 1]->timestamp : 0));
|
||||||
#else
|
#else
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
srs_info("mw sleep %dms for no msg", mw_sleep);
|
srs_info("mw sleep %dms for no msg", mw_sleep);
|
||||||
|
@ -1037,12 +1069,12 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms)
|
||||||
}
|
}
|
||||||
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, &sock_buf_size);
|
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, &sock_buf_size);
|
||||||
|
|
||||||
srs_trace("mw changed sleep %d=>%d, max_msgs=%d, esbuf=%d, sbuf %d=>%d",
|
srs_trace("mw changed sleep %d=>%d, max_msgs=%d, esbuf=%d, sbuf %d=>%d, realtime=%d",
|
||||||
mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size,
|
mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size,
|
||||||
onb_sbuf, nb_sbuf);
|
onb_sbuf, nb_sbuf, realtime);
|
||||||
#else
|
#else
|
||||||
srs_trace("mw changed sleep %d=>%d, max_msgs=%d, sbuf %d",
|
srs_trace("mw changed sleep %d=>%d, max_msgs=%d, sbuf %d, realtime=%d",
|
||||||
mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, onb_sbuf);
|
mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, onb_sbuf, realtime);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mw_sleep = sleep_ms;
|
mw_sleep = sleep_ms;
|
||||||
|
|
|
@ -75,6 +75,9 @@ private:
|
||||||
int mw_sleep;
|
int mw_sleep;
|
||||||
// the MR(merged-write) only enabled for play.
|
// the MR(merged-write) only enabled for play.
|
||||||
int mw_enabled;
|
int mw_enabled;
|
||||||
|
// for realtime
|
||||||
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/257
|
||||||
|
bool realtime;
|
||||||
public:
|
public:
|
||||||
SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
|
SrsRtmpConn(SrsServer* srs_server, st_netfd_t client_stfd);
|
||||||
virtual ~SrsRtmpConn();
|
virtual ~SrsRtmpConn();
|
||||||
|
@ -86,6 +89,7 @@ protected:
|
||||||
public:
|
public:
|
||||||
virtual int on_reload_vhost_removed(std::string vhost);
|
virtual int on_reload_vhost_removed(std::string vhost);
|
||||||
virtual int on_reload_vhost_mw(std::string vhost);
|
virtual int on_reload_vhost_mw(std::string vhost);
|
||||||
|
virtual int on_reload_vhost_realtime(std::string vhost);
|
||||||
// interface IKbpsDelta
|
// interface IKbpsDelta
|
||||||
public:
|
public:
|
||||||
virtual int64_t get_send_bytes_delta();
|
virtual int64_t get_send_bytes_delta();
|
||||||
|
|
|
@ -493,7 +493,7 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||||
void SrsConsumer::wait(int nb_msgs, int duration)
|
void SrsConsumer::wait(int nb_msgs, int duration, bool realtime)
|
||||||
{
|
{
|
||||||
mw_min_msgs = nb_msgs;
|
mw_min_msgs = nb_msgs;
|
||||||
mw_duration = duration;
|
mw_duration = duration;
|
||||||
|
@ -508,8 +508,15 @@ void SrsConsumer::wait(int nb_msgs, int duration)
|
||||||
|
|
||||||
// the enqueue will notify this cond.
|
// the enqueue will notify this cond.
|
||||||
mw_waiting = true;
|
mw_waiting = true;
|
||||||
// wait for msgs to incoming.
|
|
||||||
st_cond_wait(mw_wait);
|
// use timeout wait for realtime mode.
|
||||||
|
// @see https://github.com/winlinvip/simple-rtmp-server/issues/257
|
||||||
|
if (realtime) {
|
||||||
|
st_cond_timedwait(mw_wait, duration * 1000);
|
||||||
|
} else {
|
||||||
|
// use cond block wait for high performance mode.
|
||||||
|
st_cond_wait(mw_wait);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -245,8 +245,9 @@ public:
|
||||||
* wait for messages incomming, atleast nb_msgs and in duration.
|
* wait for messages incomming, atleast nb_msgs and in duration.
|
||||||
* @param nb_msgs the messages count to wait.
|
* @param nb_msgs the messages count to wait.
|
||||||
* @param duration the messgae duration to wait.
|
* @param duration the messgae duration to wait.
|
||||||
|
* @param realtime whether use realtime mode.
|
||||||
*/
|
*/
|
||||||
virtual void wait(int nb_msgs, int duration);
|
virtual void wait(int nb_msgs, int duration, bool realtime);
|
||||||
#endif
|
#endif
|
||||||
/**
|
/**
|
||||||
* when client send the pause message.
|
* when client send the pause message.
|
||||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
// current release version
|
// current release version
|
||||||
#define VERSION_MAJOR 2
|
#define VERSION_MAJOR 2
|
||||||
#define VERSION_MINOR 0
|
#define VERSION_MINOR 0
|
||||||
#define VERSION_REVISION 69
|
#define VERSION_REVISION 70
|
||||||
// server info.
|
// server info.
|
||||||
#define RTMP_SIG_SRS_KEY "SRS"
|
#define RTMP_SIG_SRS_KEY "SRS"
|
||||||
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
#define RTMP_SIG_SRS_ROLE "origin/edge server"
|
||||||
|
|
|
@ -128,6 +128,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||||
#define SRS_PERF_MW_MIN_MSGS 8
|
#define SRS_PERF_MW_MIN_MSGS 8
|
||||||
#endif
|
#endif
|
||||||
|
/**
|
||||||
|
* the default value of vhost for
|
||||||
|
* SRS whether use the min latency mode.
|
||||||
|
* for min latence mode:
|
||||||
|
* 1. disable the mr for vhost.
|
||||||
|
* 2. use timeout for cond wait for consumer queue.
|
||||||
|
* @see https://github.com/winlinvip/simple-rtmp-server/issues/257
|
||||||
|
*/
|
||||||
|
#define SRS_PERF_MIN_LATENCY_ENABLED true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* how many chunk stream to cache, [0, N].
|
* how many chunk stream to cache, [0, N].
|
||||||
|
|
|
@ -61,13 +61,13 @@ int64_t srs_get_system_startup_time_ms()
|
||||||
|
|
||||||
return _srs_system_time_startup_time / 1000;
|
return _srs_system_time_startup_time / 1000;
|
||||||
}
|
}
|
||||||
void srs_update_system_time_ms()
|
int64_t srs_update_system_time_ms()
|
||||||
{
|
{
|
||||||
timeval now;
|
timeval now;
|
||||||
|
|
||||||
if (gettimeofday(&now, NULL) < 0) {
|
if (gettimeofday(&now, NULL) < 0) {
|
||||||
srs_warn("gettimeofday failed, ignore");
|
srs_warn("gettimeofday failed, ignore");
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/35
|
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/35
|
||||||
|
@ -83,7 +83,7 @@ void srs_update_system_time_ms()
|
||||||
if (_srs_system_time_us_cache <= 0) {
|
if (_srs_system_time_us_cache <= 0) {
|
||||||
_srs_system_time_us_cache = now_us;
|
_srs_system_time_us_cache = now_us;
|
||||||
_srs_system_time_startup_time = now_us;
|
_srs_system_time_startup_time = now_us;
|
||||||
return;
|
return _srs_system_time_us_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
// use relative time.
|
// use relative time.
|
||||||
|
@ -99,6 +99,8 @@ void srs_update_system_time_ms()
|
||||||
_srs_system_time_us_cache = now_us;
|
_srs_system_time_us_cache = now_us;
|
||||||
srs_info("system time updated, startup=%"PRId64"us, now=%"PRId64"us",
|
srs_info("system time updated, startup=%"PRId64"us, now=%"PRId64"us",
|
||||||
_srs_system_time_startup_time, _srs_system_time_us_cache);
|
_srs_system_time_startup_time, _srs_system_time_us_cache);
|
||||||
|
|
||||||
|
return _srs_system_time_us_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
string srs_dns_resolve(string host)
|
string srs_dns_resolve(string host)
|
||||||
|
|
|
@ -40,7 +40,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
extern int64_t srs_get_system_time_ms();
|
extern int64_t srs_get_system_time_ms();
|
||||||
extern int64_t srs_get_system_startup_time_ms();
|
extern int64_t srs_get_system_startup_time_ms();
|
||||||
// the deamon st-thread will update it.
|
// the deamon st-thread will update it.
|
||||||
extern void srs_update_system_time_ms();
|
extern int64_t srs_update_system_time_ms();
|
||||||
|
|
||||||
// dns resolve utility, return the resolved ip address.
|
// dns resolve utility, return the resolved ip address.
|
||||||
extern std::string srs_dns_resolve(std::string host);
|
extern std::string srs_dns_resolve(std::string host);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue