winlin

support pithy print log message specified by stage.

@@ -46,6 +46,7 @@ url: rtmp://127.0.0.1:1935/live/livestream @@ -46,6 +46,7 @@ url: rtmp://127.0.0.1:1935/live/livestream
46 * nginx v1.5.0: 139524 lines <br/> 46 * nginx v1.5.0: 139524 lines <br/>
47 47
48 ### History 48 ### History
  49 +* v0.3, 2013-10-29, support pithy print log message specified by stage.
49 * v0.3, 2013-10-28, support librtmp without extended-timestamp in 0xCX chunk packet. 50 * v0.3, 2013-10-28, support librtmp without extended-timestamp in 0xCX chunk packet.
50 * v0.3, 2013-10-27, support cache last gop for client fast startup. 51 * v0.3, 2013-10-27, support cache last gop for client fast startup.
51 * v0.2, 2013-10-25, v0.2 released. 10125 lines. 52 * v0.2, 2013-10-25, v0.2 released. 10125 lines.
@@ -87,7 +87,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server" @@ -87,7 +87,7 @@ MODULE_FILES=("srs_core" "srs_core_log" "srs_core_server"
87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer" 87 "srs_core_rtmp" "srs_core_socket" "srs_core_buffer"
88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0" 88 "srs_core_auto_free" "srs_core_protocol" "srs_core_amf0"
89 "srs_core_stream" "srs_core_source" "srs_core_codec" 89 "srs_core_stream" "srs_core_source" "srs_core_codec"
90 - "srs_core_complex_handshake") 90 + "srs_core_complex_handshake" "srs_core_pithy_print")
91 MODULE_DIR="src/core" . auto/modules.sh 91 MODULE_DIR="src/core" . auto/modules.sh
92 CORE_OBJS="${MODULE_OBJS[@]}" 92 CORE_OBJS="${MODULE_OBJS[@]}"
93 93
@@ -22,3 +22,24 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -22,3 +22,24 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 #include <srs_core.hpp> 24 #include <srs_core.hpp>
  25 +
  26 +#include <sys/time.h>
  27 +
  28 +static int64_t _srs_system_time_us_cache = 0;
  29 +
  30 +int64_t srs_get_system_time_ms()
  31 +{
  32 + return _srs_system_time_us_cache / 1000;
  33 +}
  34 +
  35 +void srs_update_system_time_ms()
  36 +{
  37 + timeval now;
  38 +
  39 + gettimeofday(&now, NULL);
  40 +
  41 + // we must convert the tv_sec/tv_usec to int64_t.
  42 + _srs_system_time_us_cache = now.tv_sec * 1000 * 1000 + now.tv_usec;
  43 +
  44 + _srs_system_time_us_cache = srs_max(0, _srs_system_time_us_cache);
  45 +}
@@ -79,4 +79,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -79,4 +79,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
79 #define srs_min(a, b) ((a < b)? a : b) 79 #define srs_min(a, b) ((a < b)? a : b)
80 #define srs_max(a, b) ((a < b)? b : a) 80 #define srs_max(a, b) ((a < b)? b : a)
81 81
  82 +// get current system time in ms, use cache to avoid performance problem
  83 +extern int64_t srs_get_system_time_ms();
  84 +// the deamon st-thread will update it.
  85 +extern void srs_update_system_time_ms();
  86 +
82 #endif 87 #endif
@@ -32,9 +32,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -32,9 +32,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 #include <srs_core_auto_free.hpp> 32 #include <srs_core_auto_free.hpp>
33 #include <srs_core_source.hpp> 33 #include <srs_core_source.hpp>
34 #include <srs_core_server.hpp> 34 #include <srs_core_server.hpp>
  35 +#include <srs_core_pithy_print.hpp>
35 36
36 #define SRS_PULSE_TIMEOUT_MS 100 37 #define SRS_PULSE_TIMEOUT_MS 100
37 #define SRS_SEND_TIMEOUT_MS 5000 38 #define SRS_SEND_TIMEOUT_MS 5000
  39 +#define SRS_RECV_TIMEOUT_MS SRS_SEND_TIMEOUT_MS
38 40
39 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) 41 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
40 : SrsConnection(srs_server, client_stfd) 42 : SrsConnection(srs_server, client_stfd)
@@ -61,9 +63,10 @@ int SrsClient::do_cycle() @@ -61,9 +63,10 @@ int SrsClient::do_cycle()
61 srs_error("get peer ip failed. ret=%d", ret); 63 srs_error("get peer ip failed. ret=%d", ret);
62 return ret; 64 return ret;
63 } 65 }
64 - srs_verbose("get peer ip success. ip=%s", ip); 66 + srs_trace("get peer ip success. ip=%s, send_to=%d, recv_to=%d",
  67 + ip, SRS_SEND_TIMEOUT_MS, SRS_RECV_TIMEOUT_MS);
65 68
66 - rtmp->set_recv_timeout(SRS_SEND_TIMEOUT_MS * 1000); 69 + rtmp->set_recv_timeout(SRS_RECV_TIMEOUT_MS * 1000);
67 rtmp->set_send_timeout(SRS_SEND_TIMEOUT_MS * 1000); 70 rtmp->set_send_timeout(SRS_SEND_TIMEOUT_MS * 1000);
68 71
69 if ((ret = rtmp->handshake()) != ERROR_SUCCESS) { 72 if ((ret = rtmp->handshake()) != ERROR_SUCCESS) {
@@ -135,7 +138,7 @@ int SrsClient::do_cycle() @@ -135,7 +138,7 @@ int SrsClient::do_cycle()
135 return ret; 138 return ret;
136 } 139 }
137 srs_info("start to play stream %s success", req->stream.c_str()); 140 srs_info("start to play stream %s success", req->stream.c_str());
138 - return streaming_play(source); 141 + return playing(source);
139 } 142 }
140 case SrsClientFMLEPublish: { 143 case SrsClientFMLEPublish: {
141 srs_verbose("FMLE start to publish stream %s.", req->stream.c_str()); 144 srs_verbose("FMLE start to publish stream %s.", req->stream.c_str());
@@ -145,7 +148,7 @@ int SrsClient::do_cycle() @@ -145,7 +148,7 @@ int SrsClient::do_cycle()
145 return ret; 148 return ret;
146 } 149 }
147 srs_info("start to publish stream %s success", req->stream.c_str()); 150 srs_info("start to publish stream %s success", req->stream.c_str());
148 - ret = streaming_publish(source, true); 151 + ret = publish(source, true);
149 source->on_unpublish(); 152 source->on_unpublish();
150 return ret; 153 return ret;
151 } 154 }
@@ -157,7 +160,7 @@ int SrsClient::do_cycle() @@ -157,7 +160,7 @@ int SrsClient::do_cycle()
157 return ret; 160 return ret;
158 } 161 }
159 srs_info("flash start to publish stream %s success", req->stream.c_str()); 162 srs_info("flash start to publish stream %s success", req->stream.c_str());
160 - ret = streaming_publish(source, false); 163 + ret = publish(source, false);
161 source->on_unpublish(); 164 source->on_unpublish();
162 return ret; 165 return ret;
163 } 166 }
@@ -171,7 +174,7 @@ int SrsClient::do_cycle() @@ -171,7 +174,7 @@ int SrsClient::do_cycle()
171 return ret; 174 return ret;
172 } 175 }
173 176
174 -int SrsClient::streaming_play(SrsSource* source) 177 +int SrsClient::playing(SrsSource* source)
175 { 178 {
176 int ret = ERROR_SUCCESS; 179 int ret = ERROR_SUCCESS;
177 180
@@ -187,11 +190,10 @@ int SrsClient::streaming_play(SrsSource* source) @@ -187,11 +190,10 @@ int SrsClient::streaming_play(SrsSource* source)
187 190
188 rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); 191 rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);
189 192
190 - int64_t report_time = 0;  
191 - int64_t reported_time = 0; 193 + SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);
192 194
193 while (true) { 195 while (true) {
194 - report_time += SRS_PULSE_TIMEOUT_MS; 196 + pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);
195 197
196 // switch to other st-threads. 198 // switch to other st-threads.
197 st_usleep(0); 199 st_usleep(0);
@@ -223,8 +225,9 @@ int SrsClient::streaming_play(SrsSource* source) @@ -223,8 +225,9 @@ int SrsClient::streaming_play(SrsSource* source)
223 } 225 }
224 226
225 // reportable 227 // reportable
226 - if (server->can_report(reported_time, report_time)) {  
227 - srs_trace("play report, time=%"PRId64", ctl_msg_ret=%d, msgs=%d", report_time, ctl_msg_ret, count); 228 + if (pithy_print.can_print()) {
  229 + srs_trace("-> clock=%u, time=%"PRId64", cmr=%d, msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  230 + (int)srs_get_system_time_ms(), pithy_print.get_age(), ctl_msg_ret, count, rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
228 } 231 }
229 232
230 if (count <= 0) { 233 if (count <= 0) {
@@ -251,10 +254,12 @@ int SrsClient::streaming_play(SrsSource* source) @@ -251,10 +254,12 @@ int SrsClient::streaming_play(SrsSource* source)
251 return ret; 254 return ret;
252 } 255 }
253 256
254 -int SrsClient::streaming_publish(SrsSource* source, bool is_fmle) 257 +int SrsClient::publish(SrsSource* source, bool is_fmle)
255 { 258 {
256 int ret = ERROR_SUCCESS; 259 int ret = ERROR_SUCCESS;
257 260
  261 + SrsPithyPrint pithy_print(SRS_STAGE_PUBLISH_USER);
  262 +
258 while (true) { 263 while (true) {
259 // switch to other st-threads. 264 // switch to other st-threads.
260 st_usleep(0); 265 st_usleep(0);
@@ -267,6 +272,14 @@ int SrsClient::streaming_publish(SrsSource* source, bool is_fmle) @@ -267,6 +272,14 @@ int SrsClient::streaming_publish(SrsSource* source, bool is_fmle)
267 272
268 SrsAutoFree(SrsCommonMessage, msg, false); 273 SrsAutoFree(SrsCommonMessage, msg, false);
269 274
  275 + pithy_print.set_age(msg->header.timestamp);
  276 +
  277 + // reportable
  278 + if (pithy_print.can_print()) {
  279 + srs_trace("<- clock=%u, time=%"PRId64", obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
  280 + (int)srs_get_system_time_ms(), pithy_print.get_age(), rtmp->get_send_bytes(), rtmp->get_recv_bytes(), rtmp->get_send_kbps(), rtmp->get_recv_kbps());
  281 + }
  282 +
270 // process audio packet 283 // process audio packet
271 if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) { 284 if (msg->header.is_audio() && ((ret = source->on_audio(msg)) != ERROR_SUCCESS)) {
272 srs_error("process audio message failed. ret=%d", ret); 285 srs_error("process audio message failed. ret=%d", ret);
@@ -357,7 +370,7 @@ int SrsClient::get_peer_ip() @@ -357,7 +370,7 @@ int SrsClient::get_peer_ip()
357 ip = new char[strlen(buf) + 1]; 370 ip = new char[strlen(buf) + 1];
358 strcpy(ip, buf); 371 strcpy(ip, buf);
359 372
360 - srs_trace("get peer ip success. ip=%s, fd=%d", ip, fd); 373 + srs_verbose("get peer ip success. ip=%s, fd=%d", ip, fd);
361 374
362 return ret; 375 return ret;
363 } 376 }
@@ -53,8 +53,8 @@ public: @@ -53,8 +53,8 @@ public:
53 protected: 53 protected:
54 virtual int do_cycle(); 54 virtual int do_cycle();
55 private: 55 private:
56 - virtual int streaming_play(SrsSource* source);  
57 - virtual int streaming_publish(SrsSource* source, bool is_fmle); 56 + virtual int playing(SrsSource* source);
  57 + virtual int publish(SrsSource* source, bool is_fmle);
58 virtual int get_peer_ip(); 58 virtual int get_peer_ip();
59 }; 59 };
60 60
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <srs_core_pithy_print.hpp>
  25 +
  26 +#include <map>
  27 +
  28 +#include <srs_core_log.hpp>
  29 +
  30 +#define SRS_STAGE_DEFAULT_INTERVAL_MS 1200
  31 +#define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
  32 +#define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
  33 +
  34 +struct SrsStageInfo
  35 +{
  36 + int stage_id;
  37 + int pithy_print_time_ms;
  38 + int nb_clients;
  39 +
  40 + SrsStageInfo(int _stage_id)
  41 + {
  42 + stage_id = _stage_id;
  43 +
  44 + switch (_stage_id) {
  45 + case SRS_STAGE_PLAY_USER:
  46 + pithy_print_time_ms = SRS_STAGE_PLAY_USER_INTERVAL_MS;
  47 + case SRS_STAGE_PUBLISH_USER:
  48 + pithy_print_time_ms = SRS_STAGE_PUBLISH_USER_INTERVAL_MS;
  49 + break;
  50 + default:
  51 + pithy_print_time_ms = SRS_STAGE_DEFAULT_INTERVAL_MS;
  52 + break;
  53 + }
  54 +
  55 + nb_clients = 0;
  56 + }
  57 +};
  58 +static std::map<int, SrsStageInfo*> _srs_stages;
  59 +
  60 +SrsPithyPrint::SrsPithyPrint(int _stage_id)
  61 +{
  62 + stage_id = _stage_id;
  63 + client_id = enter_stage();
  64 + printed_age = age = 0;
  65 +}
  66 +
  67 +SrsPithyPrint::~SrsPithyPrint()
  68 +{
  69 + leave_stage();
  70 +}
  71 +
  72 +int SrsPithyPrint::enter_stage()
  73 +{
  74 + SrsStageInfo* stage = NULL;
  75 +
  76 + std::map<int, SrsStageInfo*>::iterator it = _srs_stages.find(stage_id);
  77 + if (it == _srs_stages.end()) {
  78 + stage = _srs_stages[stage_id] = new SrsStageInfo(stage_id);
  79 + } else {
  80 + stage = it->second;
  81 + }
  82 +
  83 + srs_assert(stage != NULL);
  84 + client_id = stage->nb_clients++;
  85 +
  86 + srs_verbose("enter stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
  87 + stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
  88 +
  89 + return client_id;
  90 +}
  91 +
  92 +void SrsPithyPrint::leave_stage()
  93 +{
  94 + SrsStageInfo* stage = _srs_stages[stage_id];
  95 + srs_assert(stage != NULL);
  96 +
  97 + stage->nb_clients--;
  98 +
  99 + srs_verbose("leave stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
  100 + stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
  101 +}
  102 +
  103 +void SrsPithyPrint::elapse(int64_t time_ms)
  104 +{
  105 + age += time_ms;
  106 +}
  107 +
  108 +bool SrsPithyPrint::can_print()
  109 +{
  110 + SrsStageInfo* stage = _srs_stages[stage_id];
  111 + srs_assert(stage != NULL);
  112 +
  113 + int64_t alive_age = age - printed_age;
  114 + int64_t can_print_age = stage->nb_clients * stage->pithy_print_time_ms;
  115 +
  116 + bool can_print = alive_age >= can_print_age;
  117 + if (can_print) {
  118 + printed_age = age;
  119 + }
  120 +
  121 + return can_print;
  122 +}
  123 +
  124 +int64_t SrsPithyPrint::get_age()
  125 +{
  126 + return age;
  127 +}
  128 +
  129 +void SrsPithyPrint::set_age(int64_t _age)
  130 +{
  131 + age = _age;
  132 +}
  133 +
  1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013 winlin
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#ifndef SRS_CORE_PITHY_PRINT_HPP
  25 +#define SRS_CORE_PITHY_PRINT_HPP
  26 +
  27 +/*
  28 +#include <srs_core_pithy_print.hpp>
  29 +*/
  30 +
  31 +#include <srs_core.hpp>
  32 +
  33 +// the pithy stage for all play clients.
  34 +#define SRS_STAGE_PLAY_USER 1
  35 +// the pithy stage for all publish clients.
  36 +#define SRS_STAGE_PUBLISH_USER 2
  37 +
  38 +/**
  39 +* the stage is used for a collection of object to do print,
  40 +* the print time in a stage is constant and not changed.
  41 +* for example, stage #1 for all play clients, print time is 3s,
  42 +* if there is 10clients, then all clients should print in 10*3s.
  43 +*/
  44 +class SrsPithyPrint
  45 +{
  46 +private:
  47 + int client_id;
  48 + int stage_id;
  49 + int64_t age;
  50 + int64_t printed_age;
  51 +public:
  52 + /**
  53 + * @param _stage_id defined in SRS_STAGE_xxx, eg. SRS_STAGE_PLAY_USER.
  54 + */
  55 + SrsPithyPrint(int _stage_id);
  56 + virtual ~SrsPithyPrint();
  57 +private:
  58 + /**
  59 + * enter the specified stage, return the client id.
  60 + */
  61 + virtual int enter_stage();
  62 + /**
  63 + * leave the specified stage, release the client id.
  64 + */
  65 + virtual void leave_stage();
  66 +public:
  67 + /**
  68 + * specified client elapse some time.
  69 + */
  70 + virtual void elapse(int64_t time_ms);
  71 + /**
  72 + * whether current client can print.
  73 + */
  74 + virtual bool can_print();
  75 + /**
  76 + * get the elapsed time in ms.
  77 + */
  78 + virtual int64_t get_age();
  79 + virtual void set_age(int64_t _age);
  80 +};
  81 +
  82 +#endif
@@ -296,6 +296,26 @@ void SrsProtocol::set_send_timeout(int64_t timeout_us) @@ -296,6 +296,26 @@ void SrsProtocol::set_send_timeout(int64_t timeout_us)
296 return skt->set_send_timeout(timeout_us); 296 return skt->set_send_timeout(timeout_us);
297 } 297 }
298 298
  299 +int64_t SrsProtocol::get_recv_bytes()
  300 +{
  301 + return skt->get_recv_bytes();
  302 +}
  303 +
  304 +int64_t SrsProtocol::get_send_bytes()
  305 +{
  306 + return skt->get_send_bytes();
  307 +}
  308 +
  309 +int SrsProtocol::get_recv_kbps()
  310 +{
  311 + return skt->get_recv_kbps();
  312 +}
  313 +
  314 +int SrsProtocol::get_send_kbps()
  315 +{
  316 + return skt->get_send_kbps();
  317 +}
  318 +
299 int SrsProtocol::recv_message(SrsCommonMessage** pmsg) 319 int SrsProtocol::recv_message(SrsCommonMessage** pmsg)
300 { 320 {
301 *pmsg = NULL; 321 *pmsg = NULL;
@@ -110,6 +110,10 @@ public: @@ -110,6 +110,10 @@ public:
110 virtual void set_recv_timeout(int64_t timeout_us); 110 virtual void set_recv_timeout(int64_t timeout_us);
111 virtual int64_t get_recv_timeout(); 111 virtual int64_t get_recv_timeout();
112 virtual void set_send_timeout(int64_t timeout_us); 112 virtual void set_send_timeout(int64_t timeout_us);
  113 + virtual int64_t get_recv_bytes();
  114 + virtual int64_t get_send_bytes();
  115 + virtual int get_recv_kbps();
  116 + virtual int get_send_kbps();
113 /** 117 /**
114 * recv a message with raw/undecoded payload from peer. 118 * recv a message with raw/undecoded payload from peer.
115 * the payload is not decoded, use srs_rtmp_expect_message<T> if requires 119 * the payload is not decoded, use srs_rtmp_expect_message<T> if requires
@@ -164,6 +164,26 @@ void SrsRtmp::set_send_timeout(int64_t timeout_us) @@ -164,6 +164,26 @@ void SrsRtmp::set_send_timeout(int64_t timeout_us)
164 return protocol->set_send_timeout(timeout_us); 164 return protocol->set_send_timeout(timeout_us);
165 } 165 }
166 166
  167 +int64_t SrsRtmp::get_recv_bytes()
  168 +{
  169 + return protocol->get_recv_bytes();
  170 +}
  171 +
  172 +int64_t SrsRtmp::get_send_bytes()
  173 +{
  174 + return protocol->get_send_bytes();
  175 +}
  176 +
  177 +int SrsRtmp::get_recv_kbps()
  178 +{
  179 + return protocol->get_recv_kbps();
  180 +}
  181 +
  182 +int SrsRtmp::get_send_kbps()
  183 +{
  184 + return protocol->get_send_kbps();
  185 +}
  186 +
167 int SrsRtmp::recv_message(SrsCommonMessage** pmsg) 187 int SrsRtmp::recv_message(SrsCommonMessage** pmsg)
168 { 188 {
169 return protocol->recv_message(pmsg); 189 return protocol->recv_message(pmsg);
@@ -108,6 +108,10 @@ public: @@ -108,6 +108,10 @@ public:
108 virtual void set_recv_timeout(int64_t timeout_us); 108 virtual void set_recv_timeout(int64_t timeout_us);
109 virtual int64_t get_recv_timeout(); 109 virtual int64_t get_recv_timeout();
110 virtual void set_send_timeout(int64_t timeout_us); 110 virtual void set_send_timeout(int64_t timeout_us);
  111 + virtual int64_t get_recv_bytes();
  112 + virtual int64_t get_send_bytes();
  113 + virtual int get_recv_kbps();
  114 + virtual int get_send_kbps();
111 virtual int recv_message(SrsCommonMessage** pmsg); 115 virtual int recv_message(SrsCommonMessage** pmsg);
112 virtual int send_message(ISrsMessage* msg); 116 virtual int send_message(ISrsMessage* msg);
113 public: 117 public:
@@ -36,14 +36,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -36,14 +36,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 #include <srs_core_client.hpp> 36 #include <srs_core_client.hpp>
37 37
38 #define SERVER_LISTEN_BACKLOG 10 38 #define SERVER_LISTEN_BACKLOG 10
39 -  
40 -// global value, ensure the report interval,  
41 -// it will be changed when clients increase.  
42 -#define SRS_CONST_REPORT_INTERVAL_MS 3000 39 +#define SRS_TIME_RESOLUTION_MS 1000
43 40
44 SrsServer::SrsServer() 41 SrsServer::SrsServer()
45 { 42 {
46 - srs_report_interval_ms = SRS_CONST_REPORT_INTERVAL_MS;  
47 } 43 }
48 44
49 SrsServer::~SrsServer() 45 SrsServer::~SrsServer()
@@ -140,8 +136,13 @@ int SrsServer::listen(int port) @@ -140,8 +136,13 @@ int SrsServer::listen(int port)
140 int SrsServer::cycle() 136 int SrsServer::cycle()
141 { 137 {
142 int ret = ERROR_SUCCESS; 138 int ret = ERROR_SUCCESS;
143 - // TODO: canbe a api thread.  
144 - st_thread_exit(NULL); 139 +
  140 + // the deamon thread, update the time cache
  141 + while (true) {
  142 + st_usleep(SRS_TIME_RESOLUTION_MS * 1000);
  143 + srs_update_system_time_ms();
  144 + }
  145 +
145 return ret; 146 return ret;
146 } 147 }
147 148
@@ -160,20 +161,6 @@ void SrsServer::remove(SrsConnection* conn) @@ -160,20 +161,6 @@ void SrsServer::remove(SrsConnection* conn)
160 srs_freep(conn); 161 srs_freep(conn);
161 } 162 }
162 163
163 -bool SrsServer::can_report(int64_t& reported, int64_t time)  
164 -{  
165 - if (srs_report_interval_ms <= 0) {  
166 - return false;  
167 - }  
168 -  
169 - if (time - reported < srs_report_interval_ms) {  
170 - return false;  
171 - }  
172 -  
173 - reported = time;  
174 - return true;  
175 -}  
176 -  
177 int SrsServer::accept_client(st_netfd_t client_stfd) 164 int SrsServer::accept_client(st_netfd_t client_stfd)
178 { 165 {
179 int ret = ERROR_SUCCESS; 166 int ret = ERROR_SUCCESS;
@@ -183,9 +170,6 @@ int SrsServer::accept_client(st_netfd_t client_stfd) @@ -183,9 +170,6 @@ int SrsServer::accept_client(st_netfd_t client_stfd)
183 // directly enqueue, the cycle thread will remove the client. 170 // directly enqueue, the cycle thread will remove the client.
184 conns.push_back(conn); 171 conns.push_back(conn);
185 srs_verbose("add conn to vector. conns=%d", (int)conns.size()); 172 srs_verbose("add conn to vector. conns=%d", (int)conns.size());
186 -  
187 - // ensure the report interval is consts  
188 - srs_report_interval_ms = SRS_CONST_REPORT_INTERVAL_MS * (int)conns.size();  
189 173
190 // cycle will start process thread and when finished remove the client. 174 // cycle will start process thread and when finished remove the client.
191 if ((ret = conn->start()) != ERROR_SUCCESS) { 175 if ((ret = conn->start()) != ERROR_SUCCESS) {
@@ -41,7 +41,6 @@ private: @@ -41,7 +41,6 @@ private:
41 int fd; 41 int fd;
42 st_netfd_t stfd; 42 st_netfd_t stfd;
43 std::vector<SrsConnection*> conns; 43 std::vector<SrsConnection*> conns;
44 - int srs_report_interval_ms;  
45 public: 44 public:
46 SrsServer(); 45 SrsServer();
47 virtual ~SrsServer(); 46 virtual ~SrsServer();
@@ -50,7 +49,6 @@ public: @@ -50,7 +49,6 @@ public:
50 virtual int listen(int port); 49 virtual int listen(int port);
51 virtual int cycle(); 50 virtual int cycle();
52 virtual void remove(SrsConnection* conn); 51 virtual void remove(SrsConnection* conn);
53 - virtual bool can_report(int64_t& reported, int64_t time);  
54 private: 52 private:
55 virtual int accept_client(st_netfd_t client_stfd); 53 virtual int accept_client(st_netfd_t client_stfd);
56 virtual void listen_cycle(); 54 virtual void listen_cycle();
@@ -30,6 +30,7 @@ SrsSocket::SrsSocket(st_netfd_t client_stfd) @@ -30,6 +30,7 @@ SrsSocket::SrsSocket(st_netfd_t client_stfd)
30 stfd = client_stfd; 30 stfd = client_stfd;
31 send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT; 31 send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT;
32 recv_bytes = send_bytes = 0; 32 recv_bytes = send_bytes = 0;
  33 + start_time_ms = srs_get_system_time_ms();
33 } 34 }
34 35
35 SrsSocket::~SrsSocket() 36 SrsSocket::~SrsSocket()
@@ -61,6 +62,28 @@ int64_t SrsSocket::get_send_bytes() @@ -61,6 +62,28 @@ int64_t SrsSocket::get_send_bytes()
61 return send_bytes; 62 return send_bytes;
62 } 63 }
63 64
  65 +int SrsSocket::get_recv_kbps()
  66 +{
  67 + int64_t diff_ms = srs_get_system_time_ms() - start_time_ms;
  68 +
  69 + if (diff_ms <= 0) {
  70 + return 0;
  71 + }
  72 +
  73 + return recv_bytes * 8 / diff_ms;
  74 +}
  75 +
  76 +int SrsSocket::get_send_kbps()
  77 +{
  78 + int64_t diff_ms = srs_get_system_time_ms() - start_time_ms;
  79 +
  80 + if (diff_ms <= 0) {
  81 + return 0;
  82 + }
  83 +
  84 + return send_bytes * 8 / diff_ms;
  85 +}
  86 +
64 int SrsSocket::read(const void* buf, size_t size, ssize_t* nread) 87 int SrsSocket::read(const void* buf, size_t size, ssize_t* nread)
65 { 88 {
66 int ret = ERROR_SUCCESS; 89 int ret = ERROR_SUCCESS;
@@ -43,6 +43,7 @@ private: @@ -43,6 +43,7 @@ private:
43 int64_t send_timeout; 43 int64_t send_timeout;
44 int64_t recv_bytes; 44 int64_t recv_bytes;
45 int64_t send_bytes; 45 int64_t send_bytes;
  46 + int64_t start_time_ms;
46 st_netfd_t stfd; 47 st_netfd_t stfd;
47 public: 48 public:
48 SrsSocket(st_netfd_t client_stfd); 49 SrsSocket(st_netfd_t client_stfd);
@@ -53,6 +54,8 @@ public: @@ -53,6 +54,8 @@ public:
53 virtual void set_send_timeout(int64_t timeout_us); 54 virtual void set_send_timeout(int64_t timeout_us);
54 virtual int64_t get_recv_bytes(); 55 virtual int64_t get_recv_bytes();
55 virtual int64_t get_send_bytes(); 56 virtual int64_t get_send_bytes();
  57 + virtual int get_recv_kbps();
  58 + virtual int get_send_kbps();
56 public: 59 public:
57 virtual int read(const void* buf, size_t size, ssize_t* nread); 60 virtual int read(const void* buf, size_t size, ssize_t* nread);
58 virtual int read_fully(const void* buf, size_t size, ssize_t* nread); 61 virtual int read_fully(const void* buf, size_t size, ssize_t* nread);
@@ -32,6 +32,8 @@ file @@ -32,6 +32,8 @@ file
32 ..\core\srs_core_socket.cpp, 32 ..\core\srs_core_socket.cpp,
33 ..\core\srs_core_buffer.hpp, 33 ..\core\srs_core_buffer.hpp,
34 ..\core\srs_core_buffer.cpp, 34 ..\core\srs_core_buffer.cpp,
  35 + ..\core\srs_core_pithy_print.hpp,
  36 + ..\core\srs_core_pithy_print.cpp,
35 ..\core\srs_core_log.hpp, 37 ..\core\srs_core_log.hpp,
36 ..\core\srs_core_log.cpp; 38 ..\core\srs_core_log.cpp;
37 mainconfig 39 mainconfig