mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
support gmd. change work_dir. hourglass. add utilies.
This commit is contained in:
parent
c9b977d337
commit
f1e7e9d933
33 changed files with 702 additions and 73 deletions
|
@ -1905,11 +1905,6 @@ int SrsConfig::parse_options(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
// cwd
|
||||
char cwd[256];
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
_cwd = cwd;
|
||||
|
||||
// config
|
||||
show_help = true;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
|
@ -1987,6 +1982,18 @@ int SrsConfig::parse_options(int argc, char** argv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsConfig::initialize_cwd()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// cwd
|
||||
char cwd[256];
|
||||
getcwd(cwd, sizeof(cwd));
|
||||
_cwd = cwd;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsConfig::persistence()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
@ -3529,7 +3536,7 @@ int SrsConfig::check_config()
|
|||
&& n != "max_connections" && n != "daemon" && n != "heartbeat"
|
||||
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms"
|
||||
&& n != "http_server" && n != "stream_caster" && n != "kafka"
|
||||
&& n != "utc_time"
|
||||
&& n != "utc_time" && n != "work_dir"
|
||||
) {
|
||||
ret = ERROR_SYSTEM_CONFIG_INVALID;
|
||||
srs_error("unsupported directive %s, ret=%d", n.c_str(), ret);
|
||||
|
@ -4179,6 +4186,17 @@ bool SrsConfig::get_utc_time()
|
|||
return SRS_CONF_PERFER_FALSE(conf->arg0());
|
||||
}
|
||||
|
||||
string SrsConfig::get_work_dir() {
|
||||
static string DEFAULT = "";
|
||||
|
||||
SrsConfDirective* conf = root->get("work_dir");
|
||||
if( !conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return conf->arg0();
|
||||
}
|
||||
|
||||
vector<SrsConfDirective*> SrsConfig::get_stream_casters()
|
||||
{
|
||||
srs_assert(root);
|
||||
|
|
|
@ -416,6 +416,11 @@ public:
|
|||
* parse the cli, the main(argc,argv) function.
|
||||
*/
|
||||
virtual int parse_options(int argc, char** argv);
|
||||
/**
|
||||
* initialize the cwd for server,
|
||||
* because we may change the workdir.
|
||||
*/
|
||||
virtual int initialize_cwd();
|
||||
/**
|
||||
* persistence current config to file.
|
||||
*/
|
||||
|
@ -607,6 +612,11 @@ public:
|
|||
* whether use utc-time to format the time.
|
||||
*/
|
||||
virtual bool get_utc_time();
|
||||
/**
|
||||
* get the configed work dir.
|
||||
* ignore if empty string.
|
||||
*/
|
||||
virtual std::string get_work_dir();
|
||||
// stream_caster section
|
||||
public:
|
||||
/**
|
||||
|
|
86
trunk/src/app/srs_app_hourglass.cpp
Normal file
86
trunk/src/app/srs_app_hourglass.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 SRS(ossrs)
|
||||
|
||||
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_app_hourglass.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_app_st.hpp>
|
||||
#include <srs_kernel_log.hpp>
|
||||
|
||||
ISrsHourGlass::ISrsHourGlass()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsHourGlass::~ISrsHourGlass()
|
||||
{
|
||||
}
|
||||
|
||||
SrsHourGlass::SrsHourGlass(ISrsHourGlass* h, int resolution_ms)
|
||||
{
|
||||
handler = h;
|
||||
resolution = resolution_ms;
|
||||
total_elapse = 0;
|
||||
}
|
||||
|
||||
SrsHourGlass::~SrsHourGlass()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsHourGlass::tick(int type, int interval)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
if (resolution > 0 && (interval % resolution) != 0) {
|
||||
ret = ERROR_SYSTEM_HOURGLASS_RESOLUTION;
|
||||
srs_error("hourglass interval=%d invalid, resolution=%d. ret=%d", interval, resolution, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ticks[type] = interval;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SrsHourGlass::cycle()
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
map<int, int>::iterator it;
|
||||
for (it = ticks.begin(); it != ticks.end(); ++it) {
|
||||
int type = it->first;
|
||||
int interval = it->second;
|
||||
|
||||
if (interval == 0 || (total_elapse % interval) == 0) {
|
||||
if ((ret = handler->notify(type, interval, total_elapse)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
total_elapse += resolution;
|
||||
st_usleep(resolution * 1000);
|
||||
|
||||
return ret;
|
||||
}
|
101
trunk/src/app/srs_app_hourglass.hpp
Normal file
101
trunk/src/app/srs_app_hourglass.hpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2016 SRS(ossrs)
|
||||
|
||||
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_APP_HOURGLASS_HPP
|
||||
#define SRS_APP_HOURGLASS_HPP
|
||||
|
||||
/*
|
||||
#include <srs_app_hourglass.hpp>
|
||||
*/
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* the handler for the tick.
|
||||
*/
|
||||
class ISrsHourGlass
|
||||
{
|
||||
public:
|
||||
ISrsHourGlass();
|
||||
virtual ~ISrsHourGlass();
|
||||
public:
|
||||
/**
|
||||
* notify the handler, the type and tick.
|
||||
*/
|
||||
virtual int notify(int type, int interval, int64_t tick) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* the hourglass used to do some specieal task,
|
||||
* while these task is cycle when some interval, for example,
|
||||
* there are N=3 tasks to do:
|
||||
* 1. heartbeat every 3s.
|
||||
* 2. print message every 5s.
|
||||
* 3. notify backend every 7s.
|
||||
* the hourglass will call back when ticks:
|
||||
* 1. notify(type=1, time=3)
|
||||
* 2. notify(type=2, time=5)
|
||||
* 3. notify(type=1, time=6)
|
||||
* 4. notify(type=3, time=7)
|
||||
* 5. notify(type=1, time=9)
|
||||
* 6. notify(type=2, time=10)
|
||||
* this is used for server and bocar server and other manager.
|
||||
*
|
||||
* Usage:
|
||||
* SrsHourGlass* hg = new SrsHourGlass(handler, 1000);
|
||||
* hg->tick(1, 3000);
|
||||
* hg->tick(2, 5000);
|
||||
* hg->tick(3, 7000);
|
||||
* // create a thread to cycle, which will call handerl when ticked.
|
||||
* while (true) {
|
||||
* hg->cycle();
|
||||
* }
|
||||
*/
|
||||
class SrsHourGlass
|
||||
{
|
||||
private:
|
||||
ISrsHourGlass* handler;
|
||||
int resolution;
|
||||
// key: the type of tick.
|
||||
// value: the interval of tick.
|
||||
std::map<int, int> ticks;
|
||||
// the total elapsed time,
|
||||
// for each cycle, we increase it with a resolution.
|
||||
int64_t total_elapse;
|
||||
public:
|
||||
SrsHourGlass(ISrsHourGlass* h, int resolution_ms);
|
||||
virtual ~SrsHourGlass();
|
||||
public:
|
||||
// add a pair of tick(type, interval).
|
||||
// @param type the type of tick.
|
||||
// @param interval the interval in ms of tick.
|
||||
virtual int tick(int type, int interval);
|
||||
public:
|
||||
// cycle the hourglass, which will sleep resolution every time.
|
||||
// and call handler when ticked.
|
||||
virtual int cycle();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -41,6 +41,9 @@ using namespace std;
|
|||
#include <srs_kernel_log.hpp>
|
||||
#include <srs_app_config.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_protocol_utility.hpp>
|
||||
#include <srs_app_utility.hpp>
|
||||
|
||||
SrsProcess::SrsProcess()
|
||||
{
|
||||
|
@ -53,6 +56,11 @@ SrsProcess::~SrsProcess()
|
|||
{
|
||||
}
|
||||
|
||||
int SrsProcess::get_pid()
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
|
||||
bool SrsProcess::started()
|
||||
{
|
||||
return is_started;
|
||||
|
@ -64,39 +72,66 @@ int SrsProcess::initialize(string binary, vector<string> argv)
|
|||
|
||||
bin = binary;
|
||||
cli = "";
|
||||
actual_cli = "";
|
||||
params.clear();
|
||||
|
||||
for (int i = 0; i < (int)argv.size(); i++) {
|
||||
std::string ffp = argv[i];
|
||||
cli += ffp;
|
||||
if (i < (int)argv.size() - 1) {
|
||||
cli += " ";
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)argv.size(); i++) {
|
||||
std::string ffp = argv[i];
|
||||
std::string nffp = (i < (int)argv.size() -1)? argv[i + 1] : "";
|
||||
std::string nffp = (i < (int)argv.size() - 1)? argv[i + 1] : "";
|
||||
std::string nnffp = (i < (int)argv.size() - 2)? argv[i + 2] : "";
|
||||
|
||||
// remove the stdout and stderr.
|
||||
if (ffp == "1" && nffp == ">") {
|
||||
if (i + 2 < (int)argv.size()) {
|
||||
stdout_file = argv[i + 2];
|
||||
i += 2;
|
||||
}
|
||||
continue;
|
||||
} else if (ffp == "2" && nffp == ">") {
|
||||
if (i + 2 < (int)argv.size()) {
|
||||
stderr_file = argv[i + 2];
|
||||
i += 2;
|
||||
}
|
||||
// 1>file
|
||||
if (srs_string_starts_with(ffp, "1>")) {
|
||||
stdout_file = ffp.substr(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2>file
|
||||
if (srs_string_starts_with(ffp, "2>")) {
|
||||
stderr_file = ffp.substr(2);
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1 >X
|
||||
if (ffp == "1" && srs_string_starts_with(nffp, ">")) {
|
||||
if (nffp == ">") {
|
||||
// 1 > file
|
||||
if (!nnffp.empty()) {
|
||||
stderr_file = nnffp;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
// 1 >file
|
||||
stdout_file = srs_string_trim_start(nffp, ">");
|
||||
}
|
||||
// skip the >
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 2 >X
|
||||
if (ffp == "2" && srs_string_starts_with(nffp, ">")) {
|
||||
if (nffp == ">") {
|
||||
// 2 > file
|
||||
if (!nnffp.empty()) {
|
||||
stderr_file = nnffp;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
// 2 >file
|
||||
stderr_file = srs_string_trim_start(nffp, ">");
|
||||
}
|
||||
// skip the >
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// startup params.
|
||||
params.push_back(ffp);
|
||||
}
|
||||
|
||||
actual_cli = srs_join_vector_string(params, " ");
|
||||
cli = srs_join_vector_string(argv, " ");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -109,7 +144,7 @@ int SrsProcess::start()
|
|||
}
|
||||
|
||||
// generate the argv of process.
|
||||
srs_trace("fork process: %s", cli.c_str());
|
||||
srs_info("fork process: %s", cli.c_str());
|
||||
|
||||
// for log
|
||||
int cid = _srs_context->get_id();
|
||||
|
@ -118,11 +153,12 @@ int SrsProcess::start()
|
|||
// TODO: fork or vfork?
|
||||
if ((pid = fork()) < 0) {
|
||||
ret = ERROR_ENCODER_FORK;
|
||||
srs_error("vfork process failed. ret=%d", ret);
|
||||
srs_error("vfork process failed, cli=%s. ret=%d", cli.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// for osx(lldb) to debug the child process.
|
||||
// user can use "lldb -p <pid>" to resume the parent or child process.
|
||||
//kill(0, SIGSTOP);
|
||||
|
||||
// child process: ffmpeg encoder engine.
|
||||
|
@ -176,6 +212,7 @@ int SrsProcess::start()
|
|||
fprintf(stderr, "process parent cid=%d\n", cid);
|
||||
fprintf(stderr, "process binary=%s\n", bin.c_str());
|
||||
fprintf(stderr, "process cli: %s\n", cli.c_str());
|
||||
fprintf(stderr, "process actual cli: %s\n", actual_cli.c_str());
|
||||
}
|
||||
|
||||
// close other fds
|
||||
|
@ -204,7 +241,8 @@ int SrsProcess::start()
|
|||
// parent.
|
||||
if (pid > 0) {
|
||||
is_started = true;
|
||||
srs_trace("vfored process, pid=%d, bin=%s", pid, bin.c_str());
|
||||
srs_trace("fored process, pid=%d, bin=%s, stdout=%s, stderr=%s, argv=%s",
|
||||
pid, bin.c_str(), stdout_file.c_str(), stdout_file.c_str(), actual_cli.c_str());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -238,7 +276,7 @@ int SrsProcess::cycle()
|
|||
return ret;
|
||||
}
|
||||
|
||||
srs_trace("process pid=%d terminate, restart it.", pid);
|
||||
srs_trace("process pid=%d terminate, please restart it.", pid);
|
||||
is_started = false;
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -61,10 +61,15 @@ private:
|
|||
std::vector<std::string> params;
|
||||
// the cli to fork process.
|
||||
std::string cli;
|
||||
std::string actual_cli;
|
||||
public:
|
||||
SrsProcess();
|
||||
virtual ~SrsProcess();
|
||||
public:
|
||||
/**
|
||||
* get pid of process.
|
||||
*/
|
||||
virtual int get_pid();
|
||||
/**
|
||||
* whether process is already started.
|
||||
*/
|
||||
|
@ -73,6 +78,7 @@ public:
|
|||
* initialize the process with binary and argv.
|
||||
* @param binary the binary path to exec.
|
||||
* @param argv the argv for binary path, the argv[0] generally is the binary.
|
||||
* @remark the argv[0] must be the binary.
|
||||
*/
|
||||
virtual int initialize(std::string binary, std::vector<std::string> argv);
|
||||
public:
|
||||
|
|
|
@ -959,6 +959,7 @@ int SrsServer::do_cycle()
|
|||
#endif
|
||||
|
||||
// the deamon thread, update the time cache
|
||||
// TODO: FIXME: use SrsHourGlass.
|
||||
while (true) {
|
||||
if (handler && (ret = handler->on_cycle()) != ERROR_SUCCESS) {
|
||||
srs_error("cycle handle failed. ret=%d", ret);
|
||||
|
|
|
@ -1270,6 +1270,66 @@ vector<string>& srs_get_local_ipv4_ips()
|
|||
return _srs_system_ipv4_ips;
|
||||
}
|
||||
|
||||
std::string _public_internet_address;
|
||||
|
||||
string srs_get_public_internet_address()
|
||||
{
|
||||
if (!_public_internet_address.empty()) {
|
||||
return _public_internet_address;
|
||||
}
|
||||
|
||||
std::vector<std::string>& ips = srs_get_local_ipv4_ips();
|
||||
|
||||
// find the best match public address.
|
||||
for (int i = 0; i < (int)ips.size(); i++) {
|
||||
std::string ip = ips[i];
|
||||
in_addr_t addr = inet_addr(ip.c_str());
|
||||
u_int32_t addr_h = ntohl(addr);
|
||||
// lo, 127.0.0.0-127.0.0.1
|
||||
if (addr_h >= 0x7f000000 && addr_h <= 0x7f000001) {
|
||||
srs_trace("ignore private address: %s", ip.c_str());
|
||||
continue;
|
||||
}
|
||||
// Class A 10.0.0.0-10.255.255.255
|
||||
if (addr_h >= 0x0a000000 && addr_h <= 0x0affffff) {
|
||||
srs_trace("ignore private address: %s", ip.c_str());
|
||||
continue;
|
||||
}
|
||||
// Class B 172.16.0.0-172.31.255.255
|
||||
if (addr_h >= 0xac100000 && addr_h <= 0xac1fffff) {
|
||||
srs_trace("ignore private address: %s", ip.c_str());
|
||||
continue;
|
||||
}
|
||||
// Class C 192.168.0.0-192.168.255.255
|
||||
if (addr_h >= 0xc0a80000 && addr_h <= 0xc0a8ffff) {
|
||||
srs_trace("ignore private address: %s", ip.c_str());
|
||||
continue;
|
||||
}
|
||||
srs_warn("use public address as ip: %s", ip.c_str());
|
||||
|
||||
_public_internet_address = ip;
|
||||
return ip;
|
||||
}
|
||||
|
||||
// no public address, use private address.
|
||||
for (int i = 0; i < (int)ips.size(); i++) {
|
||||
std::string ip = ips[i];
|
||||
in_addr_t addr = inet_addr(ip.c_str());
|
||||
u_int32_t addr_h = ntohl(addr);
|
||||
// lo, 127.0.0.0-127.0.0.1
|
||||
if (addr_h >= 0x7f000000 && addr_h <= 0x7f000001) {
|
||||
srs_trace("ignore private address: %s", ip.c_str());
|
||||
continue;
|
||||
}
|
||||
srs_warn("use private address as ip: %s", ip.c_str());
|
||||
|
||||
_public_internet_address = ip;
|
||||
return ip;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
string srs_get_local_ip(int fd)
|
||||
{
|
||||
std::string ip;
|
||||
|
@ -1347,6 +1407,11 @@ bool srs_string_is_http(string url)
|
|||
return srs_string_starts_with(url, "http://", "https://");
|
||||
}
|
||||
|
||||
bool srs_string_is_rtmp(string url)
|
||||
{
|
||||
return srs_string_starts_with(url, "rtmp://");
|
||||
}
|
||||
|
||||
bool srs_is_digit_number(const string& str)
|
||||
{
|
||||
if (str.empty()) {
|
||||
|
|
|
@ -664,6 +664,7 @@ extern std::string srs_get_peer_ip(int fd);
|
|||
|
||||
// whether the url is starts with http:// or https://
|
||||
extern bool srs_string_is_http(std::string url);
|
||||
extern bool srs_string_is_rtmp(std::string url);
|
||||
|
||||
// whether string is digit number
|
||||
// is_digit("1234567890") === true
|
||||
|
|
|
@ -45,12 +45,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
|
||||
// debug info.
|
||||
#define RTMP_SIG_SRS_ROLE "cluster"
|
||||
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)"
|
||||
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Stream Media Server)"
|
||||
#define RTMP_SIG_SRS_URL_SHORT "github.com/ossrs/srs"
|
||||
#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
|
||||
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
|
||||
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2016 SRS(ossrs)"
|
||||
#define RTMP_SIG_SRS_PRIMARY "SRS/"VERSION_STABLE_BRANCH
|
||||
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2016 "RTMP_SIG_SRS_KEY"("RTMP_SIG_SRS_AUTHROS")"
|
||||
#define RTMP_SIG_SRS_PRIMARY RTMP_SIG_SRS_KEY"/"VERSION_STABLE_BRANCH
|
||||
#define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt"
|
||||
#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY"("RTMP_SIG_SRS_VERSION")"
|
||||
#define RTMP_SIG_SRS_RELEASE RTMP_SIG_SRS_URL"/tree/"VERSION_STABLE_BRANCH".0release"
|
||||
|
|
|
@ -188,5 +188,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#undef SRS_PERF_FAST_FLV_ENCODER
|
||||
#define SRS_PERF_FAST_FLV_ENCODER
|
||||
|
||||
/**
|
||||
* whether ensure glibc memory check.
|
||||
*/
|
||||
#undef SRS_PERF_GLIBC_MEMORY_CHECK
|
||||
#define SRS_PERF_GLIBC_MEMORY_CHECK
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -103,6 +103,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED 1062
|
||||
#define ERROR_SYSTEM_CONFIG_RAW_PARAMS 1063
|
||||
#define ERROR_SYSTEM_FILE_NOT_EXISTS 1064
|
||||
#define ERROR_SYSTEM_HOURGLASS_RESOLUTION 1065
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// RTMP protocol error.
|
||||
|
|
|
@ -467,6 +467,8 @@ int srs_librtmp_context_parse_uri(Context* context)
|
|||
std::string schema;
|
||||
|
||||
srs_parse_rtmp_url(context->url, context->tcUrl, context->stream);
|
||||
|
||||
// when connect, we only need to parse the tcUrl
|
||||
srs_discovery_tc_url(context->tcUrl,
|
||||
schema, context->host, context->vhost, context->app, context->port,
|
||||
context->param);
|
||||
|
@ -688,11 +690,11 @@ int srs_rtmp_connect_app(srs_rtmp_t rtmp)
|
|||
|
||||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
|
||||
string tcUrl = srs_generate_tc_url(
|
||||
context->ip, context->vhost, context->app, context->port,
|
||||
context->param
|
||||
);
|
||||
context->ip, context->vhost, context->app, context->port,
|
||||
context->param
|
||||
);
|
||||
|
||||
if ((ret = context->rtmp->connect_app(
|
||||
context->app, tcUrl, context->req, true)) != ERROR_SUCCESS)
|
||||
|
@ -742,6 +744,38 @@ int srs_rtmp_connect_app2(srs_rtmp_t rtmp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srs_rtmp_connect_app3(srs_rtmp_t rtmp, enum srs_url_schema sus)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
srs_assert(rtmp != NULL);
|
||||
Context* context = (Context*)rtmp;
|
||||
|
||||
string tcUrl;
|
||||
switch(sus) {
|
||||
case srs_url_schema_normal:
|
||||
tcUrl=srs_generate_normal_tc_url(context->ip, context->vhost, context->app, context->port);
|
||||
break;
|
||||
case srs_url_schema_via:
|
||||
tcUrl=srs_generate_via_tc_url(context->ip, context->vhost, context->app, context->port);
|
||||
break;
|
||||
case srs_url_schema_vis:
|
||||
case srs_url_schema_vis2:
|
||||
tcUrl=srs_generate_vis_tc_url(context->ip, context->vhost, context->app, context->port);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((ret = context->rtmp->connect_app(
|
||||
context->app, tcUrl, context->req, true)) != ERROR_SUCCESS)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int srs_rtmp_play_stream(srs_rtmp_t rtmp)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
|
|
@ -68,6 +68,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
extern "C"{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* the schema of url, now bravo support 4 kinds of url:
|
||||
* srs_url_schema_normal: rtmp://vhost:port/app/stream
|
||||
* srs_url_schema_via : rtmp://ip:port/vhost/app/stream
|
||||
* srs_url_schema_vis : rtmp://ip:port/app/stream?vhost=xxx
|
||||
* srs_url_schema_vis2 : rtmp://ip:port/app/stream?domain=xxx
|
||||
*/
|
||||
enum srs_url_schema{
|
||||
srs_url_schema_normal = 0,
|
||||
srs_url_schema_via,
|
||||
srs_url_schema_vis,
|
||||
srs_url_schema_vis2
|
||||
};
|
||||
|
||||
// typedefs
|
||||
typedef int srs_bool;
|
||||
|
||||
|
@ -187,6 +201,16 @@ extern int srs_rtmp_connect_app2(srs_rtmp_t rtmp,
|
|||
char srs_version[32], int* srs_id, int* srs_pid
|
||||
);
|
||||
|
||||
/**
|
||||
* connect to rtmp vhost/app
|
||||
* category: publish/play
|
||||
* previous: handshake
|
||||
* next: publish or play
|
||||
*
|
||||
* @return 0, success; otherswise, failed.
|
||||
*/
|
||||
extern int srs_rtmp_connect_app3(srs_rtmp_t rtmp, enum srs_url_schema sus);
|
||||
|
||||
/**
|
||||
* play a live/vod stream.
|
||||
* category: play
|
||||
|
|
|
@ -261,7 +261,17 @@ int main(int argc, char** argv)
|
|||
if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// change the work dir and set cwd.
|
||||
string cwd = _srs_config->get_work_dir();
|
||||
if (!cwd.empty() && (ret = chdir(cwd.c_str())) != ERROR_SUCCESS) {
|
||||
srs_error("change cwd to %s failed. ret=%d", cwd.c_str(), ret);
|
||||
return ret;
|
||||
}
|
||||
if ((ret = _srs_config->initialize_cwd()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// config parsed, initialize log.
|
||||
if ((ret = _srs_log->initialize()) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -277,6 +287,24 @@ int main(int argc, char** argv)
|
|||
#ifdef SRS_AUTO_EMBEDED_TOOL_CHAIN
|
||||
srs_trace("crossbuild tool chain: "SRS_AUTO_EMBEDED_TOOL_CHAIN);
|
||||
#endif
|
||||
srs_trace("cwd=%s, work_dir=%s", _srs_config->cwd().c_str(), cwd.c_str());
|
||||
|
||||
#ifdef SRS_PERF_GLIBC_MEMORY_CHECK
|
||||
// ensure glibc write error to stderr.
|
||||
setenv("LIBC_FATAL_STDERR_", "1", 1);
|
||||
// ensure glibc to do alloc check.
|
||||
setenv("MALLOC_CHECK_", "1", 1);
|
||||
srs_trace("env MALLOC_CHECK_=1 LIBC_FATAL_STDERR_=1");
|
||||
#endif
|
||||
|
||||
#ifdef SRS_AUTO_GPERF_MD
|
||||
char* TCMALLOC_PAGE_FENCE = getenv("TCMALLOC_PAGE_FENCE");
|
||||
if (!TCMALLOC_PAGE_FENCE || strcmp(TCMALLOC_PAGE_FENCE, "1")) {
|
||||
srs_trace("gmd enabled without env TCMALLOC_PAGE_FENCE=1");
|
||||
} else {
|
||||
srs_trace("env TCMALLOC_PAGE_FENCE=1");
|
||||
}
|
||||
#endif
|
||||
|
||||
// we check the config when the log initialized.
|
||||
if ((ret = _srs_config->check_config()) != ERROR_SUCCESS) {
|
||||
|
|
|
@ -149,11 +149,28 @@ string srs_generate_tc_url(string ip, string vhost, string app, int port, string
|
|||
|
||||
tcUrl += "/";
|
||||
tcUrl += app;
|
||||
tcUrl += param;
|
||||
if (!param.empty()) {
|
||||
tcUrl += "?" + param;
|
||||
}
|
||||
|
||||
return tcUrl;
|
||||
}
|
||||
|
||||
string srs_generate_normal_tc_url(string ip, string vhost, string app, int port)
|
||||
{
|
||||
return "rtmp://" + vhost + ":" + srs_int2str(port) + "/" + app;
|
||||
}
|
||||
|
||||
string srs_generate_via_tc_url(string ip, string vhost, string app, int port)
|
||||
{
|
||||
return "rtmp://" + ip + ":" + srs_int2str(port) + "/" + vhost + "/" + app;
|
||||
}
|
||||
|
||||
string srs_generate_vis_tc_url(string ip, string vhost, string app, int port)
|
||||
{
|
||||
return "rtmp://" + ip + ":" + srs_int2str(port) + "/" + app;
|
||||
}
|
||||
|
||||
/**
|
||||
* compare the memory in bytes.
|
||||
*/
|
||||
|
@ -179,18 +196,19 @@ bool srs_bytes_equals(void* pa, void* pb, int size)
|
|||
return true;
|
||||
}
|
||||
|
||||
int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg)
|
||||
template<typename T>
|
||||
int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, T** ppmsg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
*ppmsg = NULL;
|
||||
SrsSharedPtrMessage* msg = NULL;
|
||||
T* msg = NULL;
|
||||
|
||||
if (type == SrsCodecFlvTagAudio) {
|
||||
SrsMessageHeader header;
|
||||
header.initialize_audio(size, timestamp, stream_id);
|
||||
|
||||
msg = new SrsSharedPtrMessage();
|
||||
msg = new T();
|
||||
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
|
@ -199,7 +217,7 @@ int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size,
|
|||
SrsMessageHeader header;
|
||||
header.initialize_video(size, timestamp, stream_id);
|
||||
|
||||
msg = new SrsSharedPtrMessage();
|
||||
msg = new T();
|
||||
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
|
@ -208,7 +226,7 @@ int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size,
|
|||
SrsMessageHeader header;
|
||||
header.initialize_amf0_script(size, stream_id);
|
||||
|
||||
msg = new SrsSharedPtrMessage();
|
||||
msg = new T();
|
||||
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
|
@ -237,6 +255,19 @@ int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, in
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsCommonMessage** ppmsg)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
// only when failed, we must free the data.
|
||||
if ((ret = srs_do_rtmp_create_msg(type, timestamp, data, size, stream_id, ppmsg)) != ERROR_SUCCESS) {
|
||||
srs_freepa(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
string srs_generate_stream_url(string vhost, string app, string stream)
|
||||
{
|
||||
std::string url = "";
|
||||
|
@ -334,3 +365,20 @@ string srs_join_vector_string(vector<string>& vs, string separator)
|
|||
return str;
|
||||
}
|
||||
|
||||
bool srs_is_ipv4(string domain)
|
||||
{
|
||||
for (int i = 0; i < (int)domain.length(); i++) {
|
||||
char ch = domain.at(i);
|
||||
if (ch == '.') {
|
||||
continue;
|
||||
}
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,11 +36,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <srs_kernel_consts.hpp>
|
||||
|
||||
class SrsMessageHeader;
|
||||
class SrsSharedPtrMessage;
|
||||
class SrsCommonMessage;
|
||||
class ISrsProtocolReaderWriter;
|
||||
|
||||
/**
|
||||
|
@ -62,6 +64,10 @@ extern void srs_discovery_tc_url(
|
|||
std::string& app, int& port, std::string& param
|
||||
);
|
||||
|
||||
// parse query string to map(k,v).
|
||||
// must format as key=value&...&keyN=valueN
|
||||
extern void srs_parse_query_string(std::string q, std::map<std::string, std::string>& query);
|
||||
|
||||
/**
|
||||
* generate ramdom data for handshake.
|
||||
*/
|
||||
|
@ -79,6 +85,24 @@ extern std::string srs_generate_tc_url(
|
|||
std::string param
|
||||
);
|
||||
|
||||
/**
|
||||
* srs_detect_tools generate the normal tcUrl
|
||||
*/
|
||||
extern std::string srs_generate_normal_tc_url(
|
||||
std::string ip, std::string vhost, std::string app, int port);
|
||||
|
||||
/**
|
||||
* srs_detect_tools generate the normal tcUrl
|
||||
*/
|
||||
extern std::string srs_generate_via_tc_url(
|
||||
std::string ip, std::string vhost, std::string app, int port);
|
||||
|
||||
/**
|
||||
* srs_detect_tools generate the vis/vis2 tcUrl
|
||||
*/
|
||||
extern std::string srs_generate_vis_tc_url(
|
||||
std::string ip, std::string vhost, std::string app, int port);
|
||||
|
||||
/**
|
||||
* compare the memory in bytes.
|
||||
* @return true if completely equal; otherwise, false.
|
||||
|
@ -94,6 +118,10 @@ extern int srs_rtmp_create_msg(
|
|||
char type, u_int32_t timestamp, char* data, int size, int stream_id,
|
||||
SrsSharedPtrMessage** ppmsg
|
||||
);
|
||||
extern int srs_rtmp_create_msg(
|
||||
char type, u_int32_t timestamp, char* data, int size, int stream_id,
|
||||
SrsCommonMessage** ppmsg
|
||||
);
|
||||
|
||||
// get the stream identify, vhost/app/stream.
|
||||
extern std::string srs_generate_stream_url(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue