Merge branch 3.0release into develop

min
winlin 6 years ago
commit a5babfe080

@ -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

3
trunk/.gitignore vendored

@ -37,4 +37,5 @@ srs
*.dSYM/
*.gcov
*.ts
*.h264
*.264

Binary file not shown.

@ -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

@ -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

@ -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

5
trunk/configure vendored

@ -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")

@ -37,17 +37,17 @@ using namespace std;
#include <srs_protocol_kbps.hpp>
#include <srs_app_st.hpp>
#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_usleep(_SRS_BANDWIDTH_FINAL_WAIT_MS * 1000);
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);
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<SrsBandwidthPacket>(&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);
}
}

@ -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);
};
/**

@ -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) {

@ -3960,6 +3960,11 @@ 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()

@ -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.
*/

@ -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;
}

@ -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:
/**

@ -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)
<< "<MPD profiles=\"urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple\" " << endl
<< " ns1:schemaLocation=\"urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd\" " << endl
<< " xmlns=\"urn:mpeg:dash:schema:mpd:2011\" xmlns:ns1=\"http://www.w3.org/2001/XMLSchema-instance\" " << endl
<< " type=\"dynamic\" minimumUpdatePeriod=\"PT" << update_period / 1000 << "S\" " << endl
<< " timeShiftBufferDepth=\"PT" << timeshit / 1000 << "S\" availabilityStartTime=\"1970-01-01T00:00:00Z\" " << endl
<< " maxSegmentDuration=\"PT" << fragment / 1000 << "S\" minBufferTime=\"PT" << fragment / 1000 << "S\" >" << 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
<< " <BaseURL>" << req->stream << "/" << "</BaseURL>" << endl
<< " <Period start=\"PT0S\">" << endl;
if (format->acodec) {
ss << " <AdaptationSet mimeType=\"audio/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl;
ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" "
ss << " <SegmentTemplate duration=\"" << fragment / SRS_UTIME_SECONDS << "\" "
<< "initialization=\"$RepresentationID$-init.mp4\" "
<< "media=\"$RepresentationID$-$Number$.m4s\" />" << endl;
ss << " <Representation id=\"audio\" bandwidth=\"48000\" codecs=\"mp4a.40.2\" />" << endl;
@ -227,7 +227,7 @@ srs_error_t SrsMpdWriter::write(SrsFormat* format)
int w = format->vcodec->width;
int h = format->vcodec->height;
ss << " <AdaptationSet mimeType=\"video/mp4\" segmentAlignment=\"true\" startWithSAP=\"1\">" << endl;
ss << " <SegmentTemplate duration=\"" << fragment / 1000 << "\" "
ss << " <SegmentTemplate duration=\"" << fragment / SRS_UTIME_SECONDS << "\" "
<< "initialization=\"$RepresentationID$-init.mp4\" "
<< "media=\"$RepresentationID$-$Number$.m4s\" />" << endl;
ss << " <Representation id=\"video\" bandwidth=\"800000\" codecs=\"avc1.64001e\" "
@ -265,8 +265,8 @@ srs_error_t SrsMpdWriter::get_fragment(bool video, std::string& home, std::strin
home = fragment_home;
sn = srs_update_system_time_ms() / fragment;
basetime = sn * fragment;
sn = srs_update_system_time() / fragment;
basetime = sn * srsu2ms(fragment);
if (video) {
file_name = "video-" + srs_int2str(sn) + ".m4s";

@ -83,14 +83,14 @@ class SrsMpdWriter
{
private:
SrsRequest* req;
int64_t last_update_mpd;
srs_utime_t last_update_mpd;
private:
// The duration of fragment in ms.
int fragment;
// The period to update the mpd in ms.
int update_period;
// The timeshift buffer depth.
int timeshit;
// The duration of fragment in srs_utime_t.
srs_utime_t fragment;
// The period to update the mpd in srs_utime_t.
srs_utime_t update_period;
// The timeshift buffer depth in srs_utime_t.
srs_utime_t timeshit;
// The base or home dir for dash to write files.
std::string home;
// The MPD path template, from which to build the file path.
@ -128,7 +128,7 @@ private:
uint64_t video_dts;
private:
// The fragment duration in ms to reap it.
int fragment;
srs_utime_t fragment;
private:
std::string home;
int video_tack_id;

@ -286,7 +286,7 @@ srs_error_t SrsDvrFlvSegmenter::refresh_metadata()
}
// duration to buf
SrsAmf0Any* dur = SrsAmf0Any::number((double)fragment->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;
}

@ -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();

@ -48,10 +48,10 @@ using namespace std;
#include <srs_app_rtmp_conn.hpp>
// 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;
}

@ -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

@ -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);

@ -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;

@ -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.

@ -54,6 +54,7 @@ using namespace std;
#include <openssl/rand.h>
// 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);

@ -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.

@ -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());
}

@ -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());

@ -23,7 +23,7 @@
#include <srs_app_http_stream.hpp>
#define SRS_STREAM_CACHE_CYCLE_SECONDS 30
#define SRS_STREAM_CACHE_CYCLE (30 * SRS_UTIME_SECONDS)
#include <sys/types.h>
#include <sys/stat.h>
@ -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.

@ -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;

@ -44,7 +44,7 @@ private:
std::string vhost;
std::string id;
SrsFFMPEG* ffmpeg;
int64_t starttime;
srs_utime_t starttime;
public:
SrsIngesterFFMPEG();
virtual ~SrsIngesterFFMPEG();

@ -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;

@ -174,7 +174,7 @@ srs_error_t SrsUdpListener::cycle()
}
if (SrsUdpPacketRecvCycleMS > 0) {
srs_usleep(SrsUdpPacketRecvCycleMS * 1000);
srs_usleep(SrsUdpPacketRecvCycleMS * SRS_UTIME_MILLISECONDS);
}
}

@ -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) {

@ -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<SrsProcess*>::iterator it;

@ -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);
}

@ -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:

@ -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);

@ -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);
};
/**

@ -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");

@ -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();

@ -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) {

@ -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) {

@ -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();
}
}

@ -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();

@ -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,7 +103,11 @@ 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();
// 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);
// 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;
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;
@ -193,6 +200,9 @@ srs_error_t SrsSTCoroutine::cycle()
return srs_error_wrap(err, "coroutine cycle");
}
// Set cycle done, no need to interrupt it.
cycle_done = true;
return err;
}

@ -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.

@ -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;
}

@ -124,7 +124,7 @@ public:
SrsRequest* req;
SrsRtmpConnType type;
int id;
int64_t create;
srs_utime_t create;
public:
SrsStatisticClient();
virtual ~SrsStatisticClient();

@ -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;

@ -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 <srs_auto_headers.hpp>
@ -86,7 +86,10 @@
#include <stddef.h>
#include <sys/types.h>
// important performance options.
// Time defines.
#include <srs_core_time.hpp>
// Some important performance options.
#include <srs_core_performance.hpp>
// free the p and set to NULL.

@ -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.

@ -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 <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 <srs_core.hpp>
// 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

@ -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

@ -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();

@ -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.

@ -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;

@ -29,6 +29,7 @@
#include <string>
#include <vector>
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.

@ -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.
}

@ -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)
{

@ -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)

@ -154,7 +154,7 @@ private:
private:
SrsHttpUri* in_hls;
std::vector<SrsTsPiece*> 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) {

@ -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."

@ -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;
/**

@ -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)

@ -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();
/**

@ -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;
}

@ -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);

@ -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

@ -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 <srs_app_st.hpp>
#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;

@ -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 <srs_utest.hpp>
*/
@ -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

@ -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 <srs_utest_app.hpp>
using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_app_fragment.hpp>
// Disable coroutine test for OSX.
#if !defined(SRS_OSX)
#include <srs_app_st.hpp>
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 = &sc;
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 = &sc;
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 = &sc;
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 = &sc;
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 = &sc;
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 = &sc;
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 = &sc;
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 = &sc;
_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());
}
}

@ -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 <srs_utest_app.hpp>
*/
#include <srs_utest.hpp>
#endif

@ -29,6 +29,8 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_app_source.hpp>
#include <srs_core_performance.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_service_st.hpp>
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);
}
}

@ -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;

@ -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());

@ -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 <srs_utest_service.hpp>
using namespace std;
#include <srs_kernel_error.hpp>
// Disable coroutine test for OSX.
#if !defined(SRS_OSX)
#include <srs_service_st.hpp>
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

@ -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 <srs_utest_service.hpp>
*/
#include <srs_utest.hpp>
#endif
Loading…
Cancel
Save