From 1b175b11070e70c824664f42e99344c93160b40a Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 6 Jan 2017 14:57:54 +0800 Subject: [PATCH] for #730, support config in/out ack size. 3.0.13 --- README.md | 2 ++ trunk/conf/full.conf | 13 ++++++++++ trunk/src/app/srs_app_config.cpp | 35 +++++++++++++++++++++++++++ trunk/src/app/srs_app_config.hpp | 4 +++ trunk/src/app/srs_app_rtmp_conn.cpp | 12 ++++++--- trunk/src/protocol/srs_rtmp_stack.cpp | 14 +++++++++-- trunk/src/protocol/srs_rtmp_stack.hpp | 12 ++++++++- 7 files changed, 86 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 81d0923f8..f975e1bd0 100755 --- a/README.md +++ b/README.md @@ -184,6 +184,7 @@ Please select your language: ### V3 changes +* v3.0, 2017-01-06, for [#730][bug #730] support config in/out ack size. 3.0.13 * v3.0, 2017-01-06, for [#711][bug #711] support perfile for transcode. 3.0.12 * v3.0, 2017-01-05, patch ST for valgrind and ARM. 3.0.11 * v3.0, 2017-01-05, for [#324][bug #324], always enable hstrs. 3.0.10 @@ -1355,6 +1356,7 @@ Winlin [bug #717]: https://github.com/ossrs/srs/issues/717 [bug #691]: https://github.com/ossrs/srs/issues/691 [bug #711]: https://github.com/ossrs/srs/issues/711 +[bug #730]: https://github.com/ossrs/srs/issues/730 [bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 1b9625bbd..c43f6bd08 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -300,6 +300,19 @@ vhost scope.vhost.srs.com { # vhost chunk size will override the global value. # default: global chunk size. chunk_size 128; + + # The input ack size, 0 to not set. + # Generally, it's set by the message from peer, + # but for some peer(encoder), it never send message but use a different ack size. + # We can chnage the default ack size in server-side, to send acknowledge message, + # or the encoder maybe blocked after publishing for some time. + # Default: 0 + in_ack_size 0; + + # The output ack size, 0 to not set. + # This is used to notify the peer(player) to send acknowledge to server. + # Default: 2500000 + out_ack_size 2500000; } # set the chunk size of vhost. diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 07b2e2374..4bc4d4621 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3826,6 +3826,7 @@ int SrsConfig::check_config() && n != "play" && n != "publish" && n != "cluster" && n != "security" && n != "http_remux" && n != "http_static" && n != "hds" && n != "exec" + && n != "in_ack_size" && n != "out_ack_size" ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret); @@ -4694,6 +4695,40 @@ SrsConfDirective* SrsConfig::get_refer_publish(string vhost) return conf->get("publish"); } +int SrsConfig::get_in_ack_size(string vhost) +{ + static int DEFAULT = 0; + + SrsConfDirective* conf = get_vhost(vhost); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("in_ack_size"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return ::atoi(conf->arg0().c_str()); +} + +int SrsConfig::get_out_ack_size(string vhost) +{ + static int DEFAULT = 2500000; + + SrsConfDirective* conf = get_vhost(vhost); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("out_ack_size"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return ::atoi(conf->arg0().c_str()); +} + int SrsConfig::get_chunk_size(string vhost) { if (vhost.empty()) { diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index e5844bee8..c718f9cc6 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -754,6 +754,10 @@ public: * @return the refer, NULL for not configed. */ virtual SrsConfDirective* get_refer_publish(std::string vhost); + // Get the input default ack size, which is generally set by message from peer. + virtual int get_in_ack_size(std::string vhost); + // Get the output default ack size, to notify the peer to send acknowledge to server. + virtual int get_out_ack_size(std::string vhost); /** * get the chunk size of vhost. * @param vhost, the vhost to get the chunk size. use global if not specified. diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index a4e9c9683..1430d3496 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -578,11 +578,17 @@ int SrsRtmpConn::service_cycle() { int ret = ERROR_SUCCESS; - if ((ret = rtmp->set_window_ack_size((int)(2.5 * 1000 * 1000))) != ERROR_SUCCESS) { - srs_error("set window acknowledgement size failed. ret=%d", ret); + int out_ack_size = _srs_config->get_out_ack_size(req->vhost); + if (out_ack_size && (ret = rtmp->set_window_ack_size(out_ack_size)) != ERROR_SUCCESS) { + srs_error("set output window acknowledgement size failed. ret=%d", ret); + return ret; + } + + int in_ack_size = _srs_config->get_in_ack_size(req->vhost); + if (in_ack_size && (ret = rtmp->set_in_window_ack_size(in_ack_size)) != ERROR_SUCCESS) { + srs_error("set input window acknowledgement size failed. ret=%d", ret); return ret; } - srs_verbose("set window acknowledgement size success"); if ((ret = rtmp->set_peer_bandwidth((int)(2.5 * 1000 * 1000), 2)) != ERROR_SUCCESS) { srs_error("set peer bandwidth failed. ret=%d", ret); diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 30585a693..e4924cfa8 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -355,6 +355,12 @@ int64_t SrsProtocol::get_send_bytes() return skt->get_send_bytes(); } +int SrsProtocol::set_in_window_ack_size(int ack_size) +{ + in_ack_size.window = ack_size; + return ERROR_SUCCESS; +} + int SrsProtocol::recv_message(SrsCommonMessage** pmsg) { *pmsg = NULL; @@ -1620,7 +1626,7 @@ int SrsProtocol::response_acknowledgement_message() } // ignore when delta bytes not exceed half of window(ack size). - uint32_t delta = (uint32_t)(skt->get_recv_bytes() - in_ack_size.nb_recv_bytes); + uint32_t delta = (uint32_t)(skt->get_recv_bytes() - in_ack_size.nb_recv_bytes)*100; if (delta < in_ack_size.window / 2) { return ret; } @@ -1635,7 +1641,6 @@ int SrsProtocol::response_acknowledgement_message() SrsAcknowledgementPacket* pkt = new SrsAcknowledgementPacket(); pkt->sequence_number = sequence_number; - srs_warn("ack sequence=%#x", sequence_number); // cache the message and use flush to send. if (!auto_response_when_recv) { @@ -2548,6 +2553,11 @@ int SrsRtmpServer::set_window_ack_size(int ack_size) return ret; } +int SrsRtmpServer::set_in_window_ack_size(int ack_size) +{ + return protocol->set_in_window_ack_size(ack_size); +} + int SrsRtmpServer::set_peer_bandwidth(int bandwidth, int type) { int ret = ERROR_SUCCESS; diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 66226084c..75e993c01 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -329,6 +329,14 @@ public: */ virtual int64_t get_recv_bytes(); virtual int64_t get_send_bytes(); +public: + // Set the input default ack size. This is generally set by the message from peer, + // but for some encoder, it never send the ack message while it default to a none zone size. + // This will cause the encoder to block after publishing some messages to server, + // because it wait for server to send acknowledge, but server default to 0 which means no need + // to ack encoder. We can change the default input ack size. We will always response the + // ack size whatever the encoder set or not. + virtual int set_in_window_ack_size(int ack_size); public: /** * recv a RTMP message, which is bytes oriented. @@ -928,9 +936,11 @@ public: */ virtual int connect_app(SrsRequest* req); /** - * set ack size to client, client will send ack-size for each ack window + * set output ack size to client, client will send ack-size for each ack window */ virtual int set_window_ack_size(int ack_size); + // Set the default input ack size value. + virtual int set_in_window_ack_size(int ack_size); /** * @type: The sender can mark this message hard (0), soft (1), or dynamic (2) * using the Limit type field.