diff --git a/README.md b/README.md
index ae0f54778c..750ade9a8c 100755
--- a/README.md
+++ b/README.md
@@ -485,6 +485,7 @@ Supported operating systems and hardware:
* 2013-10-17, Created.
## History
+* v2.0, 2014-12-04, for [#241](https://github.com/winlinvip/simple-rtmp-server/issues/241), support mr(merged-read) config and reload. 2.0.52.
* v2.0, 2014-12-04, enable [#241](https://github.com/winlinvip/simple-rtmp-server/issues/241) and [#248](https://github.com/winlinvip/simple-rtmp-server/issues/248), +25% performance, 2.5k publisher. 2.0.50
* v2.0, 2014-12-04, fix [#248](https://github.com/winlinvip/simple-rtmp-server/issues/248), improve about 15% performance for fast buffer. 2.0.49
* v2.0, 2014-12-03, fix [#244](https://github.com/winlinvip/simple-rtmp-server/issues/244), conn thread use cond to wait for recv thread error. 2.0.47.
diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
old mode 100644
new mode 100755
index 61c8b3d497..6edc5a0bb2
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -142,6 +142,26 @@ http_stream {
vhost __defaultVhost__ {
}
+# the MR(merged-read) setting for publisher.
+vhost mr.srs.com {
+ # about MR, read https://github.com/winlinvip/simple-rtmp-server/issues/241
+ mr {
+ # whether enable the MR(merged-read)
+ # default: off
+ enabled on;
+ # the latency in ms for MR(merged-read),
+ # the performance+ when latency+, and memory+,
+ # memory(buffer) = latency * kbps / 8
+ # for example, latency=500ms, kbps=3000kbps, each publish connection will consume
+ # memory = 500 * 3000 / 8 = 187500B = 183KB
+ # when there are 2500 publisher, the total memory of SRS atleast:
+ # 183KB * 2500 = 446MB
+ # the value recomment is [300, 2000]
+ # default: 500
+ latency 500;
+ }
+}
+
# vhost for edge, edge and origin is the same vhost
vhost same.edge.srs.com {
# the mode of vhost, local or remote.
diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp
index 58f0a3a86e..b804e3239a 100644
--- a/trunk/src/app/srs_app_config.cpp
+++ b/trunk/src/app/srs_app_config.cpp
@@ -816,7 +816,18 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
return ret;
}
}
- srs_trace("vhost %s reload hls success.", vhost.c_str());
+ srs_trace("vhost %s reload hlsdvrsuccess.", vhost.c_str());
+ }
+ // mr, only one per vhost
+ if (!srs_directive_equals(new_vhost->get("mr"), old_vhost->get("mr"))) {
+ for (it = subscribes.begin(); it != subscribes.end(); ++it) {
+ ISrsReloadHandler* subscribe = *it;
+ if ((ret = subscribe->on_reload_vhost_mr(vhost)) != ERROR_SUCCESS) {
+ srs_error("vhost %s notify subscribes mr failed. ret=%d", vhost.c_str(), ret);
+ return ret;
+ }
+ }
+ srs_trace("vhost %s reload mr success.", vhost.c_str());
}
// http, only one per vhost.
if (!srs_directive_equals(new_vhost->get("http"), old_vhost->get("http"))) {
@@ -1316,6 +1327,7 @@ int SrsConfig::check_config()
&& n != "time_jitter"
&& n != "atc" && n != "atc_auto"
&& n != "debug_srs_upnode"
+ && n != "mr"
) {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret);
@@ -1333,6 +1345,16 @@ int SrsConfig::check_config()
return ret;
}
}
+ } else if (n == "mr") {
+ for (int j = 0; j < (int)conf->directives.size(); j++) {
+ string m = conf->at(j)->name.c_str();
+ if (m != "enabled" && m != "latency"
+ ) {
+ ret = ERROR_SYSTEM_CONFIG_INVALID;
+ srs_error("unsupported vhost mr directive %s, ret=%d", m.c_str(), ret);
+ return ret;
+ }
+ }
} else if (n == "ingest") {
for (int j = 0; j < (int)conf->directives.size(); j++) {
string m = conf->at(j)->name.c_str();
@@ -2078,6 +2100,50 @@ int SrsConfig::get_chunk_size(string vhost)
return ::atoi(conf->arg0().c_str());
}
+bool SrsConfig::get_mr_enabled(string vhost)
+{
+
+ SrsConfDirective* conf = get_vhost(vhost);
+
+ if (!conf) {
+ return SRS_CONSTS_RTMP_MR;
+ }
+
+ conf = conf->get("mr");
+ if (!conf) {
+ return SRS_CONSTS_RTMP_MR;
+ }
+
+ conf = conf->get("enabled");
+ if (!conf || conf->arg0() != "on") {
+ return SRS_CONSTS_RTMP_MR;
+ }
+
+ return true;
+}
+
+int SrsConfig::get_mr_sleep_ms(string vhost)
+{
+
+ SrsConfDirective* conf = get_vhost(vhost);
+
+ if (!conf) {
+ return SRS_CONSTS_RTMP_MR_SLEEP;
+ }
+
+ conf = conf->get("mr");
+ if (!conf) {
+ return SRS_CONSTS_RTMP_MR_SLEEP;
+ }
+
+ conf = conf->get("latency");
+ if (!conf || conf->arg0().empty()) {
+ return SRS_CONSTS_RTMP_MR_SLEEP;
+ }
+
+ return ::atoi(conf->arg0().c_str());
+}
+
int SrsConfig::get_global_chunk_size()
{
SrsConfDirective* conf = root->get("chunk_size");
diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp
index 675036e2f2..34315406ce 100644
--- a/trunk/src/app/srs_app_config.hpp
+++ b/trunk/src/app/srs_app_config.hpp
@@ -530,6 +530,16 @@ class SrsConfig
* @remark, default 60000.
*/
virtual int get_chunk_size(std::string vhost);
+ /**
+ * whether mr is enabled for vhost.
+ * @param vhost, the vhost to get the mr.
+ */
+ virtual bool get_mr_enabled(std::string vhost);
+ /**
+ * get the mr sleep time in ms for vhost.
+ * @param vhost, the vhost to get the mr sleep time.
+ */
+ virtual int get_mr_sleep_ms(std::string vhost);
private:
/**
* get the global chunk size.
diff --git a/trunk/src/app/srs_app_recv_thread.cpp b/trunk/src/app/srs_app_recv_thread.cpp
index 74de0016b7..0226090c2d 100644
--- a/trunk/src/app/srs_app_recv_thread.cpp
+++ b/trunk/src/app/srs_app_recv_thread.cpp
@@ -29,6 +29,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
#include
+#include
+
+using namespace std;
ISrsMessageHandler::ISrsMessageHandler()
{
@@ -221,11 +224,13 @@ void SrsQueueRecvThread::on_thread_stop()
}
SrsPublishRecvThread::SrsPublishRecvThread(
- SrsRtmpServer* rtmp_sdk, int fd, int timeout_ms,
+ SrsRtmpServer* rtmp_sdk,
+ SrsRequest* _req, int mr_sock_fd, int timeout_ms,
SrsRtmpConn* conn, SrsSource* source, bool is_fmle, bool is_edge
): trd(this, rtmp_sdk, timeout_ms)
{
rtmp = rtmp_sdk;
+
_conn = conn;
_source = source;
_is_fmle = is_fmle;
@@ -234,12 +239,22 @@ SrsPublishRecvThread::SrsPublishRecvThread(
recv_error_code = ERROR_SUCCESS;
_nb_msgs = 0;
error = st_cond_new();
+
+ req = _req;
+ mr_fd = mr_sock_fd;
- mr_fd = fd;
+ // the mr settings,
+ // @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ mr = _srs_config->get_mr_enabled(req->vhost);
+ mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost);
+
+ _srs_config->subscribe(this);
}
SrsPublishRecvThread::~SrsPublishRecvThread()
{
+ _srs_config->unsubscribe(this);
+
trd.stop();
st_cond_destroy(error);
}
@@ -282,20 +297,8 @@ void SrsPublishRecvThread::on_thread_start()
// for the main thread never send message.
#ifdef SRS_PERF_MERGED_READ
- // socket recv buffer, system will double it.
- int nb_rbuf = SRS_MR_SOCKET_BUFFER / 2;
- socklen_t sock_buf_size = sizeof(int);
- if (setsockopt(mr_fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, sock_buf_size) < 0) {
- srs_warn("set sock SO_RCVBUF=%d failed.", nb_rbuf);
- }
- getsockopt(mr_fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size);
-
- srs_trace("merged read sockbuf=%d, actual=%d, sleep %d when nread<=%d",
- SRS_MR_SOCKET_BUFFER, nb_rbuf, SRS_MR_MAX_SLEEP_MS, SRS_MR_SMALL_BYTES);
-
- // enable the merge read
- // @see https://github.com/winlinvip/simple-rtmp-server/issues/241
- rtmp->set_merge_read(true, this);
+ // for mr.
+ update_buffer(mr, mr_sleep);
#endif
}
@@ -349,7 +352,11 @@ void SrsPublishRecvThread::on_recv_error(int ret)
#ifdef SRS_PERF_MERGED_READ
void SrsPublishRecvThread::on_read(ssize_t nread)
{
- if (nread < 0 || SRS_MR_MAX_SLEEP_MS <= 0) {
+ if (!mr) {
+ return;
+ }
+
+ if (nread < 0 || mr_sleep <= 0) {
return;
}
@@ -360,7 +367,72 @@ void SrsPublishRecvThread::on_read(ssize_t nread)
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
*/
if (nread < SRS_MR_SMALL_BYTES) {
- st_usleep(SRS_MR_MAX_SLEEP_MS * 1000);
+ st_usleep(mr_sleep * 1000);
}
}
#endif
+
+int SrsPublishRecvThread::on_reload_vhost_mr(string vhost)
+{
+ int ret = ERROR_SUCCESS;
+
+ // the mr settings,
+ // @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ bool mr_enabled = _srs_config->get_mr_enabled(req->vhost);
+ int sleep_ms = _srs_config->get_mr_sleep_ms(req->vhost);
+ update_buffer(mr_enabled, sleep_ms);
+
+ return ret;
+}
+
+void SrsPublishRecvThread::update_buffer(bool mr_enabled, int sleep_ms)
+{
+ // TODO: FIXME: refine it.
+
+#ifdef SRS_PERF_MERGED_READ
+ // previous enabled mr, update the buffer.
+ if (mr && mr_sleep != sleep_ms) {
+ // the underlayer api will set to SRS_MR_SOCKET_BUFFER bytes.
+ // 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
+ // 128KB=131072, 256KB=262144, 512KB=524288
+ // the buffer should set to SRS_MR_MAX_SLEEP_MS*kbps/8,
+ // for example, your system delivery stream in 1000kbps,
+ // sleep 800ms for small bytes, the buffer should set to:
+ // 800*1000/8=100000B(about 128KB).
+ // 2000*3000/8=750000B(about 732KB).
+ int kbps = 3000;
+ int socket_buffer_size = mr_sleep * kbps / 8;
+
+ // socket recv buffer, system will double it.
+ int nb_rbuf = socket_buffer_size / 2;
+ socklen_t sock_buf_size = sizeof(int);
+ if (setsockopt(mr_fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, sock_buf_size) < 0) {
+ srs_warn("set sock SO_RCVBUF=%d failed.", nb_rbuf);
+ }
+ getsockopt(mr_fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size);
+
+ srs_trace("merged read sockbuf=%d, actual=%d, sleep %d when nread<=%d",
+ socket_buffer_size, nb_rbuf, mr_sleep, SRS_MR_SMALL_BYTES);
+
+ rtmp->set_recv_buffer(nb_rbuf);
+ }
+#endif
+
+ // update to new state
+ mr = mr_enabled;
+ mr_sleep = sleep_ms;
+
+#ifdef SRS_PERF_MERGED_READ
+ // apply new state.
+ if (mr) {
+ // enable the merge read
+ // @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ rtmp->set_merge_read(true, this);
+ } else {
+ // disable the merge read
+ // @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ rtmp->set_merge_read(false, NULL);
+ }
+#endif
+}
+
diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp
index 6c219a62aa..c39ec51ca0 100644
--- a/trunk/src/app/srs_app_recv_thread.hpp
+++ b/trunk/src/app/srs_app_recv_thread.hpp
@@ -35,11 +35,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
#include
+#include
class SrsRtmpServer;
class SrsMessage;
class SrsRtmpConn;
class SrsSource;
+class SrsRequest;
/**
* for the recv thread to handle the message.
@@ -138,15 +140,19 @@ class SrsPublishRecvThread : virtual public ISrsMessageHandler
#ifdef SRS_PERF_MERGED_READ
, virtual public IMergeReadHandler
#endif
+ , virtual public ISrsReloadHandler
{
private:
SrsRecvThread trd;
SrsRtmpServer* rtmp;
+ SrsRequest* req;
// the msgs already got.
int64_t _nb_msgs;
// for mr(merged read),
// @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ bool mr;
int mr_fd;
+ int mr_sleep;
// the recv thread error code.
int recv_error_code;
SrsRtmpConn* _conn;
@@ -158,7 +164,8 @@ class SrsPublishRecvThread : virtual public ISrsMessageHandler
// @see https://github.com/winlinvip/simple-rtmp-server/issues/244
st_cond_t error;
public:
- SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, int fd, int timeout_ms,
+ SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk,
+ SrsRequest* _req, int mr_sock_fd, int timeout_ms,
SrsRtmpConn* conn, SrsSource* source, bool is_fmle, bool is_edge);
virtual ~SrsPublishRecvThread();
public:
@@ -183,6 +190,11 @@ class SrsPublishRecvThread : virtual public ISrsMessageHandler
#ifdef SRS_PERF_MERGED_READ
virtual void on_read(ssize_t nread);
#endif
+// interface ISrsReloadHandler
+public:
+ virtual int on_reload_vhost_mr(std::string vhost);
+private:
+ virtual void update_buffer(bool mr_enabled, int sleep_ms);
};
#endif
diff --git a/trunk/src/app/srs_app_reload.cpp b/trunk/src/app/srs_app_reload.cpp
index 8bed3f19ba..9581df1d17 100644
--- a/trunk/src/app/srs_app_reload.cpp
+++ b/trunk/src/app/srs_app_reload.cpp
@@ -140,6 +140,11 @@ int ISrsReloadHandler::on_reload_vhost_dvr(string /*vhost*/)
return ERROR_SUCCESS;
}
+int ISrsReloadHandler::on_reload_vhost_mr(string /*vhost*/)
+{
+ return ERROR_SUCCESS;
+}
+
int ISrsReloadHandler::on_reload_vhost_transcode(string /*vhost*/)
{
return ERROR_SUCCESS;
diff --git a/trunk/src/app/srs_app_reload.hpp b/trunk/src/app/srs_app_reload.hpp
index 85d5be016e..a133c52d8d 100644
--- a/trunk/src/app/srs_app_reload.hpp
+++ b/trunk/src/app/srs_app_reload.hpp
@@ -65,6 +65,7 @@ class ISrsReloadHandler
virtual int on_reload_vhost_forward(std::string vhost);
virtual int on_reload_vhost_hls(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_transcode(std::string vhost);
virtual int on_reload_ingest_removed(std::string vhost, std::string ingest_id);
virtual int on_reload_ingest_added(std::string vhost, std::string ingest_id);
diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp
index 9c60430e2f..958c92396c 100644
--- a/trunk/src/app/srs_app_rtmp_conn.cpp
+++ b/trunk/src/app/srs_app_rtmp_conn.cpp
@@ -660,9 +660,8 @@ int SrsRtmpConn::fmle_publishing(SrsSource* source)
// use isolate thread to recv,
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/237
- SrsPublishRecvThread trd(rtmp, st_netfd_fileno(stfd),
- SRS_CONSTS_RTMP_RECV_TIMEOUT_US / 1000,
- this, source, true, vhost_is_edge);
+ SrsPublishRecvThread trd(rtmp, req,
+ st_netfd_fileno(stfd), 0, this, source, true, vhost_is_edge);
srs_info("start to publish stream %s success", req->stream.c_str());
ret = do_publishing(source, &trd);
@@ -696,9 +695,8 @@ int SrsRtmpConn::flash_publishing(SrsSource* source)
// use isolate thread to recv,
// @see: https://github.com/winlinvip/simple-rtmp-server/issues/237
- SrsPublishRecvThread trd(rtmp, st_netfd_fileno(stfd),
- SRS_CONSTS_RTMP_RECV_TIMEOUT_US / 1000,
- this, source, false, vhost_is_edge);
+ SrsPublishRecvThread trd(rtmp, req,
+ st_netfd_fileno(stfd), 0, this, source, true, vhost_is_edge);
srs_info("start to publish stream %s success", req->stream.c_str());
ret = do_publishing(source, &trd);
diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp
index 28bc0c07eb..b5926e0383 100644
--- a/trunk/src/core/srs_core.hpp
+++ b/trunk/src/core/srs_core.hpp
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// current release version
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
-#define VERSION_REVISION 51
+#define VERSION_REVISION 52
// server info.
#define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_ROLE "origin/edge server"
diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp
index 855693feab..29abcbbb76 100644
--- a/trunk/src/core/srs_core_performance.hpp
+++ b/trunk/src/core/srs_core_performance.hpp
@@ -42,22 +42,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* @example, for the default settings, this algorithm will use:
* that is, when got nread bytes smaller than 4KB, sleep(780ms).
*/
-#if 1
- // to enable merged read.
- #define SRS_PERF_MERGED_READ
- // the max sleep time in ms
- #define SRS_MR_MAX_SLEEP_MS 780
- // the max small bytes to group
- #define SRS_MR_SMALL_BYTES 4096
- // the underlayer api will set to SRS_MR_SOCKET_BUFFER bytes.
- // 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536,
- // 128KB=131072, 256KB=262144, 512KB=524288
- // the buffer should set to SRS_MR_MAX_SLEEP_MS*kbps/8,
- // for example, your system delivery stream in 1000kbps,
- // sleep 800ms for small bytes, the buffer should set to:
- // 800*1000/8=100000B(about 128KB).
- #define SRS_MR_SOCKET_BUFFER 65536
-#endif
+/**
+* https://github.com/winlinvip/simple-rtmp-server/issues/241#issuecomment-65554690
+* The merged read algorithm is ok and can be simplified for:
+* 1. Suppose the client network is ok. All algorithm go wrong when netowrk is not ok.
+* 2. Suppose the client send each packet one by one. Although send some together, it's same.
+* 3. SRS MR algorithm will read all data then sleep.
+* So, the MR algorithm is:
+* while true:
+* read all data from socket.
+* sleep a while
+* For example, sleep 120ms. Then there is, and always 120ms data in buffer.
+* That is, the latency is 120ms(the sleep time).
+*/
+// to enable merged read.
+#undef SRS_PERF_MERGED_READ
+// the max sleep time in ms
+#define SRS_MR_MAX_SLEEP_MS 800
/**
* the send cache time in ms.
diff --git a/trunk/src/kernel/srs_kernel_consts.hpp b/trunk/src/kernel/srs_kernel_consts.hpp
index d30fd07d11..194c9f9d20 100644
--- a/trunk/src/kernel/srs_kernel_consts.hpp
+++ b/trunk/src/kernel/srs_kernel_consts.hpp
@@ -50,6 +50,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// 6. Chunking, RTMP protocol default chunk size.
#define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128
+// the default setting of mr.
+#define SRS_CONSTS_RTMP_MR false
+#define SRS_CONSTS_RTMP_MR_SLEEP 500
+
/**
* 6. Chunking
* The chunk size is configurable. It can be set using a control
diff --git a/trunk/src/rtmp/srs_protocol_buffer.cpp b/trunk/src/rtmp/srs_protocol_buffer.cpp
index 617ce148e3..4a8234dba7 100644
--- a/trunk/src/rtmp/srs_protocol_buffer.cpp
+++ b/trunk/src/rtmp/srs_protocol_buffer.cpp
@@ -28,6 +28,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include
#include
+// the max small bytes to group
+#define SRS_MR_SMALL_BYTES 4096
+// the default recv buffer size
+#define SRS_DEFAULT_RECV_BUFFER_SIZE 8192
+
// the max header size,
// @see SrsProtocol::read_message_header().
#define SRS_RTMP_MAX_MESSAGE_HEADER 11
@@ -90,11 +95,30 @@ SrsFastBuffer::SrsFastBuffer()
_handler = NULL;
#endif
- nb_buffer = SRS_MR_SOCKET_BUFFER;
+ nb_buffer = SRS_DEFAULT_RECV_BUFFER_SIZE;
buffer = new char[nb_buffer];
p = end = buffer;
}
+void SrsFastBuffer::set_buffer(int buffer_size)
+{
+ // only realloc when buffer changed bigger
+ if (buffer_size <= nb_buffer) {
+ return;
+ }
+
+ int start = p - buffer;
+ int cap = end - p;
+
+ char* buf = new char[buffer_size];
+ memcpy(buf, buffer, nb_buffer);
+ srs_freep(buffer);
+
+ buffer = buf;
+ p = buffer + start;
+ end = p + cap;
+}
+
SrsFastBuffer::~SrsFastBuffer()
{
srs_freep(buffer);
diff --git a/trunk/src/rtmp/srs_protocol_buffer.hpp b/trunk/src/rtmp/srs_protocol_buffer.hpp
index e2ec16a457..36444a08ae 100644
--- a/trunk/src/rtmp/srs_protocol_buffer.hpp
+++ b/trunk/src/rtmp/srs_protocol_buffer.hpp
@@ -122,6 +122,15 @@ class SrsFastBuffer
public:
SrsFastBuffer();
virtual ~SrsFastBuffer();
+public:
+ /**
+ * create buffer with specifeid size.
+ * @param buffer the size of buffer.
+ * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K.
+ * @remark when buffer changed, the previous ptr maybe invalid.
+ * @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ */
+ virtual void set_buffer(int buffer_size);
public:
/**
* read 1byte from buffer, move to next bytes.
diff --git a/trunk/src/rtmp/srs_protocol_rtmp.cpp b/trunk/src/rtmp/srs_protocol_rtmp.cpp
index 7c14bac490..2b6525dbd1 100644
--- a/trunk/src/rtmp/srs_protocol_rtmp.cpp
+++ b/trunk/src/rtmp/srs_protocol_rtmp.cpp
@@ -750,6 +750,11 @@ void SrsRtmpServer::set_merge_read(bool v, IMergeReadHandler* handler)
{
protocol->set_merge_read(v, handler);
}
+
+void SrsRtmpServer::set_recv_buffer(int buffer_size)
+{
+ protocol->set_recv_buffer(buffer_size);
+}
#endif
void SrsRtmpServer::set_recv_timeout(int64_t timeout_us)
diff --git a/trunk/src/rtmp/srs_protocol_rtmp.hpp b/trunk/src/rtmp/srs_protocol_rtmp.hpp
index 9b5a355ca5..f4fb0aea96 100644
--- a/trunk/src/rtmp/srs_protocol_rtmp.hpp
+++ b/trunk/src/rtmp/srs_protocol_rtmp.hpp
@@ -354,6 +354,14 @@ class SrsRtmpServer
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
*/
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
+ /**
+ * create buffer with specifeid size.
+ * @param buffer the size of buffer.
+ * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K.
+ * @remark when buffer changed, the previous ptr maybe invalid.
+ * @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ */
+ virtual void set_recv_buffer(int buffer_size);
#endif
/**
* set/get the recv timeout in us.
diff --git a/trunk/src/rtmp/srs_protocol_stack.cpp b/trunk/src/rtmp/srs_protocol_stack.cpp
index 98502f7b75..1eee9d9e87 100644
--- a/trunk/src/rtmp/srs_protocol_stack.cpp
+++ b/trunk/src/rtmp/srs_protocol_stack.cpp
@@ -504,6 +504,11 @@ void SrsProtocol::set_merge_read(bool v, IMergeReadHandler* handler)
{
in_buffer->set_merge_read(v, handler);
}
+
+void SrsProtocol::set_recv_buffer(int buffer_size)
+{
+ in_buffer->set_buffer(buffer_size);
+}
#endif
void SrsProtocol::set_recv_timeout(int64_t timeout_us)
diff --git a/trunk/src/rtmp/srs_protocol_stack.hpp b/trunk/src/rtmp/srs_protocol_stack.hpp
index 9c909c87b8..72d30a11db 100644
--- a/trunk/src/rtmp/srs_protocol_stack.hpp
+++ b/trunk/src/rtmp/srs_protocol_stack.hpp
@@ -257,10 +257,6 @@ class SrsProtocol
*/
int32_t out_chunk_size;
public:
- /**
- * use io to create the protocol stack,
- * @param io, provides io interfaces, user must free it.
- */
SrsProtocol(ISrsProtocolReaderWriter* io);
virtual ~SrsProtocol();
public:
@@ -288,6 +284,14 @@ class SrsProtocol
* @see https://github.com/winlinvip/simple-rtmp-server/issues/241
*/
virtual void set_merge_read(bool v, IMergeReadHandler* handler);
+ /**
+ * create buffer with specifeid size.
+ * @param buffer the size of buffer.
+ * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K.
+ * @remark when buffer changed, the previous ptr maybe invalid.
+ * @see https://github.com/winlinvip/simple-rtmp-server/issues/241
+ */
+ virtual void set_recv_buffer(int buffer_size);
#endif
public:
/**