mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
convert to unix format
This commit is contained in:
parent
db405b7e0e
commit
5d69236bff
10 changed files with 3516 additions and 3516 deletions
1048
trunk/src/core/srs_core_client.cpp
Executable file → Normal file
1048
trunk/src/core/srs_core_client.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load diff
1664
trunk/src/core/srs_core_config.cpp
Executable file → Normal file
1664
trunk/src/core/srs_core_config.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load diff
288
trunk/src/core/srs_core_config.hpp
Executable file → Normal file
288
trunk/src/core/srs_core_config.hpp
Executable file → Normal file
|
@ -1,145 +1,145 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRS_CORE_CONIFG_HPP
|
#ifndef SRS_CORE_CONIFG_HPP
|
||||||
#define SRS_CORE_CONIFG_HPP
|
#define SRS_CORE_CONIFG_HPP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <srs_core_config.hpp>
|
#include <srs_core_config.hpp>
|
||||||
*/
|
*/
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <srs_core_reload.hpp>
|
#include <srs_core_reload.hpp>
|
||||||
|
|
||||||
// default vhost for rtmp
|
// default vhost for rtmp
|
||||||
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
|
#define RTMP_VHOST_DEFAULT "__defaultVhost__"
|
||||||
|
|
||||||
#define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html"
|
#define SRS_CONF_DEFAULT_HLS_PATH "./objs/nginx/html"
|
||||||
#define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
|
#define SRS_CONF_DEFAULT_HLS_FRAGMENT 10
|
||||||
#define SRS_CONF_DEFAULT_HLS_WINDOW 60
|
#define SRS_CONF_DEFAULT_HLS_WINDOW 60
|
||||||
// in ms, for HLS aac sync time.
|
// in ms, for HLS aac sync time.
|
||||||
#define SRS_CONF_DEFAULT_AAC_SYNC 100
|
#define SRS_CONF_DEFAULT_AAC_SYNC 100
|
||||||
// in ms, for HLS aac flush the audio
|
// in ms, for HLS aac flush the audio
|
||||||
#define SRS_CONF_DEFAULT_AAC_DELAY 300
|
#define SRS_CONF_DEFAULT_AAC_DELAY 300
|
||||||
|
|
||||||
class SrsFileBuffer
|
class SrsFileBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int fd;
|
int fd;
|
||||||
int line;
|
int line;
|
||||||
// start of buffer.
|
// start of buffer.
|
||||||
char* start;
|
char* start;
|
||||||
// end of buffer.
|
// end of buffer.
|
||||||
char* end;
|
char* end;
|
||||||
// current consumed position.
|
// current consumed position.
|
||||||
char* pos;
|
char* pos;
|
||||||
// last available position.
|
// last available position.
|
||||||
char* last;
|
char* last;
|
||||||
|
|
||||||
SrsFileBuffer();
|
SrsFileBuffer();
|
||||||
virtual ~SrsFileBuffer();
|
virtual ~SrsFileBuffer();
|
||||||
virtual int open(const char* filename);
|
virtual int open(const char* filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsConfDirective
|
class SrsConfDirective
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int conf_line;
|
int conf_line;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
std::vector<SrsConfDirective*> directives;
|
std::vector<SrsConfDirective*> directives;
|
||||||
public:
|
public:
|
||||||
SrsConfDirective();
|
SrsConfDirective();
|
||||||
virtual ~SrsConfDirective();
|
virtual ~SrsConfDirective();
|
||||||
std::string arg0();
|
std::string arg0();
|
||||||
std::string arg1();
|
std::string arg1();
|
||||||
std::string arg2();
|
std::string arg2();
|
||||||
SrsConfDirective* at(int index);
|
SrsConfDirective* at(int index);
|
||||||
SrsConfDirective* get(std::string _name);
|
SrsConfDirective* get(std::string _name);
|
||||||
public:
|
public:
|
||||||
virtual int parse(const char* filename);
|
virtual int parse(const char* filename);
|
||||||
public:
|
public:
|
||||||
enum SrsDirectiveType{parse_file, parse_block};
|
enum SrsDirectiveType{parse_file, parse_block};
|
||||||
virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
|
virtual int parse_conf(SrsFileBuffer* buffer, SrsDirectiveType type);
|
||||||
virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
|
virtual int read_token(SrsFileBuffer* buffer, std::vector<std::string>& args);
|
||||||
virtual int refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s_quoted, int startline, char*& pstart);
|
virtual int refill_buffer(SrsFileBuffer* buffer, bool d_quoted, bool s_quoted, int startline, char*& pstart);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the config parser.
|
* the config parser.
|
||||||
* for the config supports reload, so never keep the reference cross st-thread,
|
* for the config supports reload, so never keep the reference cross st-thread,
|
||||||
* that is, never save the SrsConfDirective* get by any api of config,
|
* that is, never save the SrsConfDirective* get by any api of config,
|
||||||
* for it maybe free in the reload st-thread cycle.
|
* for it maybe free in the reload st-thread cycle.
|
||||||
* you can keep it before st-thread switch, or simply never keep it.
|
* you can keep it before st-thread switch, or simply never keep it.
|
||||||
*/
|
*/
|
||||||
class SrsConfig
|
class SrsConfig
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool show_help;
|
bool show_help;
|
||||||
bool show_version;
|
bool show_version;
|
||||||
std::string config_file;
|
std::string config_file;
|
||||||
SrsConfDirective* root;
|
SrsConfDirective* root;
|
||||||
std::vector<SrsReloadHandler*> subscribes;
|
std::vector<SrsReloadHandler*> subscribes;
|
||||||
public:
|
public:
|
||||||
SrsConfig();
|
SrsConfig();
|
||||||
virtual ~SrsConfig();
|
virtual ~SrsConfig();
|
||||||
public:
|
public:
|
||||||
virtual int reload();
|
virtual int reload();
|
||||||
virtual void subscribe(SrsReloadHandler* handler);
|
virtual void subscribe(SrsReloadHandler* handler);
|
||||||
virtual void unsubscribe(SrsReloadHandler* handler);
|
virtual void unsubscribe(SrsReloadHandler* handler);
|
||||||
public:
|
public:
|
||||||
virtual int parse_options(int argc, char** argv);
|
virtual int parse_options(int argc, char** argv);
|
||||||
virtual SrsConfDirective* get_vhost(std::string vhost);
|
virtual SrsConfDirective* get_vhost(std::string vhost);
|
||||||
virtual SrsConfDirective* get_vhost_enabled(std::string vhost);
|
virtual SrsConfDirective* get_vhost_enabled(std::string vhost);
|
||||||
virtual SrsConfDirective* get_gop_cache(std::string vhost);
|
virtual SrsConfDirective* get_gop_cache(std::string vhost);
|
||||||
virtual SrsConfDirective* get_forward(std::string vhost);
|
virtual SrsConfDirective* get_forward(std::string vhost);
|
||||||
virtual SrsConfDirective* get_hls(std::string vhost);
|
virtual SrsConfDirective* get_hls(std::string vhost);
|
||||||
virtual SrsConfDirective* get_hls_path(std::string vhost);
|
virtual SrsConfDirective* get_hls_path(std::string vhost);
|
||||||
virtual SrsConfDirective* get_hls_fragment(std::string vhost);
|
virtual SrsConfDirective* get_hls_fragment(std::string vhost);
|
||||||
virtual SrsConfDirective* get_hls_window(std::string vhost);
|
virtual SrsConfDirective* get_hls_window(std::string vhost);
|
||||||
virtual SrsConfDirective* get_refer(std::string vhost);
|
virtual SrsConfDirective* get_refer(std::string vhost);
|
||||||
virtual SrsConfDirective* get_refer_play(std::string vhost);
|
virtual SrsConfDirective* get_refer_play(std::string vhost);
|
||||||
virtual SrsConfDirective* get_refer_publish(std::string vhost);
|
virtual SrsConfDirective* get_refer_publish(std::string vhost);
|
||||||
virtual SrsConfDirective* get_listen();
|
virtual SrsConfDirective* get_listen();
|
||||||
virtual SrsConfDirective* get_chunk_size();
|
virtual SrsConfDirective* get_chunk_size();
|
||||||
virtual SrsConfDirective* get_pithy_print_publish();
|
virtual SrsConfDirective* get_pithy_print_publish();
|
||||||
virtual SrsConfDirective* get_pithy_print_forwarder();
|
virtual SrsConfDirective* get_pithy_print_forwarder();
|
||||||
virtual SrsConfDirective* get_pithy_print_play();
|
virtual SrsConfDirective* get_pithy_print_play();
|
||||||
private:
|
private:
|
||||||
virtual int parse_file(const char* filename);
|
virtual int parse_file(const char* filename);
|
||||||
virtual int parse_argv(int& i, char** argv);
|
virtual int parse_argv(int& i, char** argv);
|
||||||
virtual void print_help(char** argv);
|
virtual void print_help(char** argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deep compare directive.
|
* deep compare directive.
|
||||||
*/
|
*/
|
||||||
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b);
|
bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b);
|
||||||
|
|
||||||
// global config
|
// global config
|
||||||
extern SrsConfig* config;
|
extern SrsConfig* config;
|
||||||
|
|
||||||
#endif
|
#endif
|
700
trunk/src/core/srs_core_forward.cpp
Executable file → Normal file
700
trunk/src/core/srs_core_forward.cpp
Executable file → Normal file
|
@ -1,350 +1,350 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <srs_core_forward.hpp>
|
#include <srs_core_forward.hpp>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
|
||||||
#include <srs_core_error.hpp>
|
#include <srs_core_error.hpp>
|
||||||
#include <srs_core_rtmp.hpp>
|
#include <srs_core_rtmp.hpp>
|
||||||
#include <srs_core_log.hpp>
|
#include <srs_core_log.hpp>
|
||||||
#include <srs_core_protocol.hpp>
|
#include <srs_core_protocol.hpp>
|
||||||
#include <srs_core_pithy_print.hpp>
|
#include <srs_core_pithy_print.hpp>
|
||||||
|
|
||||||
#define SRS_PULSE_TIMEOUT_MS 100
|
#define SRS_PULSE_TIMEOUT_MS 100
|
||||||
#define SRS_FORWARDER_SLEEP_MS 2000
|
#define SRS_FORWARDER_SLEEP_MS 2000
|
||||||
#define SRS_SEND_TIMEOUT_US 3000000L
|
#define SRS_SEND_TIMEOUT_US 3000000L
|
||||||
#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US
|
#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US
|
||||||
|
|
||||||
SrsForwarder::SrsForwarder()
|
SrsForwarder::SrsForwarder()
|
||||||
{
|
{
|
||||||
client = NULL;
|
client = NULL;
|
||||||
tid = NULL;
|
tid = NULL;
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
loop = false;
|
loop = false;
|
||||||
stream_id = 0;
|
stream_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsForwarder::~SrsForwarder()
|
SrsForwarder::~SrsForwarder()
|
||||||
{
|
{
|
||||||
on_unpublish();
|
on_unpublish();
|
||||||
|
|
||||||
std::vector<SrsSharedPtrMessage*>::iterator it;
|
std::vector<SrsSharedPtrMessage*>::iterator it;
|
||||||
for (it = msgs.begin(); it != msgs.end(); ++it) {
|
for (it = msgs.begin(); it != msgs.end(); ++it) {
|
||||||
SrsSharedPtrMessage* msg = *it;
|
SrsSharedPtrMessage* msg = *it;
|
||||||
srs_freep(msg);
|
srs_freep(msg);
|
||||||
}
|
}
|
||||||
msgs.clear();
|
msgs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::on_publish(std::string vhost, std::string _app, std::string stream, std::string forward_server)
|
int SrsForwarder::on_publish(std::string vhost, std::string _app, std::string stream, std::string forward_server)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
app = _app;
|
app = _app;
|
||||||
|
|
||||||
tc_url = "rtmp://";
|
tc_url = "rtmp://";
|
||||||
tc_url += vhost;
|
tc_url += vhost;
|
||||||
tc_url += "/";
|
tc_url += "/";
|
||||||
tc_url += app;
|
tc_url += app;
|
||||||
|
|
||||||
stream_name = stream;
|
stream_name = stream;
|
||||||
server = forward_server;
|
server = forward_server;
|
||||||
port = 1935;
|
port = 1935;
|
||||||
|
|
||||||
size_t pos = forward_server.find(":");
|
size_t pos = forward_server.find(":");
|
||||||
if (pos != std::string::npos) {
|
if (pos != std::string::npos) {
|
||||||
port = ::atoi(forward_server.substr(pos + 1).c_str());
|
port = ::atoi(forward_server.substr(pos + 1).c_str());
|
||||||
server = forward_server.substr(0, pos);
|
server = forward_server.substr(0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = open_socket()) != ERROR_SUCCESS) {
|
if ((ret = open_socket()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_assert(!tid);
|
srs_assert(!tid);
|
||||||
if((tid = st_thread_create(forward_thread, this, 1, 0)) == NULL){
|
if((tid = st_thread_create(forward_thread, this, 1, 0)) == NULL){
|
||||||
ret = ERROR_ST_CREATE_FORWARD_THREAD;
|
ret = ERROR_ST_CREATE_FORWARD_THREAD;
|
||||||
srs_error("st_thread_create failed. ret=%d", ret);
|
srs_error("st_thread_create failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsForwarder::on_unpublish()
|
void SrsForwarder::on_unpublish()
|
||||||
{
|
{
|
||||||
if (tid) {
|
if (tid) {
|
||||||
loop = false;
|
loop = false;
|
||||||
st_thread_interrupt(tid);
|
st_thread_interrupt(tid);
|
||||||
st_thread_join(tid, NULL);
|
st_thread_join(tid, NULL);
|
||||||
tid = NULL;
|
tid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stfd) {
|
if (stfd) {
|
||||||
int fd = st_netfd_fileno(stfd);
|
int fd = st_netfd_fileno(stfd);
|
||||||
st_netfd_close(stfd);
|
st_netfd_close(stfd);
|
||||||
stfd = NULL;
|
stfd = NULL;
|
||||||
|
|
||||||
// st does not close it sometimes,
|
// st does not close it sometimes,
|
||||||
// close it manually.
|
// close it manually.
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_freep(client);
|
srs_freep(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata)
|
int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
msgs.push_back(metadata);
|
msgs.push_back(metadata);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::on_audio(SrsSharedPtrMessage* msg)
|
int SrsForwarder::on_audio(SrsSharedPtrMessage* msg)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
msgs.push_back(msg);
|
msgs.push_back(msg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::on_video(SrsSharedPtrMessage* msg)
|
int SrsForwarder::on_video(SrsSharedPtrMessage* msg)
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
msgs.push_back(msg);
|
msgs.push_back(msg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::open_socket()
|
int SrsForwarder::open_socket()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
srs_trace("forward stream=%s, tcUrl=%s to server=%s, port=%d",
|
srs_trace("forward stream=%s, tcUrl=%s to server=%s, port=%d",
|
||||||
stream_name.c_str(), tc_url.c_str(), server.c_str(), port);
|
stream_name.c_str(), tc_url.c_str(), server.c_str(), port);
|
||||||
|
|
||||||
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
int sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if(sock == -1){
|
if(sock == -1){
|
||||||
ret = ERROR_SOCKET_CREATE;
|
ret = ERROR_SOCKET_CREATE;
|
||||||
srs_error("create socket error. ret=%d", ret);
|
srs_error("create socket error. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
stfd = st_netfd_open_socket(sock);
|
stfd = st_netfd_open_socket(sock);
|
||||||
if(stfd == NULL){
|
if(stfd == NULL){
|
||||||
ret = ERROR_ST_OPEN_SOCKET;
|
ret = ERROR_ST_OPEN_SOCKET;
|
||||||
srs_error("st_netfd_open_socket failed. ret=%d", ret);
|
srs_error("st_netfd_open_socket failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_freep(client);
|
srs_freep(client);
|
||||||
client = new SrsRtmpClient(stfd);
|
client = new SrsRtmpClient(stfd);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::connect_server()
|
int SrsForwarder::connect_server()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
std::string ip = parse_server(server);
|
std::string ip = parse_server(server);
|
||||||
if (ip.empty()) {
|
if (ip.empty()) {
|
||||||
ret = ERROR_SYSTEM_IP_INVALID;
|
ret = ERROR_SYSTEM_IP_INVALID;
|
||||||
srs_error("dns resolve server error, ip empty. ret=%d", ret);
|
srs_error("dns resolve server error, ip empty. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
addr.sin_addr.s_addr = inet_addr(ip.c_str());
|
addr.sin_addr.s_addr = inet_addr(ip.c_str());
|
||||||
|
|
||||||
if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
|
if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
|
||||||
ret = ERROR_ST_CONNECT;
|
ret = ERROR_ST_CONNECT;
|
||||||
srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), port, ret);
|
srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), port, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_trace("connect to server success. server=%s, ip=%s, port=%d", server.c_str(), ip.c_str(), port);
|
srs_trace("connect to server success. server=%s, ip=%s, port=%d", server.c_str(), ip.c_str(), port);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SrsForwarder::parse_server(std::string host)
|
std::string SrsForwarder::parse_server(std::string host)
|
||||||
{
|
{
|
||||||
if (inet_addr(host.c_str()) != INADDR_NONE) {
|
if (inet_addr(host.c_str()) != INADDR_NONE) {
|
||||||
return host;
|
return host;
|
||||||
}
|
}
|
||||||
|
|
||||||
hostent* answer = gethostbyname(host.c_str());
|
hostent* answer = gethostbyname(host.c_str());
|
||||||
if (answer == NULL) {
|
if (answer == NULL) {
|
||||||
srs_error("dns resolve host %s error.", host.c_str());
|
srs_error("dns resolve host %s error.", host.c_str());
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
char ipv4[16];
|
char ipv4[16];
|
||||||
memset(ipv4, 0, sizeof(ipv4));
|
memset(ipv4, 0, sizeof(ipv4));
|
||||||
for (int i = 0; i < answer->h_length; i++) {
|
for (int i = 0; i < answer->h_length; i++) {
|
||||||
inet_ntop(AF_INET, answer->h_addr_list[i], ipv4, sizeof(ipv4));
|
inet_ntop(AF_INET, answer->h_addr_list[i], ipv4, sizeof(ipv4));
|
||||||
srs_info("dns resolve host %s to %s.", host.c_str(), ipv4);
|
srs_info("dns resolve host %s to %s.", host.c_str(), ipv4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ipv4;
|
return ipv4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::forward_cycle_imp()
|
int SrsForwarder::forward_cycle_imp()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
client->set_recv_timeout(SRS_RECV_TIMEOUT_US);
|
client->set_recv_timeout(SRS_RECV_TIMEOUT_US);
|
||||||
client->set_send_timeout(SRS_SEND_TIMEOUT_US);
|
client->set_send_timeout(SRS_SEND_TIMEOUT_US);
|
||||||
|
|
||||||
if ((ret = connect_server()) != ERROR_SUCCESS) {
|
if ((ret = connect_server()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
srs_assert(client);
|
srs_assert(client);
|
||||||
|
|
||||||
if ((ret = client->handshake()) != ERROR_SUCCESS) {
|
if ((ret = client->handshake()) != ERROR_SUCCESS) {
|
||||||
srs_error("handshake with server failed. ret=%d", ret);
|
srs_error("handshake with server failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((ret = client->connect_app(app, tc_url)) != ERROR_SUCCESS) {
|
if ((ret = client->connect_app(app, tc_url)) != ERROR_SUCCESS) {
|
||||||
srs_error("connect with server failed, tcUrl=%s. ret=%d", tc_url.c_str(), ret);
|
srs_error("connect with server failed, tcUrl=%s. ret=%d", tc_url.c_str(), ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {
|
if ((ret = client->create_stream(stream_id)) != ERROR_SUCCESS) {
|
||||||
srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret);
|
srs_error("connect with server failed, stream_id=%d. ret=%d", stream_id, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
if ((ret = client->publish(stream_name, stream_id)) != ERROR_SUCCESS) {
|
if ((ret = client->publish(stream_name, stream_id)) != ERROR_SUCCESS) {
|
||||||
srs_error("connect with server failed, stream_name=%s, stream_id=%d. ret=%d",
|
srs_error("connect with server failed, stream_name=%s, stream_id=%d. ret=%d",
|
||||||
stream_name.c_str(), stream_id, ret);
|
stream_name.c_str(), stream_id, ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = forward()) != ERROR_SUCCESS) {
|
if ((ret = forward()) != ERROR_SUCCESS) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsForwarder::forward()
|
int SrsForwarder::forward()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);
|
client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000);
|
||||||
|
|
||||||
SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
|
SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
|
||||||
|
|
||||||
while (loop) {
|
while (loop) {
|
||||||
pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);
|
pithy_print.elapse(SRS_PULSE_TIMEOUT_MS);
|
||||||
|
|
||||||
// switch to other st-threads.
|
// switch to other st-threads.
|
||||||
st_usleep(0);
|
st_usleep(0);
|
||||||
|
|
||||||
// read from client.
|
// read from client.
|
||||||
if (true) {
|
if (true) {
|
||||||
SrsCommonMessage* msg = NULL;
|
SrsCommonMessage* msg = NULL;
|
||||||
ret = client->recv_message(&msg);
|
ret = client->recv_message(&msg);
|
||||||
|
|
||||||
srs_verbose("play loop recv message. ret=%d", ret);
|
srs_verbose("play loop recv message. ret=%d", ret);
|
||||||
if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {
|
if (ret != ERROR_SUCCESS && ret != ERROR_SOCKET_TIMEOUT) {
|
||||||
srs_error("recv server control message failed. ret=%d", ret);
|
srs_error("recv server control message failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int count = (int)msgs.size();
|
int count = (int)msgs.size();
|
||||||
|
|
||||||
// reportable
|
// reportable
|
||||||
if (pithy_print.can_print()) {
|
if (pithy_print.can_print()) {
|
||||||
srs_trace("-> clock=%u, time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
|
srs_trace("-> clock=%u, time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
|
||||||
(int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps());
|
(int)(srs_get_system_time_ms()/1000), pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps());
|
||||||
}
|
}
|
||||||
|
|
||||||
// all msgs to forward.
|
// all msgs to forward.
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
SrsSharedPtrMessage* msg = msgs[i];
|
SrsSharedPtrMessage* msg = msgs[i];
|
||||||
msgs[i] = NULL;
|
msgs[i] = NULL;
|
||||||
|
|
||||||
if ((ret = client->send_message(msg)) != ERROR_SUCCESS) {
|
if ((ret = client->send_message(msg)) != ERROR_SUCCESS) {
|
||||||
srs_error("forwarder send message to server failed. ret=%d", ret);
|
srs_error("forwarder send message to server failed. ret=%d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msgs.clear();
|
msgs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsForwarder::forward_cycle()
|
void SrsForwarder::forward_cycle()
|
||||||
{
|
{
|
||||||
int ret = ERROR_SUCCESS;
|
int ret = ERROR_SUCCESS;
|
||||||
|
|
||||||
log_context->generate_id();
|
log_context->generate_id();
|
||||||
srs_trace("forward cycle start");
|
srs_trace("forward cycle start");
|
||||||
|
|
||||||
while (loop) {
|
while (loop) {
|
||||||
if ((ret = forward_cycle_imp()) != ERROR_SUCCESS) {
|
if ((ret = forward_cycle_imp()) != ERROR_SUCCESS) {
|
||||||
srs_warn("forward cycle failed, ignored and retry, ret=%d", ret);
|
srs_warn("forward cycle failed, ignored and retry, ret=%d", ret);
|
||||||
} else {
|
} else {
|
||||||
srs_info("forward cycle success, retry");
|
srs_info("forward cycle success, retry");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!loop) {
|
if (!loop) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
st_usleep(SRS_FORWARDER_SLEEP_MS * 1000);
|
st_usleep(SRS_FORWARDER_SLEEP_MS * 1000);
|
||||||
|
|
||||||
if ((ret = open_socket()) != ERROR_SUCCESS) {
|
if ((ret = open_socket()) != ERROR_SUCCESS) {
|
||||||
srs_warn("forward cycle reopen failed, ignored and retry, ret=%d", ret);
|
srs_warn("forward cycle reopen failed, ignored and retry, ret=%d", ret);
|
||||||
} else {
|
} else {
|
||||||
srs_info("forward cycle reopen success");
|
srs_info("forward cycle reopen success");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
srs_trace("forward cycle finished");
|
srs_trace("forward cycle finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
void* SrsForwarder::forward_thread(void* arg)
|
void* SrsForwarder::forward_thread(void* arg)
|
||||||
{
|
{
|
||||||
SrsForwarder* obj = (SrsForwarder*)arg;
|
SrsForwarder* obj = (SrsForwarder*)arg;
|
||||||
srs_assert(obj != NULL);
|
srs_assert(obj != NULL);
|
||||||
|
|
||||||
obj->loop = true;
|
obj->loop = true;
|
||||||
obj->forward_cycle();
|
obj->forward_cycle();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
160
trunk/src/core/srs_core_forward.hpp
Executable file → Normal file
160
trunk/src/core/srs_core_forward.hpp
Executable file → Normal file
|
@ -1,80 +1,80 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRS_CORE_FORWARD_HPP
|
#ifndef SRS_CORE_FORWARD_HPP
|
||||||
#define SRS_CORE_FORWARD_HPP
|
#define SRS_CORE_FORWARD_HPP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <srs_core_forward.hpp>
|
#include <srs_core_forward.hpp>
|
||||||
*/
|
*/
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <st.h>
|
#include <st.h>
|
||||||
|
|
||||||
class SrsSharedPtrMessage;
|
class SrsSharedPtrMessage;
|
||||||
class SrsOnMetaDataPacket;
|
class SrsOnMetaDataPacket;
|
||||||
class SrsRtmpClient;
|
class SrsRtmpClient;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* forward the stream to other servers.
|
* forward the stream to other servers.
|
||||||
*/
|
*/
|
||||||
class SrsForwarder
|
class SrsForwarder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::string app;
|
std::string app;
|
||||||
std::string tc_url;
|
std::string tc_url;
|
||||||
std::string stream_name;
|
std::string stream_name;
|
||||||
int stream_id;
|
int stream_id;
|
||||||
std::string server;
|
std::string server;
|
||||||
int port;
|
int port;
|
||||||
private:
|
private:
|
||||||
st_netfd_t stfd;
|
st_netfd_t stfd;
|
||||||
st_thread_t tid;
|
st_thread_t tid;
|
||||||
bool loop;
|
bool loop;
|
||||||
private:
|
private:
|
||||||
SrsRtmpClient* client;
|
SrsRtmpClient* client;
|
||||||
std::vector<SrsSharedPtrMessage*> msgs;
|
std::vector<SrsSharedPtrMessage*> msgs;
|
||||||
public:
|
public:
|
||||||
SrsForwarder();
|
SrsForwarder();
|
||||||
virtual ~SrsForwarder();
|
virtual ~SrsForwarder();
|
||||||
public:
|
public:
|
||||||
virtual int on_publish(std::string vhost, std::string app, std::string stream, std::string forward_server);
|
virtual int on_publish(std::string vhost, std::string app, std::string stream, std::string forward_server);
|
||||||
virtual void on_unpublish();
|
virtual void on_unpublish();
|
||||||
virtual int on_meta_data(SrsSharedPtrMessage* metadata);
|
virtual int on_meta_data(SrsSharedPtrMessage* metadata);
|
||||||
virtual int on_audio(SrsSharedPtrMessage* msg);
|
virtual int on_audio(SrsSharedPtrMessage* msg);
|
||||||
virtual int on_video(SrsSharedPtrMessage* msg);
|
virtual int on_video(SrsSharedPtrMessage* msg);
|
||||||
private:
|
private:
|
||||||
virtual int open_socket();
|
virtual int open_socket();
|
||||||
virtual int connect_server();
|
virtual int connect_server();
|
||||||
std::string parse_server(std::string host);
|
std::string parse_server(std::string host);
|
||||||
private:
|
private:
|
||||||
virtual int forward_cycle_imp();
|
virtual int forward_cycle_imp();
|
||||||
virtual int forward();
|
virtual int forward();
|
||||||
virtual void forward_cycle();
|
virtual void forward_cycle();
|
||||||
static void* forward_thread(void* arg);
|
static void* forward_thread(void* arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
346
trunk/src/core/srs_core_pithy_print.cpp
Executable file → Normal file
346
trunk/src/core/srs_core_pithy_print.cpp
Executable file → Normal file
|
@ -1,173 +1,173 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <srs_core_pithy_print.hpp>
|
#include <srs_core_pithy_print.hpp>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <srs_core_log.hpp>
|
#include <srs_core_log.hpp>
|
||||||
#include <srs_core_config.hpp>
|
#include <srs_core_config.hpp>
|
||||||
#include <srs_core_reload.hpp>
|
#include <srs_core_reload.hpp>
|
||||||
#include <srs_core_error.hpp>
|
#include <srs_core_error.hpp>
|
||||||
|
|
||||||
#define SRS_STAGE_DEFAULT_INTERVAL_MS 1200
|
#define SRS_STAGE_DEFAULT_INTERVAL_MS 1200
|
||||||
#define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
|
#define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
|
||||||
#define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
|
#define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
|
||||||
#define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
|
#define SRS_STAGE_FORWARDER_INTERVAL_MS 2000
|
||||||
|
|
||||||
struct SrsStageInfo : public SrsReloadHandler
|
struct SrsStageInfo : public SrsReloadHandler
|
||||||
{
|
{
|
||||||
int stage_id;
|
int stage_id;
|
||||||
int pithy_print_time_ms;
|
int pithy_print_time_ms;
|
||||||
int nb_clients;
|
int nb_clients;
|
||||||
|
|
||||||
SrsStageInfo(int _stage_id)
|
SrsStageInfo(int _stage_id)
|
||||||
{
|
{
|
||||||
stage_id = _stage_id;
|
stage_id = _stage_id;
|
||||||
nb_clients = 0;
|
nb_clients = 0;
|
||||||
|
|
||||||
update_print_time();
|
update_print_time();
|
||||||
|
|
||||||
config->subscribe(this);
|
config->subscribe(this);
|
||||||
}
|
}
|
||||||
virtual ~SrsStageInfo()
|
virtual ~SrsStageInfo()
|
||||||
{
|
{
|
||||||
config->unsubscribe(this);
|
config->unsubscribe(this);
|
||||||
}
|
}
|
||||||
void update_print_time()
|
void update_print_time()
|
||||||
{
|
{
|
||||||
switch (stage_id) {
|
switch (stage_id) {
|
||||||
case SRS_STAGE_PLAY_USER: {
|
case SRS_STAGE_PLAY_USER: {
|
||||||
pithy_print_time_ms = SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
pithy_print_time_ms = SRS_STAGE_PLAY_USER_INTERVAL_MS;
|
||||||
SrsConfDirective* conf = config->get_pithy_print_play();
|
SrsConfDirective* conf = config->get_pithy_print_play();
|
||||||
if (conf && !conf->arg0().empty()) {
|
if (conf && !conf->arg0().empty()) {
|
||||||
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SRS_STAGE_PUBLISH_USER: {
|
case SRS_STAGE_PUBLISH_USER: {
|
||||||
pithy_print_time_ms = SRS_STAGE_PUBLISH_USER_INTERVAL_MS;
|
pithy_print_time_ms = SRS_STAGE_PUBLISH_USER_INTERVAL_MS;
|
||||||
SrsConfDirective* conf = config->get_pithy_print_publish();
|
SrsConfDirective* conf = config->get_pithy_print_publish();
|
||||||
if (conf && !conf->arg0().empty()) {
|
if (conf && !conf->arg0().empty()) {
|
||||||
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SRS_STAGE_FORWARDER: {
|
case SRS_STAGE_FORWARDER: {
|
||||||
pithy_print_time_ms = SRS_STAGE_FORWARDER_INTERVAL_MS;
|
pithy_print_time_ms = SRS_STAGE_FORWARDER_INTERVAL_MS;
|
||||||
SrsConfDirective* conf = config->get_pithy_print_forwarder();
|
SrsConfDirective* conf = config->get_pithy_print_forwarder();
|
||||||
if (conf && !conf->arg0().empty()) {
|
if (conf && !conf->arg0().empty()) {
|
||||||
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
pithy_print_time_ms = ::atoi(conf->arg0().c_str());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
pithy_print_time_ms = SRS_STAGE_DEFAULT_INTERVAL_MS;
|
pithy_print_time_ms = SRS_STAGE_DEFAULT_INTERVAL_MS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
virtual int on_reload_pithy_print()
|
virtual int on_reload_pithy_print()
|
||||||
{
|
{
|
||||||
update_print_time();
|
update_print_time();
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
static std::map<int, SrsStageInfo*> _srs_stages;
|
static std::map<int, SrsStageInfo*> _srs_stages;
|
||||||
|
|
||||||
SrsPithyPrint::SrsPithyPrint(int _stage_id)
|
SrsPithyPrint::SrsPithyPrint(int _stage_id)
|
||||||
{
|
{
|
||||||
stage_id = _stage_id;
|
stage_id = _stage_id;
|
||||||
client_id = enter_stage();
|
client_id = enter_stage();
|
||||||
printed_age = age = 0;
|
printed_age = age = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsPithyPrint::~SrsPithyPrint()
|
SrsPithyPrint::~SrsPithyPrint()
|
||||||
{
|
{
|
||||||
leave_stage();
|
leave_stage();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SrsPithyPrint::enter_stage()
|
int SrsPithyPrint::enter_stage()
|
||||||
{
|
{
|
||||||
SrsStageInfo* stage = NULL;
|
SrsStageInfo* stage = NULL;
|
||||||
|
|
||||||
std::map<int, SrsStageInfo*>::iterator it = _srs_stages.find(stage_id);
|
std::map<int, SrsStageInfo*>::iterator it = _srs_stages.find(stage_id);
|
||||||
if (it == _srs_stages.end()) {
|
if (it == _srs_stages.end()) {
|
||||||
stage = _srs_stages[stage_id] = new SrsStageInfo(stage_id);
|
stage = _srs_stages[stage_id] = new SrsStageInfo(stage_id);
|
||||||
} else {
|
} else {
|
||||||
stage = it->second;
|
stage = it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_assert(stage != NULL);
|
srs_assert(stage != NULL);
|
||||||
client_id = stage->nb_clients++;
|
client_id = stage->nb_clients++;
|
||||||
|
|
||||||
srs_verbose("enter stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
|
srs_verbose("enter stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
|
||||||
stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
|
stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
|
||||||
|
|
||||||
return client_id;
|
return client_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsPithyPrint::leave_stage()
|
void SrsPithyPrint::leave_stage()
|
||||||
{
|
{
|
||||||
SrsStageInfo* stage = _srs_stages[stage_id];
|
SrsStageInfo* stage = _srs_stages[stage_id];
|
||||||
srs_assert(stage != NULL);
|
srs_assert(stage != NULL);
|
||||||
|
|
||||||
stage->nb_clients--;
|
stage->nb_clients--;
|
||||||
|
|
||||||
srs_verbose("leave stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
|
srs_verbose("leave stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d",
|
||||||
stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
|
stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsPithyPrint::elapse(int64_t time_ms)
|
void SrsPithyPrint::elapse(int64_t time_ms)
|
||||||
{
|
{
|
||||||
age += time_ms;
|
age += time_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SrsPithyPrint::can_print()
|
bool SrsPithyPrint::can_print()
|
||||||
{
|
{
|
||||||
SrsStageInfo* stage = _srs_stages[stage_id];
|
SrsStageInfo* stage = _srs_stages[stage_id];
|
||||||
srs_assert(stage != NULL);
|
srs_assert(stage != NULL);
|
||||||
|
|
||||||
int64_t alive_age = age - printed_age;
|
int64_t alive_age = age - printed_age;
|
||||||
int64_t can_print_age = stage->nb_clients * stage->pithy_print_time_ms;
|
int64_t can_print_age = stage->nb_clients * stage->pithy_print_time_ms;
|
||||||
|
|
||||||
bool can_print = alive_age >= can_print_age;
|
bool can_print = alive_age >= can_print_age;
|
||||||
if (can_print) {
|
if (can_print) {
|
||||||
printed_age = age;
|
printed_age = age;
|
||||||
}
|
}
|
||||||
|
|
||||||
return can_print;
|
return can_print;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t SrsPithyPrint::get_age()
|
int64_t SrsPithyPrint::get_age()
|
||||||
{
|
{
|
||||||
return age;
|
return age;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsPithyPrint::set_age(int64_t _age)
|
void SrsPithyPrint::set_age(int64_t _age)
|
||||||
{
|
{
|
||||||
age = _age;
|
age = _age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
166
trunk/src/core/srs_core_pithy_print.hpp
Executable file → Normal file
166
trunk/src/core/srs_core_pithy_print.hpp
Executable file → Normal file
|
@ -1,84 +1,84 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRS_CORE_PITHY_PRINT_HPP
|
#ifndef SRS_CORE_PITHY_PRINT_HPP
|
||||||
#define SRS_CORE_PITHY_PRINT_HPP
|
#define SRS_CORE_PITHY_PRINT_HPP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <srs_core_pithy_print.hpp>
|
#include <srs_core_pithy_print.hpp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
// the pithy stage for all play clients.
|
// the pithy stage for all play clients.
|
||||||
#define SRS_STAGE_PLAY_USER 1
|
#define SRS_STAGE_PLAY_USER 1
|
||||||
// the pithy stage for all publish clients.
|
// the pithy stage for all publish clients.
|
||||||
#define SRS_STAGE_PUBLISH_USER 2
|
#define SRS_STAGE_PUBLISH_USER 2
|
||||||
// the pithy stage for all forward clients.
|
// the pithy stage for all forward clients.
|
||||||
#define SRS_STAGE_FORWARDER 3
|
#define SRS_STAGE_FORWARDER 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the stage is used for a collection of object to do print,
|
* the stage is used for a collection of object to do print,
|
||||||
* the print time in a stage is constant and not changed.
|
* the print time in a stage is constant and not changed.
|
||||||
* for example, stage #1 for all play clients, print time is 3s,
|
* for example, stage #1 for all play clients, print time is 3s,
|
||||||
* if there is 10clients, then all clients should print in 10*3s.
|
* if there is 10clients, then all clients should print in 10*3s.
|
||||||
*/
|
*/
|
||||||
class SrsPithyPrint
|
class SrsPithyPrint
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int client_id;
|
int client_id;
|
||||||
int stage_id;
|
int stage_id;
|
||||||
int64_t age;
|
int64_t age;
|
||||||
int64_t printed_age;
|
int64_t printed_age;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @param _stage_id defined in SRS_STAGE_xxx, eg. SRS_STAGE_PLAY_USER.
|
* @param _stage_id defined in SRS_STAGE_xxx, eg. SRS_STAGE_PLAY_USER.
|
||||||
*/
|
*/
|
||||||
SrsPithyPrint(int _stage_id);
|
SrsPithyPrint(int _stage_id);
|
||||||
virtual ~SrsPithyPrint();
|
virtual ~SrsPithyPrint();
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* enter the specified stage, return the client id.
|
* enter the specified stage, return the client id.
|
||||||
*/
|
*/
|
||||||
virtual int enter_stage();
|
virtual int enter_stage();
|
||||||
/**
|
/**
|
||||||
* leave the specified stage, release the client id.
|
* leave the specified stage, release the client id.
|
||||||
*/
|
*/
|
||||||
virtual void leave_stage();
|
virtual void leave_stage();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* specified client elapse some time.
|
* specified client elapse some time.
|
||||||
*/
|
*/
|
||||||
virtual void elapse(int64_t time_ms);
|
virtual void elapse(int64_t time_ms);
|
||||||
/**
|
/**
|
||||||
* whether current client can print.
|
* whether current client can print.
|
||||||
*/
|
*/
|
||||||
virtual bool can_print();
|
virtual bool can_print();
|
||||||
/**
|
/**
|
||||||
* get the elapsed time in ms.
|
* get the elapsed time in ms.
|
||||||
*/
|
*/
|
||||||
virtual int64_t get_age();
|
virtual int64_t get_age();
|
||||||
virtual void set_age(int64_t _age);
|
virtual void set_age(int64_t _age);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
2232
trunk/src/core/srs_core_rtmp.cpp
Executable file → Normal file
2232
trunk/src/core/srs_core_rtmp.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load diff
428
trunk/src/core/srs_core_rtmp.hpp
Executable file → Normal file
428
trunk/src/core/srs_core_rtmp.hpp
Executable file → Normal file
|
@ -1,215 +1,215 @@
|
||||||
/*
|
/*
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2013 winlin
|
Copyright (c) 2013 winlin
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
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
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
the Software without restriction, including without limitation the rights to
|
the Software without restriction, including without limitation the rights to
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
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,
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
subject to the following conditions:
|
subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
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
|
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
|
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.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SRS_CORE_RTMP_HPP
|
#ifndef SRS_CORE_RTMP_HPP
|
||||||
#define SRS_CORE_RTMP_HPP
|
#define SRS_CORE_RTMP_HPP
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <srs_core_rtmp.hpp>
|
#include <srs_core_rtmp.hpp>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <srs_core.hpp>
|
#include <srs_core.hpp>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <st.h>
|
#include <st.h>
|
||||||
|
|
||||||
class SrsProtocol;
|
class SrsProtocol;
|
||||||
class ISrsMessage;
|
class ISrsMessage;
|
||||||
class SrsCommonMessage;
|
class SrsCommonMessage;
|
||||||
class SrsCreateStreamPacket;
|
class SrsCreateStreamPacket;
|
||||||
class SrsFMLEStartPacket;
|
class SrsFMLEStartPacket;
|
||||||
class SrsPublishPacket;
|
class SrsPublishPacket;
|
||||||
class SrsSharedPtrMessage;
|
class SrsSharedPtrMessage;
|
||||||
class SrsOnMetaDataPacket;
|
class SrsOnMetaDataPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the original request from client.
|
* the original request from client.
|
||||||
*/
|
*/
|
||||||
struct SrsRequest
|
struct SrsRequest
|
||||||
{
|
{
|
||||||
std::string tcUrl;
|
std::string tcUrl;
|
||||||
std::string pageUrl;
|
std::string pageUrl;
|
||||||
std::string swfUrl;
|
std::string swfUrl;
|
||||||
double objectEncoding;
|
double objectEncoding;
|
||||||
|
|
||||||
std::string schema;
|
std::string schema;
|
||||||
std::string vhost;
|
std::string vhost;
|
||||||
std::string port;
|
std::string port;
|
||||||
std::string app;
|
std::string app;
|
||||||
std::string stream;
|
std::string stream;
|
||||||
|
|
||||||
SrsRequest();
|
SrsRequest();
|
||||||
virtual ~SrsRequest();
|
virtual ~SrsRequest();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* disconvery vhost/app from tcUrl.
|
* disconvery vhost/app from tcUrl.
|
||||||
*/
|
*/
|
||||||
virtual int discovery_app();
|
virtual int discovery_app();
|
||||||
virtual std::string get_stream_url();
|
virtual std::string get_stream_url();
|
||||||
virtual void strip();
|
virtual void strip();
|
||||||
private:
|
private:
|
||||||
std::string& trim(std::string& str, std::string chs);
|
std::string& trim(std::string& str, std::string chs);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the response to client.
|
* the response to client.
|
||||||
*/
|
*/
|
||||||
struct SrsResponse
|
struct SrsResponse
|
||||||
{
|
{
|
||||||
int stream_id;
|
int stream_id;
|
||||||
|
|
||||||
SrsResponse();
|
SrsResponse();
|
||||||
virtual ~SrsResponse();
|
virtual ~SrsResponse();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the rtmp client type.
|
* the rtmp client type.
|
||||||
*/
|
*/
|
||||||
enum SrsClientType
|
enum SrsClientType
|
||||||
{
|
{
|
||||||
SrsClientUnknown,
|
SrsClientUnknown,
|
||||||
SrsClientPlay,
|
SrsClientPlay,
|
||||||
SrsClientFMLEPublish,
|
SrsClientFMLEPublish,
|
||||||
SrsClientFlashPublish,
|
SrsClientFlashPublish,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* implements the client role protocol.
|
* implements the client role protocol.
|
||||||
*/
|
*/
|
||||||
class SrsRtmpClient
|
class SrsRtmpClient
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsProtocol* protocol;
|
SrsProtocol* protocol;
|
||||||
st_netfd_t stfd;
|
st_netfd_t stfd;
|
||||||
public:
|
public:
|
||||||
SrsRtmpClient(st_netfd_t _stfd);
|
SrsRtmpClient(st_netfd_t _stfd);
|
||||||
virtual ~SrsRtmpClient();
|
virtual ~SrsRtmpClient();
|
||||||
public:
|
public:
|
||||||
virtual void set_recv_timeout(int64_t timeout_us);
|
virtual void set_recv_timeout(int64_t timeout_us);
|
||||||
virtual void set_send_timeout(int64_t timeout_us);
|
virtual void set_send_timeout(int64_t timeout_us);
|
||||||
virtual int64_t get_recv_bytes();
|
virtual int64_t get_recv_bytes();
|
||||||
virtual int64_t get_send_bytes();
|
virtual int64_t get_send_bytes();
|
||||||
virtual int get_recv_kbps();
|
virtual int get_recv_kbps();
|
||||||
virtual int get_send_kbps();
|
virtual int get_send_kbps();
|
||||||
virtual int recv_message(SrsCommonMessage** pmsg);
|
virtual int recv_message(SrsCommonMessage** pmsg);
|
||||||
virtual int send_message(ISrsMessage* msg);
|
virtual int send_message(ISrsMessage* msg);
|
||||||
public:
|
public:
|
||||||
virtual int handshake();
|
virtual int handshake();
|
||||||
virtual int connect_app(std::string app, std::string tc_url);
|
virtual int connect_app(std::string app, std::string tc_url);
|
||||||
virtual int create_stream(int& stream_id);
|
virtual int create_stream(int& stream_id);
|
||||||
virtual int play(std::string stream, int stream_id);
|
virtual int play(std::string stream, int stream_id);
|
||||||
virtual int publish(std::string stream, int stream_id);
|
virtual int publish(std::string stream, int stream_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the rtmp provices rtmp-command-protocol services,
|
* the rtmp provices rtmp-command-protocol services,
|
||||||
* a high level protocol, media stream oriented services,
|
* a high level protocol, media stream oriented services,
|
||||||
* such as connect to vhost/app, play stream, get audio/video data.
|
* such as connect to vhost/app, play stream, get audio/video data.
|
||||||
*/
|
*/
|
||||||
class SrsRtmp
|
class SrsRtmp
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SrsProtocol* protocol;
|
SrsProtocol* protocol;
|
||||||
st_netfd_t stfd;
|
st_netfd_t stfd;
|
||||||
public:
|
public:
|
||||||
SrsRtmp(st_netfd_t client_stfd);
|
SrsRtmp(st_netfd_t client_stfd);
|
||||||
virtual ~SrsRtmp();
|
virtual ~SrsRtmp();
|
||||||
public:
|
public:
|
||||||
virtual SrsProtocol* get_protocol();
|
virtual SrsProtocol* get_protocol();
|
||||||
virtual void set_recv_timeout(int64_t timeout_us);
|
virtual void set_recv_timeout(int64_t timeout_us);
|
||||||
virtual int64_t get_recv_timeout();
|
virtual int64_t get_recv_timeout();
|
||||||
virtual void set_send_timeout(int64_t timeout_us);
|
virtual void set_send_timeout(int64_t timeout_us);
|
||||||
virtual int64_t get_recv_bytes();
|
virtual int64_t get_recv_bytes();
|
||||||
virtual int64_t get_send_bytes();
|
virtual int64_t get_send_bytes();
|
||||||
virtual int get_recv_kbps();
|
virtual int get_recv_kbps();
|
||||||
virtual int get_send_kbps();
|
virtual int get_send_kbps();
|
||||||
virtual int recv_message(SrsCommonMessage** pmsg);
|
virtual int recv_message(SrsCommonMessage** pmsg);
|
||||||
virtual int send_message(ISrsMessage* msg);
|
virtual int send_message(ISrsMessage* msg);
|
||||||
public:
|
public:
|
||||||
virtual int handshake();
|
virtual int handshake();
|
||||||
virtual int connect_app(SrsRequest* req);
|
virtual int connect_app(SrsRequest* req);
|
||||||
virtual int set_window_ack_size(int ack_size);
|
virtual int set_window_ack_size(int ack_size);
|
||||||
/**
|
/**
|
||||||
* @type: The sender can mark this message hard (0), soft (1), or dynamic (2)
|
* @type: The sender can mark this message hard (0), soft (1), or dynamic (2)
|
||||||
* using the Limit type field.
|
* using the Limit type field.
|
||||||
*/
|
*/
|
||||||
virtual int set_peer_bandwidth(int bandwidth, int type);
|
virtual int set_peer_bandwidth(int bandwidth, int type);
|
||||||
virtual int response_connect_app(SrsRequest* req);
|
virtual int response_connect_app(SrsRequest* req);
|
||||||
virtual int on_bw_done();
|
virtual int on_bw_done();
|
||||||
/**
|
/**
|
||||||
* recv some message to identify the client.
|
* recv some message to identify the client.
|
||||||
* @stream_id, client will createStream to play or publish by flash,
|
* @stream_id, client will createStream to play or publish by flash,
|
||||||
* the stream_id used to response the createStream request.
|
* the stream_id used to response the createStream request.
|
||||||
* @type, output the client type.
|
* @type, output the client type.
|
||||||
*/
|
*/
|
||||||
virtual int identify_client(int stream_id, SrsClientType& type, std::string& stream_name);
|
virtual int identify_client(int stream_id, SrsClientType& type, std::string& stream_name);
|
||||||
/**
|
/**
|
||||||
* set the chunk size when client type identified.
|
* set the chunk size when client type identified.
|
||||||
*/
|
*/
|
||||||
virtual int set_chunk_size(int chunk_size);
|
virtual int set_chunk_size(int chunk_size);
|
||||||
/**
|
/**
|
||||||
* when client type is play, response with packets:
|
* when client type is play, response with packets:
|
||||||
* StreamBegin,
|
* StreamBegin,
|
||||||
* onStatus(NetStream.Play.Reset), onStatus(NetStream.Play.Start).,
|
* onStatus(NetStream.Play.Reset), onStatus(NetStream.Play.Start).,
|
||||||
* |RtmpSampleAccess(false, false),
|
* |RtmpSampleAccess(false, false),
|
||||||
* onStatus(NetStream.Data.Start).
|
* onStatus(NetStream.Data.Start).
|
||||||
*/
|
*/
|
||||||
virtual int start_play(int stream_id);
|
virtual int start_play(int stream_id);
|
||||||
/**
|
/**
|
||||||
* when client(type is play) send pause message,
|
* when client(type is play) send pause message,
|
||||||
* if is_pause, response the following packets:
|
* if is_pause, response the following packets:
|
||||||
* onStatus(NetStream.Pause.Notify)
|
* onStatus(NetStream.Pause.Notify)
|
||||||
* StreamEOF
|
* StreamEOF
|
||||||
* if not is_pause, response the following packets:
|
* if not is_pause, response the following packets:
|
||||||
* onStatus(NetStream.Unpause.Notify)
|
* onStatus(NetStream.Unpause.Notify)
|
||||||
* StreamBegin
|
* StreamBegin
|
||||||
*/
|
*/
|
||||||
virtual int on_play_client_pause(int stream_id, bool is_pause);
|
virtual int on_play_client_pause(int stream_id, bool is_pause);
|
||||||
/**
|
/**
|
||||||
* when client type is publish, response with packets:
|
* when client type is publish, response with packets:
|
||||||
* releaseStream response
|
* releaseStream response
|
||||||
* FCPublish
|
* FCPublish
|
||||||
* FCPublish response
|
* FCPublish response
|
||||||
* createStream response
|
* createStream response
|
||||||
* onFCPublish(NetStream.Publish.Start)
|
* onFCPublish(NetStream.Publish.Start)
|
||||||
* onStatus(NetStream.Publish.Start)
|
* onStatus(NetStream.Publish.Start)
|
||||||
*/
|
*/
|
||||||
virtual int start_fmle_publish(int stream_id);
|
virtual int start_fmle_publish(int stream_id);
|
||||||
/**
|
/**
|
||||||
* process the FMLE unpublish event.
|
* process the FMLE unpublish event.
|
||||||
* @unpublish_tid the unpublish request transaction id.
|
* @unpublish_tid the unpublish request transaction id.
|
||||||
*/
|
*/
|
||||||
virtual int fmle_unpublish(int stream_id, double unpublish_tid);
|
virtual int fmle_unpublish(int stream_id, double unpublish_tid);
|
||||||
/**
|
/**
|
||||||
* when client type is publish, response with packets:
|
* when client type is publish, response with packets:
|
||||||
* onStatus(NetStream.Publish.Start)
|
* onStatus(NetStream.Publish.Start)
|
||||||
*/
|
*/
|
||||||
virtual int start_flash_publish(int stream_id);
|
virtual int start_flash_publish(int stream_id);
|
||||||
private:
|
private:
|
||||||
virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
|
virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsClientType& type, std::string& stream_name);
|
||||||
virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name);
|
virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsClientType& type, std::string& stream_name);
|
||||||
virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name);
|
virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& type, std::string& stream_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
0
trunk/src/srs/srs.upp
Executable file → Normal file
0
trunk/src/srs/srs.upp
Executable file → Normal file
Loading…
Reference in a new issue