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