diff --git a/README.md b/README.md index eba12479f..e0da5469f 100755 --- a/README.md +++ b/README.md @@ -162,6 +162,7 @@ Please select according to languages: ### V3 changes +* v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48 * v3.0, 2019-04-06, Merge [#1304][bug #1304], Fix ST coroutine pull error. 3.0.47 * v3.0, 2019-04-05, Merge [#1339][bug #1339], Support HTTP-FLV params. 3.0.46 * v3.0, 2018-11-11, Merge [#1261][bug #1261], Support `_definst_` for Wowza. 3.0.44 diff --git a/trunk/.gitignore b/trunk/.gitignore index 6ec2ebd1d..45ec1cf0b 100644 --- a/trunk/.gitignore +++ b/trunk/.gitignore @@ -37,4 +37,5 @@ srs *.dSYM/ *.gcov *.ts - +*.h264 +*.264 diff --git a/trunk/720p.h264.264 b/trunk/720p.h264.264 deleted file mode 100644 index 571b528c6..000000000 Binary files a/trunk/720p.h264.264 and /dev/null differ diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index 029613dd7..bfd650e7d 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -103,6 +103,12 @@ else srs_undefine_macro "SRS_AUTO_MEM_WATCH" $SRS_AUTO_HEADERS_H fi +if [ $SRS_UTEST = YES ]; then + srs_define_macro "SRS_AUTO_UTEST" $SRS_AUTO_HEADERS_H +else + srs_undefine_macro "SRS_AUTO_UTEST" $SRS_AUTO_HEADERS_H +fi + # whether compile ffmpeg tool if [ $SRS_FFMPEG_TOOL = YES ]; then srs_define_macro "SRS_AUTO_FFMPEG_TOOL" $SRS_AUTO_HEADERS_H diff --git a/trunk/auto/utest.sh b/trunk/auto/utest.sh index 903ea7b40..d658bf7f4 100755 --- a/trunk/auto/utest.sh +++ b/trunk/auto/utest.sh @@ -179,7 +179,7 @@ echo "" >> ${FILE}; echo "" >> ${FILE} # echo "# generate the utest binary" >> ${FILE} cat << END >> ${FILE} -${SRS_TRUNK_PREFIX}/${SRS_OBJS_DIR}/${APP_NAME} : \$(SRS_UTEST_DEPS) ${MODULE_OBJS} gtest_main.a +${SRS_TRUNK_PREFIX}/${SRS_OBJS_DIR}/${APP_NAME} : \$(SRS_UTEST_DEPS) ${MODULE_OBJS} gtest.a \$(CXX) -o \$@ \$(CPPFLAGS) \$(CXXFLAGS) \$^ \$(DEPS_LIBRARIES_FILES) ${LINK_OPTIONS} END diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 8d6e82da9..cf3e0217e 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -49,7 +49,7 @@ daemon on; # if on, use gmtime() instead, which use UTC time. # default: off utc_time off; -# config for the pithy print, +# config for the pithy print in ms, # which always print constant message specified by interval, # whatever the clients in concurrency. # default: 10000 diff --git a/trunk/configure b/trunk/configure index 6971c7654..421b51ab6 100755 --- a/trunk/configure +++ b/trunk/configure @@ -172,7 +172,8 @@ fi MODULE_ID="CORE" MODULE_DEPENDS=() ModuleLibIncs=(${SRS_OBJS_DIR}) -MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance" "srs_core_mem_watch") +MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance" + "srs_core_mem_watch" "srs_core_time") CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh CORE_OBJS="${MODULE_OBJS[@]}" # @@ -315,7 +316,7 @@ fi if [ $SRS_UTEST = YES ]; then MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" "srs_utest_kernel" "srs_utest_core" "srs_utest_config" - "srs_utest_reload") + "srs_utest_reload" "srs_utest_service" "srs_utest_app") ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot}) ModuleLibFiles=(${LibSTfile} ${LibSSLfile}) MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP") diff --git a/trunk/src/app/srs_app_bandwidth.cpp b/trunk/src/app/srs_app_bandwidth.cpp index a490811b7..3981a6ccc 100644 --- a/trunk/src/app/srs_app_bandwidth.cpp +++ b/trunk/src/app/srs_app_bandwidth.cpp @@ -37,17 +37,17 @@ using namespace std; #include #include -#define _SRS_BANDWIDTH_LIMIT_INTERVAL_MS 100 +#define _SRS_BANDWIDTH_LIMIT_INTERVAL 100 * SRS_UTIME_MILLISECONDS // default sample duration, in ms -#define _SRS_BANDWIDTH_SAMPLE_DURATION_MS 3000 +#define _SRS_BANDWIDTH_SAMPLE_DURATION 3000 * SRS_UTIME_MILLISECONDS // wait for a while for flash to got all packets. -#define _SRS_BANDWIDTH_FINAL_WAIT_MS 600 +#define _SRS_BANDWIDTH_FINAL_WAIT 600 * SRS_UTIME_MILLISECONDS SrsBandwidthSample::SrsBandwidthSample() { - duration_ms = _SRS_BANDWIDTH_SAMPLE_DURATION_MS; + duration_ms = _SRS_BANDWIDTH_SAMPLE_DURATION; kbps = interval_ms = actual_duration_ms = bytes = 0; } @@ -144,15 +144,14 @@ srs_error_t SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStati // to prevent bandwidth check attack, // if client request check in the window(specifeid by interval), // directly reject the request. - static int64_t last_check_time = 0; - int interval_ms = _srs_config->get_bw_check_interval_ms(_req->vhost); + static srs_utime_t last_check_time = 0; + srs_utime_t interval = _srs_config->get_bw_check_interval(_req->vhost); - srs_update_system_time_ms(); - int64_t time_now = srs_get_system_time_ms(); + srs_utime_t time_now = srs_update_system_time(); // reject the connection in the interval window. - if (last_check_time > 0 && time_now - last_check_time < interval_ms) { + if (last_check_time > 0 && time_now - last_check_time < interval) { _rtmp->response_connect_reject(_req, "bandcheck rejected"); - return srs_error_new(ERROR_SYSTEM_BANDWIDTH_DENIED, "reject, last_check=%" PRId64 ", now=%" PRId64 ", interval=%d", last_check_time, time_now, interval_ms); + return srs_error_new(ERROR_SYSTEM_BANDWIDTH_DENIED, "reject, last_check=%" PRId64 ", now=%" PRId64 ", interval=%d", last_check_time, time_now, interval); } // accept and do bandwidth check. @@ -185,8 +184,7 @@ srs_error_t SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) _rtmp->set_recv_timeout(publish_sample.duration_ms * 2); // start test. - srs_update_system_time_ms(); - int64_t start_time = srs_get_system_time_ms(); + srs_utime_t start_time = srs_update_system_time(); // sample play if ((err = play_start(&play_sample, limit)) != srs_success) { @@ -211,19 +209,18 @@ srs_error_t SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) } // stop test. - srs_update_system_time_ms(); - int64_t end_time = srs_get_system_time_ms(); - - srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", - (int)(end_time - start_time), play_sample.actual_duration_ms, - publish_sample.actual_duration_ms, play_sample.kbps, - publish_sample.kbps); + srs_utime_t end_time = srs_update_system_time(); if ((err = do_final(play_sample, publish_sample, start_time, end_time)) != srs_success) { return srs_error_wrap(err, "final"); } + + srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", + srsu2msi(end_time - start_time), play_sample.actual_duration_ms, + publish_sample.actual_duration_ms, play_sample.kbps, + publish_sample.kbps); - srs_usleep(_SRS_BANDWIDTH_FINAL_WAIT_MS * 1000); + srs_usleep(_SRS_BANDWIDTH_FINAL_WAIT); return err; } @@ -262,10 +259,9 @@ srs_error_t SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit memset(random_data, 'A', size); int data_count = 1; - srs_update_system_time_ms(); - int64_t starttime = srs_get_system_time_ms(); - while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { - srs_usleep(sample->interval_ms); + srs_utime_t starttime = srs_update_system_time(); + while (int64_t(srsu2ms(srs_get_system_time() - starttime)) < sample->duration_ms) { + srs_usleep(sample->interval_ms * SRS_UTIME_MILLISECONDS); // TODO: FIXME: use shared ptr message. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing(); @@ -285,8 +281,8 @@ srs_error_t SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit limit->send_limit(); } - srs_update_system_time_ms(); - sample->calc_kbps((int)_rtmp->get_send_bytes(), (int)(srs_get_system_time_ms() - starttime)); + srs_update_system_time(); + sample->calc_kbps((int)_rtmp->get_send_bytes(), srsu2msi(srs_get_system_time() - starttime)); return err; } @@ -345,9 +341,8 @@ srs_error_t SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLi srs_error_t err = srs_success; // recv publish msgs until @duration_ms ms - srs_update_system_time_ms(); - int64_t starttime = srs_get_system_time_ms(); - while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { + srs_utime_t starttime = srs_update_system_time(); + while (int64_t(srsu2ms(srs_get_system_time() - starttime)) < sample->duration_ms) { SrsCommonMessage* msg = NULL; SrsBandwidthPacket* pkt = NULL; if ((err = _rtmp->expect_message(&msg, &pkt)) != srs_success) { @@ -364,8 +359,8 @@ srs_error_t SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLi limit->recv_limit(); } - srs_update_system_time_ms(); - sample->calc_kbps((int)_rtmp->get_recv_bytes(), (int)(srs_get_system_time_ms() - starttime)); + srs_update_system_time(); + sample->calc_kbps((int)_rtmp->get_recv_bytes(), srsu2msi(srs_get_system_time() - starttime)); return err; } @@ -402,7 +397,7 @@ srs_error_t SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* return err; } -srs_error_t SrsBandwidth::do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time) +srs_error_t SrsBandwidth::do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time) { srs_error_t err = srs_success; @@ -410,8 +405,8 @@ srs_error_t SrsBandwidth::do_final(SrsBandwidthSample& play_sample, SrsBandwidth // flash client will close connection when got this packet, // for the publish queue may contains packets. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_finish(); - pkt->data->set("start_time", SrsAmf0Any::number(start_time)); - pkt->data->set("end_time", SrsAmf0Any::number(end_time)); + pkt->data->set("start_time", SrsAmf0Any::number(srsu2ms(start_time))); + pkt->data->set("end_time", SrsAmf0Any::number(srsu2ms(end_time))); pkt->data->set("play_kbps", SrsAmf0Any::number(play_sample.kbps)); pkt->data->set("publish_kbps", SrsAmf0Any::number(publish_sample.kbps)); pkt->data->set("play_bytes", SrsAmf0Any::number(play_sample.bytes)); @@ -457,7 +452,7 @@ void SrsKbpsLimit::recv_limit() while (_kbps->get_recv_kbps() > _limit_kbps) { _kbps->sample(); - srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000); + srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL); } } @@ -468,7 +463,7 @@ void SrsKbpsLimit::send_limit() while (_kbps->get_send_kbps() > _limit_kbps) { _kbps->sample(); - srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL_MS * 1000); + srs_usleep(_SRS_BANDWIDTH_LIMIT_INTERVAL); } } diff --git a/trunk/src/app/srs_app_bandwidth.hpp b/trunk/src/app/srs_app_bandwidth.hpp index 0573ad423..0afdf9e07 100644 --- a/trunk/src/app/srs_app_bandwidth.hpp +++ b/trunk/src/app/srs_app_bandwidth.hpp @@ -193,7 +193,7 @@ private: * for flash client, the sent queue is fullfill with publishing call messages, * so server never expect the final packet from it. */ - virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time); + virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time); }; /** diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index 221c7c13d..086afdcde 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -192,8 +192,8 @@ srs_error_t SrsDynamicHttpConn::do_proxy(ISrsHttpResponseReader* rr, SrsFlvDecod srs_freep(sdk); - int64_t cto = SRS_CONSTS_RTMP_TMMS; - int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; + int64_t cto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_PULSE); sdk = new SrsSimpleRtmpClient(output, cto, sto); if ((err = sdk->connect()) != srs_success) { diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index a23285146..644eb0ee5 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3959,7 +3959,12 @@ srs_error_t SrsConfig::check_number_connections() srs_error_t SrsConfig::parse_buffer(SrsConfigBuffer* buffer) { srs_error_t err = srs_success; - + + // We use a new root to parse buffer, to allow parse multiple times. + srs_freep(root); + root = new SrsConfDirective(); + + // Parse root tree from buffer. if ((err = root->parse(buffer)) != srs_success) { return srs_error_wrap(err, "root parse"); } @@ -4050,16 +4055,16 @@ string SrsConfig::get_pid_file() return conf->arg0(); } -int SrsConfig::get_pithy_print_ms() +srs_utime_t SrsConfig::get_pithy_print() { - static int DEFAULT = 10000; + static srs_utime_t DEFAULT = 10 * SRS_UTIME_SECONDS; SrsConfDirective* conf = root->get("pithy_print_ms"); if (!conf || conf->arg0().empty()) { return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_MILLISECONDS); } bool SrsConfig::get_utc_time() @@ -4649,44 +4654,48 @@ bool SrsConfig::get_mr_enabled(string vhost) return SRS_CONF_PERFER_FALSE(conf->arg0()); } -int SrsConfig::get_mr_sleep_ms(string vhost) +srs_utime_t SrsConfig::get_mr_sleep(string vhost) { + static srs_utime_t DEFAULT = SRS_PERF_MR_SLEEP; + SrsConfDirective* conf = get_vhost(vhost); if (!conf) { - return SRS_PERF_MR_SLEEP; + return DEFAULT; } conf = conf->get("publish"); if (!conf) { - return SRS_PERF_MR_SLEEP; + return DEFAULT; } conf = conf->get("mr_latency"); if (!conf || conf->arg0().empty()) { - return SRS_PERF_MR_SLEEP; + return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_MILLISECONDS); } -int SrsConfig::get_mw_sleep_ms(string vhost) +srs_utime_t SrsConfig::get_mw_sleep(string vhost) { + static srs_utime_t DEFAULT = SRS_PERF_MW_SLEEP; + SrsConfDirective* conf = get_vhost(vhost); if (!conf) { - return SRS_PERF_MW_SLEEP; + return DEFAULT; } conf = conf->get("play"); if (!conf) { - return SRS_PERF_MW_SLEEP; + return DEFAULT; } conf = conf->get("mw_latency"); if (!conf || conf->arg0().empty()) { - return SRS_PERF_MW_SLEEP; + return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_MILLISECONDS); } bool SrsConfig::get_realtime_enabled(string vhost) @@ -4765,10 +4774,10 @@ bool SrsConfig::get_reduce_sequence_header(string vhost) return SRS_CONF_PERFER_FALSE(conf->arg0()); } -int SrsConfig::get_publish_1stpkt_timeout(string vhost) +srs_utime_t SrsConfig::get_publish_1stpkt_timeout(string vhost) { // when no msg recevied for publisher, use larger timeout. - static int DEFAULT = 20000; + static srs_utime_t DEFAULT = 20 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_vhost(vhost); if (!conf) { @@ -4785,15 +4794,15 @@ int SrsConfig::get_publish_1stpkt_timeout(string vhost) return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_MILLISECONDS); } -int SrsConfig::get_publish_normal_timeout(string vhost) +srs_utime_t SrsConfig::get_publish_normal_timeout(string vhost) { // the timeout for publish recv. // we must use more smaller timeout, for the recv never know the status // of underlayer socket. - static int DEFAULT = 5000; + static srs_utime_t DEFAULT = 5 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_vhost(vhost); if (!conf) { @@ -4810,7 +4819,7 @@ int SrsConfig::get_publish_normal_timeout(string vhost) return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_MILLISECONDS); } int SrsConfig::get_global_chunk_size() @@ -5021,9 +5030,9 @@ string SrsConfig::get_bw_check_key(string vhost) return conf->arg0(); } -int SrsConfig::get_bw_check_interval_ms(string vhost) +srs_utime_t SrsConfig::get_bw_check_interval(string vhost) { - static int DEFAULT = 30 * 1000; + static int64_t DEFAULT = 30 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_vhost(vhost); if (!conf) { @@ -5040,7 +5049,7 @@ int SrsConfig::get_bw_check_interval_ms(string vhost) return DEFAULT; } - return (int)(::atof(conf->arg0().c_str()) * 1000); + return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } int SrsConfig::get_bw_check_limit_kbps(string vhost) @@ -5890,9 +5899,9 @@ bool SrsConfig::get_dash_enabled(string vhost) return SRS_CONF_PERFER_FALSE(conf->arg0()); } -int SrsConfig::get_dash_fragment(string vhost) +srs_utime_t SrsConfig::get_dash_fragment(string vhost) { - static int DEFAULT = 3 * 1000; + static int DEFAULT = 3 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_dash(vhost); if (!conf) { @@ -5904,12 +5913,12 @@ int SrsConfig::get_dash_fragment(string vhost) return DEFAULT; } - return (int)(1000 * ::atof(conf->arg0().c_str())); + return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } -int SrsConfig::get_dash_update_period(string vhost) +srs_utime_t SrsConfig::get_dash_update_period(string vhost) { - static int DEFAULT = 30 * 1000; + static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_dash(vhost); if (!conf) { @@ -5921,12 +5930,12 @@ int SrsConfig::get_dash_update_period(string vhost) return DEFAULT; } - return (int)(1000 * ::atof(conf->arg0().c_str())); + return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } -int SrsConfig::get_dash_timeshift(string vhost) +srs_utime_t SrsConfig::get_dash_timeshift(string vhost) { - static int DEFAULT = 60 * 1000; + static srs_utime_t DEFAULT = 60 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_dash(vhost); if (!conf) { @@ -5938,7 +5947,7 @@ int SrsConfig::get_dash_timeshift(string vhost) return DEFAULT; } - return (int)(1000 * ::atof(conf->arg0().c_str())); + return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } string SrsConfig::get_dash_path(string vhost) @@ -6238,9 +6247,9 @@ bool SrsConfig::get_hls_cleanup(string vhost) return SRS_CONF_PERFER_TRUE(conf->arg0()); } -int SrsConfig::get_hls_dispose(string vhost) +srs_utime_t SrsConfig::get_hls_dispose(string vhost) { - static int DEFAULT = 0; + static srs_utime_t DEFAULT = 0; SrsConfDirective* conf = get_hls(vhost); if (!conf) { @@ -6252,7 +6261,7 @@ int SrsConfig::get_hls_dispose(string vhost) return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } bool SrsConfig::get_hls_wait_keyframe(string vhost) @@ -6515,9 +6524,9 @@ string SrsConfig::get_dvr_plan(string vhost) return conf->arg0(); } -int SrsConfig::get_dvr_duration(string vhost) +srs_utime_t SrsConfig::get_dvr_duration(string vhost) { - static int DEFAULT = 30; + static srs_utime_t DEFAULT = 30 * SRS_UTIME_SECONDS; SrsConfDirective* conf = get_dvr(vhost); if (!conf) { @@ -6529,7 +6538,7 @@ int SrsConfig::get_dvr_duration(string vhost) return DEFAULT; } - return ::atoi(conf->arg0().c_str()); + return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } bool SrsConfig::get_dvr_wait_keyframe(string vhost) @@ -6939,9 +6948,9 @@ bool SrsConfig::get_heartbeat_enabled() return SRS_CONF_PERFER_FALSE(conf->arg0()); } -int64_t SrsConfig::get_heartbeat_interval() +srs_utime_t SrsConfig::get_heartbeat_interval() { - static int64_t DEFAULT = (int64_t)(9.9 * 1000); + static srs_utime_t DEFAULT = (srs_utime_t)(9.9 * SRS_UTIME_SECONDS); SrsConfDirective* conf = get_heartbeart(); if (!conf) { @@ -6953,7 +6962,7 @@ int64_t SrsConfig::get_heartbeat_interval() return DEFAULT; } - return (int64_t)(::atof(conf->arg0().c_str()) * 1000); + return (srs_utime_t)(::atof(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } string SrsConfig::get_heartbeat_url() diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index bfea0991a..4fdeb9c0f 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -603,11 +603,11 @@ public: */ virtual std::string get_pid_file(); /** - * get pithy print pulse ms, + * get pithy print pulse in srs_utime_t, * for example, all rtmp connections only print one message * every this interval in ms. */ - virtual int get_pithy_print_ms(); + virtual srs_utime_t get_pithy_print(); /** * whether use utc-time to format the time. */ @@ -774,17 +774,17 @@ public: */ virtual bool get_mr_enabled(std::string vhost); /** - * get the mr sleep time in ms for vhost. + * get the mr sleep time in srs_utime_t for vhost. * @param vhost, the vhost to get the mr sleep time. */ // TODO: FIXME: add utest for mr config. - virtual int get_mr_sleep_ms(std::string vhost); + virtual srs_utime_t get_mr_sleep(std::string vhost); /** - * get the mw sleep time in ms for vhost. + * get the mw sleep time in srs_utime_t for vhost. * @param vhost, the vhost to get the mw sleep time. */ // TODO: FIXME: add utest for mw config. - virtual int get_mw_sleep_ms(std::string vhost); + virtual srs_utime_t get_mw_sleep(std::string vhost); /** * whether min latency mode enabled. * @param vhost, the vhost to get the min_latency. @@ -804,13 +804,13 @@ public: */ virtual bool get_reduce_sequence_header(std::string vhost); /** - * the 1st packet timeout in ms for encoder. + * the 1st packet timeout in srs_utime_t for encoder. */ - virtual int get_publish_1stpkt_timeout(std::string vhost); + virtual srs_utime_t get_publish_1stpkt_timeout(std::string vhost); /** - * the normal packet timeout in ms for encoder. + * the normal packet timeout in srs_utime_t for encoder. */ - virtual int get_publish_normal_timeout(std::string vhost); + virtual srs_utime_t get_publish_normal_timeout(std::string vhost); private: /** * get the global chunk size. @@ -896,12 +896,12 @@ public: */ virtual std::string get_bw_check_key(std::string vhost); /** - * the check interval, in ms. + * the check interval, in srs_utime_t. * if the client request check in very short time(in the interval), * SRS will reject client. * @remark this is used to prevent the bandwidth check attack. */ - virtual int get_bw_check_interval_ms(std::string vhost); + virtual srs_utime_t get_bw_check_interval(std::string vhost); /** * the max kbps that user can test, * if exceed the kbps, server will slowdown the send-recv. @@ -1150,12 +1150,12 @@ private: public: // Whether DASH is enabled. virtual bool get_dash_enabled(std::string vhost); - // Get the duration of segment in milliseconds. - virtual int get_dash_fragment(std::string vhost); - // Get the period to update MPD in milliseconds. - virtual int get_dash_update_period(std::string vhost); - // Get the depth of timeshift buffer in milliseconds. - virtual int get_dash_timeshift(std::string vhost); + // Get the duration of segment in srs_utime_t. + virtual srs_utime_t get_dash_fragment(std::string vhost); + // Get the period to update MPD in srs_utime_t. + virtual srs_utime_t get_dash_update_period(std::string vhost); + // Get the depth of timeshift buffer in srs_utime_t. + virtual srs_utime_t get_dash_timeshift(std::string vhost); // Get the base/home dir/path for dash, into which write files. virtual std::string get_dash_path(std::string vhost); // Get the path for DASH MPD, to generate the MPD file. @@ -1229,9 +1229,9 @@ public: */ virtual bool get_hls_cleanup(std::string vhost); /** - * the timeout to dispose the hls. + * the timeout in srs_utime_t to dispose the hls. */ - virtual int get_hls_dispose(std::string vhost); + virtual srs_utime_t get_hls_dispose(std::string vhost); /** * whether reap the ts when got keyframe. */ @@ -1279,6 +1279,7 @@ public: /** * get the hds fragment time, in seconds. */ + // TODO: FIXME: Refine to time unit. virtual double get_hds_fragment(const std::string &vhost); /** * get the hds window time, in seconds. @@ -1312,7 +1313,7 @@ public: /** * get the duration of dvr flv. */ - virtual int get_dvr_duration(std::string vhost); + virtual srs_utime_t get_dvr_duration(std::string vhost); /** * whether wait keyframe to reap segment. */ @@ -1422,9 +1423,9 @@ public: */ virtual bool get_heartbeat_enabled(); /** - * get the heartbeat interval, in ms. + * get the heartbeat interval, in srs_utime_t. */ - virtual int64_t get_heartbeat_interval(); + virtual srs_utime_t get_heartbeat_interval(); /** * get the heartbeat report url. */ diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp index b26278c22..79188ea95 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -36,7 +36,7 @@ SrsConnection::SrsConnection(IConnectionManager* cm, srs_netfd_t c, string cip) manager = cm; stfd = c; ip = cip; - create_time = srs_get_system_time_ms(); + create_time = srsu2ms(srs_get_system_time()); skt = new SrsStSocket(); clk = new SrsWallClock(); @@ -114,7 +114,7 @@ srs_error_t SrsConnection::set_tcp_nodelay(bool v) return err; } -srs_error_t SrsConnection::set_socket_buffer(int buffer_ms) +srs_error_t SrsConnection::set_socket_buffer(srs_utime_t buffer_v) { srs_error_t err = srs_success; @@ -143,7 +143,7 @@ srs_error_t SrsConnection::set_socket_buffer(int buffer_ms) // 2000*3000/8=750000B(about 732KB). // 2000*5000/8=1250000B(about 1220KB). int kbps = 4000; - int iv = buffer_ms * kbps / 8; + int iv = srsu2ms(buffer_v) * kbps / 8; // socket send buffer, system will double it. iv = iv / 2; @@ -161,7 +161,7 @@ srs_error_t SrsConnection::set_socket_buffer(int buffer_ms) return srs_error_new(ERROR_SOCKET_SNDBUF, "getsockopt fd=%d, r0=%d", fd, r0); } - srs_trace("set fd=%d, SO_SNDBUF=%d=>%d, buffer=%dms", fd, ov, iv, buffer_ms); + srs_trace("set fd=%d, SO_SNDBUF=%d=>%d, buffer=%dms", fd, ov, iv, srsu2ms(buffer_v)); return err; } diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index d21ba074d..01e1e268d 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -103,7 +103,7 @@ public: // Set socket option TCP_NODELAY. virtual srs_error_t set_tcp_nodelay(bool v); // Set socket option SO_SNDBUF in ms. - virtual srs_error_t set_socket_buffer(int buffer_ms); + virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v); // interface ISrsOneCycleThreadHandler public: /** diff --git a/trunk/src/app/srs_app_dash.cpp b/trunk/src/app/srs_app_dash.cpp index 7061cfb99..509410e32 100644 --- a/trunk/src/app/srs_app_dash.cpp +++ b/trunk/src/app/srs_app_dash.cpp @@ -162,7 +162,7 @@ SrsMpdWriter::SrsMpdWriter() { req = NULL; timeshit = update_period = fragment = 0; - last_update_mpd = -1; + last_update_mpd = 0; } SrsMpdWriter::~SrsMpdWriter() @@ -181,7 +181,7 @@ srs_error_t SrsMpdWriter::initialize(SrsRequest* r) string mpd_path = srs_path_build_stream(mpd_file, req->vhost, req->app, req->stream); fragment_home = srs_path_dirname(mpd_path) + "/" + req->stream; - srs_trace("DASH: Config fragment=%d, period=%d", fragment, update_period); + srs_trace("DASH: Config fragment=%" PRId64 ", period=%" PRId64, fragment, update_period); return srs_success; } @@ -190,10 +190,10 @@ srs_error_t SrsMpdWriter::write(SrsFormat* format) srs_error_t err = srs_success; // MPD is not expired? - if (last_update_mpd != -1 && srs_get_system_time_ms() - last_update_mpd < update_period) { + if (last_update_mpd != 0 && srs_get_system_time() - last_update_mpd < update_period) { return err; } - last_update_mpd = srs_get_system_time_ms(); + last_update_mpd = srs_get_system_time(); string mpd_path = srs_path_build_stream(mpd_file, req->vhost, req->app, req->stream); string full_path = home + "/" + mpd_path; @@ -210,14 +210,14 @@ srs_error_t SrsMpdWriter::write(SrsFormat* format) << "" << endl + << " type=\"dynamic\" minimumUpdatePeriod=\"PT" << update_period / SRS_UTIME_SECONDS << "S\" " << endl + << " timeShiftBufferDepth=\"PT" << timeshit / SRS_UTIME_SECONDS << "S\" availabilityStartTime=\"1970-01-01T00:00:00Z\" " << endl + << " maxSegmentDuration=\"PT" << fragment / SRS_UTIME_SECONDS << "S\" minBufferTime=\"PT" << fragment / SRS_UTIME_SECONDS << "S\" >" << endl << " " << req->stream << "/" << "" << endl << " " << endl; if (format->acodec) { ss << " " << endl; - ss << " " << endl; ss << " " << endl; @@ -227,7 +227,7 @@ srs_error_t SrsMpdWriter::write(SrsFormat* format) int w = format->vcodec->width; int h = format->vcodec->height; ss << " " << endl; - ss << " " << endl; ss << " duration() / 1000.0); + SrsAmf0Any* dur = SrsAmf0Any::number((double)srsu2ms(fragment->duration()) / 1000.0); SrsAutoFree(SrsAmf0Any, dur); stream.skip(-1 * stream.pos()); @@ -740,7 +740,7 @@ void SrsDvrSessionPlan::on_unpublish() SrsDvrSegmentPlan::SrsDvrSegmentPlan() { - cduration = -1; + cduration = 0; wait_keyframe = false; } @@ -759,8 +759,6 @@ srs_error_t SrsDvrSegmentPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, S wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost); cduration = _srs_config->get_dvr_duration(req->vhost); - // to ms - cduration *= 1000; return srs_success; } @@ -881,8 +879,6 @@ srs_error_t SrsDvrSegmentPlan::on_reload_vhost_dvr(string vhost) wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost); cduration = _srs_config->get_dvr_duration(req->vhost); - // to ms - cduration *= 1000; return err; } diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp index bcfc67d0a..453f52e86 100644 --- a/trunk/src/app/srs_app_dvr.hpp +++ b/trunk/src/app/srs_app_dvr.hpp @@ -227,8 +227,8 @@ public: class SrsDvrSegmentPlan : public SrsDvrPlan { private: - // in config, in ms - int cduration; + // in config, in srs_utime_t + srs_utime_t cduration; bool wait_keyframe; public: SrsDvrSegmentPlan(); diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index e9873bc49..a6d53508d 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -48,10 +48,10 @@ using namespace std; #include // when edge timeout, retry next. -#define SRS_EDGE_INGESTER_TMMS (5*1000) +#define SRS_EDGE_INGESTER_TMMS (5 * SRS_UTIME_MILLISECONDS) // when edge error, wait for quit -#define SRS_EDGE_FORWARDER_TMMS (150) +#define SRS_EDGE_FORWARDER_TMMS (150 * SRS_UTIME_MILLISECONDS) SrsEdgeUpstream::SrsEdgeUpstream() { @@ -114,8 +114,8 @@ srs_error_t SrsEdgeRtmpUpstream::connect(SrsRequest* r, SrsLbRoundRobin* lb) } srs_freep(sdk); - int64_t cto = SRS_EDGE_INGESTER_TMMS; - int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; + int64_t cto = srsu2ms(SRS_EDGE_INGESTER_TMMS); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_PULSE); sdk = new SrsSimpleRtmpClient(url, cto, sto); if ((err = sdk->connect()) != srs_success) { @@ -218,7 +218,7 @@ string SrsEdgeIngester::get_curr_origin() } // when error, edge ingester sleep for a while and retry. -#define SRS_EDGE_INGESTER_CIMS (3*1000) +#define SRS_EDGE_INGESTER_CIMS (3 * SRS_UTIME_MILLISECONDS) srs_error_t SrsEdgeIngester::cycle() { @@ -234,7 +234,7 @@ srs_error_t SrsEdgeIngester::cycle() return srs_error_wrap(err, "edge ingester"); } - srs_usleep(SRS_EDGE_INGESTER_CIMS * 1000); + srs_usleep(SRS_EDGE_INGESTER_CIMS); } return err; @@ -294,7 +294,7 @@ srs_error_t SrsEdgeIngester::ingest() SrsAutoFree(SrsPithyPrint, pprint); // set to larger timeout to read av data from origin. - upstream->set_recv_timeout(SRS_EDGE_INGESTER_TMMS); + upstream->set_recv_timeout(srsu2ms(SRS_EDGE_INGESTER_TMMS)); while (true) { srs_error_t err = srs_success; @@ -474,8 +474,9 @@ srs_error_t SrsEdgeForwarder::start() // open socket. srs_freep(sdk); - int64_t cto = SRS_EDGE_FORWARDER_TMMS; - int64_t sto = SRS_CONSTS_RTMP_TMMS; + // TODO: FIXME: Should switch cto with sto? + int64_t cto = srsu2ms(SRS_EDGE_FORWARDER_TMMS); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); sdk = new SrsSimpleRtmpClient(url, cto, sto); if ((err = sdk->connect()) != srs_success) { @@ -505,7 +506,7 @@ void SrsEdgeForwarder::stop() } // when error, edge ingester sleep for a while and retry. -#define SRS_EDGE_FORWARDER_CIMS (3*1000) +#define SRS_EDGE_FORWARDER_CIMS (3 * SRS_UTIME_MILLISECONDS) srs_error_t SrsEdgeForwarder::cycle() { @@ -520,7 +521,7 @@ srs_error_t SrsEdgeForwarder::cycle() return srs_error_wrap(err, "thread pull"); } - srs_usleep(SRS_EDGE_FORWARDER_CIMS * 1000); + srs_usleep(SRS_EDGE_FORWARDER_CIMS); } return err; @@ -532,7 +533,7 @@ srs_error_t SrsEdgeForwarder::do_cycle() { srs_error_t err = srs_success; - sdk->set_recv_timeout(SRS_CONSTS_RTMP_PULSE_TMMS); + sdk->set_recv_timeout(srsu2ms(SRS_CONSTS_RTMP_PULSE)); SrsPithyPrint* pprint = SrsPithyPrint::create_edge(); SrsAutoFree(SrsPithyPrint, pprint); @@ -545,7 +546,7 @@ srs_error_t SrsEdgeForwarder::do_cycle() } if (send_error_code != ERROR_SUCCESS) { - srs_usleep(SRS_EDGE_FORWARDER_TMMS * 1000); + srs_usleep(SRS_EDGE_FORWARDER_TMMS); continue; } diff --git a/trunk/src/app/srs_app_encoder.cpp b/trunk/src/app/srs_app_encoder.cpp index eabe754ec..a1cb485ee 100644 --- a/trunk/src/app/srs_app_encoder.cpp +++ b/trunk/src/app/srs_app_encoder.cpp @@ -87,7 +87,7 @@ void SrsEncoder::on_unpublish() } // when error, encoder sleep for a while and retry. -#define SRS_RTMP_ENCODER_CIMS (3000) +#define SRS_RTMP_ENCODER_CIMS (3000 * SRS_UTIME_MILLISECONDS) srs_error_t SrsEncoder::cycle() { @@ -104,7 +104,7 @@ srs_error_t SrsEncoder::cycle() break; } - srs_usleep(SRS_RTMP_ENCODER_CIMS * 1000); + srs_usleep(SRS_RTMP_ENCODER_CIMS); } // kill ffmpeg when finished and it alive diff --git a/trunk/src/app/srs_app_forward.cpp b/trunk/src/app/srs_app_forward.cpp index 10eb96bb9..11295349b 100755 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -174,7 +174,7 @@ srs_error_t SrsForwarder::on_video(SrsSharedPtrMessage* shared_video) } // when error, forwarder sleep for a while and retry. -#define SRS_FORWARDER_CIMS (3000) +#define SRS_FORWARDER_CIMS (3000 * SRS_UTIME_MILLISECONDS) srs_error_t SrsForwarder::cycle() { @@ -190,7 +190,7 @@ srs_error_t SrsForwarder::cycle() return srs_error_wrap(err, "forwarder"); } - srs_usleep(SRS_FORWARDER_CIMS * 1000); + srs_usleep(SRS_FORWARDER_CIMS); } return err; @@ -213,8 +213,9 @@ srs_error_t SrsForwarder::do_cycle() } srs_freep(sdk); - int64_t cto = SRS_FORWARDER_CIMS; - int64_t sto = SRS_CONSTS_RTMP_TMMS; + // TODO: FIXME: Should switch cto with sto? + int64_t cto = srsu2ms(SRS_FORWARDER_CIMS); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); sdk = new SrsSimpleRtmpClient(url, cto, sto); if ((err = sdk->connect()) != srs_success) { @@ -241,7 +242,7 @@ srs_error_t SrsForwarder::forward() { srs_error_t err = srs_success; - sdk->set_recv_timeout(SRS_CONSTS_RTMP_PULSE_TMMS); + sdk->set_recv_timeout(srsu2ms(SRS_CONSTS_RTMP_PULSE)); SrsPithyPrint* pprint = SrsPithyPrint::create_forwarder(); SrsAutoFree(SrsPithyPrint, pprint); diff --git a/trunk/src/app/srs_app_fragment.cpp b/trunk/src/app/srs_app_fragment.cpp index 886db1ba7..ee7df6eb2 100644 --- a/trunk/src/app/srs_app_fragment.cpp +++ b/trunk/src/app/srs_app_fragment.cpp @@ -44,16 +44,24 @@ SrsFragment::~SrsFragment() void SrsFragment::append(int64_t dts) { + // The max positive ms is 0x7fffffffffffffff/1000. + static const int64_t maxMS = 0x20c49ba5e353f7LL; + + // We reset negative or overflow dts to zero. + if (dts > maxMS || dts < 0) { + dts = 0; + } + if (start_dts == -1) { start_dts = dts; } // TODO: FIXME: Use cumulus dts. start_dts = srs_min(start_dts, dts); - dur = dts - start_dts; + dur = srs_utime_t(dts - start_dts) * SRS_UTIME_MILLISECONDS; } -int64_t SrsFragment::duration() +srs_utime_t SrsFragment::duration() { return dur; } @@ -127,7 +135,7 @@ srs_error_t SrsFragment::rename() string full_path = fullpath(); string tmp_file = tmppath(); - int tempdur = (int)duration(); + int tempdur = srsu2msi(duration()); if (true) { std::stringstream ss; ss << tempdur; @@ -195,7 +203,7 @@ void SrsFragmentWindow::append(SrsFragment* fragment) void SrsFragmentWindow::shrink(int64_t window) { - int64_t duration = 0; + srs_utime_t duration = 0; int remove_index = -1; @@ -203,7 +211,7 @@ void SrsFragmentWindow::shrink(int64_t window) SrsFragment* fragment = fragments[i]; duration += fragment->duration(); - if (duration > window) { + if (srsu2ms(duration) > window) { remove_index = i; break; } @@ -242,7 +250,7 @@ int64_t SrsFragmentWindow::max_duration() for (it = fragments.begin(); it != fragments.end(); ++it) { SrsFragment* fragment = *it; - v = srs_max(v, fragment->duration()); + v = srs_max(v, srsu2ms(fragment->duration())); } return v; diff --git a/trunk/src/app/srs_app_fragment.hpp b/trunk/src/app/srs_app_fragment.hpp index 2bd5843aa..b1aa15f60 100644 --- a/trunk/src/app/srs_app_fragment.hpp +++ b/trunk/src/app/srs_app_fragment.hpp @@ -36,8 +36,8 @@ class SrsFragment { private: - // The duration in ms. - int64_t dur; + // The duration in srs_utime_t. + srs_utime_t dur; // The full file path of fragment. std::string filepath; // The start DTS in ms of segment. @@ -51,8 +51,8 @@ public: // Append a frame with dts into fragment. // @dts The dts of frame in ms. virtual void append(int64_t dts); - // Get the duration of fragment in ms. - virtual int64_t duration(); + // Get the duration of fragment in srs_utime_t. + virtual srs_utime_t duration(); // Whether the fragment contains any sequence header. virtual bool is_sequence_header(); // Set whether contains sequence header. diff --git a/trunk/src/app/srs_app_hls.cpp b/trunk/src/app/srs_app_hls.cpp index 8f6451c69..72e133ce6 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -54,6 +54,7 @@ using namespace std; #include // drop the segment when duration of ts too small. +// TODO: FIXME: Refine to time unit. #define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100 // fragment plus the deviation percent. @@ -253,7 +254,7 @@ string SrsHlsMuxer::ts_url() double SrsHlsMuxer::duration() { - return current? current->duration()/1000.0:0; + return current? srsu2ms(current->duration())/1000.0:0; } int SrsHlsMuxer::deviation() @@ -390,7 +391,7 @@ srs_error_t SrsHlsMuxer::segment_open() ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream); if (hls_ts_floor) { // accept the floor ts for the first piece. - int64_t current_floor_ts = (int64_t)(srs_update_system_time_ms() / (1000 * hls_fragment)); + int64_t current_floor_ts = (int64_t)(srsu2ms(srs_update_system_time()) / (1000 * hls_fragment)); if (!accept_floor_ts) { accept_floor_ts = current_floor_ts - 1; } else { @@ -483,14 +484,14 @@ bool SrsHlsMuxer::is_segment_overflow() srs_assert(current); // to prevent very small segment. - if (current->duration() < 2 * SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { + if (srsu2msi(current->duration()) < 2 * SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { return false; } // use N% deviation, to smoother. double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * deviation_ts * hls_fragment : 0.0; - return current->duration() >= (hls_fragment + deviation) * 1000; + return srsu2msi(current->duration()) >= (hls_fragment + deviation) * 1000; } bool SrsHlsMuxer::wait_keyframe() @@ -504,14 +505,14 @@ bool SrsHlsMuxer::is_segment_absolutely_overflow() srs_assert(current); // to prevent very small segment. - if (current->duration() < 2 * SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { + if (srsu2msi(current->duration()) < 2 * SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { return false; } // use N% deviation, to smoother. double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * deviation_ts * hls_fragment : 0.0; - return current->duration() >= (hls_aof_ratio * hls_fragment + deviation) * 1000; + return srsu2msi(current->duration()) >= (hls_aof_ratio * hls_fragment + deviation) * 1000; } bool SrsHlsMuxer::pure_audio() @@ -591,10 +592,10 @@ srs_error_t SrsHlsMuxer::segment_close() // when too small, it maybe not enough data to play. // when too large, it maybe timestamp corrupt. // make the segment more acceptable, when in [min, max_td * 2], it's ok. - if (current->duration() >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS && (int)current->duration() <= max_td * 2 * 1000) { + if (srsu2msi(current->duration()) >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS && (int)srsu2msi(current->duration()) <= max_td * 2 * 1000) { // use async to call the http hooks, for it will cause thread switch. if ((err = async->execute(new SrsDvrAsyncCallOnHls(_srs_context->get_id(), req, current->fullpath(), - current->uri, m3u8, m3u8_url, current->sequence_no, current->duration() / 1000.0))) != srs_success) { + current->uri, m3u8, m3u8_url, current->sequence_no, srsu2msi(current->duration()) / 1000.0))) != srs_success) { return srs_error_wrap(err, "segment close"); } @@ -617,7 +618,8 @@ srs_error_t SrsHlsMuxer::segment_close() // reuse current segment index. _sequence_no--; - srs_trace("Drop ts segment, sequence_no=%d, uri=%s, duration=%" PRId64 "ms", current->sequence_no, current->uri.c_str(), current->duration()); + srs_trace("Drop ts segment, sequence_no=%d, uri=%s, duration=%dms", + current->sequence_no, current->uri.c_str(), srsu2msi(current->duration())); // rename from tmp to real path if ((err = current->unlink_tmpfile()) != srs_success) { @@ -778,13 +780,13 @@ srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file) // "#EXTINF:4294967295.208,\n" ss.precision(3); ss.setf(std::ios::fixed, std::ios::floatfield); - ss << "#EXTINF:" << segment->duration() / 1000.0 << ", no desc" << SRS_CONSTS_LF; + ss << "#EXTINF:" << srsu2msi(segment->duration()) / 1000.0 << ", no desc" << SRS_CONSTS_LF; // {file name}\n std::string seg_uri = segment->uri; if (true) { std::stringstream stemp; - stemp << (int)(segment->duration()); + stemp << srsu2msi(segment->duration()); seg_uri = srs_string_replace(seg_uri, "[duration]", stemp.str()); } //ss << segment->uri << SRS_CONSTS_LF; @@ -870,7 +872,7 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req) // whether use floor(timestamp/hls_fragment) for variable timestamp bool ts_floor = _srs_config->get_hls_ts_floor(vhost); // the seconds to dispose the hls. - int hls_dispose = _srs_config->get_hls_dispose(vhost); + srs_utime_t hls_dispose = _srs_config->get_hls_dispose(vhost); bool hls_keys = _srs_config->get_hls_keys(vhost); int hls_fragments_per_key = _srs_config->get_hls_fragments_per_key(vhost); @@ -891,9 +893,9 @@ srs_error_t SrsHlsController::on_publish(SrsRequest* req) if ((err = muxer->segment_open()) != srs_success) { return srs_error_wrap(err, "hls: segment open"); } - srs_trace("hls: win=%.2f, frag=%.2f, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%d", + srs_trace("hls: win=%.2f, frag=%.2f, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%dms", hls_window, hls_fragment, entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(), - ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose); + ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, srsu2msi(hls_dispose)); return err; } @@ -1061,7 +1063,7 @@ void SrsHls::dispose() // Ignore when hls_dispose disabled. // @see https://github.com/ossrs/srs/issues/865 - int hls_dispose = _srs_config->get_hls_dispose(req->vhost); + srs_utime_t hls_dispose = _srs_config->get_hls_dispose(req->vhost); if (!hls_dispose) { return; } @@ -1074,21 +1076,21 @@ srs_error_t SrsHls::cycle() srs_error_t err = srs_success; if (last_update_time <= 0) { - last_update_time = srs_get_system_time_ms(); + last_update_time = srs_get_system_time(); } if (!req) { return err; } - int hls_dispose = _srs_config->get_hls_dispose(req->vhost) * 1000; + srs_utime_t hls_dispose = _srs_config->get_hls_dispose(req->vhost); if (hls_dispose <= 0) { return err; } - if (srs_get_system_time_ms() - last_update_time <= hls_dispose) { + if (srs_get_system_time() - last_update_time <= hls_dispose) { return err; } - last_update_time = srs_get_system_time_ms(); + last_update_time = srs_get_system_time(); if (!disposable) { return err; @@ -1120,7 +1122,7 @@ srs_error_t SrsHls::on_publish() srs_error_t err = srs_success; // update the hls time, for hls_dispose. - last_update_time = srs_get_system_time_ms(); + last_update_time = srs_get_system_time(); // support multiple publish. if (enabled) { @@ -1170,7 +1172,7 @@ srs_error_t SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma } // update the hls time, for hls_dispose. - last_update_time = srs_get_system_time_ms(); + last_update_time = srs_get_system_time(); SrsSharedPtrMessage* audio = shared_audio->copy(); SrsAutoFree(SrsSharedPtrMessage, audio); @@ -1227,7 +1229,7 @@ srs_error_t SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* forma } // update the hls time, for hls_dispose. - last_update_time = srs_get_system_time_ms(); + last_update_time = srs_get_system_time(); SrsSharedPtrMessage* video = shared_video->copy(); SrsAutoFree(SrsSharedPtrMessage, video); diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index a51a232f7..1a340b16b 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -319,7 +319,7 @@ private: SrsRequest* req; bool enabled; bool disposable; - int64_t last_update_time; + srs_utime_t last_update_time; private: // If the diff=dts-previous_audio_dts is about 23, // that's the AAC samples is 1024, and we use the samples to calc the dts. diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index d8c9f8d2d..86a3698ac 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -681,7 +681,7 @@ srs_error_t SrsGoApiRequests::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess server->set("sigature", SrsJsonAny::str(RTMP_SIG_SRS_KEY)); server->set("version", SrsJsonAny::str(RTMP_SIG_SRS_VERSION)); server->set("link", SrsJsonAny::str(RTMP_SIG_SRS_URL)); - server->set("time", SrsJsonAny::integer(srs_get_system_time_ms())); + server->set("time", SrsJsonAny::integer(srsu2ms(srs_get_system_time()))); return srs_api_response(w, r, obj->dumps()); } diff --git a/trunk/src/app/srs_app_http_hooks.cpp b/trunk/src/app/srs_app_http_hooks.cpp index f7ee8473a..d58be2829 100644 --- a/trunk/src/app/srs_app_http_hooks.cpp +++ b/trunk/src/app/srs_app_http_hooks.cpp @@ -46,7 +46,7 @@ using namespace std; #define SRS_HTTP_BODY_BUFFER (32 * 1024) // the timeout for hls notify, in ms. -#define SRS_HLS_NOTIFY_TMMS (10 * 1000) +#define SRS_HLS_NOTIFY_TMMS (10 * SRS_UTIME_MILLISECONDS) SrsHttpHooks::SrsHttpHooks() { @@ -363,7 +363,7 @@ srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* re url = srs_string_replace(url, "[ts_url]", ts_url); url = srs_string_replace(url, "[param]", req->param); - int64_t starttime = srs_update_system_time_ms(); + int64_t starttime = srsu2ms(srs_update_system_time()); SrsHttpUri uri; if ((err = uri.initialize(url)) != srs_success) { @@ -405,7 +405,7 @@ srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* re nb_read += nb_bytes; } - int spenttime = (int)(srs_update_system_time_ms() - starttime); + int spenttime = (int)(srsu2ms(srs_update_system_time()) - starttime); srs_trace("http hook on_hls_notify success. client_id=%d, url=%s, code=%d, spent=%dms, read=%dB, err=%s", client_id, url.c_str(), msg->status_code(), spenttime, nb_read, srs_error_desc(err).c_str()); diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index a291a0bd6..99ef37494 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -23,7 +23,7 @@ #include -#define SRS_STREAM_CACHE_CYCLE_SECONDS 30 +#define SRS_STREAM_CACHE_CYCLE (30 * SRS_UTIME_SECONDS) #include #include @@ -108,7 +108,7 @@ srs_error_t SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgor return srs_error_wrap(err, "dump packets"); } - srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs", queue->size(), queue->duration(), fast_cache); + srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs", queue->size(), srsu2msi(queue->duration()), fast_cache); return err; } @@ -119,7 +119,7 @@ srs_error_t SrsBufferCache::cycle() // TODO: FIXME: support reload. if (fast_cache <= 0) { - srs_usleep(SRS_STREAM_CACHE_CYCLE_SECONDS * 1000 * 1000); + srs_usleep(SRS_STREAM_CACHE_CYCLE); return err; } @@ -155,9 +155,9 @@ srs_error_t SrsBufferCache::cycle() } if (count <= 0) { - srs_info("http: sleep %dms for no msg", SRS_CONSTS_RTMP_PULSE_TMMS); + srs_info("http: sleep %dms for no msg", srsu2msi(SRS_CONSTS_RTMP_PULSE)); // directly use sleep, donot use consumer wait. - srs_usleep(SRS_CONSTS_RTMP_PULSE_TMMS * 1000); + srs_usleep(SRS_CONSTS_RTMP_PULSE); // ignore when nothing got. continue; @@ -165,7 +165,7 @@ srs_error_t SrsBufferCache::cycle() if (pprint->can_print()) { srs_trace("-> " SRS_CONSTS_LOG_HTTP_STREAM_CACHE " http: got %d msgs, age=%d, min=%d, mw=%d", - count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS); + count, pprint->age(), SRS_PERF_MW_MIN_MSGS, srsu2msi(SRS_CONSTS_RTMP_PULSE)); } // free the messages. @@ -589,9 +589,9 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess } } - int mw_sleep = _srs_config->get_mw_sleep_ms(req->vhost); + srs_utime_t mw_sleep = _srs_config->get_mw_sleep(req->vhost); if ((err = hc->set_socket_buffer(mw_sleep)) != srs_success) { - return srs_error_wrap(err, "set mw_sleep"); + return srs_error_wrap(err, "set mw_sleep %" PRId64, mw_sleep); } SrsHttpRecvThread* trd = new SrsHttpRecvThread(hc); @@ -602,7 +602,8 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess } srs_trace("FLV %s, encoder=%s, nodelay=%d, mw_sleep=%dms, cache=%d, msgs=%d", - entry->pattern.c_str(), enc_desc.c_str(), tcp_nodelay, mw_sleep, enc->has_cache(), msgs.max); + entry->pattern.c_str(), enc_desc.c_str(), tcp_nodelay, srsu2msi(mw_sleep), + enc->has_cache(), msgs.max); // TODO: free and erase the disabled entry after all related connections is closed. while (entry->enabled) { @@ -622,14 +623,14 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess if (count <= 0) { // Directly use sleep, donot use consumer wait, because we couldn't awake consumer. - srs_usleep(mw_sleep * 1000); + srs_usleep(mw_sleep); // ignore when nothing got. continue; } if (pprint->can_print()) { srs_trace("-> " SRS_CONSTS_LOG_HTTP_STREAM " http: got %d msgs, age=%d, min=%d, mw=%d", - count, pprint->age(), SRS_PERF_MW_MIN_MSGS, mw_sleep); + count, pprint->age(), SRS_PERF_MW_MIN_MSGS, srsu2msi(mw_sleep)); } // sendout all messages. diff --git a/trunk/src/app/srs_app_ingest.cpp b/trunk/src/app/srs_app_ingest.cpp index 656b35a66..3518cb789 100644 --- a/trunk/src/app/srs_app_ingest.cpp +++ b/trunk/src/app/srs_app_ingest.cpp @@ -52,7 +52,7 @@ srs_error_t SrsIngesterFFMPEG::initialize(SrsFFMPEG* ff, string v, string i) ffmpeg = ff; vhost = v; id = i; - starttime = srs_get_system_time_ms(); + starttime = srs_get_system_time(); return err; } @@ -64,7 +64,7 @@ string SrsIngesterFFMPEG::uri() int SrsIngesterFFMPEG::alive() { - return (int)(srs_get_system_time_ms() - starttime); + return srsu2msi(srs_get_system_time() - starttime); } bool SrsIngesterFFMPEG::equals(string v) @@ -168,7 +168,7 @@ void SrsIngester::fast_stop() // when error, ingester sleep for a while and retry. // ingest never sleep a long time, for we must start the stream ASAP. -#define SRS_AUTO_INGESTER_CIMS (3000) +#define SRS_AUTO_INGESTER_CIMS (3000 * SRS_UTIME_MILLISECONDS) srs_error_t SrsIngester::cycle() { @@ -184,7 +184,7 @@ srs_error_t SrsIngester::cycle() return srs_error_wrap(err, "ingester"); } - srs_usleep(SRS_AUTO_INGESTER_CIMS * 1000); + srs_usleep(SRS_AUTO_INGESTER_CIMS); } return err; diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index 9922127d0..e8206a143 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -44,7 +44,7 @@ private: std::string vhost; std::string id; SrsFFMPEG* ffmpeg; - int64_t starttime; + srs_utime_t starttime; public: SrsIngesterFFMPEG(); virtual ~SrsIngesterFFMPEG(); diff --git a/trunk/src/app/srs_app_kafka.cpp b/trunk/src/app/srs_app_kafka.cpp index d192ab4a8..de5974fc6 100644 --- a/trunk/src/app/srs_app_kafka.cpp +++ b/trunk/src/app/srs_app_kafka.cpp @@ -485,7 +485,7 @@ srs_error_t SrsKafkaProducer::on_close(int key) return worker->execute(new SrsKafkaMessage(this, key, obj)); } -#define SRS_KAKFA_CIMS 3000 +#define SRS_KAKFA_CIMS (3000 * SRS_UTIME_MILLISECONDS) srs_error_t SrsKafkaProducer::cycle() { @@ -510,7 +510,7 @@ srs_error_t SrsKafkaProducer::cycle() return srs_error_wrap(err, "kafka cycle"); } - srs_usleep(SRS_KAKFA_CIMS * 1000); + srs_usleep(SRS_KAKFA_CIMS); } return err; diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp index 1ee437448..d901e6ed9 100755 --- a/trunk/src/app/srs_app_listener.cpp +++ b/trunk/src/app/srs_app_listener.cpp @@ -174,7 +174,7 @@ srs_error_t SrsUdpListener::cycle() } if (SrsUdpPacketRecvCycleMS > 0) { - srs_usleep(SrsUdpPacketRecvCycleMS * 1000); + srs_usleep(SrsUdpPacketRecvCycleMS * SRS_UTIME_MILLISECONDS); } } diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 94ba2d5f5..f6a4ebbf2 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -615,8 +615,8 @@ srs_error_t SrsMpegtsOverUdp::connect() return err; } - int64_t cto = SRS_CONSTS_RTMP_TMMS; - int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; + int64_t cto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_PULSE); sdk = new SrsSimpleRtmpClient(output, cto, sto); if ((err = sdk->connect()) != srs_success) { diff --git a/trunk/src/app/srs_app_ng_exec.cpp b/trunk/src/app/srs_app_ng_exec.cpp index 16393b6c9..585989796 100644 --- a/trunk/src/app/srs_app_ng_exec.cpp +++ b/trunk/src/app/srs_app_ng_exec.cpp @@ -76,7 +76,7 @@ void SrsNgExec::on_unpublish() } // when error, ng-exec sleep for a while and retry. -#define SRS_RTMP_EXEC_CIMS (3000) +#define SRS_RTMP_EXEC_CIMS (3000 * SRS_UTIME_MILLISECONDS) srs_error_t SrsNgExec::cycle() { srs_error_t err = srs_success; @@ -92,7 +92,7 @@ srs_error_t SrsNgExec::cycle() break; } - srs_usleep(SRS_RTMP_EXEC_CIMS * 1000); + srs_usleep(SRS_RTMP_EXEC_CIMS); } std::vector::iterator it; diff --git a/trunk/src/app/srs_app_pithy_print.cpp b/trunk/src/app/srs_app_pithy_print.cpp index 34c81b51e..e87847705 100644 --- a/trunk/src/app/srs_app_pithy_print.cpp +++ b/trunk/src/app/srs_app_pithy_print.cpp @@ -49,17 +49,17 @@ SrsStageInfo::~SrsStageInfo() void SrsStageInfo::update_print_time() { - pithy_print_time_ms = _srs_config->get_pithy_print_ms(); + interval = _srs_config->get_pithy_print(); } -void SrsStageInfo::elapse(int64_t diff) +void SrsStageInfo::elapse(srs_utime_t diff) { age += diff; } bool SrsStageInfo::can_print() { - int64_t can_print_age = nb_clients * pithy_print_time_ms; + srs_utime_t can_print_age = nb_clients * interval; bool can_print = age >= can_print_age; if (can_print) { @@ -81,7 +81,7 @@ SrsPithyPrint::SrsPithyPrint(int _stage_id) { stage_id = _stage_id; client_id = enter_stage(); - previous_tick = srs_get_system_time_ms(); + previous_tick = srs_get_system_time(); _age = 0; } @@ -208,12 +208,12 @@ void SrsPithyPrint::elapse() SrsStageInfo* stage = _srs_stages[stage_id]; srs_assert(stage != NULL); - int64_t diff = srs_get_system_time_ms() - previous_tick; + srs_utime_t diff = srs_get_system_time() - previous_tick; diff = srs_max(0, diff); stage->elapse(diff); _age += diff; - previous_tick = srs_get_system_time_ms(); + previous_tick = srs_get_system_time(); } bool SrsPithyPrint::can_print() @@ -226,7 +226,7 @@ bool SrsPithyPrint::can_print() int64_t SrsPithyPrint::age() { - return _age; + return srsu2ms(_age); } diff --git a/trunk/src/app/srs_app_pithy_print.hpp b/trunk/src/app/srs_app_pithy_print.hpp index 26aecd245..ffbfc8b91 100644 --- a/trunk/src/app/srs_app_pithy_print.hpp +++ b/trunk/src/app/srs_app_pithy_print.hpp @@ -35,16 +35,16 @@ class SrsStageInfo : public ISrsReloadHandler { public: int stage_id; - int pithy_print_time_ms; + srs_utime_t interval; int nb_clients; public: - int64_t age; + srs_utime_t age; public: SrsStageInfo(int _stage_id); virtual ~SrsStageInfo(); virtual void update_print_time(); public: - virtual void elapse(int64_t diff); + virtual void elapse(srs_utime_t diff); virtual bool can_print(); public: virtual srs_error_t on_reload_pithy_print(); @@ -75,9 +75,8 @@ class SrsPithyPrint private: int client_id; int stage_id; - // in ms. - int64_t _age; - int64_t previous_tick; + srs_utime_t _age; + srs_utime_t previous_tick; private: SrsPithyPrint(int _stage_id); public: diff --git a/trunk/src/app/srs_app_recv_thread.cpp b/trunk/src/app/srs_app_recv_thread.cpp index cf7e77fd4..0d1821bae 100644 --- a/trunk/src/app/srs_app_recv_thread.cpp +++ b/trunk/src/app/srs_app_recv_thread.cpp @@ -107,7 +107,7 @@ srs_error_t SrsRecvThread::cycle() // to use isolate thread to recv, can improve about 33% performance. // @see https://github.com/ossrs/srs/issues/194 // @see: https://github.com/ossrs/srs/issues/217 - rtmp->set_recv_timeout(SRS_CONSTS_NO_TMMS); + rtmp->set_recv_timeout(SRS_UTIME_NO_TIMEOUT); pumper->on_start(); @@ -292,7 +292,7 @@ SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* // the mr settings, // @see https://github.com/ossrs/srs/issues/241 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(req->vhost); realtime = _srs_config->get_realtime_enabled(req->vhost); @@ -381,7 +381,7 @@ srs_error_t SrsPublishRecvThread::consume(SrsCommonMessage* msg) // 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); + srs_update_system_time(), msg->header.timestamp, msg->size); // the rtmp connection will handle this message err = _conn->handle_publish_message(_source, msg); @@ -466,7 +466,7 @@ void SrsPublishRecvThread::on_read(ssize_t nread) * @see https://github.com/ossrs/srs/issues/241 */ if (nread < SRS_MR_SMALL_BYTES) { - srs_usleep(mr_sleep * 1000); + srs_usleep(mr_sleep); } } #endif @@ -482,11 +482,11 @@ srs_error_t SrsPublishRecvThread::on_reload_vhost_publish(string vhost) // the mr settings, // @see https://github.com/ossrs/srs/issues/241 bool mr_enabled = _srs_config->get_mr_enabled(req->vhost); - int sleep_ms = _srs_config->get_mr_sleep_ms(req->vhost); + srs_utime_t sleep_v = _srs_config->get_mr_sleep(req->vhost); // update buffer when sleep ms changed. - if (mr_sleep != sleep_ms) { - set_socket_buffer(sleep_ms); + if (mr_sleep != sleep_v) { + set_socket_buffer(sleep_v); } #ifdef SRS_PERF_MERGED_READ @@ -506,7 +506,7 @@ srs_error_t SrsPublishRecvThread::on_reload_vhost_publish(string vhost) // update to new state mr = mr_enabled; - mr_sleep = sleep_ms; + mr_sleep = sleep_v; return err; } @@ -526,7 +526,7 @@ srs_error_t SrsPublishRecvThread::on_reload_vhost_realtime(string vhost) return err; } -void SrsPublishRecvThread::set_socket_buffer(int sleep_ms) +void SrsPublishRecvThread::set_socket_buffer(srs_utime_t sleep_v) { // the bytes: // 4KB=4096, 8KB=8192, 16KB=16384, 32KB=32768, 64KB=65536, @@ -539,7 +539,7 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms) // 2000*3000/8=750000B(about 732KB). // 2000*5000/8=1250000B(about 1220KB). int kbps = 5000; - int socket_buffer_size = sleep_ms * kbps / 8; + int socket_buffer_size = srsu2msi(sleep_v) * kbps / 8; int fd = mr_fd; int onb_rbuf = 0; @@ -554,7 +554,7 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms) 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, realtime=%d", - mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf, + srsu2msi(mr_sleep), srsu2msi(sleep_v), socket_buffer_size, onb_rbuf, nb_rbuf, SRS_MR_SMALL_BYTES, realtime); rtmp->set_recv_buffer(nb_rbuf); diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp index c7d522183..785f779ab 100644 --- a/trunk/src/app/srs_app_recv_thread.hpp +++ b/trunk/src/app/srs_app_recv_thread.hpp @@ -132,6 +132,7 @@ private: srs_error_t recv_error; SrsConsumer* _consumer; public: + // TODO: FIXME: Refine timeout in time unit. SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, int timeout_ms); virtual ~SrsQueueRecvThread(); public: @@ -172,7 +173,7 @@ private: // @see https://github.com/ossrs/srs/issues/241 bool mr; int mr_fd; - int mr_sleep; + srs_utime_t mr_sleep; // for realtime // @see https://github.com/ossrs/srs/issues/257 bool realtime; @@ -220,7 +221,7 @@ public: virtual srs_error_t on_reload_vhost_publish(std::string vhost); virtual srs_error_t on_reload_vhost_realtime(std::string vhost); private: - virtual void set_socket_buffer(int sleep_ms); + virtual void set_socket_buffer(srs_utime_t sleep_v); }; /** diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 22c0d7712..4e9323ca5 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -64,15 +64,15 @@ using namespace std; // the timeout in ms to wait encoder to republish // if timeout, close the connection. -#define SRS_REPUBLISH_SEND_TMMS (3 * 60 * 1000) +#define SRS_REPUBLISH_SEND_TMMS (3 * SRS_UTIME_MINUTES) // if timeout, close the connection. -#define SRS_REPUBLISH_RECV_TMMS (3 * 60 * 1000) +#define SRS_REPUBLISH_RECV_TMMS (3 * SRS_UTIME_MINUTES) // the timeout in ms to wait client data, when client paused // if timeout, close the connection. -#define SRS_PAUSED_SEND_TMMS (3 * 60 * 1000) +#define SRS_PAUSED_SEND_TMMS (3 * SRS_UTIME_MINUTES) // if timeout, close the connection. -#define SRS_PAUSED_RECV_TMMS (3 * 60 * 1000) +#define SRS_PAUSED_RECV_TMMS (3 * SRS_UTIME_MINUTES) // when edge timeout, retry next. #define SRS_EDGE_TOKEN_TRAVERSE_TMMS (3000) @@ -166,8 +166,8 @@ srs_error_t SrsRtmpConn::do_cycle() } #endif - rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); - rtmp->set_send_timeout(SRS_CONSTS_RTMP_TMMS); + rtmp->set_recv_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); + rtmp->set_send_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); if ((err = rtmp->handshake()) != srs_success) { return srs_error_wrap(err, "rtmp handshake"); @@ -319,15 +319,15 @@ srs_error_t SrsRtmpConn::on_reload_vhost_publish(string vhost) return err; } - int p1stpt = _srs_config->get_publish_1stpkt_timeout(req->vhost); + srs_utime_t p1stpt = _srs_config->get_publish_1stpkt_timeout(req->vhost); if (p1stpt != publish_1stpkt_timeout) { - srs_trace("p1stpt changed %d=>%d", publish_1stpkt_timeout, p1stpt); + srs_trace("p1stpt changed %d=>%d", srsu2msi(publish_1stpkt_timeout), srsu2msi(p1stpt)); publish_1stpkt_timeout = p1stpt; } - int pnt = _srs_config->get_publish_normal_timeout(req->vhost); + srs_utime_t pnt = _srs_config->get_publish_normal_timeout(req->vhost); if (pnt != publish_normal_timeout) { - srs_trace("pnt changed %d=>%d", publish_normal_timeout, pnt); + srs_trace("pnt changed %d=>%d", srsu2msi(publish_normal_timeout), srsu2msi(pnt)); publish_normal_timeout = pnt; } @@ -498,8 +498,8 @@ srs_error_t SrsRtmpConn::stream_service_cycle() } // client is identified, set the timeout to service timeout. - rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); - rtmp->set_send_timeout(SRS_CONSTS_RTMP_TMMS); + rtmp->set_recv_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); + rtmp->set_send_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); // find a source to serve. SrsSource* source = NULL; @@ -646,7 +646,7 @@ srs_error_t SrsRtmpConn::playing(SrsSource* source) // Use receiving thread to receive packets from peer. // @see: https://github.com/ossrs/srs/issues/217 - SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP); + SrsQueueRecvThread trd(consumer, rtmp, srsu2msi(SRS_PERF_MW_SLEEP)); if ((err = trd.start()) != srs_success) { return srs_error_wrap(err, "rtmp: start receive thread"); @@ -688,12 +688,12 @@ srs_error_t SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, Sr // setup the mw config. // when mw_sleep changed, resize the socket send buffer. mw_enabled = true; - change_mw_sleep(_srs_config->get_mw_sleep_ms(req->vhost)); + change_mw_sleep(_srs_config->get_mw_sleep(req->vhost)); // initialize the send_min_interval send_min_interval = _srs_config->get_send_min_interval(req->vhost); srs_trace("start play smi=%.2f, mw_sleep=%d, mw_enabled=%d, realtime=%d, tcp_nodelay=%d", - send_min_interval, mw_sleep, mw_enabled, realtime, tcp_nodelay); + send_min_interval, srsu2msi(mw_sleep), mw_enabled, realtime, tcp_nodelay); while (true) { // collect elapse for pithy print. @@ -745,12 +745,12 @@ srs_error_t SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, Sr kbps->sample(); srs_trace("-> " SRS_CONSTS_LOG_PLAY " time=%d, msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mw=%d", (int)pprint->age(), count, kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), - kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), mw_sleep); + kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), srsu2msi(mw_sleep)); } if (count <= 0) { #ifndef SRS_PERF_QUEUE_COND_WAIT - srs_usleep(mw_sleep * 1000); + srs_usleep(mw_sleep); #endif // ignore when nothing got. continue; @@ -861,9 +861,10 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* if (true) { bool mr = _srs_config->get_mr_enabled(req->vhost); - int mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost); + srs_utime_t mr_sleep = _srs_config->get_mr_sleep(req->vhost); srs_trace("start publish mr=%d/%d, p1stpt=%d, pnt=%d, tcp_nodelay=%d, rtcid=%d", - mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout, tcp_nodelay, receive_thread_cid); + mr, srsu2msi(mr_sleep), srsu2msi(publish_1stpkt_timeout), srsu2msi(publish_normal_timeout), + tcp_nodelay, receive_thread_cid); } int64_t nb_msgs = 0; @@ -879,9 +880,9 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* if (nb_msgs == 0) { // when not got msgs, wait for a larger timeout. // @see https://github.com/ossrs/srs/issues/441 - rtrd->wait(publish_1stpkt_timeout); + rtrd->wait(srsu2msi(publish_1stpkt_timeout)); } else { - rtrd->wait(publish_normal_timeout); + rtrd->wait(srsu2msi(publish_normal_timeout)); } // check the thread error code. @@ -892,7 +893,7 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* // when not got any messages, timeout. if (rtrd->nb_msgs() <= nb_msgs) { return srs_error_new(ERROR_SOCKET_TIMEOUT, "rtmp: publish timeout %dms, nb_msgs=%d", - nb_msgs? publish_normal_timeout : publish_1stpkt_timeout, (int)nb_msgs); + nb_msgs? srsu2msi(publish_normal_timeout) : srsu2msi(publish_1stpkt_timeout), (int)nb_msgs); } nb_msgs = rtrd->nb_msgs(); @@ -908,10 +909,11 @@ srs_error_t SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* if (pprint->can_print()) { kbps->sample(); bool mr = _srs_config->get_mr_enabled(req->vhost); - int mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost); + srs_utime_t mr_sleep = _srs_config->get_mr_sleep(req->vhost); srs_trace("<- " SRS_CONSTS_LOG_CLIENT_PUBLISH " time=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mr=%d/%d, p1stpt=%d, pnt=%d", (int)pprint->age(), kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), - kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout); + kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), mr, srsu2msi(mr_sleep), + srsu2msi(publish_1stpkt_timeout), srsu2msi(publish_normal_timeout)); } } @@ -1111,14 +1113,14 @@ srs_error_t SrsRtmpConn::process_play_control_msg(SrsConsumer* consumer, SrsComm return err; } -void SrsRtmpConn::change_mw_sleep(int sleep_ms) +void SrsRtmpConn::change_mw_sleep(srs_utime_t sleep_v) { if (!mw_enabled) { return; } - set_socket_buffer(sleep_ms); - mw_sleep = sleep_ms; + set_socket_buffer(sleep_v); + mw_sleep = sleep_v; } void SrsRtmpConn::set_sock_options() @@ -1181,8 +1183,8 @@ srs_error_t SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client) SrsRequest* req = info->req; srs_assert(client); - client->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); - client->set_send_timeout(SRS_CONSTS_RTMP_TMMS); + client->set_recv_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); + client->set_send_timeout(srsu2ms(SRS_CONSTS_RTMP_TIMEOUT)); if ((err = client->handshake()) != srs_success) { return srs_error_wrap(err, "rtmp: handshake"); diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index e1639d517..2e55ffe1a 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -110,7 +110,7 @@ private: // @see https://github.com/ossrs/srs/issues/47 int64_t duration; // the MR(merged-write) sleep time in ms. - int mw_sleep; + srs_utime_t mw_sleep; // the MR(merged-write) only enabled for play. int mw_enabled; // for realtime @@ -118,10 +118,10 @@ private: bool realtime; // the minimal interval in ms for delivery stream. double send_min_interval; - // publish 1st packet timeout in ms - int publish_1stpkt_timeout; - // publish normal packet timeout in ms - int publish_normal_timeout; + // publish 1st packet timeout in srs_utime_t + srs_utime_t publish_1stpkt_timeout; + // publish normal packet timeout in srs_utime_t + srs_utime_t publish_normal_timeout; // whether enable the tcp_nodelay. bool tcp_nodelay; // About the rtmp client. @@ -158,7 +158,7 @@ private: virtual srs_error_t handle_publish_message(SrsSource* source, SrsCommonMessage* msg); virtual srs_error_t process_publish_message(SrsSource* source, SrsCommonMessage* msg); virtual srs_error_t process_play_control_msg(SrsConsumer* consumer, SrsCommonMessage* msg); - virtual void change_mw_sleep(int sleep_ms); + virtual void change_mw_sleep(srs_utime_t sleep_v); virtual void set_sock_options(); private: virtual srs_error_t check_edge_token_traverse_auth(); diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 8641867d0..0502a0324 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -649,8 +649,8 @@ srs_error_t SrsRtspConn::connect() } // connect host. - int64_t cto = SRS_CONSTS_RTMP_TMMS; - int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; + int64_t cto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_PULSE); sdk = new SrsSimpleRtmpClient(url, cto, sto); if ((err = sdk->connect()) != srs_success) { diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 96aa8ea5e..f16fed09b 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -60,7 +60,7 @@ using namespace std; // the meminfo canbe 6*x, for instance, 6*1=6s, // for performance refine, @see: https://github.com/ossrs/srs/issues/194 // @remark, recomment to 1000ms. -#define SRS_SYS_CYCLE_INTERVAL 1000 +#define SRS_SYS_CYCLE_INTERVAL (1000 * SRS_UTIME_MILLISECONDS) // update time interval: // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_TIME_RESOLUTION_MS_TIMES @@ -542,7 +542,7 @@ srs_error_t SrsServer::initialize(ISrsServerCycle* ch) srs_error_t err = srs_success; // ensure the time is ok. - srs_update_system_time_ms(); + srs_update_system_time(); // for the main objects(server, config, log, context), // never subscribe handler in constructor, @@ -916,7 +916,7 @@ srs_error_t SrsServer::do_cycle() int dynamic_max = srs_max(max, heartbeat_max_resolution); for (int i = 0; i < dynamic_max; i++) { - srs_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); + srs_usleep(SRS_SYS_CYCLE_INTERVAL); // asprocess check. if (asprocess && ::getppid() != ppid) { @@ -971,7 +971,7 @@ srs_error_t SrsServer::do_cycle() // update the cache time if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) { srs_info("update current time cache."); - srs_update_system_time_ms(); + srs_update_system_time(); } if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) { diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index f4807183a..8944af271 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -61,8 +61,8 @@ using namespace std; // when got these videos or audios, pure audio or video, mix ok. #define SRS_MIX_CORRECT_PURE_AV 10 -// the time to cleanup source in ms. -#define SRS_SOURCE_CLEANUP 30000 +// the time to cleanup source. +#define SRS_SOURCE_CLEANUP (30 * SRS_UTIME_SECONDS) int _srs_time_jitter_string2int(std::string time_jitter) { @@ -241,7 +241,7 @@ void SrsFastVector::free() SrsMessageQueue::SrsMessageQueue(bool ignore_shrink) { _ignore_shrink = ignore_shrink; - queue_size_ms = 0; + max_queue_size = 0; av_start_time = av_end_time = -1; } @@ -255,14 +255,14 @@ int SrsMessageQueue::size() return (int)msgs.size(); } -int SrsMessageQueue::duration() +srs_utime_t SrsMessageQueue::duration() { - return (int)(av_end_time - av_start_time); + return (av_end_time - av_start_time); } void SrsMessageQueue::set_queue_size(double queue_size) { - queue_size_ms = (int)(queue_size * 1000); + max_queue_size = srs_utime_t(queue_size * SRS_UTIME_SECONDS); } srs_error_t SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg, bool* is_overflow) @@ -271,15 +271,15 @@ srs_error_t SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg, bool* is_overflow if (msg->is_av()) { if (av_start_time == -1) { - av_start_time = msg->timestamp; + av_start_time = srs_utime_t(msg->timestamp * SRS_UTIME_MILLISECONDS); } - av_end_time = msg->timestamp; + av_end_time = srs_utime_t(msg->timestamp * SRS_UTIME_MILLISECONDS); } msgs.push_back(msg); - while (av_end_time - av_start_time > queue_size_ms) { + while (av_end_time - av_start_time > max_queue_size) { // notice the caller queue already overflow and shrinked. if (is_overflow) { *is_overflow = true; @@ -309,7 +309,7 @@ srs_error_t SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** p } SrsSharedPtrMessage* last = omsgs[count - 1]; - av_start_time = last->timestamp; + av_start_time = srs_utime_t(last->timestamp * SRS_UTIME_MILLISECONDS); if (count >= nb_msgs) { // the pmsgs is big enough and clear msgs at most time. @@ -375,17 +375,16 @@ void SrsMessageQueue::shrink() av_start_time = av_end_time; //push_back secquence header and update timestamp if (video_sh) { - video_sh->timestamp = av_end_time; + video_sh->timestamp = srsu2ms(av_end_time); msgs.push_back(video_sh); } if (audio_sh) { - audio_sh->timestamp = av_end_time; + audio_sh->timestamp = srsu2ms(av_end_time); msgs.push_back(audio_sh); } if (!_ignore_shrink) { - srs_trace("shrink the cache queue, size=%d, removed=%d, max=%.2f", - (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0); + srs_trace("shrinking, size=%d, removed=%d, max=%dms", (int)msgs.size(), msgs_size - (int)msgs.size(), srsu2msi(max_queue_size)); } } @@ -477,20 +476,20 @@ srs_error_t SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsR #ifdef SRS_PERF_QUEUE_COND_WAIT // fire the mw when msgs is enough. if (mw_waiting) { - int duration_ms = queue->duration(); + srs_utime_t duration = queue->duration(); bool match_min_msgs = queue->size() > mw_min_msgs; // For ATC, maybe the SH timestamp bigger than A/V packet, // when encoder republish or overflow. // @see https://github.com/ossrs/srs/pull/749 - if (atc && duration_ms < 0) { + if (atc && duration < 0) { srs_cond_signal(mw_wait); mw_waiting = false; return err; } // when duration ok, signal to flush. - if (match_min_msgs && duration_ms > mw_duration) { + if (match_min_msgs && duration > mw_duration) { srs_cond_signal(mw_wait); mw_waiting = false; return err; @@ -534,21 +533,21 @@ srs_error_t SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count) } #ifdef SRS_PERF_QUEUE_COND_WAIT -void SrsConsumer::wait(int nb_msgs, int duration) +void SrsConsumer::wait(int nb_msgs, srs_utime_t msgs_duration) { if (paused) { - srs_usleep(SRS_CONSTS_RTMP_PULSE_TMMS * 1000); + srs_usleep(SRS_CONSTS_RTMP_PULSE); return; } mw_min_msgs = nb_msgs; - mw_duration = duration; + mw_duration = msgs_duration; - int duration_ms = queue->duration(); + srs_utime_t duration = queue->duration(); bool match_min_msgs = queue->size() > mw_min_msgs; // when duration ok, signal to flush. - if (match_min_msgs && duration_ms > mw_duration) { + if (match_min_msgs && duration > mw_duration) { return; } @@ -1767,7 +1766,7 @@ SrsSource::SrsSource() _can_publish = true; _pre_source_id = _source_id = -1; - die_at = -1; + die_at = 0; play_edge = new SrsPlayEdge(); publish_edge = new SrsPublishEdge(); @@ -1821,7 +1820,7 @@ srs_error_t SrsSource::cycle() bool SrsSource::expired() { // unknown state? - if (die_at == -1) { + if (die_at == 0) { return false; } @@ -1835,7 +1834,7 @@ bool SrsSource::expired() return false; } - int64_t now = srs_get_system_time_ms(); + srs_utime_t now = srs_get_system_time(); if (now > die_at + SRS_SOURCE_CLEANUP) { return true; } @@ -2433,7 +2432,7 @@ void SrsSource::on_unpublish() // no consumer, stream is die. if (consumers.empty()) { - die_at = srs_get_system_time_ms(); + die_at = srs_get_system_time(); } } @@ -2498,7 +2497,7 @@ void SrsSource::on_consumer_destroy(SrsConsumer* consumer) if (consumers.empty()) { play_edge->on_all_client_stop(); - die_at = srs_get_system_time_ms(); + die_at = srs_get_system_time(); } } diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 28f041c7c..575508768 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -134,10 +134,14 @@ public: class SrsMessageQueue { private: + // The start and end time. + srs_utime_t av_start_time; + srs_utime_t av_end_time; +private: + // Whether do logging when shrinking. bool _ignore_shrink; - int64_t av_start_time; - int64_t av_end_time; - int queue_size_ms; + // The max queue size, shrink if exceed it. + srs_utime_t max_queue_size; #ifdef SRS_PERF_QUEUE_FAST_VECTOR SrsFastVector msgs; #else @@ -154,7 +158,7 @@ public: /** * get the duration of queue. */ - virtual int duration(); + virtual srs_utime_t duration(); /** * set the queue size * @param queue_size the queue size in seconds. @@ -230,7 +234,7 @@ private: srs_cond_t mw_wait; bool mw_waiting; int mw_min_msgs; - int mw_duration; + srs_utime_t mw_duration; #endif public: SrsConsumer(SrsSource* s, SrsConnection* c); @@ -267,9 +271,9 @@ public: /** * wait for messages incomming, atleast nb_msgs and in duration. * @param nb_msgs the messages count to wait. - * @param duration the messgae duration to wait. + * @param msgs_duration the messages duration to wait. */ - virtual void wait(int nb_msgs, int duration); + virtual void wait(int nb_msgs, srs_utime_t msgs_duration); #endif /** * when client send the pause message. @@ -606,7 +610,7 @@ private: bool _can_publish; // The last die time, when all consumers quit and no publisher, // we will remove the source when source die. - int64_t die_at; + srs_utime_t die_at; public: SrsSource(); virtual ~SrsSource(); diff --git a/trunk/src/app/srs_app_st.cpp b/trunk/src/app/srs_app_st.cpp index 7e36e4a67..a7219f820 100755 --- a/trunk/src/app/srs_app_st.cpp +++ b/trunk/src/app/srs_app_st.cpp @@ -79,6 +79,8 @@ int SrsDummyCoroutine::cid() return 0; } +_ST_THREAD_CREATE_PFN _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)st_thread_create; + SrsSTCoroutine::SrsSTCoroutine(const string& n, ISrsCoroutineHandler* h, int cid) { name = n; @@ -86,7 +88,7 @@ SrsSTCoroutine::SrsSTCoroutine(const string& n, ISrsCoroutineHandler* h, int cid context = cid; trd = NULL; trd_err = srs_success; - started = interrupted = disposed = false; + started = interrupted = disposed = cycle_done = false; } SrsSTCoroutine::~SrsSTCoroutine() @@ -101,8 +103,12 @@ srs_error_t SrsSTCoroutine::start() srs_error_t err = srs_success; if (started || disposed) { - err = srs_error_new(ERROR_THREAD_DISPOSED, "failed for disposed=%d, started=%d", disposed, started); - + if (disposed) { + err = srs_error_new(ERROR_THREAD_DISPOSED, "disposed"); + } else { + err = srs_error_new(ERROR_THREAD_STARTED, "started"); + } + if (trd_err == srs_success) { trd_err = srs_error_copy(err); } @@ -110,7 +116,7 @@ srs_error_t SrsSTCoroutine::start() return err; } - if((trd = (srs_thread_t)st_thread_create(pfn, this, 1, 0)) == NULL){ + if ((trd = (srs_thread_t)_pfn_st_thread_create(pfn, this, 1, 0)) == NULL) { err = srs_error_new(ERROR_ST_CREATE_CYCLE_THREAD, "create failed"); srs_freep(trd_err); @@ -126,28 +132,29 @@ srs_error_t SrsSTCoroutine::start() void SrsSTCoroutine::stop() { - if (!started || disposed) { + if (disposed) { return; } disposed = true; interrupt(); - - void* res = NULL; - int r0 = st_thread_join((st_thread_t)trd, &res); - srs_assert(!r0); - - // Always override the error by the error from worker. - srs_error_t err_res = (srs_error_t)res; - if (err_res != srs_success && trd_err != err_res) { - srs_freep(trd_err); - // It's ok to directly use it, because it's returned by st_thread_join. - trd_err = err_res; - return; + + // When not started, the rd is NULL. + if (trd) { + void* res = NULL; + int r0 = st_thread_join((st_thread_t)trd, &res); + srs_assert(!r0); + + srs_error_t err_res = (srs_error_t)res; + if (err_res != srs_success) { + // When worker cycle done, the error has already been overrided, + // so the trd_err should be equal to err_res. + srs_assert(trd_err == err_res); + } } - // If there's no error occur from worker, try to set to interrupted error. - if (trd_err == srs_success) { + // If there's no error occur from worker, try to set to terminated error. + if (trd_err == srs_success && !cycle_done) { trd_err = srs_error_new(ERROR_THREAD_TERMINATED, "terminated"); } @@ -156,7 +163,7 @@ void SrsSTCoroutine::stop() void SrsSTCoroutine::interrupt() { - if (!started || interrupted) { + if (!started || interrupted || cycle_done) { return; } interrupted = true; @@ -192,6 +199,9 @@ srs_error_t SrsSTCoroutine::cycle() if (err != srs_success) { return srs_error_wrap(err, "coroutine cycle"); } + + // Set cycle done, no need to interrupt it. + cycle_done = true; return err; } diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index 8408a5465..cc837ccd3 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -106,6 +106,10 @@ public: virtual int cid(); }; +// For utest to mock the thread create. +typedef void* (*_ST_THREAD_CREATE_PFN)(void *(*start)(void *arg), void *arg, int joinable, int stack_size); +extern _ST_THREAD_CREATE_PFN _pfn_st_thread_create; + /** * A ST-coroutine is a lightweight thread, just like the goroutine. * But the goroutine maybe run on different thread, while ST-coroutine only @@ -133,6 +137,8 @@ private: bool started; bool interrupted; bool disposed; + // Cycle done, no need to interrupt it. + bool cycle_done; public: // Create a thread with name n and handler h. // @remark User can specify a cid for thread to use, or we will allocate a new one. diff --git a/trunk/src/app/srs_app_statistic.cpp b/trunk/src/app/srs_app_statistic.cpp index 7b48b5bd0..c649c342a 100644 --- a/trunk/src/app/srs_app_statistic.cpp +++ b/trunk/src/app/srs_app_statistic.cpp @@ -138,7 +138,7 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj) obj->set("name", SrsJsonAny::str(stream.c_str())); obj->set("vhost", SrsJsonAny::integer(vhost->id)); obj->set("app", SrsJsonAny::str(app.c_str())); - obj->set("live_ms", SrsJsonAny::integer(srs_get_system_time_ms())); + obj->set("live_ms", SrsJsonAny::integer(srsu2ms(srs_get_system_time()))); obj->set("clients", SrsJsonAny::integer(nb_clients)); obj->set("frames", SrsJsonAny::integer(nb_frames)); obj->set("send_bytes", SrsJsonAny::integer(kbps->get_send_bytes())); @@ -208,7 +208,7 @@ SrsStatisticClient::SrsStatisticClient() conn = NULL; req = NULL; type = SrsRtmpConnUnknown; - create = srs_get_system_time_ms(); + create = srs_get_system_time(); } SrsStatisticClient::~SrsStatisticClient() @@ -229,7 +229,7 @@ srs_error_t SrsStatisticClient::dumps(SrsJsonObject* obj) obj->set("url", SrsJsonAny::str(req->get_stream_url().c_str())); obj->set("type", SrsJsonAny::str(srs_client_type_string(type).c_str())); obj->set("publish", SrsJsonAny::boolean(srs_client_type_is_publish(type))); - obj->set("alive", SrsJsonAny::number((srs_get_system_time_ms() - create) / 1000.0)); + obj->set("alive", SrsJsonAny::number(srsu2ms(srs_get_system_time() - create) / 1000.0)); return err; } diff --git a/trunk/src/app/srs_app_statistic.hpp b/trunk/src/app/srs_app_statistic.hpp index f722c82fb..c9d5661c0 100644 --- a/trunk/src/app/srs_app_statistic.hpp +++ b/trunk/src/app/srs_app_statistic.hpp @@ -124,7 +124,7 @@ public: SrsRequest* req; SrsRtmpConnType type; int id; - int64_t create; + srs_utime_t create; public: SrsStatisticClient(); virtual ~SrsStatisticClient(); diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 76672346e..c3f5520bf 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -236,7 +236,7 @@ void srs_update_system_rusage() return; } - _srs_system_rusage.sample_time = srs_get_system_time_ms(); + _srs_system_rusage.sample_time = srsu2ms(srs_get_system_time()); _srs_system_rusage.ok = true; } @@ -427,7 +427,7 @@ void srs_update_proc_stat() return; } - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); // calc usage in percent SrsProcSystemStat& o = _srs_system_cpu_system_stat; @@ -453,7 +453,7 @@ void srs_update_proc_stat() return; } - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); // calc usage in percent SrsProcSelfStat& o = _srs_system_cpu_self_stat; @@ -505,7 +505,7 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r) return false; } - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); static char buf[1024]; while (fgets(buf, sizeof(buf), f)) { @@ -531,7 +531,7 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r) bool srs_get_disk_diskstats_stat(SrsDiskStat& r) { r.ok = true; - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); // if disabled, ignore all devices. SrsConfDirective* conf = _srs_config->get_stats_disk_device(); @@ -731,7 +731,7 @@ void srs_update_meminfo() // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); r.MemActive = r.MemTotal - r.MemFree; r.RealInUse = r.MemActive - r.Buffers - r.Cached; r.NotInUse = r.MemTotal - r.RealInUse; @@ -795,7 +795,7 @@ void srs_update_platform_info() { SrsPlatformInfo& r = _srs_system_platform_info; - r.srs_startup_time = srs_get_system_startup_time_ms(); + r.srs_startup_time = srsu2ms(srs_get_system_startup_time()); #ifndef SRS_OSX if (true) { @@ -940,7 +940,7 @@ void srs_update_network_devices() _nb_srs_system_network_devices = i + 1; srs_info("scan network device ifname=%s, total=%d", r.name, _nb_srs_system_network_devices); - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); r.ok = true; } @@ -1090,7 +1090,7 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) r.ok = true; r.nb_conn_srs = nb_conn; - r.sample_time = srs_get_system_time_ms(); + r.sample_time = srsu2ms(srs_get_system_time()); r.rbytes = kbps->get_recv_bytes(); r.rkbps = kbps->get_recv_kbps(); @@ -1199,7 +1199,7 @@ void srs_api_dump_summaries(SrsJsonObject* obj) self_mem_percent = (float)(r->r.ru_maxrss / (double)m->MemTotal); } - int64_t now = srs_get_system_time_ms(); + int64_t now = srsu2ms(srs_get_system_time()); double srs_uptime = (now - p->srs_startup_time) / 100 / 10.0; int64_t n_sample_time = 0; diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index fb9c0b6f7..63c470485 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // current release version #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 47 +#define VERSION_REVISION 48 // generated by configure, only macros. #include @@ -86,7 +86,10 @@ #include #include -// important performance options. +// Time defines. +#include + +// Some important performance options. #include // free the p and set to NULL. diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp index 188c150d4..4e2f33888 100644 --- a/trunk/src/core/srs_core_performance.hpp +++ b/trunk/src/core/srs_core_performance.hpp @@ -56,7 +56,7 @@ #define SRS_PERF_MERGED_READ // the default config of mr. #define SRS_PERF_MR_ENABLED false -#define SRS_PERF_MR_SLEEP 350 +#define SRS_PERF_MR_SLEEP (350 * SRS_UTIME_MILLISECONDS) /** * the MW(merged-write) send cache time in ms. @@ -91,7 +91,7 @@ * 2000 150 300 */ // the default config of mw. -#define SRS_PERF_MW_SLEEP 350 +#define SRS_PERF_MW_SLEEP (350 * SRS_UTIME_MILLISECONDS) /** * how many msgs can be send entirely. * for play clients to get msgs then totally send out. diff --git a/trunk/src/core/srs_core_time.cpp b/trunk/src/core/srs_core_time.cpp new file mode 100644 index 000000000..32ee3208c --- /dev/null +++ b/trunk/src/core/srs_core_time.cpp @@ -0,0 +1,25 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2019 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + diff --git a/trunk/src/core/srs_core_time.hpp b/trunk/src/core/srs_core_time.hpp new file mode 100644 index 000000000..f9f7bdd5c --- /dev/null +++ b/trunk/src/core/srs_core_time.hpp @@ -0,0 +1,52 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2019 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SRS_CORE_TIME_HPP +#define SRS_CORE_TIME_HPP + +#include + +// Time and duration unit, in us. +typedef int64_t srs_utime_t; + +// The time unit in ms, for example 100 * SRS_UTIME_MILLISECONDS means 100ms. +#define SRS_UTIME_MILLISECONDS 1000 + +// Convert srs_utime_t in ms unit. +#define srsu2ms(us) (us / SRS_UTIME_MILLISECONDS) +#define srsu2msi(us) int(us / SRS_UTIME_MILLISECONDS) + +// The time unit in ms, for example 120 * SRS_UTIME_SECONDS means 120s. +#define SRS_UTIME_SECONDS 1000000 + +// The time unit in minutes, for example 3 * SRS_UTIME_MINUTES means 3m. +#define SRS_UTIME_MINUTES 60000000LL + +// The time unit in hours, for example 2 * SRS_UTIME_HOURS means 2h. +#define SRS_UTIME_HOURS 3600000000LL + +// Never timeout. +#define SRS_UTIME_NO_TIMEOUT ((srs_utime_t) -1LL) + +#endif + diff --git a/trunk/src/kernel/srs_kernel_consts.hpp b/trunk/src/kernel/srs_kernel_consts.hpp index 08710690b..4ffa78f49 100644 --- a/trunk/src/kernel/srs_kernel_consts.hpp +++ b/trunk/src/kernel/srs_kernel_consts.hpp @@ -64,20 +64,15 @@ // the following is the timeout for rtmp protocol, // to avoid death connection. -// Never timeout in ms -// @remake Rename from SRS_CONSTS_NO_TIMEOUT -// @see ST_UTIME_NO_TIMEOUT -#define SRS_CONSTS_NO_TMMS ((int64_t) -1LL) - -// the common io timeout, for both recv and send. -// TODO: FIXME: use ms for timeout. -#define SRS_CONSTS_RTMP_TMMS (30*1000) +// the common io timeout, for connect, recv or send. +// TODO: FIXME: Maybe change to smaller value, such as 3s? +#define SRS_CONSTS_RTMP_TIMEOUT (30 * SRS_UTIME_SECONDS) // the timeout to wait for client control message, // if timeout, we generally ignore and send the data to client, // generally, it's the pulse time for data seding. // @remark, recomment to 500ms. -#define SRS_CONSTS_RTMP_PULSE_TMMS (500) +#define SRS_CONSTS_RTMP_PULSE (500 * SRS_UTIME_MILLISECONDS) /** * max rtmp header size: @@ -226,7 +221,7 @@ #define SRS_CONSTS_HTTP_QUERY_SEP '?' // the default recv timeout. -#define SRS_HTTP_RECV_TMMS (60 * 1000) +#define SRS_HTTP_RECV_TMMS (60 * SRS_UTIME_SECONDS) // 6.1.1 Status Code and Reason Phrase #define SRS_CONSTS_HTTP_Continue 100 diff --git a/trunk/src/kernel/srs_kernel_error.cpp b/trunk/src/kernel/srs_kernel_error.cpp index 281f0b043..9ea9534de 100644 --- a/trunk/src/kernel/srs_kernel_error.cpp +++ b/trunk/src/kernel/srs_kernel_error.cpp @@ -83,9 +83,13 @@ std::string SrsCplxError::description() { while (next) { ss << "thread #" << next->cid << ": " << next->func << "() [" << next->file << ":" << next->line << "]" - << "[errno=" << next->rerrno << "]" - << endl; + << "[errno=" << next->rerrno << "]"; + next = next->wrapped; + + if (next) { + ss << endl; + } } desc = ss.str(); diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index e5b2fece8..62c776636 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -114,6 +114,7 @@ #define ERROR_SOCKET_SETKEEPALIVE 1075 #define ERROR_SOCKET_NO_NODELAY 1076 #define ERROR_SOCKET_SNDBUF 1077 +#define ERROR_THREAD_STARTED 1078 /////////////////////////////////////////////////////// // RTMP protocol error. diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index c0dc2bd07..085d74331 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -101,28 +101,28 @@ srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v) return err; } -int64_t _srs_system_time_us_cache = 0; -int64_t _srs_system_time_startup_time = 0; +srs_utime_t _srs_system_time_us_cache = 0; +srs_utime_t _srs_system_time_startup_time = 0; -int64_t srs_get_system_time_ms() +srs_utime_t srs_get_system_time() { if (_srs_system_time_us_cache <= 0) { - srs_update_system_time_ms(); + srs_update_system_time(); } - return _srs_system_time_us_cache / 1000; + return _srs_system_time_us_cache; } -int64_t srs_get_system_startup_time_ms() +srs_utime_t srs_get_system_startup_time() { if (_srs_system_time_startup_time <= 0) { - srs_update_system_time_ms(); + srs_update_system_time(); } - return _srs_system_time_startup_time / 1000; + return _srs_system_time_startup_time; } -int64_t srs_update_system_time_ms() +srs_utime_t srs_update_system_time() { timeval now; @@ -143,7 +143,7 @@ int64_t srs_update_system_time_ms() // so we use relative time. if (_srs_system_time_us_cache <= 0) { _srs_system_time_startup_time = _srs_system_time_us_cache = now_us; - return _srs_system_time_us_cache / 1000; + return _srs_system_time_us_cache; } // use relative time. @@ -158,9 +158,10 @@ int64_t srs_update_system_time_ms() _srs_system_time_us_cache = now_us; srs_info("clock updated, startup=%" PRId64 "us, now=%" PRId64 "us", _srs_system_time_startup_time, _srs_system_time_us_cache); - return _srs_system_time_us_cache / 1000; + return _srs_system_time_us_cache; } +// TODO: FIXME: Replace by ST dns resolve. string srs_dns_resolve(string host, int& family) { addrinfo hints; diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index 13c264bd9..2d22391a2 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -29,6 +29,7 @@ #include #include + class SrsBuffer; class SrsBitBuffer; @@ -40,11 +41,11 @@ class SrsBitBuffer; extern srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer* stream, int32_t& v); extern srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v); -// get current system time in ms, use cache to avoid performance problem -extern int64_t srs_get_system_time_ms(); -extern int64_t srs_get_system_startup_time_ms(); +// get current system time in srs_utime_t, use cache to avoid performance problem +extern srs_utime_t srs_get_system_time(); +extern srs_utime_t srs_get_system_startup_time(); // the deamon st-thread will update it. -extern int64_t srs_update_system_time_ms(); +extern srs_utime_t srs_update_system_time(); // the any address for listener, // it's "0.0.0.0" for ipv4, and "::" for ipv6. diff --git a/trunk/src/libs/srs_lib_bandwidth.cpp b/trunk/src/libs/srs_lib_bandwidth.cpp index 69b0de289..757912e7e 100644 --- a/trunk/src/libs/srs_lib_bandwidth.cpp +++ b/trunk/src/libs/srs_lib_bandwidth.cpp @@ -137,8 +137,7 @@ int SrsBandwidthClient::bandwidth_check( ) { int ret = ERROR_SUCCESS; - srs_update_system_time_ms(); - *start_time = srs_get_system_time_ms(); + *start_time = srsu2ms(srs_update_system_time()); // play if ((ret = play_start()) != ERROR_SUCCESS) { @@ -193,8 +192,7 @@ int SrsBandwidthClient::bandwidth_check( } } - srs_update_system_time_ms(); - *end_time = srs_get_system_time_ms(); + *end_time = srsu2ms(srs_update_system_time()); return ret; } @@ -313,9 +311,8 @@ int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) } int data_count = 1; - srs_update_system_time_ms(); - int64_t starttime = srs_get_system_time_ms(); - while ((srs_get_system_time_ms() - starttime) < duration_ms) { + int64_t starttime = srsu2ms(srs_update_system_time()); + while (int64_t(srsu2ms(srs_get_system_time()) - starttime) < duration_ms) { // TODO: FIXME: use shared ptr message. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing(); @@ -336,13 +333,12 @@ int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) } // use the play kbps to control the publish - srs_update_system_time_ms(); - int elaps = (int)(srs_get_system_time_ms() - starttime); + int elaps = (int)(srsu2ms(srs_update_system_time()) - starttime); if (elaps > 0) { int current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps); while (current_kbps > play_kbps) { - srs_update_system_time_ms(); - elaps = (int)(srs_get_system_time_ms() - starttime); + srs_update_system_time(); + elaps = (int)(srsu2ms(srs_get_system_time()) - starttime); current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps); usleep(100 * 1000); // TODO: FIXME: magic number. } diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index 5d7b994f9..9abbdcdbb 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -86,7 +86,7 @@ struct SrsBlockSyncSocket int64_t stm; SrsBlockSyncSocket() { - stm = rtm = SRS_CONSTS_NO_TMMS; + stm = rtm = SRS_UTIME_NO_TIMEOUT; rbytes = sbytes = 0; SOCKET_RESET(fd); @@ -191,7 +191,7 @@ int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm) int32_t sec = 0; int32_t usec = 0; - if (tm != SRS_CONSTS_NO_TMMS) { + if (tm != SRS_UTIME_NO_TIMEOUT) { sec = (int32_t)(tm / 1000); usec = (int32_t)((tm % 1000)*1000); } @@ -224,7 +224,7 @@ int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm) int32_t sec = 0; int32_t usec = 0; - if (tm != SRS_CONSTS_NO_TMMS) { + if (tm != SRS_UTIME_NO_TIMEOUT) { sec = (int32_t)(tm / 1000); usec = (int32_t)((tm % 1000)*1000); } @@ -278,7 +278,7 @@ int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ss } int srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t tm) { - return tm == SRS_CONSTS_NO_TMMS; + return tm == SRS_UTIME_NO_TIMEOUT; } int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) { diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 2bfbbcea0..5cced7085 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -129,7 +129,7 @@ struct Context h264_sps_pps_sent = false; h264_sps_changed = false; h264_pps_changed = false; - rtimeout = stimeout = SRS_CONSTS_NO_TMMS; + rtimeout = stimeout = SRS_UTIME_NO_TIMEOUT; schema = srs_url_schema_normal; } virtual ~Context() { @@ -635,11 +635,11 @@ int srs_rtmp_connect_server(srs_rtmp_t rtmp) Context* context = (Context*)rtmp; // set timeout if user not set. - if (context->stimeout == SRS_CONSTS_NO_TMMS) { + if (context->stimeout == SRS_UTIME_NO_TIMEOUT) { context->stimeout = SRS_SOCKET_DEFAULT_TMMS; context->skt->set_send_timeout(context->stimeout); } - if (context->rtimeout == SRS_CONSTS_NO_TMMS) { + if (context->rtimeout == SRS_UTIME_NO_TIMEOUT) { context->rtimeout = SRS_SOCKET_DEFAULT_TMMS; context->skt->set_recv_timeout(context->rtimeout); } @@ -2212,7 +2212,7 @@ void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) int64_t srs_utils_time_ms() { - return srs_update_system_time_ms(); + return srs_update_system_time(); } int64_t srs_utils_send_bytes(srs_rtmp_t rtmp) diff --git a/trunk/src/main/srs_main_ingest_hls.cpp b/trunk/src/main/srs_main_ingest_hls.cpp index 9fda82968..ba405560e 100644 --- a/trunk/src/main/srs_main_ingest_hls.cpp +++ b/trunk/src/main/srs_main_ingest_hls.cpp @@ -154,7 +154,7 @@ private: private: SrsHttpUri* in_hls; std::vector pieces; - int64_t next_connect_time; + srs_utime_t next_connect_time; private: SrsTsContext* context; public: @@ -213,10 +213,10 @@ int SrsIngestHlsInput::connect() { int ret = ERROR_SUCCESS; - int64_t now = srs_update_system_time_ms(); + srs_utime_t now = srs_update_system_time(); if (now < next_connect_time) { - srs_trace("input hls wait for %dms", next_connect_time - now); - srs_usleep((next_connect_time - now) * 1000); + srs_trace("input hls wait for %dms", srsu2msi(next_connect_time - now)); + srs_usleep(next_connect_time - now); } // set all ts to dirty. @@ -559,7 +559,7 @@ int SrsIngestHlsInput::fetch_all_ts(bool fresh_m3u8) // only wait for a duration of last piece. if (i == (int)pieces.size() - 1) { - next_connect_time = srs_update_system_time_ms() + (int)tp->duration * 1000; + next_connect_time = srs_update_system_time() + tp->duration * SRS_UTIME_SECONDS; } } @@ -696,7 +696,7 @@ SrsIngestHlsOutput::SrsIngestHlsOutput(SrsHttpUri* rtmp) { out_rtmp = rtmp; disconnected = false; - raw_aac_dts = srs_update_system_time_ms(); + raw_aac_dts = srsu2ms(srs_update_system_time()); req = NULL; sdk = NULL; @@ -1275,8 +1275,8 @@ int SrsIngestHlsOutput::connect() srs_trace("connect output=%s", url.c_str()); // connect host. - int64_t cto = SRS_CONSTS_RTMP_TMMS; - int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; + int64_t cto = srsu2ms(SRS_CONSTS_RTMP_TIMEOUT); + int64_t sto = srsu2ms(SRS_CONSTS_RTMP_PULSE); sdk = new SrsBasicRtmpClient(url, cto, sto); if ((err = sdk->connect()) != srs_success) { diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index fe48f06ed..904f2cd73 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -286,7 +286,7 @@ void show_macro_features() stringstream ss; // mw(merged-write) - ss << "mw sleep:" << SRS_PERF_MW_SLEEP << "ms"; + ss << "mw sleep:" << srsu2msi(SRS_PERF_MW_SLEEP) << "ms"; // mr(merged-read) ss << ". mr "; @@ -295,7 +295,7 @@ void show_macro_features() #else ss << "enabled:off"; #endif - ss << ", default:" << SRS_PERF_MR_ENABLED << ", sleep:" << SRS_PERF_MR_SLEEP << "ms"; + ss << ", default:" << SRS_PERF_MR_ENABLED << ", sleep:" << srsu2msi(SRS_PERF_MR_SLEEP) << "ms"; srs_trace(ss.str().c_str()); } @@ -339,10 +339,10 @@ void show_macro_features() // others int possible_mr_latency = 0; #ifdef SRS_PERF_MERGED_READ - possible_mr_latency = SRS_PERF_MR_SLEEP; + possible_mr_latency = srsu2msi(SRS_PERF_MR_SLEEP); #endif srs_trace("system default latency in ms: mw(0-%d) + mr(0-%d) + play-queue(0-%d)", - SRS_PERF_MW_SLEEP, possible_mr_latency, SRS_PERF_PLAY_QUEUE*1000); + srsu2msi(SRS_PERF_MW_SLEEP), possible_mr_latency, SRS_PERF_PLAY_QUEUE*1000); #ifdef SRS_AUTO_MEM_WATCH #warning "srs memory watcher will hurts performance. user should kill by SIGTERM or init.d script." diff --git a/trunk/src/protocol/srs_protocol_io.hpp b/trunk/src/protocol/srs_protocol_io.hpp index 49e6b064f..ec69648f2 100644 --- a/trunk/src/protocol/srs_protocol_io.hpp +++ b/trunk/src/protocol/srs_protocol_io.hpp @@ -90,7 +90,7 @@ public: public: /** * Set the timeout tm in ms for recv bytes from peer. - * @remark Use SRS_CONSTS_NO_TMMS to never timeout. + * @remark Use SRS_UTIME_NO_TIMEOUT to never timeout. */ virtual void set_recv_timeout(int64_t tm) = 0; /** @@ -118,7 +118,7 @@ public: public: /** * Set the timeout tm in ms for send bytes to peer. - * @remark Use SRS_CONSTS_NO_TMMS to never timeout. + * @remark Use SRS_UTIME_NO_TIMEOUT to never timeout. */ virtual void set_send_timeout(int64_t tm) = 0; /** diff --git a/trunk/src/protocol/srs_protocol_kbps.cpp b/trunk/src/protocol/srs_protocol_kbps.cpp index eb7167227..943bad189 100644 --- a/trunk/src/protocol/srs_protocol_kbps.cpp +++ b/trunk/src/protocol/srs_protocol_kbps.cpp @@ -113,7 +113,7 @@ SrsWallClock::~SrsWallClock() int64_t SrsWallClock::time_ms() { - return srs_get_system_time_ms(); + return srsu2ms(srs_get_system_time()); } SrsKbps::SrsKbps(SrsWallClock* c) : is(c), os(c) diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 1466c96f8..b1a0bac51 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -307,6 +307,7 @@ public: * set/get the recv timeout in ms. * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. */ + // TODO: FIXME: Refine tm in time unit. virtual void set_recv_timeout(int64_t tm); virtual int64_t get_recv_timeout(); /** diff --git a/trunk/src/service/srs_service_http_client.cpp b/trunk/src/service/srs_service_http_client.cpp index 4b5244fe7..b90f116a4 100644 --- a/trunk/src/service/srs_service_http_client.cpp +++ b/trunk/src/service/srs_service_http_client.cpp @@ -41,7 +41,7 @@ SrsHttpClient::SrsHttpClient() clk = new SrsWallClock(); kbps = new SrsKbps(clk); parser = NULL; - timeout = SRS_CONSTS_NO_TMMS; + timeout = SRS_UTIME_NO_TIMEOUT; port = 0; } diff --git a/trunk/src/service/srs_service_st.cpp b/trunk/src/service/srs_service_st.cpp index f294ef6f4..395c44e41 100644 --- a/trunk/src/service/srs_service_st.cpp +++ b/trunk/src/service/srs_service_st.cpp @@ -104,10 +104,11 @@ srs_thread_t srs_thread_self() return (srs_thread_t)st_thread_self(); } +// TODO: FXIME: Refine tm in time unit. srs_error_t srs_socket_connect(string server, int port, int64_t tm, srs_netfd_t* pstfd) { st_utime_t timeout = ST_UTIME_NO_TIMEOUT; - if (tm != SRS_CONSTS_NO_TMMS) { + if (tm != SRS_UTIME_NO_TIMEOUT) { timeout = (st_utime_t)(tm * 1000); } @@ -232,7 +233,7 @@ ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout) SrsStSocket::SrsStSocket() { stfd = NULL; - stm = rtm = SRS_CONSTS_NO_TMMS; + stm = rtm = SRS_UTIME_NO_TIMEOUT; rbytes = sbytes = 0; } @@ -248,7 +249,7 @@ srs_error_t SrsStSocket::initialize(srs_netfd_t fd) bool SrsStSocket::is_never_timeout(int64_t tm) { - return tm == SRS_CONSTS_NO_TMMS; + return tm == SRS_UTIME_NO_TIMEOUT; } void SrsStSocket::set_recv_timeout(int64_t tm) @@ -286,7 +287,7 @@ srs_error_t SrsStSocket::read(void* buf, size_t size, ssize_t* nread) srs_error_t err = srs_success; ssize_t nb_read; - if (rtm == SRS_CONSTS_NO_TMMS) { + if (rtm == SRS_UTIME_NO_TIMEOUT) { nb_read = st_read((st_netfd_t)stfd, buf, size, ST_UTIME_NO_TIMEOUT); } else { nb_read = st_read((st_netfd_t)stfd, buf, size, rtm * 1000); @@ -322,7 +323,7 @@ srs_error_t SrsStSocket::read_fully(void* buf, size_t size, ssize_t* nread) srs_error_t err = srs_success; ssize_t nb_read; - if (rtm == SRS_CONSTS_NO_TMMS) { + if (rtm == SRS_UTIME_NO_TIMEOUT) { nb_read = st_read_fully((st_netfd_t)stfd, buf, size, ST_UTIME_NO_TIMEOUT); } else { nb_read = st_read_fully((st_netfd_t)stfd, buf, size, rtm * 1000); @@ -358,7 +359,7 @@ srs_error_t SrsStSocket::write(void* buf, size_t size, ssize_t* nwrite) srs_error_t err = srs_success; ssize_t nb_write; - if (stm == SRS_CONSTS_NO_TMMS) { + if (stm == SRS_UTIME_NO_TIMEOUT) { nb_write = st_write((st_netfd_t)stfd, buf, size, ST_UTIME_NO_TIMEOUT); } else { nb_write = st_write((st_netfd_t)stfd, buf, size, stm * 1000); @@ -389,7 +390,7 @@ srs_error_t SrsStSocket::writev(const iovec *iov, int iov_size, ssize_t* nwrite) srs_error_t err = srs_success; ssize_t nb_write; - if (stm == SRS_CONSTS_NO_TMMS) { + if (stm == SRS_UTIME_NO_TIMEOUT) { nb_write = st_writev((st_netfd_t)stfd, iov, iov_size, ST_UTIME_NO_TIMEOUT); } else { nb_write = st_writev((st_netfd_t)stfd, iov, iov_size, stm * 1000); diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index aec303cfd..f5eb9cffb 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -35,9 +35,6 @@ typedef void* srs_netfd_t; typedef void* srs_thread_t; typedef void* srs_cond_t; typedef void* srs_mutex_t; -typedef uint64_t srs_utime_t; - -#define SRS_UTIME_NO_TIMEOUT ((srs_utime_t) -1LL) // initialize st, requires epoll. extern srs_error_t srs_st_init(); @@ -113,7 +110,7 @@ class SrsStSocket : public ISrsProtocolReadWriter { private: // The recv/send timeout in ms. - // @remark Use SRS_CONSTS_NO_TMMS for never timeout in ms. + // @remark Use SRS_UTIME_NO_TIMEOUT for never timeout in ms. int64_t rtm; int64_t stm; // The recv/send data in bytes diff --git a/trunk/src/utest/srs_utest.cpp b/trunk/src/utest/srs_utest.cpp index 7ba49dc40..9b0a0200e 100644 --- a/trunk/src/utest/srs_utest.cpp +++ b/trunk/src/utest/srs_utest.cpp @@ -36,6 +36,44 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext(); SrsConfig* _srs_config = NULL; SrsServer* _srs_server = NULL; +// Disable coroutine test for OSX. +#if !defined(SRS_OSX) +#include +#endif + +// Initialize global settings. +srs_error_t prepare_main() { + srs_error_t err = srs_success; + + #if !defined(SRS_OSX) + if ((err = srs_st_init()) != srs_success) { + return srs_error_wrap(err, "init st"); + } + + srs_freep(_srs_context); + _srs_context = new SrsThreadContext(); + #endif + + return err; +} + +// We could do something in the main of utest. +// Copy from gtest-1.6.0/src/gtest_main.cc +GTEST_API_ int main(int argc, char **argv) { + srs_error_t err = srs_success; + + if ((err = prepare_main()) != srs_success) { + fprintf(stderr, "Failed, %s\n", srs_error_desc(err).c_str()); + + int ret = srs_error_code(err); + srs_freep(err); + return ret; + } + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + MockEmptyLog::MockEmptyLog(SrsLogLevel l) { level = l; diff --git a/trunk/src/utest/srs_utest.hpp b/trunk/src/utest/srs_utest.hpp index 26691c743..f9222fe43 100644 --- a/trunk/src/utest/srs_utest.hpp +++ b/trunk/src/utest/srs_utest.hpp @@ -24,6 +24,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef SRS_UTEST_PUBLIC_SHARED_HPP #define SRS_UTEST_PUBLIC_SHARED_HPP +// Public all private and protected members. +#define private public +#define protected public + /* #include */ @@ -36,10 +40,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // we add an empty macro for upp to show the smart tips. #define VOID -// Public all private and protected members. -#define private public -#define protected public - // the asserts of gtest: // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 diff --git a/trunk/src/utest/srs_utest_app.cpp b/trunk/src/utest/srs_utest_app.cpp new file mode 100644 index 000000000..28f9fcd2f --- /dev/null +++ b/trunk/src/utest/srs_utest_app.cpp @@ -0,0 +1,379 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2019 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#include + +using namespace std; + +#include +#include + +// Disable coroutine test for OSX. +#if !defined(SRS_OSX) + +#include + +VOID TEST(AppCoroutineTest, Dummy) +{ + SrsDummyCoroutine dc; + + if (true) { + EXPECT_EQ(0, dc.cid()); + + srs_error_t err = dc.pull(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + + err = dc.start(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + dc.stop(); + + EXPECT_EQ(0, dc.cid()); + + srs_error_t err = dc.pull(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + + err = dc.start(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + dc.interrupt(); + + EXPECT_EQ(0, dc.cid()); + + srs_error_t err = dc.pull(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + + err = dc.start(); + EXPECT_TRUE(err != srs_success); + EXPECT_TRUE(ERROR_THREAD_DUMMY == srs_error_code(err)); + srs_freep(err); + } +} + +class MockCoroutineHandler : public ISrsCoroutineHandler { +public: + SrsSTCoroutine* trd; + srs_error_t err; + srs_cond_t running; + srs_cond_t exited; + int cid; + // Quit without error. + bool quit; +public: + MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0), quit(false) { + running = srs_cond_new(); + exited = srs_cond_new(); + } + virtual ~MockCoroutineHandler() { + srs_cond_destroy(running); + srs_cond_destroy(exited); + } +public: + virtual srs_error_t cycle() { + srs_error_t r0 = srs_success; + + srs_cond_signal(running); + cid = _srs_context->get_id(); + + while (!quit && (r0 = trd->pull()) == srs_success && err == srs_success) { + srs_usleep(10 * SRS_UTIME_MILLISECONDS); + } + + srs_cond_signal(exited); + + if (err != srs_success) { + srs_freep(r0); + return err; + } + + return r0; + } +}; + +VOID TEST(AppCoroutineTest, StartStop) +{ + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + EXPECT_EQ(0, sc.cid()); + + // Thread stop after created. + sc.stop(); + + EXPECT_EQ(0, sc.cid()); + + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_TERMINATED == srs_error_code(err)); + srs_freep(err); + + // Should never reuse a disposed thread. + err = sc.start(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_DISPOSED == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + EXPECT_EQ(0, sc.cid()); + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS); + EXPECT_TRUE(sc.cid() > 0); + + // Thread stop after started. + sc.stop(); + + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_INTERRUPED == srs_error_code(err)); + srs_freep(err); + + // Should never reuse a disposed thread. + err = sc.start(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_DISPOSED == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + EXPECT_EQ(0, sc.cid()); + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + // Error when start multiple times. + srs_error_t err = sc.start(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_STARTED == srs_error_code(err)); + srs_freep(err); + + err = sc.pull(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_THREAD_STARTED == srs_error_code(err)); + srs_freep(err); + } +} + +VOID TEST(AppCoroutineTest, Cycle) +{ + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + // Set cycle to error. + ch.err = srs_error_new(-1, "cycle"); + + srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS); + + // The cycle error should be pulled. + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(-1 == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch, 250); + ch.trd = ≻ + EXPECT_EQ(250, sc.cid()); + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + // After running, the cid in cycle should equal to the thread. + srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS); + EXPECT_EQ(250, ch.cid); + } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + srs_cond_timedwait(ch.running, 100 * SRS_UTIME_MILLISECONDS); + + // Interrupt thread, set err to interrupted. + sc.interrupt(); + + // Set cycle to error. + ch.err = srs_error_new(-1, "cycle"); + + // When thread terminated, thread will get its error. + srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS); + + // Override the error by cycle error. + sc.stop(); + + // Should be cycle error. + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(-1 == srs_error_code(err)); + srs_freep(err); + } + + if (true) { + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + EXPECT_TRUE(srs_success == sc.start()); + EXPECT_TRUE(srs_success == sc.pull()); + + // Quit without error. + ch.quit = true; + + // Wait for thread to done. + srs_cond_timedwait(ch.exited, 100 * SRS_UTIME_MILLISECONDS); + + // Override the error by cycle error. + sc.stop(); + + // Should be cycle error. + srs_error_t err = sc.pull(); + EXPECT_TRUE(srs_success == err); + srs_freep(err); + } +} + +void* mock_st_thread_create(void *(*/*start*/)(void *arg), void */*arg*/, int /*joinable*/, int /*stack_size*/) { + return NULL; +} + +VOID TEST(AppCoroutineTest, StartThread) +{ + MockCoroutineHandler ch; + SrsSTCoroutine sc("test", &ch); + ch.trd = ≻ + + _ST_THREAD_CREATE_PFN ov = _pfn_st_thread_create; + _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)mock_st_thread_create; + + srs_error_t err = sc.start(); + _pfn_st_thread_create = ov; + + EXPECT_TRUE(srs_success != err); + EXPECT_TRUE(ERROR_ST_CREATE_CYCLE_THREAD == srs_error_code(err)); + srs_freep(err); +} + +#endif + +VOID TEST(AppFragmentTest, CheckDuration) +{ + if (true) { + SrsFragment frg; + EXPECT_EQ(-1, frg.start_dts); + EXPECT_EQ(0, frg.dur); + EXPECT_FALSE(frg.sequence_header); + } + + if (true) { + SrsFragment frg; + + frg.append(0); + EXPECT_EQ(0, frg.duration()); + + frg.append(10); + EXPECT_EQ(10 * SRS_UTIME_MILLISECONDS, frg.duration()); + + frg.append(99); + EXPECT_EQ(99 * SRS_UTIME_MILLISECONDS, frg.duration()); + + frg.append(0x7fffffffLL); + EXPECT_EQ(0x7fffffffLL * SRS_UTIME_MILLISECONDS, frg.duration()); + + frg.append(0xffffffffLL); + EXPECT_EQ(0xffffffffLL * SRS_UTIME_MILLISECONDS, frg.duration()); + + frg.append(0x20c49ba5e353f7LL); + EXPECT_EQ(0x20c49ba5e353f7LL * SRS_UTIME_MILLISECONDS, frg.duration()); + } + + if (true) { + SrsFragment frg; + + frg.append(0); + EXPECT_EQ(0, frg.duration()); + + frg.append(0x7fffffffffffffffLL); + EXPECT_EQ(0, frg.duration()); + } + + if (true) { + SrsFragment frg; + + frg.append(100); + EXPECT_EQ(0, frg.duration()); + + frg.append(10); + EXPECT_EQ(0, frg.duration()); + + frg.append(100); + EXPECT_EQ(90 * SRS_UTIME_MILLISECONDS, frg.duration()); + } + + if (true) { + SrsFragment frg; + + frg.append(-10); + EXPECT_EQ(0, frg.duration()); + + frg.append(-5); + EXPECT_EQ(0, frg.duration()); + + frg.append(10); + EXPECT_EQ(10 * SRS_UTIME_MILLISECONDS, frg.duration()); + } +} + diff --git a/trunk/src/utest/srs_utest_app.hpp b/trunk/src/utest/srs_utest_app.hpp new file mode 100644 index 000000000..20c793c4c --- /dev/null +++ b/trunk/src/utest/srs_utest_app.hpp @@ -0,0 +1,33 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2019 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_UTEST_APP_HPP +#define SRS_UTEST_APP_HPP + +/* +#include +*/ +#include + +#endif + diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index f04614345..0779411dc 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -29,6 +29,8 @@ using namespace std; #include #include #include +#include +#include MockSrsConfigBuffer::MockSrsConfigBuffer(string buf) { @@ -1804,3 +1806,89 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_ingest_id) EXPECT_TRUE(ERROR_SUCCESS != conf.parse(_MIN_OK_CONF"vhost v{ingest{} ingest{}}")); } +VOID TEST(ConfigUnitTest, CheckDefaultValues) +{ + MockSrsConfig conf; + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_bw_check_interval("")); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{bandcheck{interval 4;}}")); + EXPECT_EQ(4 * SRS_UTIME_SECONDS, conf.get_bw_check_interval("v")); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(3 * SRS_UTIME_SECONDS, conf.get_dash_fragment("")); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dash_update_period("")); + EXPECT_EQ(60 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("")); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{dash{dash_fragment 4;dash_update_period 40;dash_timeshift 70;}}")); + EXPECT_EQ(4 * SRS_UTIME_SECONDS, conf.get_dash_fragment("v")); + EXPECT_EQ(40 * SRS_UTIME_SECONDS, conf.get_dash_update_period("v")); + EXPECT_EQ(70 * SRS_UTIME_SECONDS, conf.get_dash_timeshift("v")); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(srs_utime_t(9.9 * SRS_UTIME_SECONDS), conf.get_heartbeat_interval()); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"heartbeat{interval 10;}")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_heartbeat_interval()); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_pithy_print()); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"pithy_print_ms 20000;")); + EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_pithy_print()); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(350 * SRS_UTIME_MILLISECONDS, conf.get_mr_sleep("")); + EXPECT_EQ(350 * SRS_UTIME_MILLISECONDS, conf.get_mw_sleep("")); + EXPECT_EQ(20 * SRS_UTIME_SECONDS, conf.get_publish_1stpkt_timeout("")); + EXPECT_EQ(5 * SRS_UTIME_SECONDS, conf.get_publish_normal_timeout("")); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{publish{mr_latency 1000; firstpkt_timeout 100; normal_timeout 100;} play{mw_latency 1000;}}")); + EXPECT_EQ(1000 * SRS_UTIME_MILLISECONDS, conf.get_mr_sleep("v")); + EXPECT_EQ(100 * SRS_UTIME_MILLISECONDS, conf.get_publish_1stpkt_timeout("v")); + EXPECT_EQ(100 * SRS_UTIME_MILLISECONDS, conf.get_publish_normal_timeout("v")); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(30 * SRS_UTIME_SECONDS, conf.get_dvr_duration("")); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{dvr{dvr_duration 10;}}")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_dvr_duration("v")); + } + + if (true) { + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF)); + EXPECT_EQ(0, conf.get_hls_dispose("")); + + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{hls{hls_dispose 10;}}")); + EXPECT_EQ(10 * SRS_UTIME_SECONDS, conf.get_hls_dispose("v")); + } + + if (true) { + srs_utime_t t0 = srs_update_system_time(); + srs_usleep(10 * SRS_UTIME_MILLISECONDS); + srs_utime_t t1 = srs_update_system_time(); + + EXPECT_TRUE(t1 - t0 >= 10 * SRS_UTIME_MILLISECONDS); + } + + if (true) { + srs_utime_t t0 = srs_get_system_time(); + srs_utime_t t1 = srs_update_system_time(); + + EXPECT_TRUE(t0 > 0); + EXPECT_TRUE(t1 >= t0); + } +} + diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index b68d15b51..990754ce1 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -1482,15 +1482,14 @@ VOID TEST(KernelBufferTest, CoverAll) */ VOID TEST(KernelUtilityTest, UtilityTime) { - int64_t time = srs_get_system_time_ms(); + srs_utime_t time = srs_get_system_time(); EXPECT_TRUE(time > 0); - int64_t time1 = srs_get_system_time_ms(); + srs_utime_t time1 = srs_get_system_time(); EXPECT_EQ(time, time1); - usleep(1000); - srs_update_system_time_ms(); - time1 = srs_get_system_time_ms(); + usleep(1 * SRS_UTIME_MILLISECONDS); + time1 = srs_update_system_time(); EXPECT_TRUE(time1 > time); } @@ -1499,15 +1498,15 @@ VOID TEST(KernelUtilityTest, UtilityTime) */ VOID TEST(KernelUtilityTest, UtilityStartupTime) { - int64_t time = srs_get_system_startup_time_ms(); + srs_utime_t time = srs_get_system_startup_time(); EXPECT_TRUE(time > 0); - int64_t time1 = srs_get_system_startup_time_ms(); + srs_utime_t time1 = srs_get_system_startup_time(); EXPECT_EQ(time, time1); - usleep(1000); - srs_update_system_time_ms(); - time1 = srs_get_system_startup_time_ms(); + usleep(1 * SRS_UTIME_MILLISECONDS); + srs_update_system_time(); + time1 = srs_get_system_startup_time(); EXPECT_EQ(time, time1); } @@ -3182,10 +3181,10 @@ VOID TEST(KernelUtilityTest, CoverTimeUtilityAll) { _srs_system_time_us_cache = 0; _srs_system_time_startup_time = 0; - EXPECT_TRUE(srs_get_system_startup_time_ms() > 0); + EXPECT_TRUE(srs_get_system_startup_time() > 0); _srs_system_time_us_cache -= 300*1000 * 1000 + 1; - EXPECT_TRUE(srs_update_system_time_ms() > 0); + EXPECT_TRUE(srs_update_system_time() > 0); if (true) { string host; diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index 3bc35fd6b..12c0f35e6 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -98,7 +98,7 @@ srs_error_t MockEmptyIO::read(void* /*buf*/, size_t /*size*/, ssize_t* /*nread*/ MockBufferIO::MockBufferIO() { - rtm = stm = SRS_CONSTS_NO_TMMS; + rtm = stm = SRS_UTIME_NO_TIMEOUT; rbytes = sbytes = 0; } @@ -114,7 +114,7 @@ MockBufferIO* MockBufferIO::append(string data) bool MockBufferIO::is_never_timeout(int64_t tm) { - return tm == SRS_CONSTS_NO_TMMS; + return tm == SRS_UTIME_NO_TIMEOUT; } srs_error_t MockBufferIO::read_fully(void* buf, size_t size, ssize_t* nread) @@ -690,8 +690,8 @@ VOID TEST(ProtocolStackTest, ProtocolTimeout) MockBufferIO bio; SrsProtocol proto(&bio); - EXPECT_TRUE(SRS_CONSTS_NO_TMMS == proto.get_recv_timeout()); - EXPECT_TRUE(SRS_CONSTS_NO_TMMS == proto.get_send_timeout()); + EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == proto.get_recv_timeout()); + EXPECT_TRUE(SRS_UTIME_NO_TIMEOUT == proto.get_send_timeout()); proto.set_recv_timeout(10); EXPECT_TRUE(10 == proto.get_recv_timeout()); diff --git a/trunk/src/utest/srs_utest_service.cpp b/trunk/src/utest/srs_utest_service.cpp new file mode 100644 index 000000000..343c21755 --- /dev/null +++ b/trunk/src/utest/srs_utest_service.cpp @@ -0,0 +1,42 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2019 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#include + +using namespace std; + +#include + +// Disable coroutine test for OSX. +#if !defined(SRS_OSX) + +#include + +VOID TEST(ServiceTimeTest, TimeUnit) +{ + EXPECT_EQ(1000, SRS_UTIME_MILLISECONDS); + EXPECT_EQ(1000*1000, SRS_UTIME_SECONDS); + EXPECT_EQ(60*1000*1000, SRS_UTIME_MINUTES); + EXPECT_EQ(3600*1000*1000LL, SRS_UTIME_HOURS); +} + +#endif diff --git a/trunk/src/utest/srs_utest_service.hpp b/trunk/src/utest/srs_utest_service.hpp new file mode 100644 index 000000000..e6e2e2228 --- /dev/null +++ b/trunk/src/utest/srs_utest_service.hpp @@ -0,0 +1,33 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2019 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_UTEST_SERVICE_HPP +#define SRS_UTEST_SERVICE_HPP + +/* +#include +*/ +#include + +#endif +