1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Merge branch 'feature/rtc' into develop

This commit is contained in:
winlin 2020-06-23 18:58:37 +08:00
commit 1c72a89fca
97 changed files with 654 additions and 9368 deletions

View file

@ -1468,9 +1468,6 @@ srs_error_t SrsConfig::reload_conf(SrsConfig* conf)
root = conf->root;
conf->root = NULL;
// merge config.
std::vector<ISrsReloadHandler*>::iterator it;
// never support reload:
// daemon
//
@ -2246,7 +2243,7 @@ srs_error_t SrsConfig::global_to_json(SrsJsonObject* obj)
sobjs->set(dir->arg0(), sobj);
SrsStatisticVhost* svhost = stat->find_vhost(dir->arg0());
sobj->set("id", SrsJsonAny::integer(svhost? (double)svhost->id : 0));
sobj->set("id", SrsJsonAny::str(svhost? svhost->id.c_str() : ""));
sobj->set("name", dir->dumps_arg0_to_str());
sobj->set("enabled", SrsJsonAny::boolean(get_vhost_enabled(dir->arg0())));
@ -2371,7 +2368,7 @@ srs_error_t SrsConfig::vhost_to_json(SrsConfDirective* vhost, SrsJsonObject* obj
SrsStatistic* stat = SrsStatistic::instance();
SrsStatisticVhost* svhost = stat->find_vhost(vhost->arg0());
obj->set("id", SrsJsonAny::integer(svhost? (double)svhost->id : 0));
obj->set("id", SrsJsonAny::str(svhost? svhost->id.c_str() : ""));
obj->set("name", vhost->dumps_arg0_to_str());
obj->set("enabled", SrsJsonAny::boolean(get_vhost_enabled(vhost)));
@ -3937,7 +3934,8 @@ srs_error_t SrsConfig::check_normal_config()
} else if (n == "rtc") {
for (int j = 0; j < (int)conf->directives.size(); j++) {
string m = conf->at(j)->name;
if (m != "enabled" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check") {
if (m != "enabled" && m != "bframe" && m != "aac" && m != "stun_timeout" && m != "stun_strict_check"
&& m != "keep_sequence") {
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.rtc.%s of %s", m.c_str(), vhost->arg0().c_str());
}
}
@ -5020,6 +5018,24 @@ bool SrsConfig::get_rtc_stun_strict_check(string vhost)
return SRS_CONF_PERFER_FALSE(conf->arg0());
}
bool SrsConfig::get_rtc_keep_sequence(string vhost)
{
static bool DEFAULT = false;
SrsConfDirective* conf = get_rtc(vhost);
if (!conf) {
return DEFAULT;
}
conf = conf->get("keep_sequence");
if (!conf || conf->arg0().empty()) {
return DEFAULT;
}
return SRS_CONF_PERFER_FALSE(conf->arg0());
}
bool SrsConfig::get_rtc_nack_enabled(string vhost)
{
static bool DEFAULT = true;

View file

@ -544,6 +544,7 @@ public:
bool get_rtc_aac_discard(std::string vhost);
srs_utime_t get_rtc_stun_timeout(std::string vhost);
bool get_rtc_stun_strict_check(std::string vhost);
bool get_rtc_keep_sequence(std::string vhost);
bool get_rtc_nack_enabled(std::string vhost);
bool get_rtc_twcc_enabled(std::string vhost);

View file

@ -200,7 +200,7 @@ srs_error_t SrsConnection::cycle()
return srs_success;
}
int SrsConnection::srs_id()
string SrsConnection::srs_id()
{
return trd->cid();
}

View file

@ -92,7 +92,7 @@ public:
virtual srs_error_t cycle();
public:
// Get the srs id which identify the client.
virtual int srs_id();
virtual std::string srs_id();
// Get the remote ip of peer.
virtual std::string remote_ip();
// Set connection to expired.

View file

@ -533,7 +533,7 @@ srs_error_t SrsDvrMp4Segmenter::close_encoder()
return err;
}
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(int c, SrsRequest* r, string p)
SrsDvrAsyncCallOnDvr::SrsDvrAsyncCallOnDvr(std::string c, SrsRequest* r, string p)
{
cid = c;
req = r->copy();
@ -673,7 +673,7 @@ srs_error_t SrsDvrPlan::on_reap_segment()
{
srs_error_t err = srs_success;
int cid = _srs_context->get_id();
std::string cid = _srs_context->get_id();
SrsFragment* fragment = segment->current();
string fullpath = fragment->fullpath();

View file

@ -159,11 +159,11 @@ protected:
class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
{
private:
int cid;
std::string cid;
std::string path;
SrsRequest* req;
public:
SrsDvrAsyncCallOnDvr(int c, SrsRequest* r, std::string p);
SrsDvrAsyncCallOnDvr(std::string c, SrsRequest* r, std::string p);
virtual ~SrsDvrAsyncCallOnDvr();
public:
virtual srs_error_t call();

View file

@ -82,7 +82,7 @@ void SrsHlsSegment::config_cipher(unsigned char* key,unsigned char* iv)
fw->config_cipher(key, iv);
}
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(int c, SrsRequest* r, string p, string t, string m, string mu, int s, srs_utime_t d)
SrsDvrAsyncCallOnHls::SrsDvrAsyncCallOnHls(string c, SrsRequest* r, string p, string t, string m, string mu, int s, srs_utime_t d)
{
req = r->copy();
cid = c;
@ -137,7 +137,7 @@ string SrsDvrAsyncCallOnHls::to_string()
return "on_hls: " + path;
}
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(int c, SrsRequest* r, string u)
SrsDvrAsyncCallOnHlsNotify::SrsDvrAsyncCallOnHlsNotify(string c, SrsRequest* r, string u)
{
cid = c;
req = r->copy();
@ -759,9 +759,6 @@ srs_error_t SrsHlsMuxer::_refresh_m3u8(string m3u8_file)
SrsHlsSegment* first = dynamic_cast<SrsHlsSegment*>(segments->first());
ss << "#EXT-X-MEDIA-SEQUENCE:" << first->sequence_no << SRS_CONSTS_LF;
// iterator shared for td generation and segemnts wrote.
std::vector<SrsHlsSegment*>::iterator it;
// #EXT-X-TARGETDURATION:4294967295\n
/**
* @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25

View file

@ -80,7 +80,7 @@ public:
class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask
{
private:
int cid;
std::string cid;
std::string path;
std::string ts_url;
std::string m3u8;
@ -90,7 +90,7 @@ private:
srs_utime_t duration;
public:
// TODO: FIXME: Use TBN 1000.
SrsDvrAsyncCallOnHls(int c, SrsRequest* r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
SrsDvrAsyncCallOnHls(std::string c, SrsRequest* r, std::string p, std::string t, std::string m, std::string mu, int s, srs_utime_t d);
virtual ~SrsDvrAsyncCallOnHls();
public:
virtual srs_error_t call();
@ -101,11 +101,11 @@ public:
class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask
{
private:
int cid;
std::string cid;
std::string ts_url;
SrsRequest* req;
public:
SrsDvrAsyncCallOnHlsNotify(int c, SrsRequest* r, std::string u);
SrsDvrAsyncCallOnHlsNotify(std::string c, SrsRequest* r, std::string u);
virtual ~SrsDvrAsyncCallOnHlsNotify();
public:
virtual srs_error_t call();

View file

@ -699,10 +699,10 @@ srs_error_t SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessag
// path: {pattern}{vhost_id}
// e.g. /api/v1/vhosts/100 pattern= /api/v1/vhosts/, vhost_id=100
int vid = r->parse_rest_id(entry->pattern);
std::string vid = r->parse_rest_id(entry->pattern);
SrsStatisticVhost* vhost = NULL;
if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) {
if (vid != "" && (vhost = stat->find_vhost(vid)) == NULL) {
return srs_api_response_code(w, r, ERROR_RTMP_VHOST_NOT_FOUND);
}
@ -755,10 +755,10 @@ srs_error_t SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
// path: {pattern}{stream_id}
// e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
int sid = r->parse_rest_id(entry->pattern);
std::string sid = r->parse_rest_id(entry->pattern);
SrsStatisticStream* stream = NULL;
if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
if (sid != "" && (stream = stat->find_stream(sid)) == NULL) {
return srs_api_response_code(w, r, ERROR_RTMP_STREAM_NOT_FOUND);
}
@ -811,10 +811,10 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
// path: {pattern}{client_id}
// e.g. /api/v1/clients/100 pattern= /api/v1/clients/, client_id=100
int cid = r->parse_rest_id(entry->pattern);
std::string cid = r->parse_rest_id(entry->pattern);
SrsStatisticClient* client = NULL;
if (cid >= 0 && (client = stat->find_client(cid)) == NULL) {
if (cid != "" && (client = stat->find_client(cid)) == NULL) {
return srs_api_response_code(w, r, ERROR_RTMP_CLIENT_NOT_FOUND);
}
@ -854,7 +854,7 @@ srs_error_t SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
}
client->conn->expire();
srs_warn("kickoff client id=%d ok", cid);
srs_warn("kickoff client id=%s ok", cid.c_str());
} else {
return srs_go_http_error(w, SRS_CONSTS_HTTP_MethodNotAllowed);
}

View file

@ -60,13 +60,15 @@ srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest* req)
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
// TODO: FIXME: check client_id must be int?
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_connect"));
obj->set("client_id", SrsJsonAny::integer(client_id));
// obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -79,12 +81,12 @@ srs_error_t SrsHttpHooks::on_connect(string url, SrsRequest* req)
SrsHttpClient http;
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
return srs_error_wrap(err, "http: on_connect failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
return srs_error_wrap(err, "http: on_connect failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
}
srs_trace("http: on_connect ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_connect ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return err;
}
@ -93,13 +95,13 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_close"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -114,13 +116,13 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
int ret = srs_error_code(err);
srs_freep(err);
srs_warn("http: ignore on_close failed, client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
srs_warn("http: ignore on_close failed, client_id=%s, url=%s, request=%s, response=%s, code=%d, ret=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return;
}
srs_trace("http: on_close ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_close ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return;
}
@ -129,13 +131,13 @@ srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest* req)
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_publish"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -149,12 +151,12 @@ srs_error_t SrsHttpHooks::on_publish(string url, SrsRequest* req)
SrsHttpClient http;
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
return srs_error_wrap(err, "http: on_publish failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
return srs_error_wrap(err, "http: on_publish failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
}
srs_trace("http: on_publish ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_publish ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return err;
}
@ -163,13 +165,13 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_unpublish"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -184,13 +186,13 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req)
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
int ret = srs_error_code(err);
srs_freep(err);
srs_warn("http: ignore on_unpublish failed, client_id=%d, url=%s, request=%s, response=%s, status=%d, ret=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
srs_warn("http: ignore on_unpublish failed, client_id=%s, url=%s, request=%s, response=%s, status=%d, ret=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return;
}
srs_trace("http: on_unpublish ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_unpublish ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return;
}
@ -199,13 +201,13 @@ srs_error_t SrsHttpHooks::on_play(string url, SrsRequest* req)
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_play"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -219,12 +221,12 @@ srs_error_t SrsHttpHooks::on_play(string url, SrsRequest* req)
SrsHttpClient http;
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
return srs_error_wrap(err, "http: on_play failed, client_id=%d, url=%s, request=%s, response=%s, status=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
return srs_error_wrap(err, "http: on_play failed, client_id=%s, url=%s, request=%s, response=%s, status=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
}
srs_trace("http: on_play ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_play ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return err;
}
@ -233,13 +235,13 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req)
{
srs_error_t err = srs_success;
int client_id = _srs_context->get_id();
std::string client_id = _srs_context->get_id();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_stop"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -254,29 +256,29 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req)
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
int ret = srs_error_code(err);
srs_freep(err);
srs_warn("http: ignore on_stop failed, client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret);
srs_warn("http: ignore on_stop failed, client_id=%s, url=%s, request=%s, response=%s, code=%d, ret=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code, ret);
return;
}
srs_trace("http: on_stop ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_stop ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return;
}
srs_error_t SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string file)
srs_error_t SrsHttpHooks::on_dvr(std::string cid, string url, SrsRequest* req, string file)
{
srs_error_t err = srs_success;
int client_id = cid;
std::string client_id = cid;
std::string cwd = _srs_config->cwd();
SrsJsonObject* obj = SrsJsonAny::object();
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_dvr"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -291,21 +293,21 @@ srs_error_t SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string fi
SrsHttpClient http;
if ((err = do_post(&http, url, data, status_code, res)) != srs_success) {
return srs_error_wrap(err, "http post on_dvr uri failed, client_id=%d, url=%s, request=%s, response=%s, code=%d",
client_id, url.c_str(), data.c_str(), res.c_str(), status_code);
return srs_error_wrap(err, "http post on_dvr uri failed, client_id=%s, url=%s, request=%s, response=%s, code=%d",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str(), status_code);
}
srs_trace("http hook on_dvr success. client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http hook on_dvr success. client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return err;
}
srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
srs_error_t SrsHttpHooks::on_hls(std::string cid, string url, SrsRequest* req, string file, string ts_url, string m3u8, string m3u8_url, int sn, srs_utime_t duration)
{
srs_error_t err = srs_success;
int client_id = cid;
std::string client_id = cid;
std::string cwd = _srs_config->cwd();
// the ts_url is under the same dir of m3u8_url.
@ -318,7 +320,7 @@ srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string fi
SrsAutoFree(SrsJsonObject, obj);
obj->set("action", SrsJsonAny::str("on_hls"));
obj->set("client_id", SrsJsonAny::integer(client_id));
obj->set("client_id", SrsJsonAny::str(client_id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("vhost", SrsJsonAny::str(req->vhost.c_str()));
obj->set("app", SrsJsonAny::str(req->app.c_str()));
@ -341,17 +343,17 @@ srs_error_t SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string fi
return srs_error_wrap(err, "http: post %s with %s, status=%d, res=%s", url.c_str(), data.c_str(), status_code, res.c_str());
}
srs_trace("http: on_hls ok, client_id=%d, url=%s, request=%s, response=%s",
client_id, url.c_str(), data.c_str(), res.c_str());
srs_trace("http: on_hls ok, client_id=%s, url=%s, request=%s, response=%s",
client_id.c_str(), url.c_str(), data.c_str(), res.c_str());
return err;
}
srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify)
srs_error_t SrsHttpHooks::on_hls_notify(std::string cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify)
{
srs_error_t err = srs_success;
int client_id = cid;
std::string client_id = cid;
std::string cwd = _srs_config->cwd();
if (srs_string_is_http(ts_url)) {
@ -406,8 +408,8 @@ srs_error_t SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* re
}
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());
srs_trace("http hook on_hls_notify success. client_id=%s, url=%s, code=%d, spent=%dms, read=%dB, err=%s",
client_id.c_str(), url.c_str(), msg->status_code(), spenttime, nb_read, srs_error_desc(err).c_str());
// ignore any error for on_hls_notify.
srs_error_reset(err);

View file

@ -74,7 +74,7 @@ public:
// ignore if empty.
// @param file the file path, can be relative or absolute path.
// @param cid the source connection cid, for the on_dvr is async call.
static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file);
static srs_error_t on_dvr(std::string cid, std::string url, SrsRequest* req, std::string file);
// When hls reap segment, callback.
// @param url the api server url, to process the event.
// ignore if empty.
@ -85,7 +85,7 @@ public:
// @param sn the seq_no, the sequence number of ts in hls/m3u8.
// @param duration the segment duration in srs_utime_t.
// @param cid the source connection cid, for the on_dvr is async call.
static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
static srs_error_t on_hls(std::string cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration);
// When hls reap segment, callback.
// @param url the api server url, to process the event.
@ -93,7 +93,7 @@ public:
// @param ts_url the ts uri, used to replace the variable [ts_url] in url.
// @param nb_notify the max bytes to read from notify server.
// @param cid the source connection cid, for the on_dvr is async call.
static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
static srs_error_t on_hls_notify(std::string cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
// Discover co-workers for origin cluster.
static srs_error_t discover_co_workers(std::string url, std::string& host, int& port);
private:

View file

@ -1141,8 +1141,8 @@ srs_error_t SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandle
// trigger edge to fetch from origin.
bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost);
srs_trace("flv: source url=%s, is_edge=%d, source_id=[%d][%d]",
r->get_stream_url().c_str(), vhost_is_edge, ::getpid(), s->source_id());
srs_trace("flv: source url=%s, is_edge=%d, source_id=[%d][%s]",
r->get_stream_url().c_str(), vhost_is_edge, ::getpid(), s->source_id().c_str());
return err;
}

View file

@ -171,7 +171,7 @@ srs_error_t SrsUdpListener::listen()
handler->set_stfd(lfd);
srs_freep(trd);
trd = new SrsSTCoroutine("udp", this);
trd = new SrsSTCoroutine("udp", this, _srs_context->get_id());
if ((err = trd->start()) != srs_success) {
return srs_error_wrap(err, "start thread");
}

View file

@ -94,7 +94,7 @@ void SrsFastLog::reopen()
open_log_file();
}
void SrsFastLog::verbose(const char* tag, int context_id, const char* fmt, ...)
void SrsFastLog::verbose(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelVerbose) {
return;
@ -114,7 +114,7 @@ void SrsFastLog::verbose(const char* tag, int context_id, const char* fmt, ...)
write_log(fd, log_data, size, SrsLogLevelVerbose);
}
void SrsFastLog::info(const char* tag, int context_id, const char* fmt, ...)
void SrsFastLog::info(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelInfo) {
return;
@ -134,7 +134,7 @@ void SrsFastLog::info(const char* tag, int context_id, const char* fmt, ...)
write_log(fd, log_data, size, SrsLogLevelInfo);
}
void SrsFastLog::trace(const char* tag, int context_id, const char* fmt, ...)
void SrsFastLog::trace(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelTrace) {
return;
@ -154,7 +154,7 @@ void SrsFastLog::trace(const char* tag, int context_id, const char* fmt, ...)
write_log(fd, log_data, size, SrsLogLevelTrace);
}
void SrsFastLog::warn(const char* tag, int context_id, const char* fmt, ...)
void SrsFastLog::warn(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelWarn) {
return;
@ -174,7 +174,7 @@ void SrsFastLog::warn(const char* tag, int context_id, const char* fmt, ...)
write_log(fd, log_data, size, SrsLogLevelWarn);
}
void SrsFastLog::error(const char* tag, int context_id, const char* fmt, ...)
void SrsFastLog::error(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelError) {
return;

View file

@ -55,11 +55,11 @@ public:
public:
virtual srs_error_t initialize();
virtual void reopen();
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
virtual void info(const char* tag, int context_id, const char* fmt, ...);
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
virtual void error(const char* tag, int context_id, const char* fmt, ...);
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
// Interface ISrsReloadHandler.
public:
virtual srs_error_t on_reload_utc_time();

View file

@ -180,7 +180,7 @@ srs_error_t SrsProcess::start()
srs_info("fork process: %s", cli.c_str());
// for log
int cid = _srs_context->get_id();
std::string cid = _srs_context->get_id();
int ppid = getpid();
// TODO: fork or vfork?
@ -221,8 +221,8 @@ srs_error_t SrsProcess::start()
// log basic info to stderr.
if (true) {
fprintf(stdout, "\n");
fprintf(stdout, "process ppid=%d, cid=%d, pid=%d, in=%d, out=%d, err=%d\n",
ppid, cid, getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
fprintf(stdout, "process ppid=%d, cid=%s, pid=%d, in=%d, out=%d, err=%d\n",
ppid, cid.c_str(), getpid(), STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO);
fprintf(stdout, "process binary=%s, cli: %s\n", bin.c_str(), cli.c_str());
fprintf(stdout, "process actual cli: %s\n", actual_cli.c_str());
}

View file

@ -57,7 +57,7 @@ ISrsMessagePumper::~ISrsMessagePumper()
{
}
SrsRecvThread::SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, int parent_cid)
SrsRecvThread::SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, std::string parent_cid)
{
rtmp = r;
pumper = p;
@ -71,7 +71,7 @@ SrsRecvThread::~SrsRecvThread()
srs_freep(trd);
}
int SrsRecvThread::cid()
std::string SrsRecvThread::cid()
{
return trd->cid();
}
@ -161,7 +161,7 @@ srs_error_t SrsRecvThread::do_cycle()
return err;
}
SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, int parent_cid)
SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, std::string parent_cid)
: trd(this, rtmp_sdk, tm, parent_cid)
{
_consumer = consumer;
@ -278,7 +278,7 @@ void SrsQueueRecvThread::on_stop()
}
SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req,
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid)
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, std::string parent_cid)
: trd(this, rtmp_sdk, tm, parent_cid)
{
rtmp = rtmp_sdk;
@ -290,7 +290,7 @@ SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest*
_nb_msgs = 0;
video_frames = 0;
error = srs_cond_new();
ncid = cid = 0;
ncid = cid = "";
req = _req;
mr_fd = mr_sock_fd;
@ -341,12 +341,12 @@ srs_error_t SrsPublishRecvThread::error_code()
return srs_error_copy(recv_error);
}
void SrsPublishRecvThread::set_cid(int v)
void SrsPublishRecvThread::set_cid(std::string v)
{
ncid = v;
}
int SrsPublishRecvThread::get_cid()
std::string SrsPublishRecvThread::get_cid()
{
return ncid;
}

View file

@ -27,6 +27,7 @@
#include <srs_core.hpp>
#include <vector>
#include <string>
#include <srs_app_thread.hpp>
#include <srs_protocol_stream.hpp>
@ -80,16 +81,16 @@ protected:
SrsCoroutine* trd;
ISrsMessagePumper* pumper;
SrsRtmpServer* rtmp;
int _parent_cid;
std::string _parent_cid;
// The recv timeout in srs_utime_t.
srs_utime_t timeout;
public:
// Constructor.
// @param tm The receive timeout in srs_utime_t.
SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, int parent_cid);
SrsRecvThread(ISrsMessagePumper* p, SrsRtmpServer* r, srs_utime_t tm, std::string parent_cid);
virtual ~SrsRecvThread();
public:
virtual int cid();
virtual std::string cid();
public:
virtual srs_error_t start();
virtual void stop();
@ -116,7 +117,7 @@ private:
SrsConsumer* _consumer;
public:
// TODO: FIXME: Refine timeout in time unit.
SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, int parent_cid);
SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, srs_utime_t tm, std::string parent_cid);
virtual ~SrsQueueRecvThread();
public:
virtual srs_error_t start();
@ -167,11 +168,11 @@ private:
// @see https://github.com/ossrs/srs/issues/244
srs_cond_t error;
// The merged context id.
int cid;
int ncid;
std::string cid;
std::string ncid;
public:
SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req,
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid);
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, std::string parent_cid);
virtual ~SrsPublishRecvThread();
public:
// Wait for error for some timeout.
@ -179,8 +180,8 @@ public:
virtual int64_t nb_msgs();
virtual uint64_t nb_video_frames();
virtual srs_error_t error_code();
virtual void set_cid(int v);
virtual int get_cid();
virtual void set_cid(std::string v);
virtual std::string get_cid();
public:
virtual srs_error_t start();
virtual void stop();

View file

@ -136,10 +136,16 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
string eip = r->query_get("eip");
// For client to specifies whether encrypt by SRTP.
string encrypt = r->query_get("encrypt");
// If keep_sequence is off, for client to specifies the startup sequence.
string sequence_startup = r->query_get("sequence_startup");
// If keep_sequence is on, for client to specifies the delta value for sequence.
string sequence_delta = r->query_get("sequence_delta");
// Whether keep sequence, overwrite the config for debugging each session.
string sequence_keep = r->query_get("sequence_keep");
srs_trace("RTC play %s, api=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, encrypt=%s",
streamurl.c_str(), api.c_str(), clientip.c_str(), app.c_str(), stream_name.c_str(), remote_sdp_str.length(),
eip.c_str(), encrypt.c_str());
srs_trace("RTC play %s, api=%s, clientip=%s, app=%s, stream=%s, offer=%dB, eip=%s, encrypt=%s, sequence(startup=%s,delta=%s,keep=%s)",
streamurl.c_str(), api.c_str(), clientip.c_str(), app.c_str(), stream_name.c_str(), remote_sdp_str.length(), eip.c_str(), encrypt.c_str(),
sequence_startup.c_str(), sequence_delta.c_str(), sequence_keep.c_str());
// TODO: FIXME: It seems remote_sdp doesn't represents the full SDP information.
SrsSdp remote_sdp;
@ -189,6 +195,11 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe
session->set_encrypt(encrypt != "false");
}
// Set the optional parameters from client.
session->sequence_startup = sequence_startup;
session->sequence_delta = sequence_delta;
session->sequence_keep = sequence_keep;
ostringstream os;
if ((err = local_sdp.encode(os)) != srs_success) {
return srs_error_wrap(err, "encode sdp");

View file

@ -487,18 +487,16 @@ SrsRtcOutgoingInfo::~SrsRtcOutgoingInfo()
{
}
SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid)
SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, string parent_cid)
{
_parent_cid = parent_cid;
trd = new SrsDummyCoroutine();
session_ = s;
audio_timestamp = 0;
audio_sequence = 0;
video_sequence = 0;
sequence_delta = 0;
mw_msgs = 0;
realtime = true;
@ -508,6 +506,7 @@ SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid)
nn_simulate_nack_drop = 0;
nack_enabled_ = false;
keep_sequence_ = false;
_srs_config->subscribe(this);
}
@ -533,8 +532,18 @@ srs_error_t SrsRtcPlayer::initialize(const uint32_t& vssrc, const uint32_t& assr
// TODO: FIXME: Support reload.
nack_enabled_ = _srs_config->get_rtc_nack_enabled(session_->req->vhost);
srs_trace("RTC publisher video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), nack=%d",
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, nack_enabled_);
keep_sequence_ = _srs_config->get_rtc_keep_sequence(session_->req->vhost);
if (!session_->sequence_startup.empty()) {
audio_sequence = video_sequence = uint16_t(::atoi(session_->sequence_startup.c_str()));
}
if (!session_->sequence_delta.empty()) {
sequence_delta = uint16_t(::atoi(session_->sequence_delta.c_str()));
}
if (!session_->sequence_keep.empty()) {
keep_sequence_ = (session_->sequence_keep == "true");
}
srs_trace("RTC player video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), nack=%d, keep-seq=%d, sequence(audio=%u,video=%u,delta=%u)",
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, nack_enabled_, keep_sequence_, audio_sequence, video_sequence, sequence_delta);
if (_srs_rtc_hijacker) {
if ((err = _srs_rtc_hijacker->on_start_play(session_, this, session_->req)) != srs_success) {
@ -566,7 +575,7 @@ srs_error_t SrsRtcPlayer::on_reload_vhost_realtime(string vhost)
return on_reload_vhost_play(vhost);
}
int SrsRtcPlayer::cid()
std::string SrsRtcPlayer::cid()
{
return trd->cid();
}
@ -620,8 +629,8 @@ srs_error_t SrsRtcPlayer::cycle()
realtime = _srs_config->get_realtime_enabled(req->vhost, true);
mw_msgs = _srs_config->get_mw_msgs(req->vhost, realtime, true);
srs_trace("RTC source url=%s, source_id=[%d][%d], encrypt=%d, realtime=%d, mw_msgs=%d", req->get_stream_url().c_str(),
::getpid(), source->source_id(), session_->encrypt, realtime, mw_msgs);
srs_trace("RTC source url=%s, source_id=[%d][%s], encrypt=%d, realtime=%d, mw_msgs=%d", req->get_stream_url().c_str(),
::getpid(), source->source_id().c_str(), session_->encrypt, realtime, mw_msgs);
SrsPithyPrint* pprint = SrsPithyPrint::create_rtc_play();
SrsAutoFree(SrsPithyPrint, pprint);
@ -707,29 +716,36 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcSource* source, const vector<SrsRtp
// Update stats.
info.nn_bytes += pkt->nb_bytes();
// For audio, we transcoded AAC to opus in extra payloads.
uint16_t oseq = pkt->header.get_sequence();
if (pkt->is_audio()) {
info.nn_audios++;
pkt->header.set_timestamp(audio_timestamp);
pkt->header.set_sequence(audio_sequence++);
if (!keep_sequence_) {
// TODO: FIXME: Should keep the order by original sequence.
pkt->header.set_sequence(sequence_delta + audio_sequence++);
} else {
pkt->header.set_sequence(sequence_delta + oseq);
}
pkt->header.set_ssrc(audio_ssrc);
pkt->header.set_payload_type(audio_payload_type);
// TODO: FIXME: Padding audio to the max payload in RTP packets.
} else {
info.nn_videos++;
// TODO: FIXME: Why 960? Need Refactoring?
audio_timestamp += 960;
continue;
if (!keep_sequence_) {
// TODO: FIXME: Should keep the order by original sequence.
pkt->header.set_sequence(sequence_delta + video_sequence++);
} else {
pkt->header.set_sequence(sequence_delta + oseq);
}
pkt->header.set_ssrc(video_ssrc);
pkt->header.set_payload_type(video_payload_type);
}
// For video, we should process all NALUs in samples.
info.nn_videos++;
// For video, we should set the RTP packet informations about this consumer.
pkt->header.set_sequence(video_sequence++);
pkt->header.set_ssrc(video_ssrc);
pkt->header.set_payload_type(video_payload_type);
// Detail log, should disable it in release version.
srs_info("RTC: Update PT=%u, SSRC=%#x, OSEQ=%u, SEQ=%u, Time=%u, %u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(),
oseq, pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes());
}
// By default, we send packets by sendmmsg.
@ -815,6 +831,10 @@ srs_error_t SrsRtcPlayer::do_send_packets(const std::vector<SrsRtpPacket2*>& pkt
// TODO: FIXME: Handle error.
session_->sendonly_skt->sendto(iov->iov_base, iov->iov_len, 0);
// Detail log, should disable it in release version.
srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes(), iov->iov_len);
}
return err;
@ -978,6 +998,12 @@ srs_error_t SrsRtcPlayer::on_rtcp_feedback(char* buf, int nb_buf)
vector<SrsRtpPacket2*> resend_pkts;
nack_fetch(resend_pkts, ssrc_of_media_source, pid);
// If NACK disabled, print a log.
if (!nack_enabled_) {
srs_trace("RTC NACK seq=%u, ignored", pid);
return err;
}
uint16_t mask = 0x01;
for (int i = 1; i < 16 && blp; ++i, mask <<= 1) {
if (!(blp & mask)) {
@ -1031,7 +1057,7 @@ srs_error_t SrsRtcPlayer::on_rtcp_ps_feedback(char* buf, int nb_buf)
switch (fmt) {
case kPLI: {
SrsRtcPublisher* publisher = session_->source_->rtc_publisher();
ISrsRtcPublisher* publisher = session_->source_->rtc_publisher();
if (publisher) {
publisher->request_keyframe();
srs_trace("RTC request PLI");
@ -1088,10 +1114,9 @@ SrsRtcPublisher::SrsRtcPublisher(SrsRtcSession* session)
SrsRtcPublisher::~SrsRtcPublisher()
{
source->set_rtc_publisher(NULL);
// TODO: FIXME: Do unpublish when session timeout.
if (source) {
source->set_rtc_publisher(NULL);
source->on_unpublish();
}
@ -1420,11 +1445,12 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
if (true) {
pkt->set_decode_handler(this);
pkt->set_rtp_header_extensions(&extension_map_);
pkt->shared_msg = new SrsSharedPtrMessage();
pkt->shared_msg->wrap(buf, nb_buf);
SrsBuffer b(buf, nb_buf);
if ((err = pkt->decode(&b, &extension_map_)) != srs_success) {
if ((err = pkt->decode(&b)) != srs_success) {
return srs_error_wrap(err, "decode rtp packet");
}
@ -1434,6 +1460,9 @@ srs_error_t SrsRtcPublisher::on_rtp(char* data, int nb_data)
if((err = on_twcc(twcc_sn))) {
return srs_error_wrap(err, "fail to process twcc packet");
}
} else {
// TODO: FIXME: process no twcc seq number for audio ssrc
srs_error_reset(err);
}
}
}
@ -1910,9 +1939,9 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
void SrsRtcPublisher::request_keyframe()
{
int scid = _srs_context->get_id();
int pcid = session_->context_id();
srs_trace("RTC play=[%d][%d] request keyframe from publish=[%d][%d]", ::getpid(), scid, ::getpid(), pcid);
std::string scid = _srs_context->get_id();
std::string pcid = session_->context_id();
srs_trace("RTC play=[%d][%s] request keyframe from publish=[%d][%s]", ::getpid(), scid.c_str(), ::getpid(), pcid.c_str());
request_keyframe_ = true;
}
@ -1946,7 +1975,7 @@ void SrsRtcPublisher::simulate_drop_packet(SrsRtpHeader* h, int nn_bytes)
SrsRtcSession::SrsRtcSession(SrsRtcServer* s)
{
req = NULL;
cid = 0;
cid = "";
is_publisher_ = false;
encrypt = true;
@ -2039,12 +2068,12 @@ void SrsRtcSession::switch_to_context()
_srs_context->set_id(cid);
}
int SrsRtcSession::context_id()
std::string SrsRtcSession::context_id()
{
return cid;
}
srs_error_t SrsRtcSession::initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, string username, int context_id)
srs_error_t SrsRtcSession::initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, string username, std::string context_id)
{
srs_error_t err = srs_success;

View file

@ -36,6 +36,7 @@
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_kernel_rtc_rtcp.hpp>
#include <srs_app_rtc_queue.hpp>
#include <srs_app_rtc_source.hpp>
#include <string>
#include <map>
@ -188,13 +189,12 @@ public:
class SrsRtcPlayer : virtual public ISrsCoroutineHandler, virtual public ISrsReloadHandler
{
protected:
int _parent_cid;
std::string _parent_cid;
SrsCoroutine* trd;
SrsRtcSession* session_;
private:
// TODO: FIXME: How to handle timestamp overflow?
// Information for audio.
uint32_t audio_timestamp;
uint16_t audio_sequence;
uint32_t audio_ssrc;
uint16_t audio_payload_type;
@ -206,6 +206,7 @@ private:
SrsRtpRingBuffer* audio_queue_;
SrsRtpRingBuffer* video_queue_;
// Simulators.
uint16_t sequence_delta;
int nn_simulate_nack_drop;
private:
// For merged-write messages.
@ -213,8 +214,10 @@ private:
bool realtime;
// Whether enabled nack.
bool nack_enabled_;
// Whether keep original sequence number.
bool keep_sequence_;
public:
SrsRtcPlayer(SrsRtcSession* s, int parent_cid);
SrsRtcPlayer(SrsRtcSession* s, std::string parent_cid);
virtual ~SrsRtcPlayer();
public:
srs_error_t initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt);
@ -223,7 +226,7 @@ public:
virtual srs_error_t on_reload_vhost_play(std::string vhost);
virtual srs_error_t on_reload_vhost_realtime(std::string vhost);
public:
virtual int cid();
virtual std::string cid();
public:
virtual srs_error_t start();
virtual void stop();
@ -248,7 +251,7 @@ private:
srs_error_t on_rtcp_rr(char* data, int nb_data);
};
class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler
class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler, virtual public ISrsRtcPublisher
{
private:
SrsHourGlass* report_timer;
@ -341,7 +344,7 @@ private:
srs_utime_t last_stun_time;
private:
// For each RTC session, we use a specified cid for debugging logs.
int cid;
std::string cid;
// For each RTC session, whether requires encrypt.
// Read config value, rtc_server.encrypt, default to on.
// Sepcifies by HTTP API, query encrypt, optional.
@ -351,6 +354,11 @@ private:
SrsRtcSource* source_;
SrsSdp remote_sdp;
SrsSdp local_sdp;
public:
// User debugging parameters, overwrite config.
std::string sequence_startup;
std::string sequence_delta;
std::string sequence_keep;
private:
bool blackhole;
sockaddr_in* blackhole_addr;
@ -371,9 +379,9 @@ public:
std::string username();
void set_encrypt(bool v);
void switch_to_context();
int context_id();
std::string context_id();
public:
srs_error_t initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, std::string username, int context_id);
srs_error_t initialize(SrsRtcSource* source, SrsRequest* r, bool is_publisher, std::string username, std::string context_id);
// The peer address may change, we can identify that by STUN messages.
srs_error_t on_stun(SrsUdpMuxSocket* skt, SrsStunPacket* r);
srs_error_t on_dtls(char* data, int nb_data);

View file

@ -320,7 +320,7 @@ srs_error_t SrsRtcServer::create_session(
}
}
int cid = _srs_context->get_id();
std::string cid = _srs_context->get_id();
SrsRtcSession* session = new SrsRtcSession(this);
if ((err = session->initialize(source, req, publish, username, cid)) != srs_success) {
srs_freep(session);
@ -396,7 +396,7 @@ srs_error_t SrsRtcServer::setup_session2(SrsRtcSession* session, SrsRequest* req
// TODO: FIXME: Collision detect.
string username = session->get_local_sdp()->get_ice_ufrag() + ":" + remote_sdp.get_ice_ufrag();
int cid = _srs_context->get_id();
std::string cid = _srs_context->get_id();
if ((err = session->initialize(source, req, false, username, cid)) != srs_success) {
return srs_error_wrap(err, "init");
}

View file

@ -137,7 +137,7 @@ srs_error_t SrsRtcConsumer::dump_packets(std::vector<SrsRtpPacket2*>& pkts)
srs_error_t err = srs_success;
if (should_update_source_id) {
srs_trace("update source_id=%d[%d]", source->source_id(), source->source_id());
srs_trace("update source_id=%d[%d]", source->source_id().c_str(), source->source_id().c_str());
should_update_source_id = false;
}
@ -232,9 +232,17 @@ SrsRtcSource* SrsRtcSourceManager::fetch(SrsRequest* r)
SrsRtcSourceManager* _srs_rtc_sources = new SrsRtcSourceManager();
ISrsRtcPublisher::ISrsRtcPublisher()
{
}
ISrsRtcPublisher::~ISrsRtcPublisher()
{
}
SrsRtcSource::SrsRtcSource()
{
_source_id = _pre_source_id = -1;
_source_id = _pre_source_id = "";
_can_publish = true;
rtc_publisher_ = NULL;
@ -270,7 +278,7 @@ void SrsRtcSource::update_auth(SrsRequest* r)
req->update_auth(r);
}
srs_error_t SrsRtcSource::on_source_id_changed(int id)
srs_error_t SrsRtcSource::on_source_id_changed(std::string id)
{
srs_error_t err = srs_success;
@ -278,7 +286,7 @@ srs_error_t SrsRtcSource::on_source_id_changed(int id)
return err;
}
if (_pre_source_id == -1) {
if (_pre_source_id == "") {
_pre_source_id = id;
} else if (_pre_source_id != _source_id) {
_pre_source_id = _source_id;
@ -296,12 +304,12 @@ srs_error_t SrsRtcSource::on_source_id_changed(int id)
return err;
}
int SrsRtcSource::source_id()
std::string SrsRtcSource::source_id()
{
return _source_id;
}
int SrsRtcSource::pre_source_id()
std::string SrsRtcSource::pre_source_id()
{
return _pre_source_id;
}
@ -382,12 +390,12 @@ void SrsRtcSource::on_unpublish()
// TODO: FIXME: Handle by statistic.
}
SrsRtcPublisher* SrsRtcSource::rtc_publisher()
ISrsRtcPublisher* SrsRtcSource::rtc_publisher()
{
return rtc_publisher_;
}
void SrsRtcSource::set_rtc_publisher(SrsRtcPublisher* v)
void SrsRtcSource::set_rtc_publisher(ISrsRtcPublisher* v)
{
rtc_publisher_ = v;
}
@ -416,6 +424,9 @@ SrsRtcFromRtmpBridger::SrsRtcFromRtmpBridger(SrsRtcSource* source)
discard_bframe = false;
merge_nalus = false;
meta = new SrsMetaCache();
audio_timestamp = 0;
audio_sequence = 0;
video_sequence = 0;
}
SrsRtcFromRtmpBridger::~SrsRtcFromRtmpBridger()
@ -584,6 +595,11 @@ srs_error_t SrsRtcFromRtmpBridger::package_opus(char* data, int size, SrsRtpPack
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeAudio;
pkt->header.set_marker(true);
pkt->header.set_sequence(audio_sequence++);
pkt->header.set_timestamp(audio_timestamp);
// TODO: FIXME: Why 960? Need Refactoring?
audio_timestamp += 960;
SrsRtpRawPayload* raw = new SrsRtpRawPayload();
pkt->payload = raw;
@ -641,25 +657,25 @@ srs_error_t SrsRtcFromRtmpBridger::on_video(SrsSharedPtrMessage* msg)
if ((err = package_nalus(msg, samples, pkts)) != srs_success) {
return srs_error_wrap(err, "package nalus as one");
}
}
} else {
// By default, we package each NALU(sample) to a RTP or FUA packet.
for (int i = 0; i < nn_samples; i++) {
SrsSample* sample = samples[i];
// By default, we package each NALU(sample) to a RTP or FUA packet.
for (int i = 0; i < nn_samples; i++) {
SrsSample* sample = samples[i];
// We always ignore bframe here, if config to discard bframe,
// the bframe flag will not be set.
if (sample->bframe) {
continue;
}
if (sample->size <= kRtpMaxPayloadSize) {
if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) {
return srs_error_wrap(err, "package single nalu");
// We always ignore bframe here, if config to discard bframe,
// the bframe flag will not be set.
if (sample->bframe) {
continue;
}
} else {
if ((err = package_fu_a(msg, sample, kRtpMaxPayloadSize, pkts)) != srs_success) {
return srs_error_wrap(err, "package fu-a");
if (sample->size <= kRtpMaxPayloadSize) {
if ((err = package_single_nalu(msg, sample, pkts)) != srs_success) {
return srs_error_wrap(err, "package single nalu");
}
} else {
if ((err = package_fu_a(msg, sample, kRtpMaxPayloadSize, pkts)) != srs_success) {
return srs_error_wrap(err, "package fu-a");
}
}
}
}
@ -720,6 +736,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcSource* source, SrsShare
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_marker(false);
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
SrsRtpSTAPPayload* stap = new SrsRtpSTAPPayload();
@ -755,7 +772,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcSource* source, SrsShare
}
*ppkt = pkt;
srs_trace("RTC STAP-A seq=%u, sps %d, pps %d bytes", pkt->header.get_sequence(), sps.size(), pps.size());
srs_info("RTC STAP-A seq=%u, sps %d, pps %d bytes", pkt->header.get_sequence(), sps.size(), pps.size());
return err;
}
@ -789,6 +806,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
// Package NALUs in a single RTP packet.
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
pkt->payload = raw;
pkt->shared_msg = msg->copy();
@ -818,6 +836,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
fua->nri = (SrsAvcNaluType)header;
@ -843,6 +862,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_single_nalu(SrsSharedPtrMessage* msg,
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
SrsRtpRawPayload* raw = new SrsRtpRawPayload();
@ -872,6 +892,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_fu_a(SrsSharedPtrMessage* msg, SrsSam
SrsRtpPacket2* pkt = new SrsRtpPacket2();
pkt->frame_type = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
SrsRtpFUAPayload2* fua = new SrsRtpFUAPayload2();

View file

@ -35,7 +35,6 @@
class SrsRequest;
class SrsConnection;
class SrsMetaCache;
class SrsRtcPublisher;
class SrsSharedPtrMessage;
class SrsCommonMessage;
class SrsMessageArray;
@ -94,6 +93,15 @@ private:
// Global singleton instance.
extern SrsRtcSourceManager* _srs_rtc_sources;
class ISrsRtcPublisher
{
public:
ISrsRtcPublisher();
virtual ~ISrsRtcPublisher();
public:
virtual void request_keyframe() = 0;
};
class SrsRtcSource
{
private:
@ -101,11 +109,11 @@ private:
// For edge, it's the edge ingest id.
// when source id changed, for example, the edge reconnect,
// invoke the on_source_id_changed() to let all clients know.
int _source_id;
std::string _source_id;
// previous source id.
int _pre_source_id;
std::string _pre_source_id;
SrsRequest* req;
SrsRtcPublisher* rtc_publisher_;
ISrsRtcPublisher* rtc_publisher_;
// Transmux RTMP to RTC.
SrsRtcFromRtmpBridger* bridger_;
private:
@ -121,10 +129,10 @@ public:
// Update the authentication information in request.
virtual void update_auth(SrsRequest* r);
// The source id changed.
virtual srs_error_t on_source_id_changed(int id);
virtual srs_error_t on_source_id_changed(std::string id);
// Get current source id.
virtual int source_id();
virtual int pre_source_id();
virtual std::string source_id();
virtual std::string pre_source_id();
// Get the bridger.
ISrsSourceBridger* bridger();
public:
@ -145,8 +153,8 @@ public:
virtual void on_unpublish();
public:
// Get and set the publisher, passed to consumer to process requests such as PLI.
SrsRtcPublisher* rtc_publisher();
void set_rtc_publisher(SrsRtcPublisher* v);
ISrsRtcPublisher* rtc_publisher();
void set_rtc_publisher(ISrsRtcPublisher* v);
// Consume the shared RTP packet, user must free it.
srs_error_t on_rtp(SrsRtpPacket2* pkt);
};
@ -165,6 +173,9 @@ private:
SrsAudioRecode* codec;
bool discard_bframe;
bool merge_nalus;
uint32_t audio_timestamp;
uint16_t audio_sequence;
uint16_t video_sequence;
public:
SrsRtcFromRtmpBridger(SrsRtcSource* source);
virtual ~SrsRtcFromRtmpBridger();

View file

@ -515,8 +515,8 @@ srs_error_t SrsRtmpConn::stream_service_cycle()
}
bool enabled_cache = _srs_config->get_gop_cache(req->vhost);
srs_trace("source url=%s, ip=%s, cache=%d, is_edge=%d, source_id=[%d][%d]",
req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, ::getpid(), source->source_id());
srs_trace("source url=%s, ip=%s, cache=%d, is_edge=%d, source_id=[%d][%s]",
req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, ::getpid(), source->source_id().c_str());
source->set_cache(enabled_cache);
switch (info->type) {

View file

@ -120,9 +120,11 @@ srs_error_t SrsRtpConn::on_udp_packet(const sockaddr* from, const int fromlen, c
// always free it.
SrsAutoFree(SrsRtpPacket, cache);
if ((err = rtsp->on_rtp_packet(cache, stream_id)) != srs_success) {
return srs_error_wrap(err, "process rtp packet");
err = rtsp->on_rtp_packet(cache, stream_id);
if (err != srs_success) {
srs_warn("ignore RTP packet err %s", srs_error_desc(err).c_str());
srs_freep(err);
}
return err;
@ -495,54 +497,62 @@ srs_error_t SrsRtspConn::write_sequence_header()
}
// generate audio sh by audio specific config.
if (true) {
std::string sh = aac_specific_config;
SrsFormat* format = new SrsFormat();
SrsAutoFree(SrsFormat, format);
if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) {
return srs_error_wrap(err, "on aac sequence header");
}
SrsAudioCodecConfig* dec = format->acodec;
acodec->sound_format = SrsAudioCodecIdAAC;
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
acodec->sound_size = SrsAudioSampleBits16bit;
acodec->aac_packet_type = 0;
static int srs_aac_srates[] = {
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};
switch (srs_aac_srates[dec->aac_sample_rate]) {
case 11025:
acodec->sound_rate = SrsAudioSampleRate11025;
break;
case 22050:
acodec->sound_rate = SrsAudioSampleRate22050;
break;
case 44100:
acodec->sound_rate = SrsAudioSampleRate44100;
break;
default:
break;
};
if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) {
return srs_error_wrap(err, "write audio raw frame");
}
if (aac_specific_config.empty()) {
srs_warn("no audio asc");
return err;
}
std::string sh = aac_specific_config;
SrsFormat* format = new SrsFormat();
SrsAutoFree(SrsFormat, format);
if ((err = format->on_aac_sequence_header((char*)sh.c_str(), (int)sh.length())) != srs_success) {
return srs_error_wrap(err, "on aac sequence header");
}
SrsAudioCodecConfig* dec = format->acodec;
acodec->sound_format = SrsAudioCodecIdAAC;
acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono;
acodec->sound_size = SrsAudioSampleBits16bit;
acodec->aac_packet_type = 0;
static int srs_aac_srates[] = {
96000, 88200, 64000, 48000,
44100, 32000, 24000, 22050,
16000, 12000, 11025, 8000,
7350, 0, 0, 0
};
switch (srs_aac_srates[dec->aac_sample_rate]) {
case 11025:
acodec->sound_rate = SrsAudioSampleRate11025;
break;
case 22050:
acodec->sound_rate = SrsAudioSampleRate22050;
break;
case 44100:
acodec->sound_rate = SrsAudioSampleRate44100;
break;
default:
break;
};
if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != srs_success) {
return srs_error_wrap(err, "write audio raw frame");
}
return err;
}
srs_error_t SrsRtspConn::write_h264_sps_pps(uint32_t dts, uint32_t pts)
{
srs_error_t err = srs_success;
if (h264_sps.empty() || h264_pps.empty()) {
srs_warn("no sps=%dB or pps=%dB", (int)h264_sps.size(), (int)h264_pps.size());
return err;
}
// h264 raw to h264 packet.
std::string sh;
@ -687,6 +697,7 @@ void SrsRtspConn::close()
SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c)
{
// TODO: FIXME: support reload.
engine = _srs_config->get_stream_caster_engine(c);
output = _srs_config->get_stream_caster_output(c);
local_port_min = _srs_config->get_stream_caster_rtp_port_min(c);
local_port_max = _srs_config->get_stream_caster_rtp_port_max(c);
@ -728,7 +739,7 @@ srs_error_t SrsRtspCaster::alloc_port(int* pport)
break;
}
}
srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1);
srs_trace("rtsp: %s alloc port=%d-%d", engine.c_str(), *pport, *pport + 1);
return err;
}
@ -738,7 +749,7 @@ void SrsRtspCaster::free_port(int lpmin, int lpmax)
for (int i = lpmin; i < lpmax; i++) {
used_ports[i] = false;
}
srs_trace("rtsp: free rtp port=%d-%d", lpmin, lpmax);
srs_trace("rtsp: %s free rtp port=%d-%d", engine.c_str(), lpmin, lpmax);
}
srs_error_t SrsRtspCaster::on_tcp_client(srs_netfd_t stfd)

View file

@ -173,6 +173,7 @@ private:
class SrsRtspCaster : public ISrsTcpHandler
{
private:
std::string engine;
std::string output;
int local_port_min;
int local_port_max;

View file

@ -825,8 +825,8 @@ srs_error_t SrsServer::initialize_st()
return srs_error_new(ERROR_SYSTEM_ASSERT_FAILED, "ppid=%d illegal for asprocess", ppid);
}
srs_trace("server main cid=%d, pid=%d, ppid=%d, asprocess=%d",
_srs_context->get_id(), ::getpid(), ppid, asprocess);
srs_trace("server main cid=%s, pid=%d, ppid=%d, asprocess=%d",
_srs_context->get_id().c_str(), ::getpid(), ppid, asprocess);
return err;
}

View file

@ -520,7 +520,7 @@ srs_error_t SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count)
count = 0;
if (should_update_source_id) {
srs_trace("update source_id=%d[%d]", source->source_id(), source->source_id());
srs_trace("update source_id=%s[%s]", source->source_id().c_str(), source->source_id().c_str());
should_update_source_id = false;
}
@ -1792,7 +1792,7 @@ void SrsSourceManager::dispose()
srs_error_t SrsSourceManager::cycle()
{
int cid = _srs_context->get_id();
std::string cid = _srs_context->get_id();
srs_error_t err = do_cycle();
_srs_context->set_id(cid);
@ -1809,7 +1809,7 @@ srs_error_t SrsSourceManager::do_cycle()
// Do cycle source to cleanup components, such as hls dispose.
if ((err = source->cycle()) != srs_success) {
return srs_error_wrap(err, "source=%d/%d cycle", source->source_id(), source->pre_source_id());
return srs_error_wrap(err, "source=%s/%s cycle", source->source_id().c_str(), source->pre_source_id().c_str());
}
// TODO: FIXME: support source cleanup.
@ -1866,7 +1866,7 @@ SrsSource::SrsSource()
mix_queue = new SrsMixQueue();
_can_publish = true;
_pre_source_id = _source_id = -1;
_pre_source_id = _source_id = "";
die_at = 0;
handler = NULL;
@ -2065,7 +2065,7 @@ srs_error_t SrsSource::on_reload_vhost_play(string vhost)
return err;
}
srs_error_t SrsSource::on_source_id_changed(int id)
srs_error_t SrsSource::on_source_id_changed(string id)
{
srs_error_t err = srs_success;
@ -2073,7 +2073,7 @@ srs_error_t SrsSource::on_source_id_changed(int id)
return err;
}
if (_pre_source_id == -1) {
if (_pre_source_id == "") {
_pre_source_id = id;
} else if (_pre_source_id != _source_id) {
_pre_source_id = _source_id;
@ -2091,12 +2091,12 @@ srs_error_t SrsSource::on_source_id_changed(int id)
return err;
}
int SrsSource::source_id()
string SrsSource::source_id()
{
return _source_id;
}
int SrsSource::pre_source_id()
string SrsSource::pre_source_id()
{
return _pre_source_id;
}

View file

@ -508,9 +508,9 @@ private:
// For edge, it's the edge ingest id.
// when source id changed, for example, the edge reconnect,
// invoke the on_source_id_changed() to let all clients know.
int _source_id;
std::string _source_id;
// previous source id.
int _pre_source_id;
std::string _pre_source_id;
// deep copy of client request.
SrsRequest* req;
// To delivery stream to clients.
@ -567,10 +567,10 @@ public:
virtual srs_error_t on_reload_vhost_play(std::string vhost);
public:
// The source id changed.
virtual srs_error_t on_source_id_changed(int id);
virtual srs_error_t on_source_id_changed(std::string id);
// Get current source id.
virtual int source_id();
virtual int pre_source_id();
virtual std::string source_id();
virtual std::string pre_source_id();
// Whether source is inactive, which means there is no publishing stream source.
// @remark For edge, it's inactive util stream has been pulled from origin.
virtual bool inactive();

View file

@ -74,14 +74,14 @@ srs_error_t SrsDummyCoroutine::pull()
return srs_error_new(ERROR_THREAD_DUMMY, "dummy pull");
}
int SrsDummyCoroutine::cid()
string SrsDummyCoroutine::cid()
{
return 0;
return "";
}
_ST_THREAD_CREATE_PFN _pfn_st_thread_create = (_ST_THREAD_CREATE_PFN)st_thread_create;
SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h, int cid)
SrsSTCoroutine::SrsSTCoroutine(string n, ISrsCoroutineHandler* h, std::string cid)
{
name = n;
handler = h;
@ -180,7 +180,7 @@ srs_error_t SrsSTCoroutine::pull()
return srs_error_copy(trd_err);
}
int SrsSTCoroutine::cid()
string SrsSTCoroutine::cid()
{
return context;
}
@ -188,7 +188,7 @@ int SrsSTCoroutine::cid()
srs_error_t SrsSTCoroutine::cycle()
{
if (_srs_context) {
if (context) {
if (!context.empty()) {
_srs_context->set_id(context);
} else {
context = _srs_context->generate_id();

View file

@ -80,7 +80,7 @@ public:
// @return a copy of error, which should be freed by user.
// NULL if not terminated and user should pull again.
virtual srs_error_t pull() = 0;
virtual int cid() = 0;
virtual std::string cid() = 0;
};
// An empty coroutine, user can default to this object before create any real coroutine.
@ -95,7 +95,7 @@ public:
virtual void stop();
virtual void interrupt();
virtual srs_error_t pull();
virtual int cid();
virtual std::string cid();
};
// For utest to mock the thread create.
@ -121,7 +121,7 @@ private:
ISrsCoroutineHandler* handler;
private:
srs_thread_t trd;
int context;
std::string context;
srs_error_t trd_err;
private:
bool started;
@ -132,7 +132,7 @@ private:
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.
SrsSTCoroutine(std::string n, ISrsCoroutineHandler* h, int cid = 0);
SrsSTCoroutine(std::string n, ISrsCoroutineHandler* h, std::string cid = "");
virtual ~SrsSTCoroutine();
public:
// Start the thread.
@ -154,7 +154,7 @@ public:
// @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
virtual srs_error_t pull();
// Get the context id of thread.
virtual int cid();
virtual std::string cid();
private:
virtual srs_error_t cycle();
static void* pfn(void* arg);

View file

@ -71,7 +71,7 @@ srs_error_t SrsStatisticVhost::dumps(SrsJsonObject* obj)
bool hls_enabled = _srs_config->get_hls_enabled(vhost);
bool enabled = _srs_config->get_vhost_enabled(vhost);
obj->set("id", SrsJsonAny::integer(id));
obj->set("id", SrsJsonAny::str(id.c_str()));
obj->set("name", SrsJsonAny::str(vhost.c_str()));
obj->set("enabled", SrsJsonAny::boolean(enabled));
obj->set("clients", SrsJsonAny::integer(nb_clients));
@ -134,9 +134,9 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
{
srs_error_t err = srs_success;
obj->set("id", SrsJsonAny::integer(id));
obj->set("id", SrsJsonAny::str(id.c_str()));
obj->set("name", SrsJsonAny::str(stream.c_str()));
obj->set("vhost", SrsJsonAny::integer(vhost->id));
obj->set("vhost", SrsJsonAny::str(vhost->id.c_str()));
obj->set("app", SrsJsonAny::str(app.c_str()));
obj->set("live_ms", SrsJsonAny::integer(srsu2ms(srs_get_system_time())));
obj->set("clients", SrsJsonAny::integer(nb_clients));
@ -154,7 +154,7 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
obj->set("publish", publish);
publish->set("active", SrsJsonAny::boolean(active));
publish->set("cid", SrsJsonAny::integer(connection_cid));
publish->set("cid", SrsJsonAny::str(connection_cid.c_str()));
if (!has_video) {
obj->set("video", SrsJsonAny::null());
@ -184,7 +184,7 @@ srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
return err;
}
void SrsStatisticStream::publish(int cid)
void SrsStatisticStream::publish(string cid)
{
connection_cid = cid;
active = true;
@ -203,7 +203,7 @@ void SrsStatisticStream::close()
SrsStatisticClient::SrsStatisticClient()
{
id = 0;
id = "";
stream = NULL;
conn = NULL;
req = NULL;
@ -219,9 +219,9 @@ srs_error_t SrsStatisticClient::dumps(SrsJsonObject* obj)
{
srs_error_t err = srs_success;
obj->set("id", SrsJsonAny::integer(id));
obj->set("vhost", SrsJsonAny::integer(stream->vhost->id));
obj->set("stream", SrsJsonAny::integer(stream->id));
obj->set("id", SrsJsonAny::str(id.c_str()));
obj->set("vhost", SrsJsonAny::str(stream->vhost->id.c_str()));
obj->set("stream", SrsJsonAny::str(stream->id.c_str()));
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
obj->set("swfUrl", SrsJsonAny::str(req->swfUrl.c_str()));
@ -278,21 +278,21 @@ SrsStatistic::~SrsStatistic()
srs_freep(clk);
if (true) {
std::map<int64_t, SrsStatisticVhost*>::iterator it;
std::map<std::string, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
srs_freep(vhost);
}
}
if (true) {
std::map<int64_t, SrsStatisticStream*>::iterator it;
std::map<std::string, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
srs_freep(stream);
}
}
if (true) {
std::map<int, SrsStatisticClient*>::iterator it;
std::map<std::string, SrsStatisticClient*>::iterator it;
for (it = clients.begin(); it != clients.end(); it++) {
SrsStatisticClient* client = it->second;
srs_freep(client);
@ -319,40 +319,27 @@ SrsStatistic* SrsStatistic::instance()
return _instance;
}
SrsStatisticVhost* SrsStatistic::find_vhost(int vid)
SrsStatisticVhost* SrsStatistic::find_vhost(string vid)
{
std::map<int64_t, SrsStatisticVhost*>::iterator it;
std::map<std::string, SrsStatisticVhost*>::iterator it;
if ((it = vhosts.find(vid)) != vhosts.end()) {
return it->second;
}
return NULL;
}
SrsStatisticVhost* SrsStatistic::find_vhost(string name)
SrsStatisticStream* SrsStatistic::find_stream(string sid)
{
if (rvhosts.empty()) {
return NULL;
}
std::map<string, SrsStatisticVhost*>::iterator it;
if ((it = rvhosts.find(name)) != rvhosts.end()) {
return it->second;
}
return NULL;
}
SrsStatisticStream* SrsStatistic::find_stream(int sid)
{
std::map<int64_t, SrsStatisticStream*>::iterator it;
std::map<std::string, SrsStatisticStream*>::iterator it;
if ((it = streams.find(sid)) != streams.end()) {
return it->second;
}
return NULL;
}
SrsStatisticClient* SrsStatistic::find_client(int cid)
SrsStatisticClient* SrsStatistic::find_client(string cid)
{
std::map<int, SrsStatisticClient*>::iterator it;
std::map<std::string, SrsStatisticClient*>::iterator it;
if ((it = clients.find(cid)) != clients.end()) {
return it->second;
}
@ -405,7 +392,7 @@ srs_error_t SrsStatistic::on_video_frames(SrsRequest* req, int nb_frames)
return err;
}
void SrsStatistic::on_stream_publish(SrsRequest* req, int cid)
void SrsStatistic::on_stream_publish(SrsRequest* req, string cid)
{
SrsStatisticVhost* vhost = create_vhost(req);
SrsStatisticStream* stream = create_stream(vhost, req);
@ -421,7 +408,7 @@ void SrsStatistic::on_stream_close(SrsRequest* req)
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
if (true) {
std::map<int64_t, SrsStatisticStream*>::iterator it;
std::map<std::string, SrsStatisticStream*>::iterator it;
if ((it=streams.find(stream->id)) != streams.end()) {
streams.erase(it);
}
@ -436,7 +423,7 @@ void SrsStatistic::on_stream_close(SrsRequest* req)
}
}
srs_error_t SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
srs_error_t SrsStatistic::on_client(std::string id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
{
srs_error_t err = srs_success;
@ -464,9 +451,9 @@ srs_error_t SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn
return err;
}
void SrsStatistic::on_disconnect(int id)
void SrsStatistic::on_disconnect(std::string id)
{
std::map<int, SrsStatisticClient*>::iterator it;
std::map<std::string, SrsStatisticClient*>::iterator it;
if ((it = clients.find(id)) == clients.end()) {
return;
}
@ -484,7 +471,7 @@ void SrsStatistic::on_disconnect(int id)
void SrsStatistic::kbps_add_delta(SrsConnection* conn)
{
int id = conn->srs_id();
std::string id = conn->srs_id();
if (clients.find(id) == clients.end()) {
return;
}
@ -506,14 +493,14 @@ SrsKbps* SrsStatistic::kbps_sample()
{
kbps->sample();
if (true) {
std::map<int64_t, SrsStatisticVhost*>::iterator it;
std::map<std::string, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
vhost->kbps->sample();
}
}
if (true) {
std::map<int64_t, SrsStatisticStream*>::iterator it;
std::map<std::string, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
stream->kbps->sample();
@ -532,7 +519,7 @@ srs_error_t SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
{
srs_error_t err = srs_success;
std::map<int64_t, SrsStatisticVhost*>::iterator it;
std::map<std::string, SrsStatisticVhost*>::iterator it;
for (it = vhosts.begin(); it != vhosts.end(); it++) {
SrsStatisticVhost* vhost = it->second;
@ -551,7 +538,7 @@ srs_error_t SrsStatistic::dumps_streams(SrsJsonArray* arr)
{
srs_error_t err = srs_success;
std::map<int64_t, SrsStatisticStream*>::iterator it;
std::map<std::string, SrsStatisticStream*>::iterator it;
for (it = streams.begin(); it != streams.end(); it++) {
SrsStatisticStream* stream = it->second;
@ -570,7 +557,7 @@ srs_error_t SrsStatistic::dumps_clients(SrsJsonArray* arr, int start, int count)
{
srs_error_t err = srs_success;
std::map<int, SrsStatisticClient*>::iterator it = clients.begin();
std::map<std::string, SrsStatisticClient*>::iterator it = clients.begin();
for (int i = 0; i < start + count && it != clients.end(); it++, i++) {
if (i < start) {
continue;

View file

@ -43,7 +43,7 @@ class SrsJsonArray;
struct SrsStatisticVhost
{
public:
int64_t id;
std::string id;
std::string vhost;
int nb_streams;
int nb_clients;
@ -61,13 +61,13 @@ public:
struct SrsStatisticStream
{
public:
int64_t id;
std::string id;
SrsStatisticVhost* vhost;
std::string app;
std::string stream;
std::string url;
bool active;
int connection_cid;
std::string connection_cid;
int nb_clients;
uint64_t nb_frames;
public:
@ -101,7 +101,7 @@ public:
virtual srs_error_t dumps(SrsJsonObject* obj);
public:
// Publish the stream.
virtual void publish(int cid);
virtual void publish(std::string cid);
// Close the stream.
virtual void close();
};
@ -113,7 +113,7 @@ public:
SrsConnection* conn;
SrsRequest* req;
SrsRtmpConnType type;
int id;
std::string id;
srs_utime_t create;
public:
SrsStatisticClient();
@ -151,19 +151,19 @@ private:
int64_t _server_id;
private:
// The key: vhost id, value: vhost object.
std::map<int64_t, SrsStatisticVhost*> vhosts;
std::map<std::string, SrsStatisticVhost*> vhosts;
// The key: vhost url, value: vhost Object.
// @remark a fast index for vhosts.
std::map<std::string, SrsStatisticVhost*> rvhosts;
private:
// The key: stream id, value: stream Object.
std::map<int64_t, SrsStatisticStream*> streams;
std::map<std::string, SrsStatisticStream*> streams;
// The key: stream url, value: stream Object.
// @remark a fast index for streams.
std::map<std::string, SrsStatisticStream*> rstreams;
private:
// The key: client id, value: stream object.
std::map<int, SrsStatisticClient*> clients;
std::map<std::string, SrsStatisticClient*> clients;
// The server total kbps.
SrsKbps* kbps;
SrsWallClock* clk;
@ -179,10 +179,9 @@ private:
public:
static SrsStatistic* instance();
public:
virtual SrsStatisticVhost* find_vhost(int vid);
virtual SrsStatisticVhost* find_vhost(std::string name);
virtual SrsStatisticStream* find_stream(int sid);
virtual SrsStatisticClient* find_client(int cid);
virtual SrsStatisticVhost* find_vhost(std::string vid);
virtual SrsStatisticStream* find_stream(std::string sid);
virtual SrsStatisticClient* find_client(std::string cid);
public:
// When got video info for stream.
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile,
@ -196,7 +195,7 @@ public:
// When publish stream.
// @param req the request object of publish connection.
// @param cid the cid of publish connection.
virtual void on_stream_publish(SrsRequest* req, int cid);
virtual void on_stream_publish(SrsRequest* req, std::string cid);
// When close stream.
virtual void on_stream_close(SrsRequest* req);
public:
@ -205,12 +204,12 @@ public:
// @param req, the client request object.
// @param conn, the physical absract connection object.
// @param type, the type of connection.
virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
virtual srs_error_t on_client(std::string id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
// Client disconnect
// @remark the on_disconnect always call, while the on_client is call when
// only got the request object, so the client specified by id maybe not
// exists in stat.
virtual void on_disconnect(int id);
virtual void on_disconnect(std::string id);
// Sample the kbps, add delta bytes of conn.
// Use kbps_sample() to get all result of kbps stat.
// TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead.

View file

@ -27,6 +27,7 @@
#include <srs_kernel_log.hpp>
#include <vector>
#include <algorithm>
using namespace std;
SrsCoroutineManager::SrsCoroutineManager()
@ -72,7 +73,9 @@ srs_error_t SrsCoroutineManager::cycle()
void SrsCoroutineManager::remove(ISrsConnection* c)
{
conns.push_back(c);
if (::find(conns.begin(), conns.end(), c) == conns.end()) {
conns.push_back(c);
}
srs_cond_signal(cond);
}
@ -80,8 +83,8 @@ void SrsCoroutineManager::clear()
{
// To prevent thread switch when delete connection,
// we copy all connections then free one by one.
vector<ISrsConnection*> copy = conns;
conns.clear();
vector<ISrsConnection*> copy;
copy.swap(conns);
vector<ISrsConnection*>::iterator it;
for (it = copy.begin(); it != copy.end(); ++it) {

View file

@ -24,6 +24,6 @@
#ifndef SRS_CORE_VERSION4_HPP
#define SRS_CORE_VERSION4_HPP
#define SRS_VERSION4_REVISION 29
#define SRS_VERSION4_REVISION 30
#endif

View file

@ -411,7 +411,7 @@ private:
std::string file;
int line;
int cid;
std::string cid;
int rerrno;
std::string desc;

View file

@ -42,23 +42,23 @@ void ISrsLog::reopen()
{
}
void ISrsLog::verbose(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
void ISrsLog::verbose(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
{
}
void ISrsLog::info(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
void ISrsLog::info(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
{
}
void ISrsLog::trace(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
void ISrsLog::trace(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
{
}
void ISrsLog::warn(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
void ISrsLog::warn(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
{
}
void ISrsLog::error(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...)
void ISrsLog::error(const char* /*tag*/, const char* /*context_id*/, const char* /*fmt*/, ...)
{
}
@ -70,19 +70,19 @@ ISrsThreadContext::~ISrsThreadContext()
{
}
int ISrsThreadContext::generate_id()
std::string ISrsThreadContext::generate_id()
{
return 0;
return "";
}
int ISrsThreadContext::get_id()
std::string ISrsThreadContext::get_id()
{
return 0;
return "";
}
int ISrsThreadContext::set_id(int /*v*/)
std::string ISrsThreadContext::set_id(std::string /*v*/)
{
return 0;
return "";
}

View file

@ -30,6 +30,7 @@
#include <errno.h>
#include <string.h>
#include <string>
#include <srs_kernel_consts.hpp>
@ -64,16 +65,16 @@ public:
virtual void reopen();
public:
// The log for verbose, very verbose information.
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
// The log for debug, detail information.
virtual void info(const char* tag, int context_id, const char* fmt, ...);
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
// The log for trace, important information.
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
// The log for warn, warn is something should take attention, but not a error.
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
// The log for error, something error occur, do something about the error, ie. close the connection,
// but we will donot abort the program.
virtual void error(const char* tag, int context_id, const char* fmt, ...);
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
};
// The context id manager to identify context, for instance, the green-thread.
@ -89,12 +90,12 @@ public:
virtual ~ISrsThreadContext();
public:
// Generate the id for current context.
virtual int generate_id();
virtual std::string generate_id();
// Get the generated id of current context.
virtual int get_id();
virtual std::string get_id();
// Set the id of current context.
// @return the previous id value; 0 if no context.
virtual int set_id(int v);
virtual std::string set_id(std::string v);
};
// @global User must provides a log object
@ -107,25 +108,25 @@ extern ISrsThreadContext* _srs_context;
// Use __FUNCTION__ to print c method
// Use __PRETTY_FUNCTION__ to print c++ class:method
#if 1
#define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#endif
#if 0
#define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#endif
#if 0
#define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_warn(msg, ...) _srs_log->warn(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id().c_str(), msg, ##__VA_ARGS__)
#endif
// TODO: FIXME: Add more verbose and info logs.

View file

@ -119,17 +119,11 @@ SrsRtpHeader::~SrsRtpHeader()
{
}
srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap *extension_map)
{
srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf) {
srs_error_t err = srs_success;
uint16_t profile_id = buf->read_2bytes();
extension_length = buf->read_2bytes();
if (!extension_map) {
buf->skip(extension_length * 4);
return err;
}
// @see: https://tools.ietf.org/html/rfc5285#section-4.2
if (profile_id == 0xBEDE) {
uint32_t xlen = extension_length * 4;
@ -151,7 +145,7 @@ srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExte
uint8_t id = (id_len & 0xF0) >> 4;
uint8_t len = (id_len & 0x0F);
SrsRtpExtensionType xtype = extension_map->get_type(id);
SrsRtpExtensionType xtype = extension_map_.get_type(id);
if (xtype == kRtpExtensionTransportSequenceNumber) {
// 0 1 2
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
@ -176,7 +170,7 @@ srs_error_t SrsRtpHeader::parse_extension(SrsBuffer* buf, const SrsRtpHeaderExte
return err;
}
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf)
{
srs_error_t err = srs_success;
@ -231,7 +225,7 @@ srs_error_t SrsRtpHeader::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap*
| header extension |
| .... |
*/
if ((err = parse_extension(buf, extmap)) != srs_success) {
if ((err = parse_extension(buf)) != srs_success) {
return srs_error_wrap(err, "fail to parse extension");
}
}
@ -298,6 +292,12 @@ srs_error_t SrsRtpHeader::encode(SrsBuffer* buf)
return err;
}
void SrsRtpHeader::set_extensions(const SrsRtpHeaderExtensionMap* extmap)
{
if (extmap) {
extension_map_ = *extmap;
}
}
srs_error_t SrsRtpHeader::get_twcc_sequence_number(uint16_t& twcc_sn)
{
@ -449,6 +449,11 @@ SrsRtpPacket2* SrsRtpPacket2::copy()
return cp;
}
void SrsRtpPacket2::set_rtp_header_extensions(const SrsRtpHeaderExtensionMap* extmap)
{
return header.set_extensions(extmap);
}
int SrsRtpPacket2::nb_bytes()
{
if (!cached_payload_size) {
@ -482,11 +487,11 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
return err;
}
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap)
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf)
{
srs_error_t err = srs_success;
if ((err = header.decode(buf, extmap)) != srs_success) {
if ((err = header.decode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp header");
}

View file

@ -140,14 +140,15 @@ private:
uint32_t ssrc;
uint32_t csrc[15];
uint16_t extension_length;
SrsRtpHeaderExtensionMap extension_map_;
SrsRtpHeaderExtension header_extension;
public:
SrsRtpHeader();
virtual ~SrsRtpHeader();
private:
srs_error_t parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extension_map);
srs_error_t parse_extension(SrsBuffer* buf);
public:
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
virtual srs_error_t decode(SrsBuffer* buf);
virtual srs_error_t encode(SrsBuffer* buf);
virtual int nb_bytes();
public:
@ -163,6 +164,7 @@ public:
uint32_t get_ssrc() const;
void set_padding(uint8_t v);
uint8_t get_padding() const;
void set_extensions(const SrsRtpHeaderExtensionMap* extmap);
srs_error_t get_twcc_sequence_number(uint16_t& twcc_sn);
};
@ -219,12 +221,13 @@ public:
bool is_audio();
// Copy the RTP packet.
SrsRtpPacket2* copy();
// Set RTP header extensions for encoding or decoding header extension
void set_rtp_header_extensions(const SrsRtpHeaderExtensionMap* extmap);
// interface ISrsEncoder
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
// TODO: FIXME: Should follow interface ISrsEncoder.
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
virtual srs_error_t decode(SrsBuffer* buf);
};
// Single payload data.

View file

@ -1,416 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 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_lib_bandwidth.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#endif
#include <sstream>
using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_rtmp_stack.hpp>
#include <srs_rtmp_stack.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_protocol_amf0.hpp>
/**
* recv bandwidth helper.
*/
typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt);
bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt)
{
return pkt->is_start_play();
}
bool _bandwidth_is_stop_play(SrsBandwidthPacket* pkt)
{
return pkt->is_stop_play();
}
bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt)
{
return pkt->is_start_publish();
}
bool _bandwidth_is_stop_publish(SrsBandwidthPacket* pkt)
{
return pkt->is_stop_publish();
}
bool _bandwidth_is_finish(SrsBandwidthPacket* pkt)
{
return pkt->is_finish();
}
int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn)
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
while (true) {
SrsCommonMessage* msg = NULL;
SrsBandwidthPacket* pkt = NULL;
if ((err = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
return ret;
}
SrsAutoFree(SrsCommonMessage, msg);
SrsAutoFree(SrsBandwidthPacket, pkt);
srs_info("get final message success.");
if (pfn(pkt)) {
return ret;
}
}
return ret;
}
int _srs_expect_bandwidth_packet2(SrsRtmpClient* rtmp, _CheckPacketType pfn, SrsBandwidthPacket** ppkt)
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
while (true) {
SrsCommonMessage* msg = NULL;
SrsBandwidthPacket* pkt = NULL;
if ((err = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
return ret;
}
SrsAutoFree(SrsCommonMessage, msg);
srs_info("get final message success.");
if (pfn(pkt)) {
*ppkt = pkt;
return ret;
}
srs_freep(pkt);
}
return ret;
}
SrsBandwidthClient::SrsBandwidthClient()
{
_rtmp = NULL;
}
SrsBandwidthClient::~SrsBandwidthClient()
{
}
int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp)
{
_rtmp = rtmp;
return ERROR_SUCCESS;
}
int SrsBandwidthClient::bandwidth_check(
int64_t* start_time, int64_t* end_time,
int* play_kbps, int* publish_kbps,
int* play_bytes, int* publish_bytes,
int* play_duration, int* publish_duration
) {
int ret = ERROR_SUCCESS;
*start_time = srsu2ms(srs_update_system_time());
// play
if ((ret = play_start()) != ERROR_SUCCESS) {
return ret;
}
if ((ret = play_checking()) != ERROR_SUCCESS) {
return ret;
}
if ((ret = play_stop()) != ERROR_SUCCESS) {
return ret;
}
// publish
int duration_ms = 0;
int actual_play_kbps = 0;
if ((ret = publish_start(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) {
return ret;
}
if ((ret = publish_checking(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) {
return ret;
}
if ((ret = publish_stop()) != ERROR_SUCCESS) {
return ret;
}
SrsBandwidthPacket* pkt = NULL;
if ((ret = do_final(&pkt)) != ERROR_SUCCESS) {
return ret;
}
SrsAutoFree(SrsBandwidthPacket, pkt);
// get data
if (true ) {
SrsAmf0Any* prop = NULL;
if ((prop = pkt->data->ensure_property_number("play_kbps")) != NULL) {
*play_kbps = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("publish_kbps")) != NULL) {
*publish_kbps = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("play_bytes")) != NULL) {
*play_bytes = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("publish_bytes")) != NULL) {
*publish_bytes = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("play_time")) != NULL) {
*play_duration = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("publish_time")) != NULL) {
*publish_duration = (int)prop->to_number();
}
}
*end_time = srsu2ms(srs_update_system_time());
return ret;
}
int SrsBandwidthClient::play_start()
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) {
return ret;
}
srs_info("BW check recv play begin request.");
if (true) {
// send start play response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check start play message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW check play begin.");
return ret;
}
int SrsBandwidthClient::play_checking()
{
int ret = ERROR_SUCCESS;
return ret;
}
int SrsBandwidthClient::play_stop()
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) {
return ret;
}
srs_info("BW check recv play stop request.");
if (true) {
// send stop play response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check stop play message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW check play stop.");
return ret;
}
int SrsBandwidthClient::publish_start(int& duration_ms, int& play_kbps)
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if (true) {
SrsBandwidthPacket* pkt = NULL;
if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) {
return ret;
}
SrsAutoFree(SrsBandwidthPacket, pkt);
SrsAmf0Any* prop = NULL;
if ((prop = pkt->data->ensure_property_number("duration_ms")) != NULL) {
duration_ms = (int)prop->to_number();
}
if ((prop = pkt->data->ensure_property_number("limit_kbps")) != NULL) {
play_kbps = (int)prop->to_number();
}
}
srs_info("BW check recv publish begin request.");
if (true) {
// send start publish response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check start publish message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW check publish begin.");
return ret;
}
int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps)
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if (duration_ms <= 0) {
ret = ERROR_RTMP_BWTC_DATA;
srs_error("server must specifies the duration, ret=%d", ret);
return ret;
}
if (play_kbps <= 0) {
ret = ERROR_RTMP_BWTC_DATA;
srs_error("server must specifies the play kbp, ret=%d", ret);
return ret;
}
int data_count = 1;
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();
// TODO: FIXME: magic number
for (int i = 0; i < data_count; ++i) {
std::stringstream seq;
seq << i;
std::string play_data = "SRS band check data from server's publishing......";
pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
}
data_count += 2;
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check publish messages failed. ret=%d", ret);
return ret;
}
// use the play kbps to control the publish
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();
elaps = (int)(srsu2ms(srs_get_system_time()) - starttime);
current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps);
usleep(100 * 1000); // TODO: FIXME: magic number.
}
}
}
srs_info("BW check send publish bytes over.");
return ret;
}
int SrsBandwidthClient::publish_stop()
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if (true) {
// send start publish response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW client stop publish request.");
if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) {
return ret;
}
srs_info("BW check recv publish stop request.");
if (true) {
// send start publish response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW check publish stop.");
return ret;
}
int SrsBandwidthClient::do_final(SrsBandwidthPacket** ppkt)
{
int ret = ERROR_SUCCESS;
srs_error_t err = srs_success;
if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) {
return ret;
}
srs_info("BW check recv finish/report request.");
if (true) {
// send final response to server.
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final();
if ((err = _rtmp->send_and_free_packet(pkt, 0)) != srs_success) {
ret = srs_error_code(err);
srs_freep(err);
srs_error("send bandwidth check final message failed. ret=%d", ret);
return ret;
}
}
srs_info("BW check final.");
return ret;
}

View file

@ -1,85 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 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_LIB_BANDWIDTH_HPP
#define SRS_LIB_BANDWIDTH_HPP
#include <srs_core.hpp>
class SrsRtmpClient;
class SrsBandwidthPacket;
/**
* bandwith client library for srs-librtmp.
*/
class SrsBandwidthClient
{
private:
SrsRtmpClient* _rtmp;
public:
SrsBandwidthClient();
virtual ~SrsBandwidthClient();
public:
/**
* initialize the bandwidth check client.
*/
virtual int initialize(SrsRtmpClient* rtmp);
/**
* do bandwidth check.
*
* bandwidth info:
* @param start_time, output the start time, in ms.
* @param end_time, output the end time, in ms.
* @param play_kbps, output the play/download kbps.
* @param publish_kbps, output the publish/upload kbps.
* @param play_bytes, output the play/download bytes.
* @param publish_bytes, output the publish/upload bytes.
* @param play_duration, output the play/download test duration, in ms.
* @param publish_duration, output the publish/upload test duration, in ms.
*/
virtual int bandwidth_check(
int64_t* start_time, int64_t* end_time,
int* play_kbps, int* publish_kbps,
int* play_bytes, int* publish_bytes,
int* play_duration, int* publish_duration);
private:
/**
* play check/test, downloading bandwidth kbps.
*/
virtual int play_start();
virtual int play_checking();
virtual int play_stop();
/**
* publish check/test, publishing bandwidth kbps.
*/
virtual int publish_start(int& duration_ms, int& play_kbps);
virtual int publish_checking(int duration_ms, int play_kbps);
virtual int publish_stop();
/**
* report and final packet
*/
virtual int do_final(SrsBandwidthPacket** ppkt);
};
#endif

View file

@ -1,486 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 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_lib_simple_socket.hpp>
#include <netinet/tcp.h>
#include <srs_kernel_error.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#define SOCKET_ETIME EWOULDBLOCK
#define SOCKET_ECONNRESET ECONNRESET
#define SOCKET_ERRNO() errno
#define SOCKET_RESET(fd) fd = -1; (void)0
#define SOCKET_CLOSE(fd) \
if (fd > 0) {\
::close(fd); \
fd = -1; \
} \
(void)0
#define SOCKET_VALID(x) (x > 0)
#define SOCKET_SETUP() (void)0
#define SOCKET_CLEANUP() (void)0
#else
#define SOCKET_ETIME WSAETIMEDOUT
#define SOCKET_ECONNRESET WSAECONNRESET
#define SOCKET_ERRNO() WSAGetLastError()
#define SOCKET_RESET(x) x=INVALID_SOCKET
#define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;}
#define SOCKET_VALID(x) (x!=INVALID_SOCKET)
#define SOCKET_BUFF(x) ((char*)x)
#define SOCKET_SETUP() socket_setup()
#define SOCKET_CLEANUP() socket_cleanup()
#endif
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/uio.h>
#endif
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <netdb.h>
#include <srs_core_autofree.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_kernel_consts.hpp>
// when io not hijacked, use simple socket, the block sync stream.
#ifndef SRS_HIJACK_IO
struct SrsBlockSyncSocket
{
int family;
SOCKET fd;
SOCKET fdv4;
SOCKET fdv6;
// Bytes transmit.
int64_t rbytes;
int64_t sbytes;
// The send/recv timeout in ms.
int64_t rtm;
int64_t stm;
SrsBlockSyncSocket() {
family = AF_UNSPEC;
stm = rtm = SRS_UTIME_NO_TIMEOUT;
rbytes = sbytes = 0;
SOCKET_RESET(fd);
SOCKET_RESET(fdv4);
SOCKET_RESET(fdv6);
SOCKET_SETUP();
}
virtual ~SrsBlockSyncSocket() {
if (SOCKET_VALID(fd)) {
SOCKET_CLOSE(fd);
}
if (SOCKET_VALID(fdv4)) {
SOCKET_CLOSE(fdv4);
}
if (SOCKET_VALID(fdv6)) {
SOCKET_CLOSE(fdv6);
}
SOCKET_CLEANUP();
}
};
srs_hijack_io_t srs_hijack_io_create()
{
SrsBlockSyncSocket* skt = new SrsBlockSyncSocket();
return skt;
}
void srs_hijack_io_destroy(srs_hijack_io_t ctx)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
srs_freep(skt);
}
int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
skt->family = AF_UNSPEC;
skt->fdv4 = ::socket(AF_INET, SOCK_STREAM, 0);
skt->fdv6 = ::socket(AF_INET6, SOCK_STREAM, 0);
if (!SOCKET_VALID(skt->fdv4) && !SOCKET_VALID(skt->fdv4)) {
return ERROR_SOCKET_CREATE;
}
// No TCP cache.
int v = 1;
setsockopt(skt->fdv4, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
setsockopt(skt->fdv6, IPPROTO_TCP, TCP_NODELAY, &v, sizeof(v));
return ERROR_SUCCESS;
}
int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
char sport[8];
snprintf(sport, sizeof(sport), "%d", port);
addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
addrinfo* r = NULL;
SrsAutoFree(addrinfo, r);
if(getaddrinfo(server_ip, sport, (const addrinfo*)&hints, &r)) {
return ERROR_SOCKET_CONNECT;
}
skt->family = r->ai_family;
if (r->ai_family == AF_INET6) {
skt->fd = skt->fdv6;
SOCKET_RESET(skt->fdv6);
} else {
skt->fd = skt->fdv4;
SOCKET_RESET(skt->fdv4);
}
if(::connect(skt->fd, r->ai_addr, r->ai_addrlen) < 0){
return ERROR_SOCKET_CONNECT;
}
return ERROR_SUCCESS;
}
int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
int ret = ERROR_SUCCESS;
ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0);
if (nread) {
*nread = nb_read;
}
// On success a non-negative integer indicating the number of bytes actually read is returned
// (a value of 0 means the network connection is closed or end of file is reached).
if (nb_read <= 0) {
if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
return ERROR_SOCKET_TIMEOUT;
}
if (nb_read == 0) {
errno = SOCKET_ECONNRESET;
}
return ERROR_SOCKET_READ;
}
skt->rbytes += nb_read;
return ret;
}
int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
#ifdef _WIN32
DWORD tv = (DWORD)(tm);
// To convert tv to const char* to make VS2015 happy.
if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
#else
// The default for this option is zero,
// which indicates that a receive operation shall not time out.
int32_t sec = 0;
int32_t usec = 0;
if (tm != SRS_UTIME_NO_TIMEOUT) {
sec = (int32_t)(tm / 1000);
usec = (int32_t)((tm % 1000)*1000);
}
struct timeval tv = { sec , usec };
if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
#endif
skt->rtm = tm;
return ERROR_SUCCESS;
}
int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
return skt->rtm;
}
int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
return skt->rbytes;
}
int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
#ifdef _WIN32
DWORD tv = (DWORD)(tm);
// To convert tv to const char* to make VS2015 happy.
if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
#else
// The default for this option is zero,
// which indicates that a receive operation shall not time out.
int32_t sec = 0;
int32_t usec = 0;
if (tm != SRS_UTIME_NO_TIMEOUT) {
sec = (int32_t)(tm / 1000);
usec = (int32_t)((tm % 1000)*1000);
}
struct timeval tv = { sec , usec };
if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) {
return SOCKET_ERRNO();
}
#endif
skt->stm = tm;
return ERROR_SUCCESS;
}
int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
return skt->stm;
}
int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
return skt->sbytes;
}
int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
int ret = ERROR_SUCCESS;
ssize_t nb_write = ::writev(skt->fd, iov, iov_size);
if (nwrite) {
*nwrite = nb_write;
}
// On success, the readv() function returns the number of bytes read;
// the writev() function returns the number of bytes written. On error, -1 is
// returned, and errno is set appropriately.
if (nb_write <= 0) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
return ERROR_SOCKET_TIMEOUT;
}
return ERROR_SOCKET_WRITE;
}
skt->sbytes += nb_write;
return ret;
}
int srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t tm)
{
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)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
int ret = ERROR_SUCCESS;
size_t left = size;
ssize_t nb_read = 0;
while (left > 0) {
char* this_buf = (char*)buf + nb_read;
ssize_t this_nread;
if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) {
return ret;
}
nb_read += this_nread;
left -= (size_t)this_nread;
}
if (nread) {
*nread = nb_read;
}
skt->rbytes += nb_read;
return ret;
}
int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite)
{
SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
int ret = ERROR_SUCCESS;
ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0);
if (nwrite) {
*nwrite = nb_write;
}
if (nb_write <= 0) {
// @see https://github.com/ossrs/srs/issues/200
if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) {
return ERROR_SOCKET_TIMEOUT;
}
return ERROR_SOCKET_WRITE;
}
skt->sbytes += nb_write;
return ret;
}
#endif
SimpleSocketStream::SimpleSocketStream()
{
io = srs_hijack_io_create();
}
SimpleSocketStream::~SimpleSocketStream()
{
if (io) {
srs_hijack_io_destroy(io);
io = NULL;
}
}
srs_hijack_io_t SimpleSocketStream::hijack_io()
{
return io;
}
int SimpleSocketStream::create_socket(srs_rtmp_t owner)
{
srs_assert(io);
return srs_hijack_io_create_socket(io, owner);
}
int SimpleSocketStream::connect(const char* server_ip, int port)
{
srs_assert(io);
return srs_hijack_io_connect(io, server_ip, port);
}
// Interface ISrsReader
srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
{
srs_assert(io);
int ret = srs_hijack_io_read(io, buf, size, nread);
if (ret != ERROR_SUCCESS) {
return srs_error_new(ret, "read");
}
return srs_success;
}
// Interface ISrsProtocolReader
void SimpleSocketStream::set_recv_timeout(srs_utime_t tm)
{
srs_assert(io);
srs_hijack_io_set_recv_timeout(io, srsu2ms(tm));
}
srs_utime_t SimpleSocketStream::get_recv_timeout()
{
srs_assert(io);
return srs_hijack_io_get_recv_timeout(io) * SRS_UTIME_MILLISECONDS;
}
int64_t SimpleSocketStream::get_recv_bytes()
{
srs_assert(io);
return srs_hijack_io_get_recv_bytes(io);
}
// Interface ISrsProtocolWriter
void SimpleSocketStream::set_send_timeout(srs_utime_t tm)
{
srs_assert(io);
srs_hijack_io_set_send_timeout(io, srsu2ms(tm));
}
srs_utime_t SimpleSocketStream::get_send_timeout()
{
srs_assert(io);
return srs_hijack_io_get_send_timeout(io) * SRS_UTIME_MILLISECONDS;
}
int64_t SimpleSocketStream::get_send_bytes()
{
srs_assert(io);
return srs_hijack_io_get_send_bytes(io);
}
srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite)
{
srs_assert(io);
int ret = srs_hijack_io_writev(io, iov, iov_size, nwrite);
if (ret != ERROR_SUCCESS) {
return srs_error_new(ret, "read");
}
return srs_success;
}
srs_error_t SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread)
{
srs_assert(io);
int ret = srs_hijack_io_read_fully(io, buf, size, nread);
if (ret != ERROR_SUCCESS) {
return srs_error_new(ret, "read");
}
return srs_success;
}
srs_error_t SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite)
{
srs_assert(io);
int ret = srs_hijack_io_write(io, buf, size, nwrite);
if (ret != ERROR_SUCCESS) {
return srs_error_new(ret, "read");
}
return srs_success;
}

View file

@ -1,73 +0,0 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 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_LIB_SIMPLE_SOCKET_HPP
#define SRS_LIB_SIMPLE_SOCKET_HPP
#include <srs_core.hpp>
#include <srs_protocol_io.hpp>
#include <srs_librtmp.hpp>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32
#define SOCKET int
#endif
/**
* simple socket stream,
* use tcp socket, sync block mode, for client like srs-librtmp.
*/
class SimpleSocketStream : public ISrsProtocolReadWriter
{
private:
srs_hijack_io_t io;
public:
SimpleSocketStream();
virtual ~SimpleSocketStream();
public:
virtual srs_hijack_io_t hijack_io();
virtual int create_socket(srs_rtmp_t owner);
virtual int connect(const char* server, int port);
// Interface ISrsReader
public:
virtual srs_error_t read(void* buf, size_t size, ssize_t* nread);
// Interface ISrsProtocolReader
public:
virtual void set_recv_timeout(srs_utime_t tm);
virtual srs_utime_t get_recv_timeout();
virtual int64_t get_recv_bytes();
// Interface ISrsProtocolWriter
public:
virtual void set_send_timeout(srs_utime_t tm);
virtual srs_utime_t get_send_timeout();
virtual int64_t get_send_bytes();
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
// Interface ISrsProtocolReadWriter
public:
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite);
};
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -490,7 +490,7 @@ public:
// then the rest id is 100.
// @param pattern the handler pattern which will serve the request.
// @return the REST id; -1 if not matched.
virtual int parse_rest_id(std::string pattern) = 0;
virtual std::string parse_rest_id(std::string pattern) = 0;
public:
// The left all data is chunked body, the infinite chunked mode,
// which is chunked encoding without chunked header.

View file

@ -2453,7 +2453,7 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser
}
// for edge to directly get the id of client.
data->set("srs_pid", SrsAmf0Any::number(getpid()));
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
data->set("srs_id", SrsAmf0Any::str(_srs_context->get_id().c_str()));
if ((err = protocol->send_and_free_packet(pkt, 0)) != srs_success) {
return srs_error_wrap(err, "send connect app response");

View file

@ -535,19 +535,19 @@ string SrsHttpMessage::ext()
return _ext;
}
int SrsHttpMessage::parse_rest_id(string pattern)
std::string SrsHttpMessage::parse_rest_id(string pattern)
{
string p = _uri->get_path();
if (p.length() <= pattern.length()) {
return -1;
return "";
}
string id = p.substr((int)pattern.length());
if (!id.empty()) {
return ::atoi(id.c_str());
return id;
}
return -1;
return "";
}
srs_error_t SrsHttpMessage::enter_infinite_chunked()

View file

@ -172,7 +172,7 @@ public:
virtual std::string query();
virtual std::string ext();
// Get the RESTful matched id.
virtual int parse_rest_id(std::string pattern);
virtual std::string parse_rest_id(std::string pattern);
public:
virtual srs_error_t enter_infinite_chunked();
public:

View file

@ -26,6 +26,7 @@
#include <stdarg.h>
#include <sys/time.h>
#include <unistd.h>
#include <sstream>
using namespace std;
#include <srs_kernel_error.hpp>
@ -41,29 +42,31 @@ SrsThreadContext::~SrsThreadContext()
{
}
int SrsThreadContext::generate_id()
string SrsThreadContext::generate_id()
{
static int id = 0;
if (id == 0) {
id = (100 + ((uint32_t)(int64_t)this)%1000);
}
int gid = id++;
cache[srs_thread_self()] = gid;
return gid;
stringstream ss;
ss << gid;
cache[srs_thread_self()] = ss.str();
return ss.str();
}
int SrsThreadContext::get_id()
string SrsThreadContext::get_id()
{
return cache[srs_thread_self()];
}
int SrsThreadContext::set_id(int v)
string SrsThreadContext::set_id(string v)
{
srs_thread_t self = srs_thread_self();
int ov = 0;
string ov;
if (cache.find(self) != cache.end()) {
ov = cache[self];
}
@ -76,7 +79,7 @@ int SrsThreadContext::set_id(int v)
void SrsThreadContext::clear_cid()
{
srs_thread_t self = srs_thread_self();
std::map<srs_thread_t, int>::iterator it = cache.find(self);
std::map<srs_thread_t, string>::iterator it = cache.find(self);
if (it != cache.end()) {
cache.erase(it);
}
@ -105,7 +108,7 @@ void SrsConsoleLog::reopen()
{
}
void SrsConsoleLog::verbose(const char* tag, int context_id, const char* fmt, ...)
void SrsConsoleLog::verbose(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelVerbose) {
return;
@ -125,7 +128,7 @@ void SrsConsoleLog::verbose(const char* tag, int context_id, const char* fmt, ..
fprintf(stdout, "%s\n", buffer);
}
void SrsConsoleLog::info(const char* tag, int context_id, const char* fmt, ...)
void SrsConsoleLog::info(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelInfo) {
return;
@ -145,7 +148,7 @@ void SrsConsoleLog::info(const char* tag, int context_id, const char* fmt, ...)
fprintf(stdout, "%s\n", buffer);
}
void SrsConsoleLog::trace(const char* tag, int context_id, const char* fmt, ...)
void SrsConsoleLog::trace(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelTrace) {
return;
@ -165,7 +168,7 @@ void SrsConsoleLog::trace(const char* tag, int context_id, const char* fmt, ...)
fprintf(stdout, "%s\n", buffer);
}
void SrsConsoleLog::warn(const char* tag, int context_id, const char* fmt, ...)
void SrsConsoleLog::warn(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelWarn) {
return;
@ -185,7 +188,7 @@ void SrsConsoleLog::warn(const char* tag, int context_id, const char* fmt, ...)
fprintf(stderr, "%s\n", buffer);
}
void SrsConsoleLog::error(const char* tag, int context_id, const char* fmt, ...)
void SrsConsoleLog::error(const char* tag, const char* context_id, const char* fmt, ...)
{
if (level > SrsLogLevelError) {
return;
@ -211,7 +214,7 @@ void SrsConsoleLog::error(const char* tag, int context_id, const char* fmt, ...)
}
// LCOV_EXCL_STOP
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize)
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, const char* cid, const char* level, int* psize)
{
// clock time
timeval tv;
@ -235,24 +238,24 @@ bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char
if (dangerous) {
if (tag) {
written = snprintf(buffer, size,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ",
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%s][%d] ",
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
level, tag, getpid(), cid, errno);
} else {
written = snprintf(buffer, size,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ",
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%s][%d] ",
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
level, getpid(), cid, errno);
}
} else {
if (tag) {
written = snprintf(buffer, size,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ",
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%s] ",
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
level, tag, getpid(), cid);
} else {
written = snprintf(buffer, size,
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ",
"[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%s] ",
1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000),
level, getpid(), cid);
}

View file

@ -27,6 +27,7 @@
#include <srs_core.hpp>
#include <map>
#include <string>
#include <srs_service_st.hpp>
#include <srs_kernel_log.hpp>
@ -36,14 +37,14 @@
class SrsThreadContext : public ISrsThreadContext
{
private:
std::map<srs_thread_t, int> cache;
std::map<srs_thread_t, std::string> cache;
public:
SrsThreadContext();
virtual ~SrsThreadContext();
public:
virtual int generate_id();
virtual int get_id();
virtual int set_id(int v);
virtual std::string generate_id();
virtual std::string get_id();
virtual std::string set_id(std::string v);
public:
virtual void clear_cid();
};
@ -63,11 +64,11 @@ public:
public:
virtual srs_error_t initialize();
virtual void reopen();
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
virtual void info(const char* tag, int context_id, const char* fmt, ...);
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
virtual void error(const char* tag, int context_id, const char* fmt, ...);
virtual void verbose(const char* tag, const char* context_id, const char* fmt, ...);
virtual void info(const char* tag, const char* context_id, const char* fmt, ...);
virtual void trace(const char* tag, const char* context_id, const char* fmt, ...);
virtual void warn(const char* tag, const char* context_id, const char* fmt, ...);
virtual void error(const char* tag, const char* context_id, const char* fmt, ...);
};
// Generate the log header.
@ -75,6 +76,6 @@ public:
// @param utc Whether use UTC time format in the log header.
// @param psize Output the actual header size.
// @remark It's a internal API.
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize);
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, const char* cid, const char* level, int* psize);
#endif

View file

@ -122,7 +122,7 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
// for edge to directly get the id of client.
data->set("srs_pid", SrsAmf0Any::number(getpid()));
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
data->set("srs_id", SrsAmf0Any::str(_srs_context->get_id().c_str()));
// local ip of edge
data->set("srs_server_ip", SrsAmf0Any::str(local_ip.c_str()));

View file

@ -214,7 +214,7 @@ srs_error_t do_srs_tcp_listen(int fd, addrinfo* r, srs_netfd_t* pfd)
return srs_error_wrap(err, "set reuseport");
}
if (bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
if (::bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
return srs_error_new(ERROR_SOCKET_BIND, "bind");
}
@ -279,7 +279,7 @@ srs_error_t do_srs_udp_listen(int fd, addrinfo* r, srs_netfd_t* pfd)
return srs_error_wrap(err, "set reuseport");
}
if (bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
if (::bind(fd, r->ai_addr, r->ai_addrlen) == -1) {
return srs_error_new(ERROR_SOCKET_BIND, "bind");
}

View file

@ -129,3 +129,11 @@ VOID TEST(SampleTest, FastSampleMacrosTest)
EXPECT_NEAR(10, 15, 5);
}
VOID TEST(SampleTest, StringEQTest)
{
string str = "100";
EXPECT_TRUE("100" == str);
EXPECT_EQ("100", str);
EXPECT_STREQ("100", str.c_str());
}

View file

@ -36,7 +36,7 @@ VOID TEST(AppCoroutineTest, Dummy)
SrsDummyCoroutine dc;
if (true) {
EXPECT_EQ(0, dc.cid());
EXPECT_EQ("", dc.cid());
srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success);
@ -52,7 +52,7 @@ VOID TEST(AppCoroutineTest, Dummy)
if (true) {
dc.stop();
EXPECT_EQ(0, dc.cid());
EXPECT_EQ("", dc.cid());
srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success);
@ -68,7 +68,7 @@ VOID TEST(AppCoroutineTest, Dummy)
if (true) {
dc.interrupt();
EXPECT_EQ(0, dc.cid());
EXPECT_EQ("", dc.cid());
srs_error_t err = dc.pull();
EXPECT_TRUE(err != srs_success);
@ -88,11 +88,11 @@ public:
srs_error_t err;
srs_cond_t running;
srs_cond_t exited;
int cid;
std::string cid;
// Quit without error.
bool quit;
public:
MockCoroutineHandler() : trd(NULL), err(srs_success), cid(0), quit(false) {
MockCoroutineHandler() : trd(NULL), err(srs_success), cid("0"), quit(false) {
running = srs_cond_new();
exited = srs_cond_new();
}
@ -128,12 +128,12 @@ VOID TEST(AppCoroutineTest, StartStop)
MockCoroutineHandler ch;
SrsSTCoroutine sc("test", &ch);
ch.trd = &sc;
EXPECT_EQ(0, sc.cid());
EXPECT_EQ("", sc.cid());
// Thread stop after created.
sc.stop();
EXPECT_EQ(0, sc.cid());
EXPECT_EQ("", sc.cid());
srs_error_t err = sc.pull();
EXPECT_TRUE(srs_success != err);
@ -151,13 +151,13 @@ VOID TEST(AppCoroutineTest, StartStop)
MockCoroutineHandler ch;
SrsSTCoroutine sc("test", &ch);
ch.trd = &sc;
EXPECT_EQ(0, sc.cid());
EXPECT_EQ("", 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);
EXPECT_TRUE(!sc.cid().empty());
// Thread stop after started.
sc.stop();
@ -178,7 +178,7 @@ VOID TEST(AppCoroutineTest, StartStop)
MockCoroutineHandler ch;
SrsSTCoroutine sc("test", &ch);
ch.trd = &sc;
EXPECT_EQ(0, sc.cid());
EXPECT_EQ("", sc.cid());
EXPECT_TRUE(srs_success == sc.start());
EXPECT_TRUE(srs_success == sc.pull());
@ -220,16 +220,16 @@ VOID TEST(AppCoroutineTest, Cycle)
if (true) {
MockCoroutineHandler ch;
SrsSTCoroutine sc("test", &ch, 250);
SrsSTCoroutine sc("test", &ch, "250");
ch.trd = &sc;
EXPECT_EQ(250, sc.cid());
EXPECT_TRUE("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);
EXPECT_TRUE("250" == ch.cid);
}
if (true) {

View file

@ -4099,16 +4099,16 @@ VOID TEST(KernelLogTest, CoverAll)
HELPER_EXPECT_SUCCESS(l.initialize());
l.reopen();
l.verbose("TAG", 0, "log");
l.info("TAG", 0, "log");
l.trace("TAG", 0, "log");
l.warn("TAG", 0, "log");
l.error("TAG", 0, "log");
l.verbose("TAG", "0", "log");
l.info("TAG", "0", "log");
l.trace("TAG", "0", "log");
l.warn("TAG", "0", "log");
l.error("TAG", "0", "log");
ISrsThreadContext ctx;
ctx.set_id(10);
EXPECT_EQ(0, ctx.get_id());
EXPECT_EQ(0, ctx.generate_id());
ctx.set_id("10");
EXPECT_EQ("", ctx.get_id());
EXPECT_EQ("", ctx.generate_id());
}
}

View file

@ -558,7 +558,7 @@ VOID TEST(TCPServerTest, MessageConnection)
if (true) {
SrsHttpMessage m;
HELPER_EXPECT_SUCCESS(m.set_url("http://127.0.0.1/v1/streams/100", false));
EXPECT_EQ(100, m.parse_rest_id("/v1/streams/")); EXPECT_FALSE(m.is_jsonp());
EXPECT_EQ("100", m.parse_rest_id("/v1/streams/")); EXPECT_FALSE(m.is_jsonp());
}
}
@ -782,7 +782,7 @@ class MockOnCycleThread : public ISrsCoroutineHandler
public:
SrsSTCoroutine trd;
srs_cond_t cond;
MockOnCycleThread() : trd("mock", this, 0) {
MockOnCycleThread() : trd("mock", this, "0") {
cond = srs_cond_new();
};
virtual ~MockOnCycleThread() {
@ -822,7 +822,7 @@ class MockOnCycleThread2 : public ISrsCoroutineHandler
public:
SrsSTCoroutine trd;
srs_mutex_t lock;
MockOnCycleThread2() : trd("mock", this, 0) {
MockOnCycleThread2() : trd("mock", this, "0") {
lock = srs_mutex_new();
};
virtual ~MockOnCycleThread2() {
@ -863,7 +863,7 @@ class MockOnCycleThread3 : public ISrsCoroutineHandler
public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread3() : trd("mock", this, 0) {
MockOnCycleThread3() : trd("mock", this, "0") {
fd = NULL;
};
virtual ~MockOnCycleThread3() {
@ -1116,7 +1116,7 @@ class MockOnCycleThread4 : public ISrsCoroutineHandler
public:
SrsSTCoroutine trd;
srs_netfd_t fd;
MockOnCycleThread4() : trd("mock", this, 0) {
MockOnCycleThread4() : trd("mock", this, "0") {
fd = NULL;
};
virtual ~MockOnCycleThread4() {
@ -1268,38 +1268,38 @@ VOID TEST(TCPServerTest, ContextUtility)
if (true) {
SrsThreadContext ctx;
EXPECT_EQ(0, ctx.set_id(100));
EXPECT_EQ(100, ctx.set_id(1000));
EXPECT_EQ(1000, ctx.get_id());
EXPECT_TRUE("" == ctx.set_id("100"));
EXPECT_TRUE("100" == ctx.set_id("1000"));
EXPECT_TRUE("1000" == ctx.get_id());
ctx.clear_cid();
EXPECT_EQ(0, ctx.set_id(100));
EXPECT_TRUE("" == ctx.set_id("100"));
}
int base_size = 0;
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", 100, "Trace", &size));
ASSERT_TRUE(srs_log_header(buf, 1024, true, true, "SRS", "100", "Trace", &size));
base_size = size;
EXPECT_TRUE(base_size > 0);
}
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, "SRS", 100, "Trace", &size));
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, "SRS", "100", "Trace", &size));
EXPECT_EQ(base_size, size);
}
if (true) {
errno = 0;
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, NULL, 100, "Trace", &size));
ASSERT_TRUE(srs_log_header(buf, 1024, false, true, NULL, "100", "Trace", &size));
EXPECT_EQ(base_size - 5, size);
}
if (true) {
int size = 0; char buf[1024]; HELPER_ARRAY_INIT(buf, 1024, 0);
ASSERT_TRUE(srs_log_header(buf, 1024, false, false, NULL, 100, "Trace", &size));
ASSERT_TRUE(srs_log_header(buf, 1024, false, false, NULL, "100", "Trace", &size));
EXPECT_EQ(base_size - 8, size);
}