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:
commit
1c72a89fca
97 changed files with 654 additions and 9368 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ srs_error_t SrsConnection::cycle()
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
int SrsConnection::srs_id()
|
||||
string SrsConnection::srs_id()
|
||||
{
|
||||
return trd->cid();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -173,6 +173,7 @@ private:
|
|||
class SrsRtspCaster : public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
std::string engine;
|
||||
std::string output;
|
||||
int local_port_min;
|
||||
int local_port_max;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue