1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

Merge branch 3.0release into develop

This commit is contained in:
winlin 2019-05-05 07:59:15 +08:00
commit 7c002308e9
87 changed files with 7840 additions and 9677 deletions

View file

@ -147,9 +147,9 @@ Please select according to languages:
- [x] Enhanced complex error code with description and stack, read [#913][bug #913]. - [x] Enhanced complex error code with description and stack, read [#913][bug #913].
- [x] Enhanced RTMP url which supports vhost in stream, read [#1059][bug #1059]. - [x] Enhanced RTMP url which supports vhost in stream, read [#1059][bug #1059].
- [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92]. - [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92].
- [x] Support listen at IPv4 and IPv6, read [#460][bug #460].
- [ ] Utest cover almost all kernel code. - [ ] Utest cover almost all kernel code.
- [ ] Enhanced forwarding with vhost and variables. - [ ] Enhanced forwarding with vhost and variables.
- [ ] Support listen at IPv4 and IPv6, read [#460][bug #460].
- [ ] Support source cleanup for idle streams. - [ ] Support source cleanup for idle streams.
- [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465]. - [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465].
- [ ] Support HLS+, the HLS edge server, please read [#466][bug #466] and [#468][bug #468]. - [ ] Support HLS+, the HLS edge server, please read [#466][bug #466] and [#468][bug #468].
@ -164,6 +164,8 @@ Please select according to languages:
### V3 changes ### V3 changes
* v3.0, 2019-04-30, Refine typo in files. 3.0.51
* v3.0, 2019-04-25, Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50
* v3.0, 2019-04-22, Refine in time unit. 3.0.49 * v3.0, 2019-04-22, Refine in time unit. 3.0.49
* v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48 * v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48
* v3.0, 2019-04-06, Merge [#1304][bug #1304], Fix ST coroutine pull error. 3.0.47 * v3.0, 2019-04-06, Merge [#1304][bug #1304], Fix ST coroutine pull error. 3.0.47

View file

@ -200,12 +200,16 @@ echo "" >> $SRS_AUTO_HEADERS_H
##################################################################################### #####################################################################################
# generated the contributors from AUTHORS.txt # generated the contributors from AUTHORS.txt
##################################################################################### #####################################################################################
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'` if [[ -f ../AUTHORS.txt ]]; then
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
done done
echo "\"" >> $SRS_AUTO_HEADERS_H echo "\"" >> $SRS_AUTO_HEADERS_H
else
echo "#define SRS_AUTO_CONSTRIBUTORS \"ossrs\"" >> $SRS_AUTO_HEADERS_H
fi
# new empty line to auto headers file. # new empty line to auto headers file.
echo "" >> $SRS_AUTO_HEADERS_H echo "" >> $SRS_AUTO_HEADERS_H

View file

@ -428,15 +428,15 @@ SED="sed_utility" && echo "SED is $SED"
##################################################################################### #####################################################################################
# check the os. # check the os.
##################################################################################### #####################################################################################
# user must specifies something what a fuck, we suppport following os: # Only supports:
# centos/ubuntu/osx, # linux, centos/ubuntu as such,
# cross build for embeded system, for example, mips or arm, # cross build for embeded system, for example, mips or arm,
# directly build on arm/mips, for example, pi or cubie, # directly build on arm/mips, for example, pi or cubie,
# export srs-librtmp # export srs-librtmp
# others is invalid. # others is invalid.
if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $OS_IS_OSX = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $OS_IS_OSX = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then
if [[ $SRS_PI = NO && $SRS_CUBIE = NO && $SRS_CROSS_BUILD = NO ]]; then if [[ $SRS_PI = NO && $SRS_CUBIE = NO && $SRS_CROSS_BUILD = NO ]]; then
echo "What a fuck, your OS `uname -s` is not supported." echo "Your OS `uname -s` is not supported."
exit 1 exit 1
fi fi
fi fi

View file

@ -31,38 +31,29 @@
#include <srs_app_thread.hpp> #include <srs_app_thread.hpp>
/** // The async call for http hooks, for the http hooks will switch st-thread,
* the async call for http hooks, // so we must use isolate thread to avoid the thread corrupt,
* for the http hooks will switch st-thread, // for example, when dvr call http hooks, the video receive thread got
* so we must use isolate thread to avoid the thread corrupt, // a video and pass it to the dvr again.
* for example, when dvr call http hooks, the video receive thread got // Futhurmore, the aync call never block the main worker thread.
* a video and pass it to the dvr again.
* futhurmore, the aync call never block the main worker thread.
*/
class ISrsAsyncCallTask class ISrsAsyncCallTask
{ {
public: public:
ISrsAsyncCallTask(); ISrsAsyncCallTask();
virtual ~ISrsAsyncCallTask(); virtual ~ISrsAsyncCallTask();
public: public:
/** // Execute the task async.
* execute the task async. // This method is the actual execute method of task,
* this method is the actual execute method of task, // for example, to notify callback server.
* for example, to notify callback server.
*/
virtual srs_error_t call() = 0; virtual srs_error_t call() = 0;
/** // Convert task to string to describe it.
* convert task to string to describe it. // It's used for logger.
* used for logger.
*/
virtual std::string to_string() = 0; virtual std::string to_string() = 0;
}; };
/** // The async callback for dvr, callback and other async worker.
* the async callback for dvr, callback and other async worker. // When worker call with the task, the worker will do it in isolate thread.
* when worker call with the task, the worker will do it in isolate thread. // That is, the task is execute/call in async mode.
* that is, the task is execute/call in async mode.
*/
class SrsAsyncCallWorker : public ISrsCoroutineHandler class SrsAsyncCallWorker : public ISrsCoroutineHandler
{ {
private: private:
@ -79,7 +70,7 @@ public:
public: public:
virtual srs_error_t start(); virtual srs_error_t start();
virtual void stop(); virtual void stop();
// interface ISrsReusableThreadHandler // Interface ISrsReusableThreadHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };

View file

@ -36,85 +36,69 @@ class SrsRtmpServer;
class SrsKbpsLimit; class SrsKbpsLimit;
class ISrsProtocolStatistic; class ISrsProtocolStatistic;
/** // The bandwidth check/test sample.
* bandwidth check/test sample.
*/
class SrsBandwidthSample class SrsBandwidthSample
{ {
public: public:
/** // The plan, how long to do the test, in ms,
* the plan, how long to do the test, in ms, // if exceed the duration, abort the test.
* if exceed the duration, abort the test.
*/
int duration_ms; int duration_ms;
/** // The plan, interval for each check/test packet, in ms
* the plan, interval for each check/test packet, in ms
*/
int interval_ms; int interval_ms;
public: public:
/** // The actual test duration, in ms.
* the actual test duration, in ms.
*/
int actual_duration_ms; int actual_duration_ms;
/** // The actual test bytes
* the actual test bytes
*/
int bytes; int bytes;
/** // The actual test kbps
* the actual test kbps
*/
int kbps; int kbps;
public: public:
SrsBandwidthSample(); SrsBandwidthSample();
virtual ~SrsBandwidthSample(); virtual ~SrsBandwidthSample();
public: public:
/** // Update the bytes and actual duration, then calc the kbps.
* update the bytes and actual duration, then calc the kbps. // @param _bytes update the sample bytes.
* @param _bytes update the sample bytes. // @param _duration update the actual duration, in ms.
* @param _duration update the actual duration, in ms.
*/
virtual void calc_kbps(int _bytes, int _duration); virtual void calc_kbps(int _bytes, int _duration);
}; };
/** // The bandwidth test agent which provides the interfaces for bandwidth check.
* bandwidth test agent which provides the interfaces for bandwidth check. // 1. if vhost disabled bandwidth check, ignore.
* 1. if vhost disabled bandwidth check, ignore. // 2. otherwise, check the key, error if verify failed.
* 2. otherwise, check the key, error if verify failed. // 3. check the interval limit, error if bandwidth in the interval window.
* 3. check the interval limit, error if bandwidth in the interval window. // 4. check the bandwidth under the max kbps.
* 4. check the bandwidth under the max kbps. // 5. send the bandwidth data to client.
* 5. send the bandwidth data to client. // bandwidth workflow:
* bandwidth workflow: // +------------+ +----------+
* +------------+ +----------+ // | Client | | Server |
* | Client | | Server | // +-----+------+ +-----+----+
* +-----+------+ +-----+----+ // | |
* | | // | connect vhost------> | if vhost enable bandwidth,
* | connect vhost------> | if vhost enable bandwidth, // | <-----result(success) | do bandwidth check.
* | <-----result(success) | do bandwidth check. // | |
* | | // | <----call(start play) | onSrsBandCheckStartPlayBytes
* | <----call(start play) | onSrsBandCheckStartPlayBytes // | result(playing)-----> | onSrsBandCheckStartingPlayBytes
* | result(playing)-----> | onSrsBandCheckStartingPlayBytes // | <-------data(playing) | onSrsBandCheckStartingPlayBytes
* | <-------data(playing) | onSrsBandCheckStartingPlayBytes // | <-----call(stop play) | onSrsBandCheckStopPlayBytes
* | <-----call(stop play) | onSrsBandCheckStopPlayBytes // | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes
* | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes // | |
* | | // | <-call(start publish) | onSrsBandCheckStartPublishBytes
* | <-call(start publish) | onSrsBandCheckStartPublishBytes // | result(publishing)--> | onSrsBandCheckStartingPublishBytes
* | result(publishing)--> | onSrsBandCheckStartingPublishBytes // | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
* | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes // | <--call(stop publish) | onSrsBandCheckStopPublishBytes
* | <--call(stop publish) | onSrsBandCheckStopPublishBytes // | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
* | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes // | |
* | | // | <--------------report |
* | <--------------report | // | final(2)------------> | finalClientPacket
* | final(2)------------> | finalClientPacket // | <END> |
* | <END> | //
* // 1. when flash client, server never wait the stop publish response,
* 1. when flash client, server never wait the stop publish response, // for the flash client queue is fullfill with other packets.
* for the flash client queue is fullfill with other packets. // 2. when flash client, server never wait the final packet,
* 2. when flash client, server never wait the final packet, // for the flash client directly close when got report packet.
* for the flash client directly close when got report packet. // 3. for linux client, it will send the publish data then send a stop publish,
* 3. for linux client, it will send the publish data then send a stop publish, // for the linux client donot know when to stop the publish.
* for the linux client donot know when to stop the publish. // when server got publishing and stop publish, stop publish.
* when server got publishing and stop publish, stop publish.
*/
class SrsBandwidth class SrsBandwidth
{ {
private: private:
@ -124,81 +108,61 @@ public:
SrsBandwidth(); SrsBandwidth();
virtual ~SrsBandwidth(); virtual ~SrsBandwidth();
public: public:
/** // Do the bandwidth check.
* do the bandwidth check. // @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client.
* @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. // @param io_stat, the underlayer io statistic, provides send/recv bytes count.
* @param io_stat, the underlayer io statistic, provides send/recv bytes count. // @param req, client request object, specifies the request info from client.
* @param req, client request object, specifies the request info from client. // @param local_ip, the ip of server which client connected at
* @param local_ip, the ip of server which client connected at
*/
virtual srs_error_t bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip); virtual srs_error_t bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip);
private: private:
/** // Used to process band width check from client.
* used to process band width check from client. // @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
* @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
*/
virtual srs_error_t do_bandwidth_check(SrsKbpsLimit* limit); virtual srs_error_t do_bandwidth_check(SrsKbpsLimit* limit);
// play check/test, downloading bandwidth kbps. // play check/test, downloading bandwidth kbps.
private: private:
/** // Start play/download bandwidth check/test,
* start play/download bandwidth check/test, // send start-play command to client, client must response starting-play
* send start-play command to client, client must response starting-play // to start the test.
* to start the test.
*/
virtual srs_error_t play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** // Do play/download bandwidth check/test,
* do play/download bandwidth check/test, // server send call messages to client in specified time,
* server send call messages to client in specified time, // calc the time and bytes sent, then we got the kbps.
* calc the time and bytes sent, then we got the kbps.
*/
virtual srs_error_t play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** // stop play/download bandwidth check/test,
* stop play/download bandwidth check/test, // send stop-play command to client, client must response stopped-play
* send stop-play command to client, client must response stopped-play // to stop the test.
* to stop the test.
*/
virtual srs_error_t play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
// publish check/test, publishing bandwidth kbps. // publish check/test, publishing bandwidth kbps.
private: private:
/** // Start publish/upload bandwidth check/test,
* start publish/upload bandwidth check/test, // send start-publish command to client, client must response starting-publish
* send start-publish command to client, client must response starting-publish // to start the test.
* to start the test.
*/
virtual srs_error_t publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** // Do publish/upload bandwidth check/test,
* do publish/upload bandwidth check/test, // client send call messages to client in specified time,
* client send call messages to client in specified time, // server calc the time and bytes received, then we got the kbps.
* server calc the time and bytes received, then we got the kbps. // @remark, for linux client, it will send a stop publish client, server will stop publishing.
* @remark, for linux client, it will send a stop publish client, server will stop publishing. // then enter the publish-stop stage with client.
* then enter the publish-stop stage with client. // @remark, for flash client, it will send many many call messages, that is,
* @remark, for flash client, it will send many many call messages, that is, // the send queue is fullfill with call messages, so we should never expect the
* the send queue is fullfill with call messages, so we should never expect the // response message in the publish-stop stage.
* response message in the publish-stop stage.
*/
virtual srs_error_t publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
/** // Stop publish/upload bandwidth check/test,
* stop publish/upload bandwidth check/test, // send stop-publish command to client,
* send stop-publish command to client, // for linux client, always expect a stopped-publish response from client,
* for linux client, always expect a stopped-publish response from client, // for flash client, the sent queue is fullfill with publishing call messages,
* for flash client, the sent queue is fullfill with publishing call messages, // so server never expect the stopped-publish from it.
* so server never expect the stopped-publish from it.
*/
virtual srs_error_t publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); virtual srs_error_t publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
private: private:
/** // Report and final packet
* report and final packet // report a finish packet, with the bytes/time/kbps bandwidth check/test result,
* report a finish packet, with the bytes/time/kbps bandwidth check/test result, // for linux client, server always expect a final packet from client,
* for linux client, server always expect a final packet from client, // for flash client, the sent queue is fullfill with publishing call messages,
* for flash client, the sent queue is fullfill with publishing call messages, // so server never expect the final packet from it.
* so server never expect the final packet from it.
*/
virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time); virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time);
}; };
/** // The kbps limit, if exceed the kbps, slow down.
* the kbps limit, if exceed the kbps, slow down.
*/
class SrsKbpsLimit class SrsKbpsLimit
{ {
private: private:
@ -208,17 +172,11 @@ public:
SrsKbpsLimit(SrsKbps* kbps, int limit_kbps); SrsKbpsLimit(SrsKbps* kbps, int limit_kbps);
virtual ~SrsKbpsLimit(); virtual ~SrsKbpsLimit();
public: public:
/** // Get the system limit kbps.
* get the system limit kbps.
*/
virtual int limit_kbps(); virtual int limit_kbps();
/** // Limit the recv bandwidth.
* limit the recv bandwidth.
*/
virtual void recv_limit(); virtual void recv_limit();
/** // Limit the send bandwidth.
* limit the send bandwidth.
*/
virtual void send_limit(); virtual void send_limit();
}; };

View file

@ -46,9 +46,7 @@ class SrsSimpleRtmpClient;
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
#include <srs_kernel_file.hpp> #include <srs_kernel_file.hpp>
/** // The stream caster for flv stream over HTTP POST.
* the stream caster for flv stream over HTTP POST.
*/
class SrsAppCasterFlv : virtual public ISrsTcpHandler class SrsAppCasterFlv : virtual public ISrsTcpHandler
, virtual public IConnectionManager, virtual public ISrsHttpHandler , virtual public IConnectionManager, virtual public ISrsHttpHandler
{ {
@ -62,20 +60,18 @@ public:
virtual ~SrsAppCasterFlv(); virtual ~SrsAppCasterFlv();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
// ISrsTcpHandler // Interface ISrsTcpHandler
public: public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd); virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
// IConnectionManager // Interface IConnectionManager
public: public:
virtual void remove(ISrsConnection* c); virtual void remove(ISrsConnection* c);
// ISrsHttpHandler // Interface ISrsHttpHandler
public: public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
}; };
/** // The dynamic http connection, never drop the body.
* the dynamic http connection, never drop the body.
*/
class SrsDynamicHttpConn : public SrsHttpConn class SrsDynamicHttpConn : public SrsHttpConn
{ {
private: private:
@ -93,10 +89,7 @@ private:
virtual srs_error_t do_proxy(ISrsHttpResponseReader* rr, SrsFlvDecoder* dec); virtual srs_error_t do_proxy(ISrsHttpResponseReader* rr, SrsFlvDecoder* dec);
}; };
/** // The http wrapper for file reader, to read http post stream like a file.
* the http wrapper for file reader,
* to read http post stream like a file.
*/
class SrsHttpFileReader : public SrsFileReader class SrsHttpFileReader : public SrsFileReader
{ {
private: private:
@ -105,9 +98,7 @@ public:
SrsHttpFileReader(ISrsHttpResponseReader* h); SrsHttpFileReader(ISrsHttpResponseReader* h);
virtual ~SrsHttpFileReader(); virtual ~SrsHttpFileReader();
public: public:
/** // Open file reader, can open then close then open...
* open file reader, can open then close then open...
*/
virtual srs_error_t open(std::string file); virtual srs_error_t open(std::string file);
virtual void close(); virtual void close();
public: public:

View file

@ -3433,25 +3433,16 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv)
void SrsConfig::print_help(char** argv) void SrsConfig::print_help(char** argv)
{ {
printf( printf(
RTMP_SIG_SRS_SERVER " " RTMP_SIG_SRS_COPYRIGHT "\n" RTMP_SIG_SRS_SERVER ", " RTMP_SIG_SRS_URL ", licensed under " RTMP_SIG_SRS_LICENSE
"License: " RTMP_SIG_SRS_LICENSE "\n" ", built at " SRS_AUTO_BUILD_DATE ", configured by " SRS_AUTO_USER_CONFIGURE
"Primary: " RTMP_SIG_SRS_PRIMARY "\n" ", which means " SRS_AUTO_CONFIGURE "\n""\n"
"Authors: " RTMP_SIG_SRS_AUTHROS "\n" "Usage: %s <-h?vVgG>|<[-t] -c filename>\n"
"Build: " SRS_AUTO_BUILD_DATE " Configuration:" SRS_AUTO_USER_CONFIGURE "\n"
"Features:" SRS_AUTO_CONFIGURE "\n""\n"
"Usage: %s [-h?vVgG] [[-t] -c <filename>]\n"
"\n"
"Options:\n" "Options:\n"
" -?, -h : show this help and exit(0)\n" " -?, -h : Show this help and exit 0.\n"
" -v, -V : show version and exit(0)\n" " -v, -V : Show version and exit 0.\n"
" -g, -G : show server signature and exit(0)\n" " -g, -G : Show server signature and exit 0.\n"
" -t : test configuration file, exit(error_code).\n" " -t : Test configuration file, exit with error code(0 for success).\n"
" -c filename : use configuration file for SRS\n" " -c filename : Use config file to start server.\n"
"\n"
RTMP_SIG_SRS_WEB "\n"
RTMP_SIG_SRS_URL "\n"
"Email: " RTMP_SIG_SRS_EMAIL "\n"
"\n"
"For example:\n" "For example:\n"
" %s -v\n" " %s -v\n"
" %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n" " %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n"

File diff suppressed because it is too large Load diff

View file

@ -36,95 +36,67 @@
class SrsWallClock; class SrsWallClock;
/** // The basic connection of SRS,
* the basic connection of SRS, // all connections accept from listener must extends from this base class,
* all connections accept from listener must extends from this base class, // server will add the connection to manager, and delete it when remove.
* server will add the connection to manager, and delete it when remove.
*/
class SrsConnection : virtual public ISrsConnection, virtual public ISrsCoroutineHandler class SrsConnection : virtual public ISrsConnection, virtual public ISrsCoroutineHandler
, virtual public ISrsKbpsDelta, virtual public ISrsReloadHandler , virtual public ISrsKbpsDelta, virtual public ISrsReloadHandler
{ {
protected: protected:
/** // Each connection start a green thread,
* each connection start a green thread, // when thread stop, the connection will be delete by server.
* when thread stop, the connection will be delete by server.
*/
SrsCoroutine* trd; SrsCoroutine* trd;
/** // The manager object to manage the connection.
* the manager object to manage the connection.
*/
IConnectionManager* manager; IConnectionManager* manager;
/** // The underlayer st fd handler.
* the underlayer st fd handler.
*/
srs_netfd_t stfd; srs_netfd_t stfd;
/** // The ip of client.
* the ip of client.
*/
std::string ip; std::string ip;
/** // The underlayer socket.
* the underlayer socket.
*/
SrsStSocket* skt; SrsStSocket* skt;
/** // The connection total kbps.
* connection total kbps. // not only the rtmp or http connection, all type of connection are
* not only the rtmp or http connection, all type of connection are // need to statistic the kbps of io.
* need to statistic the kbps of io. // The SrsStatistic will use it indirectly to statistic the bytes delta of current connection.
* the SrsStatistic will use it indirectly to statistic the bytes delta of current connection.
*/
SrsKbps* kbps; SrsKbps* kbps;
SrsWallClock* clk; SrsWallClock* clk;
/** // The create time in milliseconds.
* the create time in milliseconds. // for current connection to log self create time and calculate the living time.
* for current connection to log self create time and calculate the living time.
*/
int64_t create_time; int64_t create_time;
public: public:
SrsConnection(IConnectionManager* cm, srs_netfd_t c, std::string cip); SrsConnection(IConnectionManager* cm, srs_netfd_t c, std::string cip);
virtual ~SrsConnection(); virtual ~SrsConnection();
// interface ISrsKbpsDelta // Interface ISrsKbpsDelta
public: public:
virtual void remark(int64_t* in, int64_t* out); virtual void remark(int64_t* in, int64_t* out);
public: public:
/** // To dipose the connection.
* to dipose the connection.
*/
virtual void dispose(); virtual void dispose();
/** // Start the client green thread.
* start the client green thread. // when server get a client from listener,
* when server get a client from listener, // 1. server will create an concrete connection(for instance, RTMP connection),
* 1. server will create an concrete connection(for instance, RTMP connection), // 2. then add connection to its connection manager,
* 2. then add connection to its connection manager, // 3. start the client thread by invoke this start()
* 3. start the client thread by invoke this start() // when client cycle thread stop, invoke the on_thread_stop(), which will use server
* when client cycle thread stop, invoke the on_thread_stop(), which will use server // To remove the client by server->remove(this).
* to remove the client by server->remove(this).
*/
virtual srs_error_t start(); virtual srs_error_t start();
// Set socket option TCP_NODELAY. // Set socket option TCP_NODELAY.
virtual srs_error_t set_tcp_nodelay(bool v); virtual srs_error_t set_tcp_nodelay(bool v);
// Set socket option SO_SNDBUF in srs_utime_t. // Set socket option SO_SNDBUF in srs_utime_t.
virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v); virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v);
// interface ISrsOneCycleThreadHandler // Interface ISrsOneCycleThreadHandler
public: public:
/** // The thread cycle function,
* the thread cycle function, // when serve connection completed, terminate the loop which will terminate the thread,
* when serve connection completed, terminate the loop which will terminate the thread, // thread will invoke the on_thread_stop() when it terminated.
* thread will invoke the on_thread_stop() when it terminated.
*/
virtual srs_error_t cycle(); virtual srs_error_t cycle();
public: public:
/** // Get the srs id which identify the client.
* get the srs id which identify the client.
*/
virtual int srs_id(); virtual int srs_id();
/** // Set connection to expired.
* set connection to expired.
*/
virtual void expire(); virtual void expire();
protected: protected:
/** // For concrete connection to do the cycle.
* for concrete connection to do the cycle.
*/
virtual srs_error_t do_cycle() = 0; virtual srs_error_t do_cycle() = 0;
}; };

View file

@ -33,6 +33,7 @@ class SrsJsonAny;
class SrsRequest; class SrsRequest;
class SrsSource; class SrsSource;
// For origin cluster.
class SrsCoWorkers class SrsCoWorkers
{ {
private: private:

View file

@ -40,9 +40,7 @@ class SrsMpdWriter;
class SrsMp4M2tsInitEncoder; class SrsMp4M2tsInitEncoder;
class SrsMp4M2tsSegmentEncoder; class SrsMp4M2tsSegmentEncoder;
/** // The init mp4 for FMP4.
* The init mp4 for FMP4.
*/
class SrsInitMp4 : public SrsFragment class SrsInitMp4 : public SrsFragment
{ {
private: private:
@ -56,9 +54,7 @@ public:
virtual srs_error_t write(SrsFormat* format, bool video, int tid); virtual srs_error_t write(SrsFormat* format, bool video, int tid);
}; };
/** // The FMP4(Fragmented MP4) for DASH streaming.
* The FMP4(Fragmented MP4) for DASH streaming.
*/
class SrsFragmentedMp4 : public SrsFragment class SrsFragmentedMp4 : public SrsFragment
{ {
private: private:
@ -76,9 +72,7 @@ public:
virtual srs_error_t reap(uint64_t& dts); virtual srs_error_t reap(uint64_t& dts);
}; };
/** // The writer to write MPD for DASH.
* The writer to write MPD for DASH.
*/
class SrsMpdWriter class SrsMpdWriter
{ {
private: private:
@ -113,9 +107,7 @@ public:
virtual srs_error_t get_fragment(bool video, std::string& home, std::string& filename, int64_t& sn, srs_utime_t& basetime); virtual srs_error_t get_fragment(bool video, std::string& home, std::string& filename, int64_t& sn, srs_utime_t& basetime);
}; };
/** // The controller for DASH, control the MPD and FMP4 generating system.
* The controller for DASH, control the MPD and FMP4 generating system.
*/
class SrsDashController class SrsDashController
{ {
private: private:
@ -149,9 +141,7 @@ private:
virtual srs_error_t refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* format); virtual srs_error_t refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* format);
}; };
/** // The MPEG-DASH encoder, transmux RTMP to DASH.
* The MPEG-DASH encoder, transmux RTMP to DASH.
*/
class SrsDash class SrsDash
{ {
private: private:

View file

@ -49,9 +49,7 @@ class SrsFormat;
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>
#include <srs_app_async_call.hpp> #include <srs_app_async_call.hpp>
/** // The segmenter for DVR, to write a segment file in flv/mp4.
* The segmenter for DVR, to write a segment file in flv/mp4.
*/
class SrsDvrSegmenter : public ISrsReloadHandler class SrsDvrSegmenter : public ISrsReloadHandler
{ {
protected: protected:
@ -105,14 +103,12 @@ private:
virtual std::string generate_path(); virtual std::string generate_path();
// When update the duration of segment by rtmp msg. // When update the duration of segment by rtmp msg.
virtual srs_error_t on_update_duration(SrsSharedPtrMessage* msg); virtual srs_error_t on_update_duration(SrsSharedPtrMessage* msg);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_dvr(std::string vhost); virtual srs_error_t on_reload_vhost_dvr(std::string vhost);
}; };
/** // The FLV segmenter to use FLV encoder to write file.
* The FLV segmenter to use FLV encoder to write file.
*/
class SrsDvrFlvSegmenter : public SrsDvrSegmenter class SrsDvrFlvSegmenter : public SrsDvrSegmenter
{ {
private: private:
@ -140,9 +136,7 @@ protected:
virtual srs_error_t close_encoder(); virtual srs_error_t close_encoder();
}; };
/** // The MP4 segmenter to use MP4 encoder to write file.
* The MP4 segmenter to use MP4 encoder to write file.
*/
class SrsDvrMp4Segmenter : public SrsDvrSegmenter class SrsDvrMp4Segmenter : public SrsDvrSegmenter
{ {
private: private:
@ -161,9 +155,7 @@ protected:
virtual srs_error_t close_encoder(); virtual srs_error_t close_encoder();
}; };
/** // the dvr async call.
* the dvr async call.
*/
class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
{ {
private: private:
@ -178,9 +170,7 @@ public:
virtual std::string to_string(); virtual std::string to_string();
}; };
/** // The DVR plan, when and how to reap segment.
* The DVR plan, when and how to reap segment.
*/
class SrsDvrPlan : public ISrsReloadHandler class SrsDvrPlan : public ISrsReloadHandler
{ {
public: public:
@ -208,9 +198,7 @@ public:
static srs_error_t create_plan(std::string vhost, SrsDvrPlan** pplan); static srs_error_t create_plan(std::string vhost, SrsDvrPlan** pplan);
}; };
/** // The DVR session plan: reap flv when session complete(unpublish)
* The DVR session plan: reap flv when session complete(unpublish)
*/
class SrsDvrSessionPlan : public SrsDvrPlan class SrsDvrSessionPlan : public SrsDvrPlan
{ {
public: public:
@ -221,9 +209,7 @@ public:
virtual void on_unpublish(); virtual void on_unpublish();
}; };
/** // The DVR segment plan: reap flv when duration exceed.
* The DVR segment plan: reap flv when duration exceed.
*/
class SrsDvrSegmentPlan : public SrsDvrPlan class SrsDvrSegmentPlan : public SrsDvrPlan
{ {
private: private:
@ -241,14 +227,12 @@ public:
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
private: private:
virtual srs_error_t update_duration(SrsSharedPtrMessage* msg); virtual srs_error_t update_duration(SrsSharedPtrMessage* msg);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_dvr(std::string vhost); virtual srs_error_t on_reload_vhost_dvr(std::string vhost);
}; };
/** // DVR(Digital Video Recorder) to record RTMP stream to flv/mp4 file.
* DVR(Digital Video Recorder) to record RTMP stream to flv/mp4 file.
*/
class SrsDvr : public ISrsReloadHandler class SrsDvr : public ISrsReloadHandler
{ {
private: private:
@ -264,38 +248,26 @@ public:
SrsDvr(); SrsDvr();
virtual ~SrsDvr(); virtual ~SrsDvr();
public: public:
/** // initialize dvr, create dvr plan.
* initialize dvr, create dvr plan. // when system initialize(encoder publish at first time, or reload),
* when system initialize(encoder publish at first time, or reload), // initialize the dvr will reinitialize the plan, the whole dvr framework.
* initialize the dvr will reinitialize the plan, the whole dvr framework.
*/
virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r); virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r);
/** // publish stream event,
* publish stream event, // when encoder start to publish RTMP stream.
* when encoder start to publish RTMP stream. // @param fetch_sequence_header whether fetch sequence from source.
* @param fetch_sequence_header whether fetch sequence from source.
*/
virtual srs_error_t on_publish(); virtual srs_error_t on_publish();
/** // the unpublish event.,
* the unpublish event., // when encoder stop(unpublish) to publish RTMP stream.
* when encoder stop(unpublish) to publish RTMP stream.
*/
virtual void on_unpublish(); virtual void on_unpublish();
/** // get some information from metadata, it's optinal.
* get some information from metadata, it's optinal.
*/
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* metadata); virtual srs_error_t on_meta_data(SrsSharedPtrMessage* metadata);
/** // mux the audio packets to dvr.
* mux the audio packets to dvr. // @param shared_audio, directly ptr, copy it if need to save it.
* @param shared_audio, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* foramt); virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* foramt);
/** // mux the video packets to dvr.
* mux the video packets to dvr. // @param shared_video, directly ptr, copy it if need to save it.
* @param shared_video, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_dvr_apply(std::string vhost); virtual srs_error_t on_reload_vhost_dvr_apply(std::string vhost);
}; };

View file

@ -47,34 +47,28 @@ class SrsTcpClient;
class SrsSimpleRtmpClient; class SrsSimpleRtmpClient;
class SrsPacket; class SrsPacket;
/** // The state of edge, auto machine
* the state of edge, auto machine
*/
enum SrsEdgeState enum SrsEdgeState
{ {
SrsEdgeStateInit = 0, SrsEdgeStateInit = 0,
// for play edge // For play edge
SrsEdgeStatePlay = 100, SrsEdgeStatePlay = 100,
// play stream from origin, ingest stream // play stream from origin, ingest stream
SrsEdgeStateIngestConnected = 101, SrsEdgeStateIngestConnected = 101,
// for publish edge // For publish edge
SrsEdgeStatePublish = 200, SrsEdgeStatePublish = 200,
}; };
/** // The state of edge from user, manual machine
* the state of edge from user, manual machine
*/
enum SrsEdgeUserState enum SrsEdgeUserState
{ {
SrsEdgeUserStateInit = 0, SrsEdgeUserStateInit = 0,
SrsEdgeUserStateReloading = 100, SrsEdgeUserStateReloading = 100,
}; };
/** // The upstream of edge, can be rtmp or http.
* the upstream of edge, can be rtmp or http.
*/
class SrsEdgeUpstream class SrsEdgeUpstream
{ {
public: public:
@ -93,7 +87,7 @@ public:
class SrsEdgeRtmpUpstream : public SrsEdgeUpstream class SrsEdgeRtmpUpstream : public SrsEdgeUpstream
{ {
private: private:
// for RTMP 302, if not empty, // For RTMP 302, if not empty,
// use this <ip[:port]> as upstream. // use this <ip[:port]> as upstream.
std::string redirect; std::string redirect;
SrsSimpleRtmpClient* sdk; SrsSimpleRtmpClient* sdk;
@ -111,9 +105,7 @@ public:
virtual void kbps_sample(const char* label, int64_t age); virtual void kbps_sample(const char* label, int64_t age);
}; };
/** // The edge used to ingest stream from origin.
* edge used to ingest stream from origin.
*/
class SrsEdgeIngester : public ISrsCoroutineHandler class SrsEdgeIngester : public ISrsCoroutineHandler
{ {
private: private:
@ -123,7 +115,7 @@ private:
SrsCoroutine* trd; SrsCoroutine* trd;
SrsLbRoundRobin* lb; SrsLbRoundRobin* lb;
SrsEdgeUpstream* upstream; SrsEdgeUpstream* upstream;
// for RTMP 302 redirect. // For RTMP 302 redirect.
std::string redirect; std::string redirect;
public: public:
SrsEdgeIngester(); SrsEdgeIngester();
@ -133,7 +125,7 @@ public:
virtual srs_error_t start(); virtual srs_error_t start();
virtual void stop(); virtual void stop();
virtual std::string get_curr_origin(); virtual std::string get_curr_origin();
// interface ISrsReusableThread2Handler // Interface ISrsReusableThread2Handler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
@ -143,9 +135,7 @@ private:
virtual srs_error_t process_publish_message(SrsCommonMessage* msg); virtual srs_error_t process_publish_message(SrsCommonMessage* msg);
}; };
/** // The edge used to forward stream to origin.
* edge used to forward stream to origin.
*/
class SrsEdgeForwarder : public ISrsCoroutineHandler class SrsEdgeForwarder : public ISrsCoroutineHandler
{ {
private: private:
@ -155,16 +145,12 @@ private:
SrsCoroutine* trd; SrsCoroutine* trd;
SrsSimpleRtmpClient* sdk; SrsSimpleRtmpClient* sdk;
SrsLbRoundRobin* lb; SrsLbRoundRobin* lb;
/** // we must ensure one thread one fd principle,
* we must ensure one thread one fd principle, // that is, a fd must be write/read by the one thread.
* that is, a fd must be write/read by the one thread. // The publish service thread will proxy(msg), and the edge forward thread
* the publish service thread will proxy(msg), and the edge forward thread // will cycle(), so we use queue for cycle to send the msg of proxy.
* will cycle(), so we use queue for cycle to send the msg of proxy.
*/
SrsMessageQueue* queue; SrsMessageQueue* queue;
/** // error code of send, for edge proxy thread to query.
* error code of send, for edge proxy thread to query.
*/
int send_error_code; int send_error_code;
public: public:
SrsEdgeForwarder(); SrsEdgeForwarder();
@ -175,7 +161,7 @@ public:
virtual srs_error_t initialize(SrsSource* s, SrsPublishEdge* e, SrsRequest* r); virtual srs_error_t initialize(SrsSource* s, SrsPublishEdge* e, SrsRequest* r);
virtual srs_error_t start(); virtual srs_error_t start();
virtual void stop(); virtual void stop();
// interface ISrsReusableThread2Handler // Interface ISrsReusableThread2Handler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
@ -184,10 +170,7 @@ public:
virtual srs_error_t proxy(SrsCommonMessage* msg); virtual srs_error_t proxy(SrsCommonMessage* msg);
}; };
/** // The play edge control service.
* play edge control service.
* downloading edge speed-up.
*/
class SrsPlayEdge class SrsPlayEdge
{ {
private: private:
@ -197,32 +180,21 @@ public:
SrsPlayEdge(); SrsPlayEdge();
virtual ~SrsPlayEdge(); virtual ~SrsPlayEdge();
public: public:
/** // Always use the req of source,
* always use the req of source, // For we assume all client to edge is invalid,
* for we assume all client to edge is invalid, // if auth open, edge must valid it from origin, then service it.
* if auth open, edge must valid it from origin, then service it.
*/
virtual srs_error_t initialize(SrsSource* source, SrsRequest* req); virtual srs_error_t initialize(SrsSource* source, SrsRequest* req);
/** // When client play stream on edge.
* when client play stream on edge.
*/
virtual srs_error_t on_client_play(); virtual srs_error_t on_client_play();
/** // When all client stopped play, disconnect to origin.
* when all client stopped play, disconnect to origin.
*/
virtual void on_all_client_stop(); virtual void on_all_client_stop();
virtual std::string get_curr_origin(); virtual std::string get_curr_origin();
public: public:
/** // When ingester start to play stream.
* when ingester start to play stream.
*/
virtual srs_error_t on_ingest_play(); virtual srs_error_t on_ingest_play();
}; };
/** // The publish edge control service.
* publish edge control service.
* uploading edge speed-up.
*/
class SrsPublishEdge class SrsPublishEdge
{ {
private: private:
@ -236,17 +208,11 @@ public:
public: public:
virtual srs_error_t initialize(SrsSource* source, SrsRequest* req); virtual srs_error_t initialize(SrsSource* source, SrsRequest* req);
virtual bool can_publish(); virtual bool can_publish();
/** // When client publish stream on edge.
* when client publish stream on edge.
*/
virtual srs_error_t on_client_publish(); virtual srs_error_t on_client_publish();
/** // Proxy publish stream to edge
* proxy publish stream to edge
*/
virtual srs_error_t on_proxy_publish(SrsCommonMessage* msg); virtual srs_error_t on_proxy_publish(SrsCommonMessage* msg);
/** // Proxy unpublish stream to edge.
* proxy unpublish stream to edge.
*/
virtual void on_proxy_unpublish(); virtual void on_proxy_unpublish();
}; };

View file

@ -36,10 +36,8 @@ class SrsRequest;
class SrsPithyPrint; class SrsPithyPrint;
class SrsFFMPEG; class SrsFFMPEG;
/** // The encoder for a stream, may use multiple
* the encoder for a stream, // ffmpegs to transcode the specified stream.
* may use multiple ffmpegs to transcode the specified stream.
*/
class SrsEncoder : public ISrsCoroutineHandler class SrsEncoder : public ISrsCoroutineHandler
{ {
private: private:
@ -54,7 +52,7 @@ public:
public: public:
virtual srs_error_t on_publish(SrsRequest* req); virtual srs_error_t on_publish(SrsRequest* req);
virtual void on_unpublish(); virtual void on_unpublish();
// interface ISrsReusableThreadHandler. // Interface ISrsReusableThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:

View file

@ -35,10 +35,7 @@ class SrsConfDirective;
class SrsPithyPrint; class SrsPithyPrint;
class SrsProcess; class SrsProcess;
/** // A transcode engine: ffmepg, used to transcode a stream to another.
* a transcode engine: ffmepg,
* used to transcode a stream to another.
*/
class SrsFFMPEG class SrsFFMPEG
{ {
private: private:

View file

@ -43,14 +43,11 @@ class SrsOriginHub;
class SrsKbps; class SrsKbps;
class SrsSimpleRtmpClient; class SrsSimpleRtmpClient;
/** // Forward the stream to other servers.
* forward the stream to other servers.
*/
// TODO: FIXME: refine the error log, comments it.
class SrsForwarder : public ISrsCoroutineHandler class SrsForwarder : public ISrsCoroutineHandler
{ {
private: private:
// the ep to forward, server[:port]. // The ep to forward, server[:port].
std::string ep_forward; std::string ep_forward;
SrsRequest* req; SrsRequest* req;
private: private:
@ -60,10 +57,8 @@ private:
SrsSimpleRtmpClient* sdk; SrsSimpleRtmpClient* sdk;
SrsRtmpJitter* jitter; SrsRtmpJitter* jitter;
SrsMessageQueue* queue; SrsMessageQueue* queue;
/** // Cache the sequence header for retry when slave is failed.
* cache the sequence header for retry when slave is failed. // @see https://github.com/ossrs/srs/issues/150
* @see https://github.com/ossrs/srs/issues/150
*/
SrsSharedPtrMessage* sh_audio; SrsSharedPtrMessage* sh_audio;
SrsSharedPtrMessage* sh_video; SrsSharedPtrMessage* sh_video;
public: public:
@ -75,22 +70,16 @@ public:
public: public:
virtual srs_error_t on_publish(); virtual srs_error_t on_publish();
virtual void on_unpublish(); virtual void on_unpublish();
/** // Forward the audio packet.
* forward the audio packet. // @param shared_metadata, directly ptr, copy it if need to save it.
* @param shared_metadata, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata); virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata);
/** // Forward the audio packet.
* forward the audio packet. // @param shared_audio, directly ptr, copy it if need to save it.
* @param shared_audio, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio); virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio);
/** // Forward the video packet.
* forward the video packet. // @param shared_video, directly ptr, copy it if need to save it.
* @param shared_video, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video); virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video);
// interface ISrsReusableThread2Handler. // Interface ISrsReusableThread2Handler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:

View file

@ -29,10 +29,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
/** // Represent a fragment, such as HLS segment, DVR segment or DASH segment.
* Represent a fragment, such as HLS segment, DVR segment or DASH segment. // It's a media file, for example FLV or MP4, with duration.
* It's a media file, for example FLV or MP4, with duration.
*/
class SrsFragment class SrsFragment
{ {
private: private:
@ -75,9 +73,7 @@ public:
virtual srs_error_t rename(); virtual srs_error_t rename();
}; };
/** // The fragment window manage a series of fragment.
* The fragment window manage a series of fragment.
*/
class SrsFragmentWindow class SrsFragmentWindow
{ {
private: private:

View file

@ -35,6 +35,7 @@ class SrsSharedPtrMessage;
class SrsHdsFragment; class SrsHdsFragment;
class SrsSource; class SrsSource;
// Mux RTMP to Adobe HDS streaming.
class SrsHds class SrsHds
{ {
public: public:

View file

@ -26,10 +26,7 @@
#include <srs_core.hpp> #include <srs_core.hpp>
/** // The http heartbeat to api-server to notice api that the information of SRS.
* the http heartbeat to api-server to notice api
* that the information of SRS.
*/
class SrsHttpHeartbeat class SrsHttpHeartbeat
{ {
public: public:

View file

@ -50,12 +50,10 @@ class SrsTsMessageCache;
class SrsHlsSegment; class SrsHlsSegment;
class SrsTsContext; class SrsTsContext;
/** // The wrapper of m3u8 segment from specification:
* the wrapper of m3u8 segment from specification: //
* // 3.3.2. EXTINF
* 3.3.2. EXTINF // The EXTINF tag specifies the duration of a media segment.
* The EXTINF tag specifies the duration of a media segment.
*/
class SrsHlsSegment : public SrsFragment class SrsHlsSegment : public SrsFragment
{ {
public: public:
@ -63,7 +61,7 @@ public:
int sequence_no; int sequence_no;
// ts uri in m3u8. // ts uri in m3u8.
std::string uri; std::string uri;
// the underlayer file writer. // The underlayer file writer.
SrsFileWriter* writer; SrsFileWriter* writer;
// The TS context writer to write TS to file. // The TS context writer to write TS to file.
SrsTsContextWriter* tscw; SrsTsContextWriter* tscw;
@ -78,9 +76,7 @@ public:
void config_cipher(unsigned char* key,unsigned char* iv); void config_cipher(unsigned char* key,unsigned char* iv);
}; };
/** // The hls async call: on_hls
* the hls async call: on_hls
*/
class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask
{ {
private: private:
@ -101,9 +97,7 @@ public:
virtual std::string to_string(); virtual std::string to_string();
}; };
/** // The hls async call: on_hls_notify
* the hls async call: on_hls_notify
*/
class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask
{ {
private: private:
@ -118,14 +112,12 @@ public:
virtual std::string to_string(); virtual std::string to_string();
}; };
/** // Mux the HLS stream(m3u8 and ts files).
* muxer the HLS stream(m3u8 and ts files). // Generally, the m3u8 muxer only provides methods to open/close segments,
* generally, the m3u8 muxer only provides methods to open/close segments, // to flush video/audio, without any mechenisms.
* to flush video/audio, without any mechenisms. //
* // That is, user must use HlsCache, which will control the methods of muxer,
* that is, user must use HlsCache, which will control the methods of muxer, // and provides HLS mechenisms.
* and provides HLS mechenisms.
*/
class SrsHlsMuxer class SrsHlsMuxer
{ {
private: private:
@ -143,26 +135,26 @@ private:
srs_utime_t hls_window; srs_utime_t hls_window;
SrsAsyncCallWorker* async; SrsAsyncCallWorker* async;
private: private:
// whether use floor algorithm for timestamp. // Whether use floor algorithm for timestamp.
bool hls_ts_floor; bool hls_ts_floor;
// the deviation in piece to adjust the fragment to be more // The deviation in piece to adjust the fragment to be more
// bigger or smaller. // bigger or smaller.
int deviation_ts; int deviation_ts;
// the previous reap floor timestamp, // The previous reap floor timestamp,
// used to detect the dup or jmp or ts. // used to detect the dup or jmp or ts.
int64_t accept_floor_ts; int64_t accept_floor_ts;
int64_t previous_floor_ts; int64_t previous_floor_ts;
private: private:
// encrypted or not // Whether encrypted or not
bool hls_keys; bool hls_keys;
int hls_fragments_per_key; int hls_fragments_per_key;
// key file name // The key file name
std::string hls_key_file; std::string hls_key_file;
// key file path // The key file path
std::string hls_key_file_path; std::string hls_key_file_path;
// key file url // The key file url
std::string hls_key_url; std::string hls_key_url;
// key and iv. // The key and iv.
unsigned char key[16]; unsigned char key[16];
unsigned char iv[16]; unsigned char iv[16];
SrsFileWriter *writer; SrsFileWriter *writer;
@ -176,10 +168,8 @@ private:
SrsFragmentWindow* segments; SrsFragmentWindow* segments;
// The current writing segment. // The current writing segment.
SrsHlsSegment* current; SrsHlsSegment* current;
/** // The ts context, to keep cc continous between ts.
* the ts context, to keep cc continous between ts. // @see https://github.com/ossrs/srs/issues/375
* @see https://github.com/ossrs/srs/issues/375
*/
SrsTsContext* context; SrsTsContext* context;
public: public:
SrsHlsMuxer(); SrsHlsMuxer();
@ -192,48 +182,32 @@ public:
virtual srs_utime_t duration(); virtual srs_utime_t duration();
virtual int deviation(); virtual int deviation();
public: public:
/** // Initialize the hls muxer.
* initialize the hls muxer.
*/
virtual srs_error_t initialize(); virtual srs_error_t initialize();
/** // When publish, update the config for muxer.
* when publish, update the config for muxer.
*/
virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix, virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix,
std::string path, std::string m3u8_file, std::string ts_file, std::string path, std::string m3u8_file, std::string ts_file,
srs_utime_t fragment, srs_utime_t window, bool ts_floor, double aof_ratio, srs_utime_t fragment, srs_utime_t window, bool ts_floor, double aof_ratio,
bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key, bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key,
std::string key_file, std::string key_file_path, std::string key_url); std::string key_file, std::string key_file_path, std::string key_url);
/** // Open a new segment(a new ts file)
* open a new segment(a new ts file)
*/
virtual srs_error_t segment_open(); virtual srs_error_t segment_open();
virtual srs_error_t on_sequence_header(); virtual srs_error_t on_sequence_header();
/** // Whether segment overflow,
* whether segment overflow, // that is whether the current segment duration>=(the segment in config)
* that is whether the current segment duration>=(the segment in config)
*/
virtual bool is_segment_overflow(); virtual bool is_segment_overflow();
/** // Whether wait keyframe to reap the ts.
* whether wait keyframe to reap the ts.
*/
virtual bool wait_keyframe(); virtual bool wait_keyframe();
/** // Whether segment absolutely overflow, for pure audio to reap segment,
* whether segment absolutely overflow, for pure audio to reap segment, // that is whether the current segment duration>=2*(the segment in config)
* that is whether the current segment duration>=2*(the segment in config) // @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
* @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
*/
virtual bool is_segment_absolutely_overflow(); virtual bool is_segment_absolutely_overflow();
public: public:
/** // Whether current hls muxer is pure audio mode.
* whether current hls muxer is pure audio mode.
*/
virtual bool pure_audio(); virtual bool pure_audio();
virtual srs_error_t flush_audio(SrsTsMessageCache* cache); virtual srs_error_t flush_audio(SrsTsMessageCache* cache);
virtual srs_error_t flush_video(SrsTsMessageCache* cache); virtual srs_error_t flush_video(SrsTsMessageCache* cache);
/** // Close segment(ts).
* Close segment(ts).
*/
virtual srs_error_t segment_close(); virtual srs_error_t segment_close();
private: private:
virtual srs_error_t do_segment_close(); virtual srs_error_t do_segment_close();
@ -242,23 +216,21 @@ private:
virtual srs_error_t _refresh_m3u8(std::string m3u8_file); virtual srs_error_t _refresh_m3u8(std::string m3u8_file);
}; };
/** // The hls stream cache,
* hls stream cache, // use to cache hls stream and flush to hls muxer.
* use to cache hls stream and flush to hls muxer. //
* // When write stream to ts file:
* when write stream to ts file: // video frame will directly flush to M3u8Muxer,
* video frame will directly flush to M3u8Muxer, // audio frame need to cache, because it's small and flv tbn problem.
* audio frame need to cache, because it's small and flv tbn problem. //
* // Whatever, the Hls cache used to cache video/audio,
* whatever, the Hls cache used to cache video/audio, // and flush video/audio to m3u8 muxer if needed.
* and flush video/audio to m3u8 muxer if needed. //
* // About the flv tbn problem:
* about the flv tbn problem: // flv tbn is 1/1000, ts tbn is 1/90000,
* flv tbn is 1/1000, ts tbn is 1/90000, // when timestamp convert to flv tbn, it will loose precise,
* when timestamp convert to flv tbn, it will loose precise, // so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter,
* so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter, // we use a aac jitter to correct the audio pts.
* we use a aac jitter to correct the audio pts.
*/
class SrsHlsController class SrsHlsController
{ {
private: private:
@ -278,40 +250,28 @@ public:
virtual srs_utime_t duration(); virtual srs_utime_t duration();
virtual int deviation(); virtual int deviation();
public: public:
/** // When publish or unpublish stream.
* when publish or unpublish stream.
*/
virtual srs_error_t on_publish(SrsRequest* req); virtual srs_error_t on_publish(SrsRequest* req);
virtual srs_error_t on_unpublish(); virtual srs_error_t on_unpublish();
/** // When get sequence header,
* when get sequence header, // must write a #EXT-X-DISCONTINUITY to m3u8.
* must write a #EXT-X-DISCONTINUITY to m3u8. // @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt
* @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt // @see: 3.4.11. EXT-X-DISCONTINUITY
* @see: 3.4.11. EXT-X-DISCONTINUITY
*/
virtual srs_error_t on_sequence_header(); virtual srs_error_t on_sequence_header();
/** // write audio to cache, if need to flush, flush to muxer.
* write audio to cache, if need to flush, flush to muxer.
*/
virtual srs_error_t write_audio(SrsAudioFrame* frame, int64_t pts); virtual srs_error_t write_audio(SrsAudioFrame* frame, int64_t pts);
/** // write video to muxer.
* write video to muxer.
*/
virtual srs_error_t write_video(SrsVideoFrame* frame, int64_t dts); virtual srs_error_t write_video(SrsVideoFrame* frame, int64_t dts);
private: private:
/** // Reopen the muxer for a new hls segment,
* reopen the muxer for a new hls segment, // close current segment, open a new segment,
* close current segment, open a new segment, // then write the key frame to the new segment.
* then write the key frame to the new segment. // so, user must reap_segment then flush_video to hls muxer.
* so, user must reap_segment then flush_video to hls muxer.
*/
virtual srs_error_t reap_segment(); virtual srs_error_t reap_segment();
}; };
/** // Transmux RTMP stream to HLS(m3u8 and ts).
* Transmux RTMP stream to HLS(m3u8 and ts). // TODO: FIXME: add utest for hls.
* TODO: FIXME: add utest for hls.
*/
class SrsHls class SrsHls
{ {
private: private:
@ -338,31 +298,21 @@ public:
virtual void dispose(); virtual void dispose();
virtual srs_error_t cycle(); virtual srs_error_t cycle();
public: public:
/** // Initialize the hls by handler and source.
* initialize the hls by handler and source.
*/
virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r); virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r);
/** // Publish stream event, continue to write the m3u8,
* publish stream event, continue to write the m3u8, // for the muxer object not destroyed.
* for the muxer object not destroyed. // @param fetch_sequence_header whether fetch sequence from source.
* @param fetch_sequence_header whether fetch sequence from source.
*/
virtual srs_error_t on_publish(); virtual srs_error_t on_publish();
/** // The unpublish event, only close the muxer, donot destroy the
* the unpublish event, only close the muxer, donot destroy the // muxer, for when we continue to publish, the m3u8 will continue.
* muxer, for when we continue to publish, the m3u8 will continue.
*/
virtual void on_unpublish(); virtual void on_unpublish();
/** // Mux the audio packets to ts.
* mux the audio packets to ts. // @param shared_audio, directly ptr, copy it if need to save it.
* @param shared_audio, directly ptr, copy it if need to save it.
*/
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format); virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
/** // Mux the video packets to ts.
* mux the video packets to ts. // @param shared_video, directly ptr, copy it if need to save it.
* @param shared_video, directly ptr, copy it if need to save it. // @param is_sps_pps whether the video is h.264 sps/pps.
* @param is_sps_pps whether the video is h.264 sps/pps.
*/
// TODO: FIXME: Remove param is_sps_pps. // TODO: FIXME: Remove param is_sps_pps.
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
private: private:

View file

@ -28,68 +28,63 @@
#include <map> #include <map>
/** // The handler for the tick.
* the handler for the tick.
*/
class ISrsHourGlass class ISrsHourGlass
{ {
public: public:
ISrsHourGlass(); ISrsHourGlass();
virtual ~ISrsHourGlass(); virtual ~ISrsHourGlass();
public: public:
/** // When time is ticked, this function is called.
* notify the handler, the type and tick.
*/
virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick) = 0; virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick) = 0;
}; };
/** // he hourglass used to do some specieal task,
* the hourglass used to do some specieal task, // while these task is cycle when some interval, for example,
* while these task is cycle when some interval, for example, // there are N=3 tasks to do:
* there are N=3 tasks to do: // 1. heartbeat every 3s.
* 1. heartbeat every 3s. // 2. print message every 5s.
* 2. print message every 5s. // 3. notify backend every 7s.
* 3. notify backend every 7s. // The hourglass will call back when ticks:
* the hourglass will call back when ticks: // 1. notify(type=1, time=3)
* 1. notify(type=1, time=3) // 2. notify(type=2, time=5)
* 2. notify(type=2, time=5) // 3. notify(type=1, time=6)
* 3. notify(type=1, time=6) // 4. notify(type=3, time=7)
* 4. notify(type=3, time=7) // 5. notify(type=1, time=9)
* 5. notify(type=1, time=9) // 6. notify(type=2, time=10)
* 6. notify(type=2, time=10) // This is used for server and bocar server and other manager.
* this is used for server and bocar server and other manager. //
* // Usage:
* Usage: // SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS);
* SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS); // hg->tick(1, 3 * SRS_UTIME_MILLISECONDS);
* hg->tick(1, 3 * SRS_UTIME_MILLISECONDS); // hg->tick(2, 5 * SRS_UTIME_MILLISECONDS);
* hg->tick(2, 5 * SRS_UTIME_MILLISECONDS); // hg->tick(3, 7 * SRS_UTIME_MILLISECONDS);
* hg->tick(3, 7 * SRS_UTIME_MILLISECONDS); // // create a thread to cycle, which will call handerl when ticked.
* // create a thread to cycle, which will call handerl when ticked. // while (true) {
* while (true) { // hg->cycle();
* hg->cycle(); // }
* }
*/
class SrsHourGlass class SrsHourGlass
{ {
private: private:
ISrsHourGlass* handler; ISrsHourGlass* handler;
srs_utime_t _resolution; srs_utime_t _resolution;
// The ticks:
// key: the type of tick. // key: the type of tick.
// value: the interval of tick. // value: the interval of tick.
std::map<int, srs_utime_t> ticks; std::map<int, srs_utime_t> ticks;
// the total elapsed time, // The total elapsed time,
// for each cycle, we increase it with a resolution. // for each cycle, we increase it with a resolution.
srs_utime_t total_elapse; srs_utime_t total_elapse;
public: public:
SrsHourGlass(ISrsHourGlass* h, srs_utime_t resolution); SrsHourGlass(ISrsHourGlass* h, srs_utime_t resolution);
virtual ~SrsHourGlass(); virtual ~SrsHourGlass();
public: public:
// add a pair of tick(type, interval). // Add a pair of tick(type, interval).
// @param type the type of tick. // @param type the type of tick.
// @param interval the interval in srs_utime_t of tick. // @param interval the interval in srs_utime_t of tick.
virtual srs_error_t tick(int type, srs_utime_t interval); virtual srs_error_t tick(int type, srs_utime_t interval);
public: public:
// cycle the hourglass, which will sleep resolution every time. // Cycle the hourglass, which will sleep resolution every time.
// and call handler when ticked. // and call handler when ticked.
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };

View file

@ -550,10 +550,7 @@ srs_error_t SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
SrsJsonObject* data = SrsJsonAny::object(); SrsJsonObject* data = SrsJsonAny::object();
obj->set("data", data); obj->set("data", data);
data->set("primary", SrsJsonAny::str(RTMP_SIG_SRS_PRIMARY));
data->set("license", SrsJsonAny::str(RTMP_SIG_SRS_LICENSE)); data->set("license", SrsJsonAny::str(RTMP_SIG_SRS_LICENSE));
data->set("copyright", SrsJsonAny::str(RTMP_SIG_SRS_COPYRIGHT));
data->set("authors", SrsJsonAny::str(RTMP_SIG_SRS_AUTHROS));
data->set("contributors", SrsJsonAny::str(SRS_AUTO_CONSTRIBUTORS)); data->set("contributors", SrsJsonAny::str(SRS_AUTO_CONSTRIBUTORS));
return srs_api_response(w, r, obj->dumps()); return srs_api_response(w, r, obj->dumps());

View file

@ -37,7 +37,7 @@ class SrsServer;
#include <srs_http_stack.hpp> #include <srs_http_stack.hpp>
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>
// for http root. // For http root.
class SrsGoApiRoot : public ISrsHttpHandler class SrsGoApiRoot : public ISrsHttpHandler
{ {
public: public:
@ -187,7 +187,7 @@ public:
virtual ~SrsGoApiRaw(); virtual ~SrsGoApiRaw();
public: public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_http_api_raw_api(); virtual srs_error_t on_reload_http_api_raw_api();
}; };
@ -219,14 +219,14 @@ private:
public: public:
SrsHttpApi(IConnectionManager* cm, srs_netfd_t fd, SrsHttpServeMux* m, std::string cip); SrsHttpApi(IConnectionManager* cm, srs_netfd_t fd, SrsHttpServeMux* m, std::string cip);
virtual ~SrsHttpApi(); virtual ~SrsHttpApi();
// interface ISrsKbpsDelta // Interface ISrsKbpsDelta
public: public:
virtual void remark(int64_t* in, int64_t* out); virtual void remark(int64_t* in, int64_t* out);
protected: protected:
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
private: private:
virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_http_api_crossdomain(); virtual srs_error_t on_reload_http_api_crossdomain();
}; };

View file

@ -55,9 +55,7 @@ class SrsHttpMessage;
class SrsHttpStreamServer; class SrsHttpStreamServer;
class SrsHttpStaticServer; class SrsHttpStaticServer;
/** // The http connection which request the static or stream content.
* The http connection which request the static or stream content.
*/
class SrsHttpConn : public SrsConnection class SrsHttpConn : public SrsConnection
{ {
protected: protected:
@ -67,32 +65,28 @@ protected:
public: public:
SrsHttpConn(IConnectionManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, std::string cip); SrsHttpConn(IConnectionManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, std::string cip);
virtual ~SrsHttpConn(); virtual ~SrsHttpConn();
// interface ISrsKbpsDelta // Interface ISrsKbpsDelta
public: public:
virtual void remark(int64_t* in, int64_t* out); virtual void remark(int64_t* in, int64_t* out);
protected: protected:
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
protected: protected:
// when got http message, // When got http message,
// for the static service or api, discard any body. // for the static service or api, discard any body.
// for the stream caster, for instance, http flv streaming, may discard the flv header or not. // for the stream caster, for instance, http flv streaming, may discard the flv header or not.
virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg) = 0; virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg) = 0;
private: private:
virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
/** // When the connection disconnect, call this method.
* when the connection disconnect, call this method. // e.g. log msg of connection and report to other system.
* e.g. log msg of connection and report to other system. // @param request: request which is converted by the last http message.
* @param request: request which is converted by the last http message.
*/
virtual srs_error_t on_disconnect(SrsRequest* req); virtual srs_error_t on_disconnect(SrsRequest* req);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_http_stream_crossdomain(); virtual srs_error_t on_reload_http_stream_crossdomain();
}; };
/** // Drop body of request, only process the response.
* drop body of request, only process the response.
*/
class SrsResponseOnlyHttpConn : public SrsHttpConn class SrsResponseOnlyHttpConn : public SrsHttpConn
{ {
public: public:
@ -109,9 +103,7 @@ public:
virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg); virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg);
}; };
/** // The http server, use http stream or static server to serve requests.
* the http server, use http stream or static server to serve requests.
*/
class SrsHttpServer : public ISrsHttpServeMux class SrsHttpServer : public ISrsHttpServeMux
{ {
private: private:
@ -123,10 +115,9 @@ public:
virtual ~SrsHttpServer(); virtual ~SrsHttpServer();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
// ISrsHttpServeMux // Interface ISrsHttpServeMux
public: public:
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
// http flv/ts/mp3/aac stream
public: public:
virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r); virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r);
virtual void http_unmount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r);

View file

@ -34,11 +34,10 @@ class SrsRequest;
class SrsHttpParser; class SrsHttpParser;
class SrsHttpClient; class SrsHttpClient;
/** // the http hooks, http callback api,
* the http hooks, http callback api, // for some event, such as on_connect, call
* for some event, such as on_connect, call // a http api(hooks).
* a http api(hooks). // TODO: Refine to global variable.
*/
class SrsHttpHooks class SrsHttpHooks
{ {
private: private:
@ -46,76 +45,56 @@ private:
public: public:
virtual ~SrsHttpHooks(); virtual ~SrsHttpHooks();
public: public:
/** // The on_connect hook, when client connect to srs.
* on_connect hook, when client connect to srs. // @param url the api server url, to valid the client.
* @param url the api server url, to valid the client. // ignore if empty.
* ignore if empty.
*/
static srs_error_t on_connect(std::string url, SrsRequest* req); static srs_error_t on_connect(std::string url, SrsRequest* req);
/** // The on_close hook, when client disconnect to srs, where client is valid by on_connect.
* on_close hook, when client disconnect to srs, where client is valid by on_connect. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty.
*/
static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes); static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes);
/** // The on_publish hook, when client(encoder) start to publish stream
* on_publish hook, when client(encoder) start to publish stream // @param url the api server url, to valid the client.
* @param url the api server url, to valid the client. // ignore if empty.
* ignore if empty.
*/
static srs_error_t on_publish(std::string url, SrsRequest* req); static srs_error_t on_publish(std::string url, SrsRequest* req);
/** // The on_unpublish hook, when client(encoder) stop publish stream.
* on_unpublish hook, when client(encoder) stop publish stream. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty.
*/
static void on_unpublish(std::string url, SrsRequest* req); static void on_unpublish(std::string url, SrsRequest* req);
/** // The on_play hook, when client start to play stream.
* on_play hook, when client start to play stream. // @param url the api server url, to valid the client.
* @param url the api server url, to valid the client. // ignore if empty.
* ignore if empty.
*/
static srs_error_t on_play(std::string url, SrsRequest* req); static srs_error_t on_play(std::string url, SrsRequest* req);
/** // The on_stop hook, when client stop to play the stream.
* on_stop hook, when client stop to play the stream. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty.
*/
static void on_stop(std::string url, SrsRequest* req); static void on_stop(std::string url, SrsRequest* req);
/** // The on_dvr hook, when reap a dvr file.
* on_dvr hook, when reap a dvr file. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty. // @param file the file path, can be relative or absolute path.
* @param file the file path, can be relative or absolute path. // @param cid the source connection cid, for the on_dvr is async call.
* @param cid the source connection cid, for the on_dvr is async call.
*/
static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file); static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file);
/** // When hls reap segment, callback.
* when hls reap segment, callback. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty. // @param file the ts file path, can be relative or absolute path.
* @param file the ts file path, can be relative or absolute path. // @param ts_url the ts url, which used for m3u8.
* @param ts_url the ts url, which used for m3u8. // @param m3u8 the m3u8 file path, can be relative or absolute path.
* @param m3u8 the m3u8 file path, can be relative or absolute path. // @param m3u8_url the m3u8 url, which is used for the http mount path.
* @param m3u8_url the m3u8 url, which is used for the http mount path. // @param sn the seq_no, the sequence number of ts in hls/m3u8.
* @param sn the seq_no, the sequence number of ts in hls/m3u8. // @param duration the segment duration in srs_utime_t.
* @param duration the segment duration in srs_utime_t. // @param cid the source connection cid, for the on_dvr is async call.
* @param cid the source connection cid, for the on_dvr is async call.
*/
static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url, static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration); std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration);
/** // When hls reap segment, callback.
* when hls reap segment, callback. // @param url the api server url, to process the event.
* @param url the api server url, to process the event. // ignore if empty.
* ignore if empty. // @param ts_url the ts uri, used to replace the variable [ts_url] in url.
* @param ts_url the ts uri, used to replace the variable [ts_url] in url. // @param nb_notify the max bytes to read from notify server.
* @param nb_notify the max bytes to read from notify server. // @param cid the source connection cid, for the on_dvr is async call.
* @param cid the source connection cid, for the on_dvr is async call.
*/
static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify); static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
/** // Discover co-workers for origin cluster.
* Discover co-workers for origin cluster.
*/
static srs_error_t discover_co_workers(std::string url, std::string& host, int& port); static srs_error_t discover_co_workers(std::string url, std::string& host, int& port);
private: private:
static srs_error_t do_post(SrsHttpClient* hc, std::string url, std::string req, int& code, std::string& res); static srs_error_t do_post(SrsHttpClient* hc, std::string url, std::string req, int& code, std::string& res);

View file

@ -28,12 +28,10 @@
#include <srs_app_http_conn.hpp> #include <srs_app_http_conn.hpp>
/** // The flv vod stream supports flv?start=offset-bytes.
* the flv vod stream supports flv?start=offset-bytes. // For example, http://server/file.flv?start=10240
* for example, http://server/file.flv?start=10240 // server will write flv header and sequence header,
* server will write flv header and sequence header, // then seek(10240) and response flv tag data.
* then seek(10240) and response flv tag data.
*/
class SrsVodStream : public SrsHttpFileServer class SrsVodStream : public SrsHttpFileServer
{ {
public: public:
@ -44,10 +42,8 @@ protected:
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end); virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
}; };
/** // The http static server instance,
* the http static server instance, // serve http static file and flv/mp4 vod stream.
* serve http static file and flv/mp4 vod stream.
*/
class SrsHttpStaticServer : virtual public ISrsReloadHandler class SrsHttpStaticServer : virtual public ISrsReloadHandler
{ {
private: private:
@ -61,7 +57,7 @@ public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
private: private:
virtual srs_error_t mount_vhost(std::string vhost, std::string& pmount); virtual srs_error_t mount_vhost(std::string vhost, std::string& pmount);
// interface ISrsReloadHandler. // Interface ISrsReloadHandler.
public: public:
virtual srs_error_t on_reload_vhost_added(std::string vhost); virtual srs_error_t on_reload_vhost_added(std::string vhost);
virtual srs_error_t on_reload_vhost_http_updated(); virtual srs_error_t on_reload_vhost_http_updated();

View file

@ -33,9 +33,7 @@ class SrsMp3Transmuxer;
class SrsFlvTransmuxer; class SrsFlvTransmuxer;
class SrsTsTransmuxer; class SrsTsTransmuxer;
/** // A cache for HTTP Live Streaming encoder, to make android(weixin) happy.
* A cache for HTTP Live Streaming encoder, to make android(weixin) happy.
*/
class SrsBufferCache : public ISrsCoroutineHandler class SrsBufferCache : public ISrsCoroutineHandler
{ {
private: private:
@ -52,48 +50,36 @@ public:
public: public:
virtual srs_error_t start(); virtual srs_error_t start();
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
// interface ISrsEndlessThreadHandler. // Interface ISrsEndlessThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };
/** // The encoder to transmux RTMP stream.
* The encoder to transmux RTMP stream.
*/
class ISrsBufferEncoder class ISrsBufferEncoder
{ {
public: public:
ISrsBufferEncoder(); ISrsBufferEncoder();
virtual ~ISrsBufferEncoder(); virtual ~ISrsBufferEncoder();
public: public:
/** // Initialize the encoder with file writer(to http response) and stream cache.
* initialize the encoder with file writer(to http response) and stream cache. // @param w the writer to write to http response.
* @param w the writer to write to http response. // @param c the stream cache for audio stream fast startup.
* @param c the stream cache for audio stream fast startup.
*/
virtual srs_error_t initialize(SrsFileWriter* w, SrsBufferCache* c) = 0; virtual srs_error_t initialize(SrsFileWriter* w, SrsBufferCache* c) = 0;
/** // Write rtmp video/audio/metadata.
* write rtmp video/audio/metadata.
*/
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size) = 0; virtual srs_error_t write_audio(int64_t timestamp, char* data, int size) = 0;
virtual srs_error_t write_video(int64_t timestamp, char* data, int size) = 0; virtual srs_error_t write_video(int64_t timestamp, char* data, int size) = 0;
virtual srs_error_t write_metadata(int64_t timestamp, char* data, int size) = 0; virtual srs_error_t write_metadata(int64_t timestamp, char* data, int size) = 0;
public: public:
/** // For some stream, for example, mp3 and aac, the audio stream,
* for some stream, for example, mp3 and aac, the audio stream, // we use large gop cache in encoder, for the gop cache of SrsSource is ignore audio.
* we use large gop cache in encoder, for the gop cache of SrsSource is ignore audio. // @return true to use gop cache of encoder; otherwise, use SrsSource.
* @return true to use gop cache of encoder; otherwise, use SrsSource.
*/
virtual bool has_cache() = 0; virtual bool has_cache() = 0;
/** // Dumps the cache of encoder to consumer.
* dumps the cache of encoder to consumer.
*/
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0; virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0;
}; };
/** // Transmux RTMP to HTTP Live Streaming.
* Transmux RTMP to HTTP Live Streaming.
*/
class SrsFlvStreamEncoder : public ISrsBufferEncoder class SrsFlvStreamEncoder : public ISrsBufferEncoder
{ {
protected: protected:
@ -112,26 +98,20 @@ public:
}; };
#ifdef SRS_PERF_FAST_FLV_ENCODER #ifdef SRS_PERF_FAST_FLV_ENCODER
/** // A Fast HTTP FLV Live Streaming, to write multiple tags by writev.
* A Fast HTTP FLV Live Streaming, to write multiple tags by writev. // @see https://github.com/ossrs/srs/issues/405
* @see https://github.com/ossrs/srs/issues/405
*/
class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder
{ {
public: public:
SrsFastFlvStreamEncoder(); SrsFastFlvStreamEncoder();
virtual ~SrsFastFlvStreamEncoder(); virtual ~SrsFastFlvStreamEncoder();
public: public:
/** // Write the tags in a time.
* write the tags in a time.
*/
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count); virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
}; };
#endif #endif
/** // Transmux RTMP to HTTP TS Streaming.
* Transmux RTMP to HTTP TS Streaming.
*/
class SrsTsStreamEncoder : public ISrsBufferEncoder class SrsTsStreamEncoder : public ISrsBufferEncoder
{ {
private: private:
@ -149,9 +129,7 @@ public:
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
}; };
/** // Transmux RTMP with AAC stream to HTTP AAC Streaming.
* Transmux RTMP with AAC stream to HTTP AAC Streaming.
*/
class SrsAacStreamEncoder : public ISrsBufferEncoder class SrsAacStreamEncoder : public ISrsBufferEncoder
{ {
private: private:
@ -170,9 +148,7 @@ public:
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
}; };
/** // Transmux RTMP with MP3 stream to HTTP MP3 Streaming.
* Transmux RTMP with MP3 stream to HTTP MP3 Streaming.
*/
class SrsMp3StreamEncoder : public ISrsBufferEncoder class SrsMp3StreamEncoder : public ISrsBufferEncoder
{ {
private: private:
@ -191,9 +167,7 @@ public:
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
}; };
/** // Write stream to http response direclty.
* write stream to http response direclty.
*/
class SrsBufferWriter : public SrsFileWriter class SrsBufferWriter : public SrsFileWriter
{ {
private: private:
@ -212,9 +186,7 @@ public:
virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite); virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite);
}; };
/** // HTTP Live Streaming, to transmux RTMP to HTTP FLV or other format.
* HTTP Live Streaming, to transmux RTMP to HTTP FLV or other format.
*/
class SrsLiveStream : public ISrsHttpHandler class SrsLiveStream : public ISrsHttpHandler
{ {
private: private:
@ -234,9 +206,7 @@ private:
virtual srs_error_t streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs); virtual srs_error_t streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs);
}; };
/** // The Live Entry, to handle HTTP Live Streaming.
* The Live Entry, to handle HTTP Live Streaming.
*/
struct SrsLiveEntry struct SrsLiveEntry
{ {
private: private:
@ -248,8 +218,8 @@ public:
SrsRequest* req; SrsRequest* req;
SrsSource* source; SrsSource* source;
public: public:
// for template, the mount contains variables. // For template, the mount contains variables.
// for concrete stream, the mount is url to access. // For concrete stream, the mount is url to access.
std::string mount; std::string mount;
SrsLiveStream* stream; SrsLiveStream* stream;
@ -263,9 +233,7 @@ public:
bool is_aac(); bool is_aac();
}; };
/** // The HTTP Live Streaming Server, to serve FLV/TS/MP3/AAC stream.
* The HTTP Live Streaming Server, to serve FLV/TS/MP3/AAC stream.
*/
// TODO: Support multiple stream. // TODO: Support multiple stream.
class SrsHttpStreamServer : virtual public ISrsReloadHandler class SrsHttpStreamServer : virtual public ISrsReloadHandler
, virtual public ISrsHttpMatchHijacker , virtual public ISrsHttpMatchHijacker
@ -274,24 +242,24 @@ private:
SrsServer* server; SrsServer* server;
public: public:
SrsHttpServeMux mux; SrsHttpServeMux mux;
// the http live streaming template, to create streams. // The http live streaming template, to create streams.
std::map<std::string, SrsLiveEntry*> tflvs; std::map<std::string, SrsLiveEntry*> tflvs;
// the http live streaming streams, crote by template. // The http live streaming streams, crote by template.
std::map<std::string, SrsLiveEntry*> sflvs; std::map<std::string, SrsLiveEntry*> sflvs;
public: public:
SrsHttpStreamServer(SrsServer* svr); SrsHttpStreamServer(SrsServer* svr);
virtual ~SrsHttpStreamServer(); virtual ~SrsHttpStreamServer();
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
// http flv/ts/mp3/aac stream
public: public:
// HTTP flv/ts/mp3/aac stream
virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r); virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r);
virtual void http_unmount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r);
// interface ISrsReloadHandler. // Interface ISrsReloadHandler.
public: public:
virtual srs_error_t on_reload_vhost_added(std::string vhost); virtual srs_error_t on_reload_vhost_added(std::string vhost);
virtual srs_error_t on_reload_vhost_http_remux_updated(std::string vhost); virtual srs_error_t on_reload_vhost_http_remux_updated(std::string vhost);
// interface ISrsHttpMatchHijacker // Interface ISrsHttpMatchHijacker
public: public:
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph); virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph);
private: private:

View file

@ -35,9 +35,7 @@ class SrsFFMPEG;
class SrsConfDirective; class SrsConfDirective;
class SrsPithyPrint; class SrsPithyPrint;
/** // Ingester ffmpeg object.
* ingester ffmpeg object.
*/
class SrsIngesterFFMPEG class SrsIngesterFFMPEG
{ {
private: private:
@ -50,9 +48,9 @@ public:
virtual ~SrsIngesterFFMPEG(); virtual ~SrsIngesterFFMPEG();
public: public:
virtual srs_error_t initialize(SrsFFMPEG* ff, std::string v, std::string i); virtual srs_error_t initialize(SrsFFMPEG* ff, std::string v, std::string i);
// the ingest uri, [vhost]/[ingest id] // The ingest uri, [vhost]/[ingest id]
virtual std::string uri(); virtual std::string uri();
// the alive in srs_utime_t. // The alive in srs_utime_t.
virtual srs_utime_t alive(); virtual srs_utime_t alive();
virtual bool equals(std::string v, std::string i); virtual bool equals(std::string v, std::string i);
virtual bool equals(std::string v); virtual bool equals(std::string v);
@ -64,11 +62,9 @@ public:
virtual void fast_stop(); virtual void fast_stop();
}; };
/** // Ingest file/stream/device,
* ingest file/stream/device, // encode with FFMPEG(optional),
* encode with FFMPEG(optional), // push to SRS(or any RTMP server) over RTMP.
* push to SRS(or any RTMP server) over RTMP.
*/
class SrsIngester : public ISrsCoroutineHandler, public ISrsReloadHandler class SrsIngester : public ISrsCoroutineHandler, public ISrsReloadHandler
{ {
private: private:
@ -76,8 +72,7 @@ private:
private: private:
SrsCoroutine* trd; SrsCoroutine* trd;
SrsPithyPrint* pprint; SrsPithyPrint* pprint;
// whether the ingesters are expired, // Whether the ingesters are expired, for example, the listen port changed,
// for example, the listen port changed,
// all ingesters must be restart. // all ingesters must be restart.
bool expired; bool expired;
public: public:
@ -90,7 +85,7 @@ public:
virtual void stop(); virtual void stop();
private: private:
virtual void fast_stop(); virtual void fast_stop();
// interface ISrsReusableThreadHandler. // Interface ISrsReusableThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
@ -102,7 +97,7 @@ private:
virtual srs_error_t parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest); virtual srs_error_t parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest);
virtual srs_error_t initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine); virtual srs_error_t initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine);
virtual void show_ingest_log_message(); virtual void show_ingest_log_message();
// interface ISrsReloadHandler. // Interface ISrsReloadHandler.
public: public:
virtual srs_error_t on_reload_vhost_removed(std::string vhost); virtual srs_error_t on_reload_vhost_removed(std::string vhost);
virtual srs_error_t on_reload_vhost_added(std::string vhost); virtual srs_error_t on_reload_vhost_added(std::string vhost);

View file

@ -42,14 +42,10 @@ class SrsKafkaProducer;
#ifdef SRS_AUTO_KAFKA #ifdef SRS_AUTO_KAFKA
/** // The partition messages cache.
* the partition messages cache.
*/
typedef std::vector<SrsJsonObject*> SrsKafkaPartitionCache; typedef std::vector<SrsJsonObject*> SrsKafkaPartitionCache;
/** // The kafka partition info.
* the kafka partition info.
*/
struct SrsKafkaPartition struct SrsKafkaPartition
{ {
private: private:
@ -75,9 +71,7 @@ private:
virtual void disconnect(); virtual void disconnect();
}; };
/** // The following is all types of kafka messages.
* the following is all types of kafka messages.
*/
class SrsKafkaMessage : public ISrsAsyncCallTask class SrsKafkaMessage : public ISrsAsyncCallTask
{ {
private: private:
@ -87,25 +81,23 @@ private:
public: public:
SrsKafkaMessage(SrsKafkaProducer* p, int k, SrsJsonObject* j); SrsKafkaMessage(SrsKafkaProducer* p, int k, SrsJsonObject* j);
virtual ~SrsKafkaMessage(); virtual ~SrsKafkaMessage();
// interface ISrsAsyncCallTask // Interface ISrsAsyncCallTask
public: public:
virtual srs_error_t call(); virtual srs_error_t call();
virtual std::string to_string(); virtual std::string to_string();
}; };
/** // A message cache for kafka.
* a message cache for kafka.
*/
class SrsKafkaCache class SrsKafkaCache
{ {
public: public:
// the total partitions, // The total partitions,
// for the key to map to the parition by key%nb_partitions. // for the key to map to the parition by key%nb_partitions.
int nb_partitions; int nb_partitions;
private: private:
// total messages for all partitions. // Total messages for all partitions.
int count; int count;
// key is the partition id, value is the message set to write to this partition. // The key is the partition id, value is the message set to write to this partition.
// @remark, when refresh metadata, the partition will increase, // @remark, when refresh metadata, the partition will increase,
// so maybe some message will dispatch to new partition. // so maybe some message will dispatch to new partition.
std::map< int32_t, SrsKafkaPartitionCache*> cache; std::map< int32_t, SrsKafkaPartitionCache*> cache;
@ -115,37 +107,27 @@ public:
public: public:
virtual void append(int key, SrsJsonObject* obj); virtual void append(int key, SrsJsonObject* obj);
virtual int size(); virtual int size();
/** // Fetch out a available partition cache.
* fetch out a available partition cache. // @return true when got a key and pc; otherwise, false.
* @return true when got a key and pc; otherwise, false.
*/
virtual bool fetch(int* pkey, SrsKafkaPartitionCache** ppc); virtual bool fetch(int* pkey, SrsKafkaPartitionCache** ppc);
/** // Flush the specified partition cache.
* flush the specified partition cache.
*/
virtual srs_error_t flush(SrsKafkaPartition* partition, int key, SrsKafkaPartitionCache* pc); virtual srs_error_t flush(SrsKafkaPartition* partition, int key, SrsKafkaPartitionCache* pc);
}; };
/** // The kafka cluster interface.
* the kafka cluster interface.
*/
class ISrsKafkaCluster class ISrsKafkaCluster
{ {
public: public:
ISrsKafkaCluster(); ISrsKafkaCluster();
virtual ~ISrsKafkaCluster(); virtual ~ISrsKafkaCluster();
public: public:
/** // When got any client connect to SRS, notify kafka.
* when got any client connect to SRS, notify kafka. // @param key the partition map key, the client id or hash(ip).
* @param key the partition map key, the client id or hash(ip). // @param type the type of client.
* @param type the type of client. // @param ip the peer ip of client.
* @param ip the peer ip of client.
*/
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip) = 0; virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip) = 0;
/** // When client close or disconnect for error.
* when client close or disconnect for error. // @param key the partition map key, the client id or hash(ip).
* @param key the partition map key, the client id or hash(ip).
*/
virtual srs_error_t on_close(int key) = 0; virtual srs_error_t on_close(int key) = 0;
}; };
@ -155,9 +137,7 @@ extern ISrsKafkaCluster* _srs_kafka;
extern srs_error_t srs_initialize_kafka(); extern srs_error_t srs_initialize_kafka();
extern void srs_dispose_kafka(); extern void srs_dispose_kafka();
/** // The kafka producer used to save log to kafka cluster.
* the kafka producer used to save log to kafka cluster.
*/
class SrsKafkaProducer : virtual public ISrsCoroutineHandler, virtual public ISrsKafkaCluster class SrsKafkaProducer : virtual public ISrsCoroutineHandler, virtual public ISrsKafkaCluster
{ {
private: private:
@ -183,25 +163,23 @@ public:
virtual void stop(); virtual void stop();
// internal: for worker to call task to send object. // internal: for worker to call task to send object.
public: public:
/** // Send json object to kafka cluster.
* send json object to kafka cluster. // The producer will aggregate message and send in kafka message set.
* the producer will aggregate message and send in kafka message set. // @param key the key to map to the partition, user can use cid or hash.
* @param key the key to map to the partition, user can use cid or hash. // @param obj the json object; user must never free it again.
* @param obj the json object; user must never free it again.
*/
virtual srs_error_t send(int key, SrsJsonObject* obj); virtual srs_error_t send(int key, SrsJsonObject* obj);
// interface ISrsKafkaCluster // Interface ISrsKafkaCluster
public: public:
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip); virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip);
virtual srs_error_t on_close(int key); virtual srs_error_t on_close(int key);
// interface ISrsReusableThreadHandler // Interface ISrsReusableThreadHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
virtual void clear_metadata(); virtual void clear_metadata();
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
virtual srs_error_t request_metadata(); virtual srs_error_t request_metadata();
// set the metadata to invalid and refresh it. // Set the metadata to invalid and refresh it.
virtual void refresh_metadata(); virtual void refresh_metadata();
virtual srs_error_t flush(); virtual srs_error_t flush();
}; };

View file

@ -33,51 +33,39 @@
struct sockaddr; struct sockaddr;
/** // The udp packet handler.
* the udp packet handler.
*/
class ISrsUdpHandler class ISrsUdpHandler
{ {
public: public:
ISrsUdpHandler(); ISrsUdpHandler();
virtual ~ISrsUdpHandler(); virtual ~ISrsUdpHandler();
public: public:
/** // When fd changed, for instance, reload the listen port,
* when fd changed, for instance, reload the listen port, // notify the handler and user can do something.
* notify the handler and user can do something.
*/
virtual srs_error_t on_stfd_change(srs_netfd_t fd); virtual srs_error_t on_stfd_change(srs_netfd_t fd);
public: public:
/** // When udp listener got a udp packet, notice server to process it.
* when udp listener got a udp packet, notice server to process it. // @param type, the client type, used to create concrete connection,
* @param type, the client type, used to create concrete connection, // for instance RTMP connection to serve client.
* for instance RTMP connection to serve client. // @param from, the udp packet from address.
* @param from, the udp packet from address. // @param buf, the udp packet bytes, user should copy if need to use.
* @param buf, the udp packet bytes, user should copy if need to use. // @param nb_buf, the size of udp packet bytes.
* @param nb_buf, the size of udp packet bytes. // @remark user should never use the buf, for it's a shared memory bytes.
* @remark user should never use the buf, for it's a shared memory bytes.
*/
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) = 0; virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) = 0;
}; };
/** // The tcp connection handler.
* the tcp connection handler.
*/
class ISrsTcpHandler class ISrsTcpHandler
{ {
public: public:
ISrsTcpHandler(); ISrsTcpHandler();
virtual ~ISrsTcpHandler(); virtual ~ISrsTcpHandler();
public: public:
/** // When got tcp client.
* when got tcp client.
*/
virtual srs_error_t on_tcp_client(srs_netfd_t stfd) = 0; virtual srs_error_t on_tcp_client(srs_netfd_t stfd) = 0;
}; };
/** // Bind udp port, start thread to recv packet and handler it.
* bind udp port, start thread to recv packet and handler it.
*/
class SrsUdpListener : public ISrsCoroutineHandler class SrsUdpListener : public ISrsCoroutineHandler
{ {
private: private:
@ -99,14 +87,12 @@ public:
virtual srs_netfd_t stfd(); virtual srs_netfd_t stfd();
public: public:
virtual srs_error_t listen(); virtual srs_error_t listen();
// interface ISrsReusableThreadHandler. // Interface ISrsReusableThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };
/** // Bind and listen tcp port, use handler to process the client.
* bind and listen tcp port, use handler to process the client.
*/
class SrsTcpListener : public ISrsCoroutineHandler class SrsTcpListener : public ISrsCoroutineHandler
{ {
private: private:
@ -124,7 +110,7 @@ public:
virtual int fd(); virtual int fd();
public: public:
virtual srs_error_t listen(); virtual srs_error_t listen();
// interface ISrsReusableThreadHandler. // Interface ISrsReusableThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };

View file

@ -32,29 +32,26 @@
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>
#include <srs_service_log.hpp> #include <srs_service_log.hpp>
/** // Use memory/disk cache and donot flush when write log.
* we use memory/disk cache and donot flush when write log. // it's ok to use it without config, which will log to console, and default trace level.
* it's ok to use it without config, which will log to console, and default trace level. // when you want to use different level, override this classs, set the protected _level.
* when you want to use different level, override this classs, set the protected _level.
*/
class SrsFastLog : public ISrsLog, public ISrsReloadHandler class SrsFastLog : public ISrsLog, public ISrsReloadHandler
{ {
// for utest to override private:
protected: // Defined in SrsLogLevel.
// defined in SrsLogLevel.
SrsLogLevel level; SrsLogLevel level;
private: private:
char* log_data; char* log_data;
// log to file if specified srs_log_file // Log to file if specified srs_log_file
int fd; int fd;
// whether log to file tank // Whether log to file tank
bool log_to_file_tank; bool log_to_file_tank;
// whether use utc time. // Whether use utc time.
bool utc; bool utc;
public: public:
SrsFastLog(); SrsFastLog();
virtual ~SrsFastLog(); virtual ~SrsFastLog();
// interface ISrsLog // Interface ISrsLog
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual void reopen(); virtual void reopen();
@ -63,7 +60,7 @@ public:
virtual void trace(const char* tag, int context_id, const char* fmt, ...); virtual void trace(const char* tag, int context_id, const char* fmt, ...);
virtual void warn(const char* tag, int context_id, const char* fmt, ...); virtual void warn(const char* tag, int context_id, const char* fmt, ...);
virtual void error(const char* tag, int context_id, const char* fmt, ...); virtual void error(const char* tag, int context_id, const char* fmt, ...);
// interface ISrsReloadHandler. // Interface ISrsReloadHandler.
public: public:
virtual srs_error_t on_reload_utc_time(); virtual srs_error_t on_reload_utc_time();
virtual srs_error_t on_reload_log_tank(); virtual srs_error_t on_reload_log_tank();

View file

@ -48,15 +48,13 @@ class SrsSimpleRtmpClient;
#include <srs_kernel_ts.hpp> #include <srs_kernel_ts.hpp>
#include <srs_app_listener.hpp> #include <srs_app_listener.hpp>
/** // The queue for mpegts over udp to send packets.
* the queue for mpegts over udp to send packets. // For the aac in mpegts contains many flv packets in a pes packet,
* for the aac in mpegts contains many flv packets in a pes packet, // we must recalc the timestamp.
* we must recalc the timestamp.
*/
class SrsMpegtsQueue class SrsMpegtsQueue
{ {
private: private:
// key: dts, value: msg. // The key: dts, value: msg.
std::map<int64_t, SrsSharedPtrMessage*> msgs; std::map<int64_t, SrsSharedPtrMessage*> msgs;
int nb_audios; int nb_audios;
int nb_videos; int nb_videos;
@ -68,11 +66,8 @@ public:
virtual SrsSharedPtrMessage* dequeue(); virtual SrsSharedPtrMessage* dequeue();
}; };
/** // The mpegts over udp stream caster.
* the mpegts over udp stream caster. class SrsMpegtsOverUdp : virtual public ISrsTsHandler, virtual public ISrsUdpHandler
*/
class SrsMpegtsOverUdp : virtual public ISrsTsHandler
, virtual public ISrsUdpHandler
{ {
private: private:
SrsTsContext* context; SrsTsContext* context;
@ -96,12 +91,12 @@ private:
public: public:
SrsMpegtsOverUdp(SrsConfDirective* c); SrsMpegtsOverUdp(SrsConfDirective* c);
virtual ~SrsMpegtsOverUdp(); virtual ~SrsMpegtsOverUdp();
// interface ISrsUdpHandler // Interface ISrsUdpHandler
public: public:
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
private: private:
virtual srs_error_t on_udp_bytes(std::string host, int port, char* buf, int nb_buf); virtual srs_error_t on_udp_bytes(std::string host, int port, char* buf, int nb_buf);
// interface ISrsTsHandler // Interface ISrsTsHandler
public: public:
virtual srs_error_t on_ts_message(SrsTsMessage* msg); virtual srs_error_t on_ts_message(SrsTsMessage* msg);
private: private:

View file

@ -35,11 +35,9 @@ class SrsRequest;
class SrsPithyPrint; class SrsPithyPrint;
class SrsProcess; class SrsProcess;
/** // The ng-exec is the exec feature introduced by nginx-rtmp,
* the ng-exec is the exec feature introduced by nginx-rtmp, // @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec_push
* @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec_push // @see https://github.com/ossrs/srs/issues/367
* @see https://github.com/ossrs/srs/issues/367
*/
class SrsNgExec : public ISrsCoroutineHandler class SrsNgExec : public ISrsCoroutineHandler
{ {
private: private:
@ -53,7 +51,7 @@ public:
public: public:
virtual srs_error_t on_publish(SrsRequest* req); virtual srs_error_t on_publish(SrsRequest* req);
virtual void on_unpublish(); virtual void on_unpublish();
// interface ISrsReusableThreadHandler. // Interface ISrsReusableThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:

View file

@ -28,9 +28,7 @@
#include <srs_app_reload.hpp> #include <srs_app_reload.hpp>
/** // The stage info to calc the age.
* the stage info to calc the age.
*/
class SrsStageInfo : public ISrsReloadHandler class SrsStageInfo : public ISrsReloadHandler
{ {
public: public:
@ -50,26 +48,24 @@ public:
virtual srs_error_t on_reload_pithy_print(); virtual srs_error_t on_reload_pithy_print();
}; };
/** // 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, // that is, we always got one message to print every specified time.
* that is, we always got one message to print every specified time. //
* // 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 1client, it will print every 3s.
* if there is 1client, it will print every 3s. // if there is 10clients, random select one to print every 3s.
* if there is 10clients, random select one to print every 3s. // Usage:
* Usage: // SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play();
* SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); // SrsAutoFree(SrsPithyPrint, pprint);
* SrsAutoFree(SrsPithyPrint, pprint); // while (true) {
* while (true) { // pprint->elapse();
* pprint->elapse(); // if (pprint->can_print()) {
* if (pprint->can_print()) { // // print pithy message.
* // print pithy message. // // user can get the elapse time by: pprint->age()
* // user can get the elapse time by: pprint->age() // }
* } // // read and write RTMP messages.
* // read and write RTMP messages. // }
* }
*/
class SrsPithyPrint class SrsPithyPrint
{ {
private: private:
@ -93,26 +89,16 @@ public:
static SrsPithyPrint* create_http_stream_cache(); static SrsPithyPrint* create_http_stream_cache();
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:
/** // Auto calc the elapse time
* auto calc the elapse time
*/
virtual void elapse(); virtual void elapse();
/** // Whether current client can print.
* whether current client can print.
*/
virtual bool can_print(); virtual bool can_print();
/** // Get the elapsed time in srs_utime_t.
* get the elapsed time in srs_utime_t.
*/
virtual srs_utime_t age(); virtual srs_utime_t age();
}; };

View file

@ -29,26 +29,24 @@
#include <string> #include <string>
#include <vector> #include <vector>
/** // Start and stop a process. Call cycle to restart the process when terminated.
* to start and stop a process, cycle to restart the process when terminated. // The usage:
* the usage: // // the binary is the process to fork.
* // the binary is the process to fork. // binary = "./objs/ffmpeg/bin/ffmpeg";
* binary = "./objs/ffmpeg/bin/ffmpeg"; // // where argv is a array contains each params.
* // where argv is a array contains each params. // argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"];
* argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"]; //
* // process = new SrsProcess();
* process = new SrsProcess(); // if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; }
* if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; } // if ((ret = process->start()) != ERROR_SUCCESS) { return ret; }
* if ((ret = process->start()) != ERROR_SUCCESS) { return ret; } // if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; }
* if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; } // process->fast_stop();
* process->fast_stop(); // process->stop();
* process->stop();
*/
class SrsProcess class SrsProcess
{ {
private: private:
bool is_started; bool is_started;
// whether SIGTERM send but need to wait or SIGKILL. // Whether SIGTERM send but need to wait or SIGKILL.
bool fast_stopped; bool fast_stopped;
pid_t pid; pid_t pid;
private: private:
@ -56,56 +54,42 @@ private:
std::string stdout_file; std::string stdout_file;
std::string stderr_file; std::string stderr_file;
std::vector<std::string> params; std::vector<std::string> params;
// the cli to fork process. // The cli to fork process.
std::string cli; std::string cli;
std::string actual_cli; std::string actual_cli;
public: public:
SrsProcess(); SrsProcess();
virtual ~SrsProcess(); virtual ~SrsProcess();
public: public:
/** // Get pid of process.
* get pid of process.
*/
virtual int get_pid(); virtual int get_pid();
/** // whether process is already started.
* whether process is already started.
*/
virtual bool started(); virtual bool started();
/** // Initialize the process with binary and argv.
* initialize the process with binary and argv. // @param binary the binary path to exec.
* @param binary the binary path to exec. // @param argv the argv for binary path, the argv[0] generally is the binary.
* @param argv the argv for binary path, the argv[0] generally is the binary. // @remark the argv[0] must be the binary.
* @remark the argv[0] must be the binary.
*/
virtual srs_error_t initialize(std::string binary, std::vector<std::string> argv); virtual srs_error_t initialize(std::string binary, std::vector<std::string> argv);
public: public:
/** // Start the process, ignore when already started.
* start the process, ignore when already started.
*/
virtual srs_error_t start(); virtual srs_error_t start();
/** // cycle check the process, update the state of process.
* cycle check the process, update the state of process. // @remark when process terminated(not started), user can restart it again by start().
* @remark when process terminated(not started), user can restart it again by start().
*/
virtual srs_error_t cycle(); virtual srs_error_t cycle();
/** // Send SIGTERM then SIGKILL to ensure the process stopped.
* send SIGTERM then SIGKILL to ensure the process stopped. // the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the
* the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the // process quit timeout.
* process quit timeout. // @remark use fast_stop before stop one by one, when got lots of process to quit.
* @remark use fast_stop before stop one by one, when got lots of process to quit.
*/
virtual void stop(); virtual void stop();
public: public:
/** // The fast stop is to send a SIGTERM.
* the fast stop is to send a SIGTERM. // for example, the ingesters owner lots of FFMPEG, it will take a long time
* for example, the ingesters owner lots of FFMPEG, it will take a long time // to stop one by one, instead the ingesters can fast_stop all FFMPEG, then
* to stop one by one, instead the ingesters can fast_stop all FFMPEG, then // wait one by one to stop, it's more faster.
* wait one by one to stop, it's more faster. // @remark user must use stop() to ensure the ffmpeg to stopped.
* @remark user must use stop() to ensure the ffmpeg to stopped. // @remark we got N processes to stop, compare the time we spend,
* @remark we got N processes to stop, compare the time we spend, // when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N]
* when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N] // but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
* but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
*/
virtual void fast_stop(); virtual void fast_stop();
}; };

View file

@ -42,54 +42,38 @@ class SrsConsumer;
class SrsHttpConn; class SrsHttpConn;
class SrsResponseOnlyHttpConn; class SrsResponseOnlyHttpConn;
/** // The message consumer which consume a message.
* The message consumer which consume a message.
*/
class ISrsMessageConsumer class ISrsMessageConsumer
{ {
public: public:
ISrsMessageConsumer(); ISrsMessageConsumer();
virtual ~ISrsMessageConsumer(); virtual ~ISrsMessageConsumer();
public: public:
/** // Consume the received message.
* Consume the received message. // @remark user must free this message.
* @remark user must free this message.
*/
virtual srs_error_t consume(SrsCommonMessage* msg) = 0; virtual srs_error_t consume(SrsCommonMessage* msg) = 0;
}; };
/** // The message pumper to pump messages to processer.
* The message pumper to pump messages to processer.
*/
class ISrsMessagePumper : public ISrsMessageConsumer class ISrsMessagePumper : public ISrsMessageConsumer
{ {
public: public:
ISrsMessagePumper(); ISrsMessagePumper();
virtual ~ISrsMessagePumper(); virtual ~ISrsMessagePumper();
public: public:
/** // Whether the pumper is interrupted.
* Whether the pumper is interrupted. // For example, when pumpter is busy, it's interrupted,
* For example, when pumpter is busy, it's interrupted, // please wait for a while then try to feed the pumper.
* please wait for a while then try to feed the pumper.
*/
virtual bool interrupted() = 0; virtual bool interrupted() = 0;
/** // Interrupt the pumper for a error.
* Interrupt the pumper for a error.
*/
virtual void interrupt(srs_error_t error) = 0; virtual void interrupt(srs_error_t error) = 0;
/** // When start the pumper.
* When start the pumper.
*/
virtual void on_start() = 0; virtual void on_start() = 0;
/** // When stop the pumper.
* When stop the pumper.
*/
virtual void on_stop() = 0; virtual void on_stop() = 0;
}; };
/** // The recv thread, use message handler to handle each received message.
* the recv thread, use message handler to handle each received message.
*/
class SrsRecvThread : public ISrsCoroutineHandler class SrsRecvThread : public ISrsCoroutineHandler
{ {
protected: protected:
@ -110,26 +94,24 @@ public:
virtual srs_error_t start(); virtual srs_error_t start();
virtual void stop(); virtual void stop();
virtual void stop_loop(); virtual void stop_loop();
// interface ISrsReusableThread2Handler // Interface ISrsReusableThread2Handler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
}; };
/** // The recv thread used to replace the timeout recv,
* the recv thread used to replace the timeout recv, // which hurt performance for the epoll_ctrl is frequently used.
* which hurt performance for the epoll_ctrl is frequently used. // @see: SrsRtmpConn::playing
* @see: SrsRtmpConn::playing // @see: https://github.com/ossrs/srs/issues/217
* @see: https://github.com/ossrs/srs/issues/217
*/
class SrsQueueRecvThread : public ISrsMessagePumper class SrsQueueRecvThread : public ISrsMessagePumper
{ {
private: private:
std::vector<SrsCommonMessage*> queue; std::vector<SrsCommonMessage*> queue;
SrsRecvThread trd; SrsRecvThread trd;
SrsRtmpServer* rtmp; SrsRtmpServer* rtmp;
// the recv thread error code. // The recv thread error code.
srs_error_t recv_error; srs_error_t recv_error;
SrsConsumer* _consumer; SrsConsumer* _consumer;
public: public:
@ -144,7 +126,7 @@ public:
virtual int size(); virtual int size();
virtual SrsCommonMessage* pump(); virtual SrsCommonMessage* pump();
virtual srs_error_t error_code(); virtual srs_error_t error_code();
// interface ISrsMessagePumper // Interface ISrsMessagePumper
public: public:
virtual srs_error_t consume(SrsCommonMessage* msg); virtual srs_error_t consume(SrsCommonMessage* msg);
virtual bool interrupted(); virtual bool interrupted();
@ -153,10 +135,8 @@ public:
virtual void on_stop(); virtual void on_stop();
}; };
/** // The publish recv thread got message and callback the source method to process message.
* the publish recv thread got message and callback the source method to process message. // @see: https://github.com/ossrs/srs/issues/237
* @see: https://github.com/ossrs/srs/issues/237
*/
class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
, virtual public IMergeReadHandler , virtual public IMergeReadHandler
@ -166,27 +146,27 @@ private:
SrsRecvThread trd; SrsRecvThread trd;
SrsRtmpServer* rtmp; SrsRtmpServer* rtmp;
SrsRequest* req; SrsRequest* req;
// the msgs already got. // The msgs already got.
int64_t _nb_msgs; int64_t _nb_msgs;
// The video frames we got. // The video frames we got.
uint64_t video_frames; uint64_t video_frames;
// for mr(merged read), // For mr(merged read),
// @see https://github.com/ossrs/srs/issues/241 // @see https://github.com/ossrs/srs/issues/241
bool mr; bool mr;
int mr_fd; int mr_fd;
srs_utime_t mr_sleep; srs_utime_t mr_sleep;
// for realtime // For realtime
// @see https://github.com/ossrs/srs/issues/257 // @see https://github.com/ossrs/srs/issues/257
bool realtime; bool realtime;
// the recv thread error code. // The recv thread error code.
srs_error_t recv_error; srs_error_t recv_error;
SrsRtmpConn* _conn; SrsRtmpConn* _conn;
// the params for conn callback. // The params for conn callback.
SrsSource* _source; SrsSource* _source;
// the error timeout cond // The error timeout cond
// @see https://github.com/ossrs/srs/issues/244 // @see https://github.com/ossrs/srs/issues/244
srs_cond_t error; srs_cond_t error;
// merged context id. // The merged context id.
int cid; int cid;
int ncid; int ncid;
public: public:
@ -194,9 +174,7 @@ public:
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid); int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid);
virtual ~SrsPublishRecvThread(); virtual ~SrsPublishRecvThread();
public: public:
/** // Wait for error for some timeout.
* wait for error for some timeout.
*/
virtual srs_error_t wait(srs_utime_t tm); virtual srs_error_t wait(srs_utime_t tm);
virtual int64_t nb_msgs(); virtual int64_t nb_msgs();
virtual uint64_t nb_video_frames(); virtual uint64_t nb_video_frames();
@ -206,19 +184,19 @@ public:
public: public:
virtual srs_error_t start(); virtual srs_error_t start();
virtual void stop(); virtual void stop();
// interface ISrsMessagePumper // Interface ISrsMessagePumper
public: public:
virtual srs_error_t consume(SrsCommonMessage* msg); virtual srs_error_t consume(SrsCommonMessage* msg);
virtual bool interrupted(); virtual bool interrupted();
virtual void interrupt(srs_error_t err); virtual void interrupt(srs_error_t err);
virtual void on_start(); virtual void on_start();
virtual void on_stop(); virtual void on_stop();
// interface IMergeReadHandler // Interface IMergeReadHandler
public: public:
#ifdef SRS_PERF_MERGED_READ #ifdef SRS_PERF_MERGED_READ
virtual void on_read(ssize_t nread); virtual void on_read(ssize_t nread);
#endif #endif
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_publish(std::string vhost); virtual srs_error_t on_reload_vhost_publish(std::string vhost);
virtual srs_error_t on_reload_vhost_realtime(std::string vhost); virtual srs_error_t on_reload_vhost_realtime(std::string vhost);
@ -226,12 +204,10 @@ private:
virtual void set_socket_buffer(srs_utime_t sleep_v); virtual void set_socket_buffer(srs_utime_t sleep_v);
}; };
/** // The HTTP receive thread, try to read messages util EOF.
* The HTTP receive thread, try to read messages util EOF. // For example, the HTTP FLV serving thread will use the receive thread to break
* For example, the HTTP FLV serving thread will use the receive thread to break // when client closed the request, to avoid FD leak.
* when client closed the request, to avoid FD leak. // @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
* @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
*/
class SrsHttpRecvThread : public ISrsCoroutineHandler class SrsHttpRecvThread : public ISrsCoroutineHandler
{ {
private: private:
@ -244,7 +220,7 @@ public:
virtual srs_error_t start(); virtual srs_error_t start();
public: public:
virtual srs_error_t pull(); virtual srs_error_t pull();
// interface ISrsOneCycleThreadHandler // Interface ISrsOneCycleThreadHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
}; };

View file

@ -36,11 +36,9 @@ public:
SrsRefer(); SrsRefer();
virtual ~SrsRefer(); virtual ~SrsRefer();
public: public:
/** // Check the refer.
* to check the refer. // @param page_url the client page url.
* @param page_url the client page url. // @param refer the refer in config.
* @param refer the refer in config.
*/
virtual srs_error_t check(std::string page_url, SrsConfDirective* refer); virtual srs_error_t check(std::string page_url, SrsConfDirective* refer);
private: private:
virtual srs_error_t check_single_refer(std::string page_url, std::string refer); virtual srs_error_t check_single_refer(std::string page_url, std::string refer);

View file

@ -28,13 +28,11 @@
#include <string> #include <string>
/** // The handler for config reload.
* the handler for config reload. // When reload callback, the config is updated yet.
* when reload callback, the config is updated yet. //
* // Features not support reload,
* features not support reload, // @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
* @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
*/
class ISrsReloadHandler class ISrsReloadHandler
{ {
public: public:

View file

@ -58,9 +58,7 @@ class SrsPacket;
class ISrsKafkaCluster; class ISrsKafkaCluster;
#endif #endif
/** // The simple rtmp client for SRS.
* The simple rtmp client for SRS.
*/
class SrsSimpleRtmpClient : public SrsBasicRtmpClient class SrsSimpleRtmpClient : public SrsBasicRtmpClient
{ {
public: public:
@ -70,9 +68,7 @@ protected:
virtual srs_error_t connect_app(); virtual srs_error_t connect_app();
}; };
/** // Some information of client.
* Some information of client.
*/
class SrsClientInfo class SrsClientInfo
{ {
public: public:
@ -89,12 +85,10 @@ public:
virtual ~SrsClientInfo(); virtual ~SrsClientInfo();
}; };
/** // The client provides the main logic control for RTMP clients.
* the client provides the main logic control for RTMP clients.
*/
class SrsRtmpConn : virtual public SrsConnection, virtual public ISrsReloadHandler class SrsRtmpConn : virtual public SrsConnection, virtual public ISrsReloadHandler
{ {
// for the thread to directly access any field of connection. // For the thread to directly access any field of connection.
friend class SrsPublishRecvThread; friend class SrsPublishRecvThread;
private: private:
SrsServer* server; SrsServer* server;
@ -102,27 +96,27 @@ private:
SrsRefer* refer; SrsRefer* refer;
SrsBandwidth* bandwidth; SrsBandwidth* bandwidth;
SrsSecurity* security; SrsSecurity* security;
// the wakable handler, maybe NULL. // The wakable handler, maybe NULL.
// TODO: FIXME: Should refine the state for receiving thread. // TODO: FIXME: Should refine the state for receiving thread.
ISrsWakable* wakable; ISrsWakable* wakable;
// elapse duration in srs_utime_t // The elapsed duration in srs_utime_t
// for live play duration, for instance, rtmpdump to record. // For live play duration, for instance, rtmpdump to record.
// @see https://github.com/ossrs/srs/issues/47 // @see https://github.com/ossrs/srs/issues/47
srs_utime_t duration; srs_utime_t duration;
// the MR(merged-write) sleep time in srs_utime_t. // The MR(merged-write) sleep time in srs_utime_t.
srs_utime_t mw_sleep; srs_utime_t mw_sleep;
// the MR(merged-write) only enabled for play. // The MR(merged-write) only enabled for play.
int mw_enabled; int mw_enabled;
// for realtime // For realtime
// @see https://github.com/ossrs/srs/issues/257 // @see https://github.com/ossrs/srs/issues/257
bool realtime; bool realtime;
// the minimal interval in srs_utime_t for delivery stream. // The minimal interval in srs_utime_t for delivery stream.
srs_utime_t send_min_interval; srs_utime_t send_min_interval;
// publish 1st packet timeout in srs_utime_t // The publish 1st packet timeout in srs_utime_t
srs_utime_t publish_1stpkt_timeout; srs_utime_t publish_1stpkt_timeout;
// publish normal packet timeout in srs_utime_t // The publish normal packet timeout in srs_utime_t
srs_utime_t publish_normal_timeout; srs_utime_t publish_normal_timeout;
// whether enable the tcp_nodelay. // Whether enable the tcp_nodelay.
bool tcp_nodelay; bool tcp_nodelay;
// About the rtmp client. // About the rtmp client.
SrsClientInfo* info; SrsClientInfo* info;
@ -133,20 +127,20 @@ public:
virtual void dispose(); virtual void dispose();
protected: protected:
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_removed(std::string vhost); virtual srs_error_t on_reload_vhost_removed(std::string vhost);
virtual srs_error_t on_reload_vhost_play(std::string vhost); virtual srs_error_t on_reload_vhost_play(std::string vhost);
virtual srs_error_t on_reload_vhost_tcp_nodelay(std::string vhost); virtual srs_error_t on_reload_vhost_tcp_nodelay(std::string vhost);
virtual srs_error_t on_reload_vhost_realtime(std::string vhost); virtual srs_error_t on_reload_vhost_realtime(std::string vhost);
virtual srs_error_t on_reload_vhost_publish(std::string vhost); virtual srs_error_t on_reload_vhost_publish(std::string vhost);
// interface ISrsKbpsDelta // Interface ISrsKbpsDelta
public: public:
virtual void remark(int64_t* in, int64_t* out); virtual void remark(int64_t* in, int64_t* out);
private: private:
// when valid and connected to vhost/app, service the client. // When valid and connected to vhost/app, service the client.
virtual srs_error_t service_cycle(); virtual srs_error_t service_cycle();
// stream(play/publish) service cycle, identify client first. // The stream(play/publish) service cycle, identify client first.
virtual srs_error_t stream_service_cycle(); virtual srs_error_t stream_service_cycle();
virtual srs_error_t check_vhost(bool try_default_vhost); virtual srs_error_t check_vhost(bool try_default_vhost);
virtual srs_error_t playing(SrsSource* source); virtual srs_error_t playing(SrsSource* source);
@ -164,10 +158,8 @@ private:
virtual srs_error_t check_edge_token_traverse_auth(); virtual srs_error_t check_edge_token_traverse_auth();
virtual srs_error_t do_token_traverse_auth(SrsRtmpClient* client); virtual srs_error_t do_token_traverse_auth(SrsRtmpClient* client);
private: private:
/** // When the connection disconnect, call this method.
* when the connection disconnect, call this method. // e.g. log msg of connection and report to other system.
* e.g. log msg of connection and report to other system.
*/
virtual srs_error_t on_disconnect(); virtual srs_error_t on_disconnect();
private: private:
virtual srs_error_t http_hooks_on_connect(); virtual srs_error_t http_hooks_on_connect();

View file

@ -52,9 +52,7 @@ class SrsSimpleStream;
class SrsPithyPrint; class SrsPithyPrint;
class SrsSimpleRtmpClient; class SrsSimpleRtmpClient;
/** // A rtp connection which transport a stream.
* a rtp connection which transport a stream.
*/
class SrsRtpConn: public ISrsUdpHandler class SrsRtpConn: public ISrsUdpHandler
{ {
private: private:
@ -70,14 +68,12 @@ public:
public: public:
virtual int port(); virtual int port();
virtual srs_error_t listen(); virtual srs_error_t listen();
// interface ISrsUdpHandler // Interface ISrsUdpHandler
public: public:
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
}; };
/** // The audio cache, audio is grouped by frames.
* audio is group by frames.
*/
struct SrsRtspAudioCache struct SrsRtspAudioCache
{ {
int64_t dts; int64_t dts;
@ -88,9 +84,7 @@ struct SrsRtspAudioCache
virtual ~SrsRtspAudioCache(); virtual ~SrsRtspAudioCache();
}; };
/** // The time jitter correct for rtsp.
* the time jitter correct for rtsp.
*/
class SrsRtspJitter class SrsRtspJitter
{ {
private: private:
@ -105,9 +99,7 @@ public:
virtual srs_error_t correct(int64_t& ts); virtual srs_error_t correct(int64_t& ts);
}; };
/** // The rtsp connection serve the fd.
* the rtsp connection serve the fd.
*/
class SrsRtspConn : public ISrsCoroutineHandler class SrsRtspConn : public ISrsCoroutineHandler
{ {
private: private:
@ -156,7 +148,7 @@ private:
// internal methods // internal methods
public: public:
virtual srs_error_t on_rtp_packet(SrsRtpPacket* pkt, int stream_id); virtual srs_error_t on_rtp_packet(SrsRtpPacket* pkt, int stream_id);
// interface ISrsOneCycleThreadHandler // Interface ISrsOneCycleThreadHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
@ -176,16 +168,14 @@ private:
virtual void close(); virtual void close();
}; };
/** // The caster for rtsp.
* the caster for rtsp.
*/
class SrsRtspCaster : public ISrsTcpHandler class SrsRtspCaster : public ISrsTcpHandler
{ {
private: private:
std::string output; std::string output;
int local_port_min; int local_port_min;
int local_port_max; int local_port_max;
// key: port, value: whether used. // The key: port, value: whether used.
std::map<int, bool> used_ports; std::map<int, bool> used_ports;
private: private:
std::vector<SrsRtspConn*> clients; std::vector<SrsRtspConn*> clients;
@ -193,19 +183,15 @@ public:
SrsRtspCaster(SrsConfDirective* c); SrsRtspCaster(SrsConfDirective* c);
virtual ~SrsRtspCaster(); virtual ~SrsRtspCaster();
public: public:
/** // Alloc a rtp port from local ports pool.
* alloc a rtp port from local ports pool. // @param pport output the rtp port.
* @param pport output the rtp port.
*/
virtual srs_error_t alloc_port(int* pport); virtual srs_error_t alloc_port(int* pport);
/** // Free the alloced rtp port.
* free the alloced rtp port.
*/
virtual void free_port(int lpmin, int lpmax); virtual void free_port(int lpmin, int lpmax);
// interface ISrsTcpHandler // Interface ISrsTcpHandler
public: public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd); virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
// internal methods. // internal methods.
public: public:
virtual void remove(SrsRtspConn* conn); virtual void remove(SrsRtspConn* conn);
}; };

View file

@ -32,33 +32,25 @@
class SrsConfDirective; class SrsConfDirective;
/** // The security apply on vhost.
* the security apply on vhost. // @see https://github.com/ossrs/srs/issues/211
* @see https://github.com/ossrs/srs/issues/211
*/
class SrsSecurity class SrsSecurity
{ {
public: public:
SrsSecurity(); SrsSecurity();
virtual ~SrsSecurity(); virtual ~SrsSecurity();
public: public:
/** // Security check the client apply by vhost security strategy
* security check the client apply by vhost security strategy // @param type the client type, publish or play.
* @param type the client type, publish or play. // @param ip the ip address of client.
* @param ip the ip address of client. // @param req the request object of client.
* @param req the request object of client.
*/
virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest* req); virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest* req);
private: private:
/** // Security check the allow,
* security check the allow, // @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
* @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
*/
virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
/** // Security check the deny,
* security check the deny, // @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
* @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
*/
virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
}; };

View file

@ -55,7 +55,7 @@ class SrsKafkaProducer;
#endif #endif
class SrsCoroutineManager; class SrsCoroutineManager;
// listener type for server to identify the connection, // The listener type for server to identify the connection,
// that is, use different type to process the connection. // that is, use different type to process the connection.
enum SrsListenerType enum SrsListenerType
{ {
@ -73,9 +73,7 @@ enum SrsListenerType
SrsListenerFlv = 5, SrsListenerFlv = 5,
}; };
/** // A common tcp listener, for RTMP/HTTP server.
* the common tcp listener, for RTMP/HTTP server.
*/
class SrsListener class SrsListener
{ {
protected: protected:
@ -92,9 +90,7 @@ public:
virtual srs_error_t listen(std::string i, int p) = 0; virtual srs_error_t listen(std::string i, int p) = 0;
}; };
/** // A buffered TCP listener.
* tcp listener.
*/
class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler
{ {
private: private:
@ -104,14 +100,12 @@ public:
virtual ~SrsBufferListener(); virtual ~SrsBufferListener();
public: public:
virtual srs_error_t listen(std::string ip, int port); virtual srs_error_t listen(std::string ip, int port);
// ISrsTcpHandler // Interface ISrsTcpHandler
public: public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd); virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
}; };
/** // A TCP listener, for rtsp server.
* the tcp listener, for rtsp server.
*/
class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler
{ {
private: private:
@ -122,14 +116,12 @@ public:
virtual ~SrsRtspListener(); virtual ~SrsRtspListener();
public: public:
virtual srs_error_t listen(std::string i, int p); virtual srs_error_t listen(std::string i, int p);
// ISrsTcpHandler // Interface ISrsTcpHandler
public: public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd); virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
}; };
/** // A TCP listener, for flv stream server.
* the tcp listener, for flv stream server.
*/
class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler
{ {
private: private:
@ -140,14 +132,12 @@ public:
virtual ~SrsHttpFlvListener(); virtual ~SrsHttpFlvListener();
public: public:
virtual srs_error_t listen(std::string i, int p); virtual srs_error_t listen(std::string i, int p);
// ISrsTcpHandler // Interface ISrsTcpHandler
public: public:
virtual srs_error_t on_tcp_client(srs_netfd_t stfd); virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
}; };
/** // A UDP listener, for udp server.
* the udp listener, for udp server.
*/
class SrsUdpStreamListener : public SrsListener class SrsUdpStreamListener : public SrsListener
{ {
protected: protected:
@ -160,9 +150,7 @@ public:
virtual srs_error_t listen(std::string i, int p); virtual srs_error_t listen(std::string i, int p);
}; };
/** // A UDP listener, for udp stream caster server.
* the udp listener, for udp stream caster server.
*/
class SrsUdpCasterListener : public SrsUdpStreamListener class SrsUdpCasterListener : public SrsUdpStreamListener
{ {
public: public:
@ -170,15 +158,13 @@ public:
virtual ~SrsUdpCasterListener(); virtual ~SrsUdpCasterListener();
}; };
/** // Convert signal to io,
* convert signal to io, // @see: st-1.9/docs/notes.html
* @see: st-1.9/docs/notes.html
*/
class SrsSignalManager : public ISrsCoroutineHandler class SrsSignalManager : public ISrsCoroutineHandler
{ {
private: private:
/* Per-process pipe which is used as a signal queue. */ // Per-process pipe which is used as a signal queue.
/* Up to PIPE_BUF/sizeof(int) signals can be queued up. */ // Up to PIPE_BUF/sizeof(int) signals can be queued up.
int sig_pipe[2]; int sig_pipe[2];
srs_netfd_t signal_read_stfd; srs_netfd_t signal_read_stfd;
private: private:
@ -190,47 +176,34 @@ public:
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual srs_error_t start(); virtual srs_error_t start();
// interface ISrsEndlessThreadHandler. // Interface ISrsEndlessThreadHandler.
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
private: private:
// global singleton instance // Global singleton instance
static SrsSignalManager* instance; static SrsSignalManager* instance;
/* Signal catching function. */ // Signal catching function.
/* Converts signal event to I/O event. */ // Converts signal event to I/O event.
static void sig_catcher(int signo); static void sig_catcher(int signo);
}; };
/** // A handler to the handle cycle in SRS RTMP server.
* the handler to the handle cycle in SRS RTMP server.
*/
class ISrsServerCycle class ISrsServerCycle
{ {
public: public:
ISrsServerCycle(); ISrsServerCycle();
virtual ~ISrsServerCycle(); virtual ~ISrsServerCycle();
public: public:
/** // Initialize the cycle handler.
* initialize the cycle handler.
*/
virtual srs_error_t initialize() = 0; virtual srs_error_t initialize() = 0;
/** // Do on_cycle while server doing cycle.
* do on_cycle while server doing cycle.
*/
virtual srs_error_t on_cycle() = 0; virtual srs_error_t on_cycle() = 0;
/** // Callback the handler when got client.
* callback the handler when got client.
*/
virtual srs_error_t on_accept_client(int max, int cur) = 0; virtual srs_error_t on_accept_client(int max, int cur) = 0;
}; };
/** // SRS RTMP server, initialize and listen, start connection service thread, destroy client.
* SRS RTMP server, initialize and listen, class SrsServer : virtual public ISrsReloadHandler, virtual public ISrsSourceHandler, virtual public IConnectionManager
* start connection service thread, destroy client.
*/
class SrsServer : virtual public ISrsReloadHandler
, virtual public ISrsSourceHandler
, virtual public IConnectionManager
{ {
private: private:
// TODO: FIXME: rename to http_api // TODO: FIXME: rename to http_api
@ -240,59 +213,41 @@ private:
SrsIngester* ingester; SrsIngester* ingester;
SrsCoroutineManager* conn_manager; SrsCoroutineManager* conn_manager;
private: private:
/** // The pid file fd, lock the file write when server is running.
* the pid file fd, lock the file write when server is running. // @remark the init.d script should cleanup the pid file, when stop service,
* @remark the init.d script should cleanup the pid file, when stop service, // for the server never delete the file; when system startup, the pid in pid file
* for the server never delete the file; when system startup, the pid in pid file // maybe valid but the process is not SRS, the init.d script will never start server.
* maybe valid but the process is not SRS, the init.d script will never start server.
*/
int pid_fd; int pid_fd;
/** // All connections, connection manager
* all connections, connection manager
*/
std::vector<SrsConnection*> conns; std::vector<SrsConnection*> conns;
/** // All listners, listener manager.
* all listners, listener manager.
*/
std::vector<SrsListener*> listeners; std::vector<SrsListener*> listeners;
/** // Signal manager which convert gignal to io message.
* signal manager which convert gignal to io message.
*/
SrsSignalManager* signal_manager; SrsSignalManager* signal_manager;
/** // Handle in server cycle.
* handle in server cycle.
*/
ISrsServerCycle* handler; ISrsServerCycle* handler;
/** // User send the signal, convert to variable.
* user send the signal, convert to variable.
*/
bool signal_reload; bool signal_reload;
bool signal_persistence_config; bool signal_persistence_config;
bool signal_gmc_stop; bool signal_gmc_stop;
bool signal_gracefully_quit; bool signal_gracefully_quit;
// parent pid for asprocess. // Parent pid for asprocess.
int ppid; int ppid;
public: public:
SrsServer(); SrsServer();
virtual ~SrsServer(); virtual ~SrsServer();
private: private:
/** // The destroy is for gmc to analysis the memory leak,
* the destroy is for gmc to analysis the memory leak, // if not destroy global/static data, the gmc will warning memory leak.
* if not destroy global/static data, the gmc will warning memory leak. // In service, server never destroy, directly exit when restart.
* in service, server never destroy, directly exit when restart.
*/
virtual void destroy(); virtual void destroy();
/** // When SIGTERM, SRS should do cleanup, for example,
* when SIGTERM, SRS should do cleanup, for example, // to stop all ingesters, cleanup HLS and dvr.
* to stop all ingesters, cleanup HLS and dvr.
*/
virtual void dispose(); virtual void dispose();
// server startup workflow, @see run_master() // server startup workflow, @see run_master()
public: public:
/** // Initialize server with callback handler ch.
* initialize server with callback handler ch. // @remark user must free the handler.
* @remark user must free the handler.
*/
virtual srs_error_t initialize(ISrsServerCycle* ch); virtual srs_error_t initialize(ISrsServerCycle* ch);
virtual srs_error_t initialize_st(); virtual srs_error_t initialize_st();
virtual srs_error_t initialize_signal(); virtual srs_error_t initialize_signal();
@ -304,64 +259,50 @@ public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
// server utilities. // server utilities.
public: public:
/** // The callback for signal manager got a signal.
* callback for signal manager got a signal. // The signal manager convert signal to io message,
* the signal manager convert signal to io message, // whatever, we will got the signo like the orignal signal(int signo) handler.
* whatever, we will got the signo like the orignal signal(int signo) handler. // @param signo the signal number from user, where:
* @param signo the signal number from user, where: // SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit.
* SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit. // SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file.
* SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file. // SRS_SIGNAL_RELOAD, the SIGHUP, reload the config.
* SRS_SIGNAL_RELOAD, the SIGHUP, reload the config. // SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file.
* SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file. // @remark, for SIGINT:
* @remark, for SIGINT: // no gmc, directly exit.
* no gmc, directly exit. // for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc.
* for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc. // @remark, maybe the HTTP RAW API will trigger the on_signal() also.
* @remark, maybe the HTTP RAW API will trigger the on_signal() also.
*/
virtual void on_signal(int signo); virtual void on_signal(int signo);
private: private:
/** // The server thread main cycle,
* the server thread main cycle, // update the global static data, for instance, the current time,
* update the global static data, for instance, the current time, // the cpu/mem/network statistic.
* the cpu/mem/network statistic.
*/
virtual srs_error_t do_cycle(); virtual srs_error_t do_cycle();
/** // listen at specified protocol.
* listen at specified protocol.
*/
virtual srs_error_t listen_rtmp(); virtual srs_error_t listen_rtmp();
virtual srs_error_t listen_http_api(); virtual srs_error_t listen_http_api();
virtual srs_error_t listen_http_stream(); virtual srs_error_t listen_http_stream();
virtual srs_error_t listen_stream_caster(); virtual srs_error_t listen_stream_caster();
/** // Close the listeners for specified type,
* close the listeners for specified type, // Remove the listen object from manager.
* remove the listen object from manager.
*/
virtual void close_listeners(SrsListenerType type); virtual void close_listeners(SrsListenerType type);
/** // Resample the server kbs.
* resample the server kbs.
*/
virtual void resample_kbps(); virtual void resample_kbps();
// internal only // For internal only
public: public:
/** // When listener got a fd, notice server to accept it.
* when listener got a fd, notice server to accept it. // @param type, the client type, used to create concrete connection,
* @param type, the client type, used to create concrete connection, // for instance RTMP connection to serve client.
* for instance RTMP connection to serve client. // @param stfd, the client fd in st boxed, the underlayer fd.
* @param stfd, the client fd in st boxed, the underlayer fd.
*/
virtual srs_error_t accept_client(SrsListenerType type, srs_netfd_t stfd); virtual srs_error_t accept_client(SrsListenerType type, srs_netfd_t stfd);
private: private:
virtual srs_error_t fd2conn(SrsListenerType type, srs_netfd_t stfd, SrsConnection** pconn); virtual srs_error_t fd2conn(SrsListenerType type, srs_netfd_t stfd, SrsConnection** pconn);
// IConnectionManager // Interface IConnectionManager
public: public:
/** // A callback for connection to remove itself.
* callback for connection to remove itself. // When connection thread cycle terminated, callback this to delete connection.
* when connection thread cycle terminated, callback this to delete connection. // @see SrsConnection.on_thread_stop().
* @see SrsConnection.on_thread_stop().
*/
virtual void remove(ISrsConnection* c); virtual void remove(ISrsConnection* c);
// interface ISrsReloadHandler. // Interface ISrsReloadHandler.
public: public:
virtual srs_error_t on_reload_listen(); virtual srs_error_t on_reload_listen();
virtual srs_error_t on_reload_pid(); virtual srs_error_t on_reload_pid();
@ -372,7 +313,7 @@ public:
virtual srs_error_t on_reload_http_stream_enabled(); virtual srs_error_t on_reload_http_stream_enabled();
virtual srs_error_t on_reload_http_stream_disabled(); virtual srs_error_t on_reload_http_stream_disabled();
virtual srs_error_t on_reload_http_stream_updated(); virtual srs_error_t on_reload_http_stream_updated();
// interface ISrsSourceHandler // Interface ISrsSourceHandler
public: public:
virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r); virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r);
virtual void on_unpublish(SrsSource* s, SrsRequest* r); virtual void on_unpublish(SrsSource* s, SrsRequest* r);

View file

@ -1590,8 +1590,6 @@ srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPac
// add server info to metadata // add server info to metadata
metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
metadata->metadata->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));
metadata->metadata->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));
// version, for example, 1.0.0 // version, for example, 1.0.0
// add version to metadata, please donot remove it, for debug. // add version to metadata, please donot remove it, for debug.

View file

@ -61,12 +61,10 @@ class SrsBuffer;
class SrsHds; class SrsHds;
#endif #endif
/** // The time jitter algorithm:
* the time jitter algorithm: // 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
* 1. full, to ensure stream start at zero, and ensure stream monotonically increasing. // 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
* 2. zero, only ensure sttream start at zero, ignore timestamp jitter. // 3. off, disable the time jitter algorithm, like atc.
* 3. off, disable the time jitter algorithm, like atc.
*/
enum SrsRtmpJitterAlgorithm enum SrsRtmpJitterAlgorithm
{ {
SrsRtmpJitterAlgorithmFULL = 0x01, SrsRtmpJitterAlgorithmFULL = 0x01,
@ -75,10 +73,7 @@ enum SrsRtmpJitterAlgorithm
}; };
int _srs_time_jitter_string2int(std::string time_jitter); int _srs_time_jitter_string2int(std::string time_jitter);
/** // Time jitter detect and correct, to ensure the rtmp stream is monotonically.
* time jitter detect and correct,
* to ensure the rtmp stream is monotonically.
*/
class SrsRtmpJitter class SrsRtmpJitter
{ {
private: private:
@ -88,23 +83,16 @@ public:
SrsRtmpJitter(); SrsRtmpJitter();
virtual ~SrsRtmpJitter(); virtual ~SrsRtmpJitter();
public: public:
/** // detect the time jitter and correct it.
* detect the time jitter and correct it. // @param ag the algorithm to use for time jitter.
* @param ag the algorithm to use for time jitter.
*/
virtual srs_error_t correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag); virtual srs_error_t correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag);
/** // Get current client time, the last packet time.
* get current client time, the last packet time.
*/
virtual int64_t get_time(); virtual int64_t get_time();
}; };
#ifdef SRS_PERF_QUEUE_FAST_VECTOR #ifdef SRS_PERF_QUEUE_FAST_VECTOR
/** // To alloc and increase fixed space, fast remove and insert for msgs sender.
* to alloc and increase fixed space, // @see https://github.com/ossrs/srs/issues/251
* fast remove and insert for msgs sender.
* @see https://github.com/ossrs/srs/issues/251
*/
class SrsFastVector class SrsFastVector
{ {
private: private:
@ -127,10 +115,8 @@ public:
}; };
#endif #endif
/** // The message queue for the consumer(client), forwarder.
* the message queue for the consumer(client), forwarder. // We limit the size in seconds, drop old messages(the whole gop) if full.
* we limit the size in seconds, drop old messages(the whole gop) if full.
*/
class SrsMessageQueue class SrsMessageQueue
{ {
private: private:
@ -151,85 +137,63 @@ public:
SrsMessageQueue(bool ignore_shrink = false); SrsMessageQueue(bool ignore_shrink = false);
virtual ~SrsMessageQueue(); virtual ~SrsMessageQueue();
public: public:
/** // Get the size of queue.
* get the size of queue.
*/
virtual int size(); virtual int size();
/** // Get the duration of queue.
* get the duration of queue.
*/
virtual srs_utime_t duration(); virtual srs_utime_t duration();
/** // Set the queue size
* set the queue size // @param queue_size the queue size in srs_utime_t.
* @param queue_size the queue size in srs_utime_t.
*/
virtual void set_queue_size(srs_utime_t queue_size); virtual void set_queue_size(srs_utime_t queue_size);
public: public:
/** // Enqueue the message, the timestamp always monotonically.
* enqueue the message, the timestamp always monotonically. // @param msg, the msg to enqueue, user never free it whatever the return code.
* @param msg, the msg to enqueue, user never free it whatever the return code. // @param is_overflow, whether overflow and shrinked. NULL to ignore.
* @param is_overflow, whether overflow and shrinked. NULL to ignore.
*/
virtual srs_error_t enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL); virtual srs_error_t enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL);
/** // Get packets in consumer queue.
* get packets in consumer queue. // @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it.
* @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it. // @count the count in array, output param.
* @count the count in array, output param. // @max_count the max count to dequeue, must be positive.
* @max_count the max count to dequeue, must be positive.
*/
virtual srs_error_t dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count); virtual srs_error_t dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
/** // Dumps packets to consumer, use specified args.
* dumps packets to consumer, use specified args. // @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
* @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
*/
virtual srs_error_t dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag); virtual srs_error_t dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag);
private: private:
/** // Remove a gop from the front.
* remove a gop from the front. // if no iframe found, clear it.
* if no iframe found, clear it.
*/
virtual void shrink(); virtual void shrink();
public: public:
/** // clear all messages in queue.
* clear all messages in queue.
*/
virtual void clear(); virtual void clear();
}; };
/** // The wakable used for some object
* the wakable used for some object // which is waiting on cond.
* which is waiting on cond.
*/
class ISrsWakable class ISrsWakable
{ {
public: public:
ISrsWakable(); ISrsWakable();
virtual ~ISrsWakable(); virtual ~ISrsWakable();
public: public:
/** // when the consumer(for player) got msg from recv thread,
* when the consumer(for player) got msg from recv thread, // it must be processed for maybe it's a close msg, so the cond
* it must be processed for maybe it's a close msg, so the cond // wait must be wakeup.
* wait must be wakeup.
*/
virtual void wakeup() = 0; virtual void wakeup() = 0;
}; };
/** // The consumer for SrsSource, that is a play client.
* the consumer for SrsSource, that is a play client.
*/
class SrsConsumer : public ISrsWakable class SrsConsumer : public ISrsWakable
{ {
private: private:
SrsRtmpJitter* jitter; SrsRtmpJitter* jitter;
SrsSource* source; SrsSource* source;
SrsMessageQueue* queue; SrsMessageQueue* queue;
// the owner connection for debug, maybe NULL. // The owner connection for debug, maybe NULL.
SrsConnection* conn; SrsConnection* conn;
bool paused; bool paused;
// when source id changed, notice all consumers // when source id changed, notice all consumers
bool should_update_source_id; bool should_update_source_id;
#ifdef SRS_PERF_QUEUE_COND_WAIT #ifdef SRS_PERF_QUEUE_COND_WAIT
// the cond wait for mw. // The cond wait for mw.
// @see https://github.com/ossrs/srs/issues/251 // @see https://github.com/ossrs/srs/issues/251
srs_cond_t mw_wait; srs_cond_t mw_wait;
bool mw_waiting; bool mw_waiting;
@ -240,159 +204,109 @@ public:
SrsConsumer(SrsSource* s, SrsConnection* c); SrsConsumer(SrsSource* s, SrsConnection* c);
virtual ~SrsConsumer(); virtual ~SrsConsumer();
public: public:
/** // Set the size of queue.
* set the size of queue.
*/
virtual void set_queue_size(srs_utime_t queue_size); virtual void set_queue_size(srs_utime_t queue_size);
/** // when source id changed, notice client to print.
* when source id changed, notice client to print.
*/
virtual void update_source_id(); virtual void update_source_id();
public: public:
/** // Get current client time, the last packet time.
* get current client time, the last packet time.
*/
virtual int64_t get_time(); virtual int64_t get_time();
/** // Enqueue an shared ptr message.
* enqueue an shared ptr message. // @param shared_msg, directly ptr, copy it if need to save it.
* @param shared_msg, directly ptr, copy it if need to save it. // @param whether atc, donot use jitter correct if true.
* @param whether atc, donot use jitter correct if true. // @param ag the algorithm of time jitter.
* @param ag the algorithm of time jitter.
*/
virtual srs_error_t enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); virtual srs_error_t enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag);
/** // Get packets in consumer queue.
* get packets in consumer queue. // @param msgs the msgs array to dump packets to send.
* @param msgs the msgs array to dump packets to send. // @param count the count in array, intput and output param.
* @param count the count in array, intput and output param. // @remark user can specifies the count to get specified msgs; 0 to get all if possible.
* @remark user can specifies the count to get specified msgs; 0 to get all if possible.
*/
virtual srs_error_t dump_packets(SrsMessageArray* msgs, int& count); virtual srs_error_t dump_packets(SrsMessageArray* msgs, int& count);
#ifdef SRS_PERF_QUEUE_COND_WAIT #ifdef SRS_PERF_QUEUE_COND_WAIT
/** // wait for messages incomming, atleast nb_msgs and in duration.
* wait for messages incomming, atleast nb_msgs and in duration. // @param nb_msgs the messages count to wait.
* @param nb_msgs the messages count to wait. // @param msgs_duration the messages duration to wait.
* @param msgs_duration the messages duration to wait.
*/
virtual void wait(int nb_msgs, srs_utime_t msgs_duration); virtual void wait(int nb_msgs, srs_utime_t msgs_duration);
#endif #endif
/** // when client send the pause message.
* when client send the pause message.
*/
virtual srs_error_t on_play_client_pause(bool is_pause); virtual srs_error_t on_play_client_pause(bool is_pause);
// ISrsWakable // Interface ISrsWakable
public: public:
/** // when the consumer(for player) got msg from recv thread,
* when the consumer(for player) got msg from recv thread, // it must be processed for maybe it's a close msg, so the cond
* it must be processed for maybe it's a close msg, so the cond // wait must be wakeup.
* wait must be wakeup.
*/
virtual void wakeup(); virtual void wakeup();
}; };
/** // cache a gop of video/audio data,
* cache a gop of video/audio data, // delivery at the connect of flash player,
* delivery at the connect of flash player, // To enable it to fast startup.
* to enable it to fast startup.
*/
class SrsGopCache class SrsGopCache
{ {
private: private:
/** // if disabled the gop cache,
* if disabled the gop cache, // The client will wait for the next keyframe for h264,
* the client will wait for the next keyframe for h264, // and will be black-screen.
* and will be black-screen.
*/
bool enable_gop_cache; bool enable_gop_cache;
/** // The video frame count, avoid cache for pure audio stream.
* the video frame count, avoid cache for pure audio stream.
*/
int cached_video_count; int cached_video_count;
/** // when user disabled video when publishing, and gop cache enalbed,
* when user disabled video when publishing, and gop cache enalbed, // We will cache the audio/video for we already got video, but we never
* we will cache the audio/video for we already got video, but we never // know when to clear the gop cache, for there is no video in future,
* know when to clear the gop cache, for there is no video in future, // so we must guess whether user disabled the video.
* so we must guess whether user disabled the video. // when we got some audios after laster video, for instance, 600 audio packets,
* when we got some audios after laster video, for instance, 600 audio packets, // about 3s(26ms per packet) 115 audio packets, clear gop cache.
* about 3s(26ms per packet) 115 audio packets, clear gop cache. //
* // @remark, it is ok for performance, for when we clear the gop cache,
* @remark, it is ok for performance, for when we clear the gop cache, // gop cache is disabled for pure audio stream.
* gop cache is disabled for pure audio stream. // @see: https://github.com/ossrs/srs/issues/124
* @see: https://github.com/ossrs/srs/issues/124
*/
int audio_after_last_video_count; int audio_after_last_video_count;
/** // cached gop.
* cached gop.
*/
std::vector<SrsSharedPtrMessage*> gop_cache; std::vector<SrsSharedPtrMessage*> gop_cache;
public: public:
SrsGopCache(); SrsGopCache();
virtual ~SrsGopCache(); virtual ~SrsGopCache();
public: public:
/** // cleanup when system quit.
* cleanup when system quit.
*/
virtual void dispose(); virtual void dispose();
/** // To enable or disable the gop cache.
* to enable or disable the gop cache.
*/
virtual void set(bool v); virtual void set(bool v);
virtual bool enabled(); virtual bool enabled();
/** // only for h264 codec
* only for h264 codec // 1. cache the gop when got h264 video packet.
* 1. cache the gop when got h264 video packet. // 2. clear gop when got keyframe.
* 2. clear gop when got keyframe. // @param shared_msg, directly ptr, copy it if need to save it.
* @param shared_msg, directly ptr, copy it if need to save it.
*/
virtual srs_error_t cache(SrsSharedPtrMessage* shared_msg); virtual srs_error_t cache(SrsSharedPtrMessage* shared_msg);
/** // clear the gop cache.
* clear the gop cache.
*/
virtual void clear(); virtual void clear();
/** // dump the cached gop to consumer.
* dump the cached gop to consumer.
*/
virtual srs_error_t dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm); virtual srs_error_t dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm);
/** // used for atc to get the time of gop cache,
* used for atc to get the time of gop cache, // The atc will adjust the sequence header timestamp to gop cache.
* the atc will adjust the sequence header timestamp to gop cache.
*/
virtual bool empty(); virtual bool empty();
/** // Get the start time of gop cache, in srs_utime_t.
* get the start time of gop cache, in srs_utime_t. // @return 0 if no packets.
* @return 0 if no packets.
*/
virtual srs_utime_t start_time(); virtual srs_utime_t start_time();
/** // whether current stream is pure audio,
* whether current stream is pure audio, // when no video in gop cache, the stream is pure audio right now.
* when no video in gop cache, the stream is pure audio right now.
*/
virtual bool pure_audio(); virtual bool pure_audio();
}; };
/** // The handler to handle the event of srs source.
* the handler to handle the event of srs source. // For example, the http flv streaming module handle the event and
* for example, the http flv streaming module handle the event and // mount http when rtmp start publishing.
* mount http when rtmp start publishing.
*/
class ISrsSourceHandler class ISrsSourceHandler
{ {
public: public:
ISrsSourceHandler(); ISrsSourceHandler();
virtual ~ISrsSourceHandler(); virtual ~ISrsSourceHandler();
public: public:
/** // when stream start publish, mount stream.
* when stream start publish, mount stream.
*/
virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r) = 0; virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r) = 0;
/** // when stream stop publish, unmount stream.
* when stream stop publish, unmount stream.
*/
virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0; virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0;
}; };
/** // The mix queue to correct the timestamp for mix_correct algorithm.
* the mix queue to correct the timestamp for mix_correct algorithm.
*/
class SrsMixQueue class SrsMixQueue
{ {
private: private:
@ -408,11 +322,9 @@ public:
virtual SrsSharedPtrMessage* pop(); virtual SrsSharedPtrMessage* pop();
}; };
/** // The hub for origin is a collection of utilities for origin only,
* The hub for origin is a collection of utilities for origin only, // For example, DVR, HLS, Forward and Transcode are only available for origin,
* for example, DVR, HLS, Forward and Transcode are only available for origin, // they are meanless for edge server.
* they are meanless for edge server.
*/
class SrsOriginHub : public ISrsReloadHandler class SrsOriginHub : public ISrsReloadHandler
{ {
private: private:
@ -437,7 +349,7 @@ private:
#endif #endif
// nginx-rtmp exec feature. // nginx-rtmp exec feature.
SrsNgExec* ng_exec; SrsNgExec* ng_exec;
// to forward stream to other servers // To forward stream to other servers
std::vector<SrsForwarder*> forwarders; std::vector<SrsForwarder*> forwarders;
public: public:
SrsOriginHub(); SrsOriginHub();
@ -447,10 +359,10 @@ public:
// @param r The request object, managed by source. // @param r The request object, managed by source.
virtual srs_error_t initialize(SrsSource* s, SrsRequest* r); virtual srs_error_t initialize(SrsSource* s, SrsRequest* r);
// Dispose the hub, release utilities resource, // Dispose the hub, release utilities resource,
// for example, delete all HLS pieces. // For example, delete all HLS pieces.
virtual void dispose(); virtual void dispose();
// Cycle the hub, process some regular events, // Cycle the hub, process some regular events,
// for example, dispose hls in cycle. // For example, dispose hls in cycle.
virtual srs_error_t cycle(); virtual srs_error_t cycle();
public: public:
// When got a parsed metadata. // When got a parsed metadata.
@ -466,11 +378,11 @@ public:
virtual void on_unpublish(); virtual void on_unpublish();
// Internal callback. // Internal callback.
public: public:
// for the SrsForwarder to callback to request the sequence headers. // For the SrsForwarder to callback to request the sequence headers.
virtual srs_error_t on_forwarder_start(SrsForwarder* forwarder); virtual srs_error_t on_forwarder_start(SrsForwarder* forwarder);
// for the SrsDvr to callback to request the sequence headers. // For the SrsDvr to callback to request the sequence headers.
virtual srs_error_t on_dvr_request_sh(); virtual srs_error_t on_dvr_request_sh();
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_forward(std::string vhost); virtual srs_error_t on_reload_vhost_forward(std::string vhost);
virtual srs_error_t on_reload_vhost_dash(std::string vhost); virtual srs_error_t on_reload_vhost_dash(std::string vhost);
@ -484,10 +396,8 @@ private:
virtual void destroy_forwarders(); virtual void destroy_forwarders();
}; };
/** // Each stream have optional meta(sps/pps in sequence header and metadata).
* Each stream have optional meta(sps/pps in sequence header and metadata). // This class cache and update the meta.
* This class cache and update the meta.
*/
class SrsMetaCache class SrsMetaCache
{ {
private: private:
@ -528,46 +438,35 @@ public:
virtual srs_error_t update_vsh(SrsSharedPtrMessage* msg); virtual srs_error_t update_vsh(SrsSharedPtrMessage* msg);
}; };
/** // live streaming source.
* live streaming source.
*/
class SrsSource : public ISrsReloadHandler class SrsSource : public ISrsReloadHandler
{ {
friend class SrsOriginHub; friend class SrsOriginHub;
private: private:
static std::map<std::string, SrsSource*> pool; static std::map<std::string, SrsSource*> pool;
public: public:
/** // create source when fetch from cache failed.
* create source when fetch from cache failed. // @param r the client request.
* @param r the client request. // @param h the event handler for source.
* @param h the event handler for source. // @param pps the matched source, if success never be NULL.
* @param pps the matched source, if success never be NULL.
*/
static srs_error_t fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps); static srs_error_t fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps);
private: private:
/** // Get the exists source, NULL when not exists.
* get the exists source, NULL when not exists. // update the request and return the exists source.
* update the request and return the exists source.
*/
static SrsSource* fetch(SrsRequest* r); static SrsSource* fetch(SrsRequest* r);
public: public:
/** // dispose and cycle all sources.
* dispose and cycle all sources.
*/
static void dispose_all(); static void dispose_all();
static srs_error_t cycle_all(); static srs_error_t cycle_all();
private: private:
static srs_error_t do_cycle_all(); static srs_error_t do_cycle_all();
public: public:
/** // when system exit, destroy the sources,
* when system exit, destroy the sources, // For gmc to analysis mem leaks.
* for gmc to analysis mem leaks.
*/
static void destroy(); static void destroy();
private: private:
// source id, // For publish, it's the publish client id.
// for publish, it's the publish client id. // For edge, it's the edge ingest id.
// for edge, it's the edge ingest id.
// when source id changed, for example, the edge reconnect, // when source id changed, for example, the edge reconnect,
// invoke the on_source_id_changed() to let all clients know. // invoke the on_source_id_changed() to let all clients know.
int _source_id; int _source_id;
@ -575,31 +474,29 @@ private:
int _pre_source_id; int _pre_source_id;
// deep copy of client request. // deep copy of client request.
SrsRequest* req; SrsRequest* req;
// to delivery stream to clients. // To delivery stream to clients.
std::vector<SrsConsumer*> consumers; std::vector<SrsConsumer*> consumers;
// the time jitter algorithm for vhost. // The time jitter algorithm for vhost.
SrsRtmpJitterAlgorithm jitter_algorithm; SrsRtmpJitterAlgorithm jitter_algorithm;
// for play, whether use interlaced/mixed algorithm to correct timestamp. // For play, whether use interlaced/mixed algorithm to correct timestamp.
bool mix_correct; bool mix_correct;
// the mix queue to implements the mix correct algorithm. // The mix queue to implements the mix correct algorithm.
SrsMixQueue* mix_queue; SrsMixQueue* mix_queue;
/** // For play, whether enabled atc.
* for play, whether enabled atc. // The atc(use absolute time and donot adjust time),
* atc whether atc(use absolute time and donot adjust time), // directly use msg time and donot adjust if atc is true,
* directly use msg time and donot adjust if atc is true, // otherwise, adjust msg time to start from 0 to make flash happy.
* otherwise, adjust msg time to start from 0 to make flash happy.
*/
bool atc; bool atc;
// whether stream is monotonically increase. // whether stream is monotonically increase.
bool is_monotonically_increase; bool is_monotonically_increase;
// the time of the packet we just got. // The time of the packet we just got.
int64_t last_packet_time; int64_t last_packet_time;
// the event handler. // The event handler.
ISrsSourceHandler* handler; ISrsSourceHandler* handler;
// edge control service // The edge control service
SrsPlayEdge* play_edge; SrsPlayEdge* play_edge;
SrsPublishEdge* publish_edge; SrsPublishEdge* publish_edge;
// gop cache for client fast startup. // The gop cache for client fast startup.
SrsGopCache* gop_cache; SrsGopCache* gop_cache;
// The hub for origin server. // The hub for origin server.
SrsOriginHub* hub; SrsOriginHub* hub;
@ -609,7 +506,7 @@ private:
// Whether source is avaiable for publishing. // Whether source is avaiable for publishing.
bool _can_publish; bool _can_publish;
// The last die time, when all consumers quit and no publisher, // The last die time, when all consumers quit and no publisher,
// we will remove the source when source die. // We will remove the source when source die.
srs_utime_t die_at; srs_utime_t die_at;
public: public:
SrsSource(); SrsSource();
@ -617,26 +514,23 @@ public:
public: public:
virtual void dispose(); virtual void dispose();
virtual srs_error_t cycle(); virtual srs_error_t cycle();
// remove source when expired. // Remove source when expired.
virtual bool expired(); virtual bool expired();
// initialize, get and setter.
public: public:
// initialize the hls with handlers. // Initialize the hls with handlers.
virtual srs_error_t initialize(SrsRequest* r, ISrsSourceHandler* h); virtual srs_error_t initialize(SrsRequest* r, ISrsSourceHandler* h);
// interface ISrsReloadHandler // Interface ISrsReloadHandler
public: public:
virtual srs_error_t on_reload_vhost_play(std::string vhost); virtual srs_error_t on_reload_vhost_play(std::string vhost);
// for the tools callback
public: public:
// source id changed. // The source id changed.
virtual srs_error_t on_source_id_changed(int id); virtual srs_error_t on_source_id_changed(int id);
// get current source id. // Get current source id.
virtual int source_id(); virtual int source_id();
virtual int pre_source_id(); virtual int pre_source_id();
// Whether source is inactive, which means there is no publishing stream source. // Whether source is inactive, which means there is no publishing stream source.
// @remark For edge, it's inactive util stream has been pulled from origin. // @remark For edge, it's inactive util stream has been pulled from origin.
virtual bool inactive(); virtual bool inactive();
// logic data methods
public: public:
virtual bool can_publish(bool is_edge); virtual bool can_publish(bool is_edge);
virtual srs_error_t on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); virtual srs_error_t on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata);
@ -650,33 +544,27 @@ private:
virtual srs_error_t on_video_imp(SrsSharedPtrMessage* video); virtual srs_error_t on_video_imp(SrsSharedPtrMessage* video);
public: public:
virtual srs_error_t on_aggregate(SrsCommonMessage* msg); virtual srs_error_t on_aggregate(SrsCommonMessage* msg);
/** // Publish stream event notify.
* publish stream event notify. // @param _req the request from client, the source will deep copy it,
* @param _req the request from client, the source will deep copy it, // for when reload the request of client maybe invalid.
* for when reload the request of client maybe invalid.
*/
virtual srs_error_t on_publish(); virtual srs_error_t on_publish();
virtual void on_unpublish(); virtual void on_unpublish();
// consumer methods
public: public:
/** // Create consumer and dumps packets in cache.
* create consumer and dumps packets in cache. // @param consumer, output the create consumer.
* @param consumer, output the create consumer. // @param ds, whether dumps the sequence header.
* @param ds, whether dumps the sequence header. // @param dm, whether dumps the metadata.
* @param dm, whether dumps the metadata. // @param dg, whether dumps the gop cache.
* @param dg, whether dumps the gop cache.
*/
virtual srs_error_t create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true); virtual srs_error_t create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true);
virtual void on_consumer_destroy(SrsConsumer* consumer); virtual void on_consumer_destroy(SrsConsumer* consumer);
virtual void set_cache(bool enabled); virtual void set_cache(bool enabled);
virtual SrsRtmpJitterAlgorithm jitter(); virtual SrsRtmpJitterAlgorithm jitter();
// internal
public: public:
// for edge, when publish edge stream, check the state // For edge, when publish edge stream, check the state
virtual srs_error_t on_edge_start_publish(); virtual srs_error_t on_edge_start_publish();
// for edge, proxy the publish // For edge, proxy the publish
virtual srs_error_t on_edge_proxy_publish(SrsCommonMessage* msg); virtual srs_error_t on_edge_proxy_publish(SrsCommonMessage* msg);
// for edge, proxy stop publish // For edge, proxy stop publish
virtual void on_edge_proxy_unpublish(); virtual void on_edge_proxy_unpublish();
public: public:
virtual std::string get_curr_origin(); virtual std::string get_curr_origin();

View file

@ -31,49 +31,43 @@
#include <srs_service_st.hpp> #include <srs_service_st.hpp>
#include <srs_protocol_io.hpp> #include <srs_protocol_io.hpp>
/** // Each ST-coroutine must implements this interface,
* Each ST-coroutine must implements this interface, // to do the cycle job and handle some events.
* to do the cycle job and handle some events. //
* // Thread do a job then terminated normally, it's a SrsOneCycleThread:
* Thread do a job then terminated normally, it's a SrsOneCycleThread: // class SrsOneCycleThread : public ISrsCoroutineHandler {
* class SrsOneCycleThread : public ISrsCoroutineHandler { // public: SrsCoroutine trd;
* public: SrsCoroutine trd; // public: virtual srs_error_t cycle() {
* public: virtual srs_error_t cycle() { // // Do something, then return this cycle and thread terminated normally.
* // Do something, then return this cycle and thread terminated normally. // }
* } // };
* }; //
* // Thread has its inside loop, such as the RTMP receive thread:
* Thread has its inside loop, such as the RTMP receive thread: // class SrsReceiveThread : public ISrsCoroutineHandler {
* class SrsReceiveThread : public ISrsCoroutineHandler { // public: SrsCoroutine* trd;
* public: SrsCoroutine* trd; // public: virtual srs_error_t cycle() {
* public: virtual srs_error_t cycle() { // while (true) {
* while (true) { // // Check whether thread interrupted.
* // Check whether thread interrupted. // if ((err = trd->pull()) != srs_success) {
* if ((err = trd->pull()) != srs_success) { // return err;
* return err; // }
* } // // Do something, such as st_read() packets, it'll be wakeup
* // Do something, such as st_read() packets, it'll be wakeup // // when user stop or interrupt the thread.
* // when user stop or interrupt the thread. // }
* } // }
* } // };
* };
*/
class ISrsCoroutineHandler class ISrsCoroutineHandler
{ {
public: public:
ISrsCoroutineHandler(); ISrsCoroutineHandler();
virtual ~ISrsCoroutineHandler(); virtual ~ISrsCoroutineHandler();
public: public:
/** // Do the work. The ST-coroutine will terminated normally if it returned.
* Do the work. The ST-coroutine will terminated normally if it returned. // @remark If the cycle has its own loop, it must check the thread pull.
* @remark If the cycle has its own loop, it must check the thread pull.
*/
virtual srs_error_t cycle() = 0; virtual srs_error_t cycle() = 0;
}; };
/** // The corotine object.
* The corotine object.
*/
class SrsCoroutine class SrsCoroutine
{ {
public: public:
@ -89,10 +83,8 @@ public:
virtual int cid() = 0; virtual int cid() = 0;
}; };
/** // An empty coroutine, user can default to this object before create any real coroutine.
* An empty coroutine, user can default to this object before create any real coroutine. // @see https://github.com/ossrs/srs/pull/908
* @see https://github.com/ossrs/srs/pull/908
*/
class SrsDummyCoroutine : public SrsCoroutine class SrsDummyCoroutine : public SrsCoroutine
{ {
public: public:
@ -110,20 +102,18 @@ public:
typedef void* (*_ST_THREAD_CREATE_PFN)(void *(*start)(void *arg), void *arg, int joinable, int stack_size); typedef void* (*_ST_THREAD_CREATE_PFN)(void *(*start)(void *arg), void *arg, int joinable, int stack_size);
extern _ST_THREAD_CREATE_PFN _pfn_st_thread_create; extern _ST_THREAD_CREATE_PFN _pfn_st_thread_create;
/** // A ST-coroutine is a lightweight thread, just like the goroutine.
* A ST-coroutine is a lightweight thread, just like the goroutine. // But the goroutine maybe run on different thread, while ST-coroutine only
* But the goroutine maybe run on different thread, while ST-coroutine only // run in single thread, because it use setjmp and longjmp, so it may cause
* run in single thread, because it use setjmp and longjmp, so it may cause // problem in multiple threads. For SRS, we only use single thread module,
* problem in multiple threads. For SRS, we only use single thread module, // like NGINX to get very high performance, with asynchronous and non-blocking
* like NGINX to get very high performance, with asynchronous and non-blocking // sockets.
* sockets. // @reamrk For multiple processes, please use go-oryx to fork many SRS processes.
* @reamrk For multiple processes, please use go-oryx to fork many SRS processes. // Please read https://github.com/ossrs/go-oryx
* Please read https://github.com/ossrs/go-oryx // @remark For debugging of ST-coroutine, read _st_iterate_threads_flag of ST/README
* @remark For debugging of ST-coroutine, read _st_iterate_threads_flag of ST/README // https://github.com/ossrs/state-threads/blob/st-1.9/README#L115
* https://github.com/ossrs/state-threads/blob/st-1.9/README#L115 // @remark We always create joinable thread, so we must join it or memory leak,
* @remark We always create joinable thread, so we must join it or memory leak, // Please read https://github.com/ossrs/srs/issues/78
* Please read https://github.com/ossrs/srs/issues/78
*/
class SrsSTCoroutine : public SrsCoroutine class SrsSTCoroutine : public SrsCoroutine
{ {
private: private:
@ -145,35 +135,25 @@ public:
SrsSTCoroutine(const std::string& n, ISrsCoroutineHandler* h, int cid = 0); SrsSTCoroutine(const std::string& n, ISrsCoroutineHandler* h, int cid = 0);
virtual ~SrsSTCoroutine(); virtual ~SrsSTCoroutine();
public: public:
/** // Start the thread.
* Start the thread. // @remark Should never start it when stopped or terminated.
* @remark Should never start it when stopped or terminated.
*/
virtual srs_error_t start(); virtual srs_error_t start();
/** // Interrupt the thread then wait to terminated.
* Interrupt the thread then wait to terminated. // @remark If user want to notify thread to quit async, for example if there are
* @remark If user want to notify thread to quit async, for example if there are // many threads to stop like the encoder, use the interrupt to notify all threads
* many threads to stop like the encoder, use the interrupt to notify all threads // to terminate then use stop to wait for each to terminate.
* to terminate then use stop to wait for each to terminate.
*/
virtual void stop(); virtual void stop();
/** // Interrupt the thread and notify it to terminate, it will be wakeup if it's blocked
* Interrupt the thread and notify it to terminate, it will be wakeup if it's blocked // in some IO operations, such as st_read or st_write, then it will found should quit,
* in some IO operations, such as st_read or st_write, then it will found should quit, // finally the thread should terminated normally, user can use the stop to join it.
* finally the thread should terminated normally, user can use the stop to join it.
*/
virtual void interrupt(); virtual void interrupt();
/** // Check whether thread is terminated normally or error(stopped or termianted with error),
* Check whether thread is terminated normally or error(stopped or termianted with error), // and the thread should be running if it return ERROR_SUCCESS.
* and the thread should be running if it return ERROR_SUCCESS. // @remark Return specified error when thread terminated normally with error.
* @remark Return specified error when thread terminated normally with error. // @remark Return ERROR_THREAD_TERMINATED when thread terminated normally without error.
* @remark Return ERROR_THREAD_TERMINATED when thread terminated normally without error. // @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
* @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted.
*/
virtual srs_error_t pull(); virtual srs_error_t pull();
/** // Get the context id of thread.
* Get the context id of thread.
*/
virtual int cid(); virtual int cid();
private: private:
virtual srs_error_t cycle(); virtual srs_error_t cycle();

View file

@ -48,9 +48,7 @@ public:
int nb_streams; int nb_streams;
int nb_clients; int nb_clients;
public: public:
/** // The vhost total kbps.
* vhost total kbps.
*/
SrsKbps* kbps; SrsKbps* kbps;
SrsWallClock* clk; SrsWallClock* clk;
public: public:
@ -73,19 +71,17 @@ public:
int nb_clients; int nb_clients;
uint64_t nb_frames; uint64_t nb_frames;
public: public:
/** // The stream total kbps.
* stream total kbps.
*/
SrsKbps* kbps; SrsKbps* kbps;
SrsWallClock* clk; SrsWallClock* clk;
public: public:
bool has_video; bool has_video;
SrsVideoCodecId vcodec; SrsVideoCodecId vcodec;
// profile_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. // The profile_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45.
SrsAvcProfile avc_profile; SrsAvcProfile avc_profile;
// level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. // The level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45.
SrsAvcLevel avc_level; SrsAvcLevel avc_level;
// the width and height in codec info. // The width and height in codec info.
int width; int width;
int height; int height;
public: public:
@ -93,12 +89,10 @@ public:
SrsAudioCodecId acodec; SrsAudioCodecId acodec;
SrsAudioSampleRate asample_rate; SrsAudioSampleRate asample_rate;
SrsAudioChannels asound_type; SrsAudioChannels asound_type;
/** // The audio specified
* audio specified // audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
* audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33, // 1.5.1.1 Audio object type definition, page 23,
* 1.5.1.1 Audio object type definition, page 23, // in ISO_IEC_14496-3-AAC-2001.pdf.
* in ISO_IEC_14496-3-AAC-2001.pdf.
*/
SrsAacObjectType aac_object; SrsAacObjectType aac_object;
public: public:
SrsStatisticStream(); SrsStatisticStream();
@ -106,13 +100,9 @@ public:
public: public:
virtual srs_error_t dumps(SrsJsonObject* obj); virtual srs_error_t dumps(SrsJsonObject* obj);
public: public:
/** // Publish the stream.
* publish the stream.
*/
virtual void publish(int cid); virtual void publish(int cid);
/** // Close the stream.
* close the stream.
*/
virtual void close(); virtual void close();
}; };
@ -136,24 +126,24 @@ class SrsStatistic
{ {
private: private:
static SrsStatistic *_instance; static SrsStatistic *_instance;
// the id to identify the sever. // The id to identify the sever.
int64_t _server_id; int64_t _server_id;
private: private:
// key: vhost id, value: vhost object. // The key: vhost id, value: vhost object.
std::map<int64_t, SrsStatisticVhost*> vhosts; std::map<int64_t, SrsStatisticVhost*> vhosts;
// key: vhost url, value: vhost Object. // The key: vhost url, value: vhost Object.
// @remark a fast index for vhosts. // @remark a fast index for vhosts.
std::map<std::string, SrsStatisticVhost*> rvhosts; std::map<std::string, SrsStatisticVhost*> rvhosts;
private: private:
// key: stream id, value: stream Object. // The key: stream id, value: stream Object.
std::map<int64_t, SrsStatisticStream*> streams; std::map<int64_t, SrsStatisticStream*> streams;
// key: stream url, value: stream Object. // The key: stream url, value: stream Object.
// @remark a fast index for streams. // @remark a fast index for streams.
std::map<std::string, SrsStatisticStream*> rstreams; std::map<std::string, SrsStatisticStream*> rstreams;
private: private:
// key: client id, value: stream object. // The key: client id, value: stream object.
std::map<int, SrsStatisticClient*> clients; std::map<int, SrsStatisticClient*> clients;
// server total kbps. // The server total kbps.
SrsKbps* kbps; SrsKbps* kbps;
SrsWallClock* clk; SrsWallClock* clk;
private: private:
@ -167,77 +157,51 @@ public:
virtual SrsStatisticStream* find_stream(int sid); virtual SrsStatisticStream* find_stream(int sid);
virtual SrsStatisticClient* find_client(int cid); virtual SrsStatisticClient* find_client(int cid);
public: public:
/** // When got video info for stream.
* when got video info for stream.
*/
virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile,
SrsAvcLevel avc_level, int width, int height); SrsAvcLevel avc_level, int width, int height);
/** // When got audio info for stream.
* when got audio info for stream.
*/
virtual srs_error_t on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, virtual srs_error_t on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate,
SrsAudioChannels asound_type, SrsAacObjectType aac_object); SrsAudioChannels asound_type, SrsAacObjectType aac_object);
/** // When got videos, update the frames.
* When got videos, update the frames. // We only stat the total number of video frames.
* We only stat the total number of video frames.
*/
virtual srs_error_t on_video_frames(SrsRequest* req, int nb_frames); virtual srs_error_t on_video_frames(SrsRequest* req, int nb_frames);
/** // When publish stream.
* when publish stream. // @param req the request object of publish connection.
* @param req the request object of publish connection. // @param cid the cid of publish connection.
* @param cid the cid of publish connection.
*/
virtual void on_stream_publish(SrsRequest* req, int cid); virtual void on_stream_publish(SrsRequest* req, int cid);
/** // When close stream.
* when close stream.
*/
virtual void on_stream_close(SrsRequest* req); virtual void on_stream_close(SrsRequest* req);
public: public:
/** // When got a client to publish/play stream,
* when got a client to publish/play stream, // @param id, the client srs id.
* @param id, the client srs id. // @param req, the client request object.
* @param req, the client request object. // @param conn, the physical absract connection object.
* @param conn, the physical absract connection object. // @param type, the type of connection.
* @param type, the type of connection.
*/
virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type); virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
/** // Client disconnect
* client disconnect // @remark the on_disconnect always call, while the on_client is call when
* @remark the on_disconnect always call, while the on_client is call when // only got the request object, so the client specified by id maybe not
* only got the request object, so the client specified by id maybe not // exists in stat.
* exists in stat.
*/
virtual void on_disconnect(int id); virtual void on_disconnect(int id);
/** // Sample the kbps, add delta bytes of conn.
* sample the kbps, add delta bytes of conn. // Use kbps_sample() to get all result of kbps stat.
* use kbps_sample() to get all result of kbps stat.
*/
// TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead. // TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead.
virtual void kbps_add_delta(SrsConnection* conn); virtual void kbps_add_delta(SrsConnection* conn);
/** // Calc the result for all kbps.
* calc the result for all kbps. // @return the server kbps.
* @return the server kbps.
*/
virtual SrsKbps* kbps_sample(); virtual SrsKbps* kbps_sample();
public: public:
/** // Get the server id, used to identify the server.
* get the server id, used to identify the server. // For example, when restart, the server id must changed.
* for example, when restart, the server id must changed.
*/
virtual int64_t server_id(); virtual int64_t server_id();
/** // Dumps the vhosts to amf0 array.
* dumps the vhosts to amf0 array.
*/
virtual srs_error_t dumps_vhosts(SrsJsonArray* arr); virtual srs_error_t dumps_vhosts(SrsJsonArray* arr);
/** // Dumps the streams to amf0 array.
* dumps the streams to amf0 array.
*/
virtual srs_error_t dumps_streams(SrsJsonArray* arr); virtual srs_error_t dumps_streams(SrsJsonArray* arr);
/** // Dumps the clients to amf0 array
* dumps the clients to amf0 array // @param start the start index, from 0.
* @param start the start index, from 0. // @param count the max count of clients to dump.
* @param count the max count of clients to dump.
*/
virtual srs_error_t dumps_clients(SrsJsonArray* arr, int start, int count); virtual srs_error_t dumps_clients(SrsJsonArray* arr, int start, int count);
private: private:
virtual SrsStatisticVhost* create_vhost(SrsRequest* req); virtual SrsStatisticVhost* create_vhost(SrsRequest* req);

View file

@ -31,12 +31,10 @@
#include <srs_app_st.hpp> #include <srs_app_st.hpp>
#include <srs_service_conn.hpp> #include <srs_service_conn.hpp>
/** // The coroutine manager use a thread to delete a connection, which will stop the service
* The coroutine manager use a thread to delete a connection, which will stop the service // thread, for example, when the RTMP connection thread cycle terminated, it will notify
* thread, for example, when the RTMP connection thread cycle terminated, it will notify // the manager(the server) to remove the connection from list of server and push it to
* the manager(the server) to remove the connection from list of server and push it to // the manager thread to delete it, finally the thread of connection will stop.
* the manager thread to delete it, finally the thread of connection will stop.
*/
class SrsCoroutineManager : virtual public ISrsCoroutineHandler, virtual public IConnectionManager class SrsCoroutineManager : virtual public ISrsCoroutineHandler, virtual public IConnectionManager
{ {
private: private:
@ -48,10 +46,10 @@ public:
virtual ~SrsCoroutineManager(); virtual ~SrsCoroutineManager();
public: public:
srs_error_t start(); srs_error_t start();
// ISrsCoroutineHandler // Interface ISrsCoroutineHandler
public: public:
virtual srs_error_t cycle(); virtual srs_error_t cycle();
// IConnectionManager // Interface IConnectionManager
public: public:
virtual void remove(ISrsConnection* c); virtual void remove(ISrsConnection* c);
private: private:

View file

@ -362,7 +362,6 @@ bool get_proc_system_stat(SrsProcSystemStat& r)
fclose(f); fclose(f);
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.ok = true; r.ok = true;
@ -401,7 +400,6 @@ bool get_proc_self_stat(SrsProcSelfStat& r)
fclose(f); fclose(f);
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.ok = true; r.ok = true;
@ -520,7 +518,6 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r)
fclose(f); fclose(f);
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.ok = true; r.ok = true;
@ -606,7 +603,6 @@ bool srs_get_disk_diskstats_stat(SrsDiskStat& r)
fclose(f); fclose(f);
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.ok = true; r.ok = true;
@ -728,7 +724,6 @@ void srs_update_meminfo()
fclose(f); fclose(f);
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
r.sample_time = srsu2ms(srs_get_system_time()); r.sample_time = srsu2ms(srs_get_system_time());
@ -948,7 +943,6 @@ void srs_update_network_devices()
} }
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
} }
@ -1029,7 +1023,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
} }
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
nb_socks = 0; nb_socks = 0;
nb_tcp4_hashed = 0; nb_tcp4_hashed = 0;
nb_tcp_orphans = 0; nb_tcp_orphans = 0;
@ -1073,7 +1066,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
} }
#else #else
// TODO: FIXME: impelments it. // TODO: FIXME: impelments it.
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
#endif #endif
// @see: https://github.com/shemminger/iproute2/blob/master/misc/ss.c // @see: https://github.com/shemminger/iproute2/blob/master/misc/ss.c

View file

@ -41,51 +41,43 @@ class SrsKbps;
class SrsBuffer; class SrsBuffer;
class SrsJsonObject; class SrsJsonObject;
/** // Convert level in string to log level in int.
* convert level in string to log level in int. // @return the log level defined in SrsLogLevel.
* @return the log level defined in SrsLogLevel.
*/
extern SrsLogLevel srs_get_log_level(std::string level); extern SrsLogLevel srs_get_log_level(std::string level);
/** // Build the path according to vhost/app/stream, where replace variables:
* build the path according to vhost/app/stream, where replace variables: // [vhost], the vhost of stream.
* [vhost], the vhost of stream. // [app], the app of stream.
* [app], the app of stream. // [stream], the stream name of stream.
* [stream], the stream name of stream. // @return the replaced path.
* @return the replaced path.
*/
extern std::string srs_path_build_stream(std::string template_path, std::string vhost, std::string app, std::string stream); extern std::string srs_path_build_stream(std::string template_path, std::string vhost, std::string app, std::string stream);
/** // Build the path according to timestamp, where replace variables:
* build the path according to timestamp, where replace variables: // [2006], replace this const to current year.
* [2006], replace this const to current year. // [01], replace this const to current month.
* [01], replace this const to current month. // [02], replace this const to current date.
* [02], replace this const to current date. // [15], replace this const to current hour.
* [15], replace this const to current hour. // [04], repleace this const to current minute.
* [04], repleace this const to current minute. // [05], repleace this const to current second.
* [05], repleace this const to current second. // [999], repleace this const to current millisecond.
* [999], repleace this const to current millisecond. // [timestamp],replace this const to current UNIX timestamp in ms.
* [timestamp],replace this const to current UNIX timestamp in ms. // @return the replaced path.
* @return the replaced path.
*/
extern std::string srs_path_build_timestamp(std::string template_path); extern std::string srs_path_build_timestamp(std::string template_path);
/** // Kill the pid by SIGINT, then wait to quit,
* kill the pid by SIGINT, then wait to quit, // Kill the pid by SIGKILL again when exceed the timeout.
* kill the pid by SIGKILL again when exceed the timeout. // @param pid the pid to kill. ignore for -1. set to -1 when killed.
* @param pid the pid to kill. ignore for -1. set to -1 when killed. // @return an int error code.
* @return an int error code.
*/
extern srs_error_t srs_kill_forced(int& pid); extern srs_error_t srs_kill_forced(int& pid);
// current process resouce usage. // Current process resouce usage.
// @see: man getrusage // @see: man getrusage
class SrsRusage class SrsRusage
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// the time in ms when sample. // The time in ms when sample.
int64_t sample_time; int64_t sample_time;
public: public:
@ -95,21 +87,21 @@ public:
SrsRusage(); SrsRusage();
}; };
// get system rusage, use cache to avoid performance problem. // Get system rusage, use cache to avoid performance problem.
extern SrsRusage* srs_get_system_rusage(); extern SrsRusage* srs_get_system_rusage();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_system_rusage(); extern void srs_update_system_rusage();
// to stat the process info. // To stat the process info.
// @see: man 5 proc, /proc/[pid]/stat // @see: man 5 proc, /proc/[pid]/stat
class SrsProcSelfStat class SrsProcSelfStat
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// the time in ms when sample. // The time in ms when sample.
int64_t sample_time; int64_t sample_time;
// the percent of usage. 0.153 is 15.3%. // The percent of usage. 0.153 is 15.3%.
float percent; float percent;
// data of /proc/[pid]/stat // data of /proc/[pid]/stat
@ -256,49 +248,47 @@ public:
SrsProcSelfStat(); SrsProcSelfStat();
}; };
// to stat the cpu time. // To stat the cpu time.
// @see: man 5 proc, /proc/stat // @see: man 5 proc, /proc/stat
/** // about the cpu time, @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files
* about the cpu time, @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files // for example, for ossrs.net, a single cpu machine:
* for example, for ossrs.net, a single cpu machine: // [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat // 5275153.01 4699624.99
* 5275153.01 4699624.99 // cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0
* cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0 // Where the uptime is 5275153.01s
* where the uptime is 5275153.01s // generally, USER_HZ sysconf(_SC_CLK_TCK)=100, which means the unit of /proc/stat is "1/100ths seconds"
* generally, USER_HZ sysconf(_SC_CLK_TCK)=100, which means the unit of /proc/stat is "1/100ths seconds" // that is, USER_HZ=1/100 seconds
* that is, USER_HZ=1/100 seconds // cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ)
* cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ) // = 523331687 (USER_HZ)
* = 523331687 (USER_HZ) // = 523331687 * 1/100 (seconds)
* = 523331687 * 1/100 (seconds) // = 5233316.87 seconds
* = 5233316.87 seconds // The cpu total seconds almost the uptime, the delta is more precise.
* the cpu total seconds almost the uptime, the delta is more precise. //
* // we run the command about 26minutes:
* we run the command about 26minutes: // [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat // 5276739.83 4701090.76
* 5276739.83 4701090.76 // cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0
* cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0 // Where the uptime is 5276739.83s
* where the uptime is 5276739.83s // cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ)
* cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ) // = 523488898 (USER_HZ)
* = 523488898 (USER_HZ) // = 523488898 * 1/100 (seconds)
* = 523488898 * 1/100 (seconds) // = 5234888.98 seconds
* = 5234888.98 seconds // where:
* where: // uptime delta = 1586.82s
* uptime delta = 1586.82s // cpu total delta = 1572.11s
* cpu total delta = 1572.11s // The deviation is more smaller.
* the deviation is more smaller.
*/
class SrsProcSystemStat class SrsProcSystemStat
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// the time in ms when sample. // The time in ms when sample.
int64_t sample_time; int64_t sample_time;
// the percent of usage. 0.153 is 15.3%. // The percent of usage. 0.153 is 15.3%.
// the percent is in [0, 1], where 1 is 100%. // The percent is in [0, 1], where 1 is 100%.
// for multiple core cpu, max also is 100%. // for multiple core cpu, max also is 100%.
float percent; float percent;
// the total cpu time units // The total cpu time units
// @remark, zero for the previous total() is zero. // @remark, zero for the previous total() is zero.
// the usaged_cpu_delta = total_delta * percent // the usaged_cpu_delta = total_delta * percent
// previous cpu total = this->total() - total_delta // previous cpu total = this->total() - total_delta
@ -310,7 +300,7 @@ public:
// (1/100ths of a second on most architectures, use // (1/100ths of a second on most architectures, use
// sysconf(_SC_CLK_TCK) to obtain the right value) // sysconf(_SC_CLK_TCK) to obtain the right value)
// //
// the system spent in user mode, // The system spent in user mode,
unsigned long long user; unsigned long long user;
// user mode with low priority (nice), // user mode with low priority (nice),
unsigned long long nice; unsigned long long nice;
@ -341,18 +331,18 @@ public:
public: public:
SrsProcSystemStat(); SrsProcSystemStat();
// get total cpu units. // Get total cpu units.
int64_t total(); int64_t total();
}; };
// get system cpu stat, use cache to avoid performance problem. // Get system cpu stat, use cache to avoid performance problem.
extern SrsProcSelfStat* srs_get_self_proc_stat(); extern SrsProcSelfStat* srs_get_self_proc_stat();
// get system cpu stat, use cache to avoid performance problem. // Get system cpu stat, use cache to avoid performance problem.
extern SrsProcSystemStat* srs_get_system_proc_stat(); extern SrsProcSystemStat* srs_get_system_proc_stat();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_proc_stat(); extern void srs_update_proc_stat();
// stat disk iops // Stat disk iops
// @see: http://stackoverflow.com/questions/4458183/how-the-util-of-iostat-is-computed // @see: http://stackoverflow.com/questions/4458183/how-the-util-of-iostat-is-computed
// for total disk io, @see: cat /proc/vmstat |grep pgpg // for total disk io, @see: cat /proc/vmstat |grep pgpg
// for device disk io, @see: cat /proc/diskstats // for device disk io, @see: cat /proc/diskstats
@ -364,9 +354,9 @@ extern void srs_update_proc_stat();
class SrsDiskStat class SrsDiskStat
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// the time in ms when sample. // The time in ms when sample.
int64_t sample_time; int64_t sample_time;
// input(read) KBytes per seconds // input(read) KBytes per seconds
@ -382,10 +372,10 @@ public:
public: public:
// @see: cat /proc/vmstat // @see: cat /proc/vmstat
// the in(read) page count, pgpgin*1024 is the read bytes. // The in(read) page count, pgpgin*1024 is the read bytes.
// Total number of kilobytes the system paged in from disk per second. // Total number of kilobytes the system paged in from disk per second.
unsigned long pgpgin; unsigned long pgpgin;
// the out(write) page count, pgpgout*1024 is the write bytes. // The out(write) page count, pgpgout*1024 is the write bytes.
// Total number of kilobytes the system paged out to disk per second. // Total number of kilobytes the system paged out to disk per second.
unsigned long pgpgout; unsigned long pgpgout;
@ -415,7 +405,7 @@ public:
// Write I/O operations // Write I/O operations
unsigned int wr_ios; unsigned int wr_ios;
// Number of writes merged Reads and writes which are adjacent // Number of writes merged Reads and writes which are adjacent
// to each other may be merged for efficiency. Thus two 4K // To each other may be merged for efficiency. Thus two 4K
// reads may become one 8K read before it is ultimately // reads may become one 8K read before it is ultimately
// handed to the disk, and so it will be counted (and queued) // handed to the disk, and so it will be counted (and queued)
// as only one I/O. This field lets you know how often this was done. // as only one I/O. This field lets you know how often this was done.
@ -446,7 +436,7 @@ public:
// progress (field 9) times the number of milliseconds spent // progress (field 9) times the number of milliseconds spent
// doing I/O since the last update of this field. This can // doing I/O since the last update of this field. This can
// provide an easy measure of both I/O completion time and // provide an easy measure of both I/O completion time and
// the backlog that may be accumulating. // The backlog that may be accumulating.
// Average queue length // Average queue length
unsigned int aveq; unsigned int aveq;
@ -454,21 +444,21 @@ public:
SrsDiskStat(); SrsDiskStat();
}; };
// get disk stat, use cache to avoid performance problem. // Get disk stat, use cache to avoid performance problem.
extern SrsDiskStat* srs_get_disk_stat(); extern SrsDiskStat* srs_get_disk_stat();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_disk_stat(); extern void srs_update_disk_stat();
// stat system memory info // Stat system memory info
// @see: cat /proc/meminfo // @see: cat /proc/meminfo
class SrsMemInfo class SrsMemInfo
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// the time in ms when sample. // The time in ms when sample.
int64_t sample_time; int64_t sample_time;
// the percent of usage. 0.153 is 15.3%. // The percent of usage. 0.153 is 15.3%.
float percent_ram; float percent_ram;
float percent_swap; float percent_swap;
@ -495,9 +485,9 @@ public:
SrsMemInfo(); SrsMemInfo();
}; };
// get system meminfo, use cache to avoid performance problem. // Get system meminfo, use cache to avoid performance problem.
extern SrsMemInfo* srs_get_meminfo(); extern SrsMemInfo* srs_get_meminfo();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_meminfo(); extern void srs_update_meminfo();
// system cpu hardware info. // system cpu hardware info.
@ -506,7 +496,7 @@ extern void srs_update_meminfo();
class SrsCpuInfo class SrsCpuInfo
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// data of /proc/cpuinfo // data of /proc/cpuinfo
@ -520,14 +510,14 @@ public:
SrsCpuInfo(); SrsCpuInfo();
}; };
// get system cpu info, use cache to avoid performance problem. // Get system cpu info, use cache to avoid performance problem.
extern SrsCpuInfo* srs_get_cpuinfo(); extern SrsCpuInfo* srs_get_cpuinfo();
// platform(os, srs) uptime/load summary // The platform(os, srs) uptime/load summary
class SrsPlatformInfo class SrsPlatformInfo
{ {
public: public:
// whether the data is ok. // Whether the data is ok.
bool ok; bool ok;
// srs startup time, in ms. // srs startup time, in ms.
@ -551,22 +541,21 @@ public:
SrsPlatformInfo(); SrsPlatformInfo();
}; };
// get platform info, use cache to avoid performance problem. // Get platform info, use cache to avoid performance problem.
extern SrsPlatformInfo* srs_get_platform_info(); extern SrsPlatformInfo* srs_get_platform_info();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_platform_info(); extern void srs_update_platform_info();
// network device summary for each network device, // The network device summary for each network device, for example, eth0, eth1, ethN
// for example, eth0, eth1, ethN
class SrsNetworkDevices class SrsNetworkDevices
{ {
public: public:
// whether the network device is ok. // Whether the network device is ok.
bool ok; bool ok;
// 6-chars interfaces name // 6-chars interfaces name
char name[7]; char name[7];
// the sample time in ms. // The sample time in ms.
int64_t sample_time; int64_t sample_time;
public: public:
@ -594,20 +583,20 @@ public:
SrsNetworkDevices(); SrsNetworkDevices();
}; };
// get network devices info, use cache to avoid performance problem. // Get network devices info, use cache to avoid performance problem.
extern SrsNetworkDevices* srs_get_network_devices(); extern SrsNetworkDevices* srs_get_network_devices();
extern int srs_get_network_devices_count(); extern int srs_get_network_devices_count();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_network_devices(); extern void srs_update_network_devices();
// system connections, and srs rtmp network summary // The system connections, and srs rtmp network summary
class SrsNetworkRtmpServer class SrsNetworkRtmpServer
{ {
public: public:
// whether the network device is ok. // Whether the network device is ok.
bool ok; bool ok;
// the sample time in ms. // The sample time in ms.
int64_t sample_time; int64_t sample_time;
public: public:
@ -638,32 +627,32 @@ public:
SrsNetworkRtmpServer(); SrsNetworkRtmpServer();
}; };
// get network devices info, use cache to avoid performance problem. // Get network devices info, use cache to avoid performance problem.
extern SrsNetworkRtmpServer* srs_get_network_rtmp_server(); extern SrsNetworkRtmpServer* srs_get_network_rtmp_server();
// the deamon st-thread will update it. // The deamon st-thread will update it.
extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps); extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps);
// get local or peer ip. // Get local or peer ip.
// where local ip is the server ip which client connected. // Where local ip is the server ip which client connected.
extern std::string srs_get_local_ip(int fd); extern std::string srs_get_local_ip(int fd);
// get the local id port. // Get the local id port.
extern int srs_get_local_port(int fd); extern int srs_get_local_port(int fd);
// where peer ip is the client public ip which connected to server. // Where peer ip is the client public ip which connected to server.
extern std::string srs_get_peer_ip(int fd); extern std::string srs_get_peer_ip(int fd);
// whether string is digit number // Whether string is digit number
// is_digit("1234567890") === true // is_digit("1234567890") === true
// is_digit("0123456789") === false // is_digit("0123456789") === false
// is_digit("1234567890a") === false // is_digit("1234567890a") === false
// is_digit("a1234567890") === false // is_digit("a1234567890") === false
extern bool srs_is_digit_number(const std::string& str); extern bool srs_is_digit_number(const std::string& str);
// whether string is boolean // Whether string is boolean
// is_bool("true") == true // is_bool("true") == true
// is_bool("false") == true // is_bool("false") == true
// otherwise, false. // otherwise, false.
extern bool srs_is_boolean(const std::string& str); extern bool srs_is_boolean(const std::string& str);
// dump summaries for /api/v1/summaries. // Dump summaries for /api/v1/summaries.
extern void srs_api_dump_summaries(SrsJsonObject* obj); extern void srs_api_dump_summaries(SrsJsonObject* obj);
#endif #endif

View file

@ -24,58 +24,43 @@
#ifndef SRS_CORE_HPP #ifndef SRS_CORE_HPP
#define SRS_CORE_HPP #define SRS_CORE_HPP
// current release version // The version config.
#define VERSION_MAJOR 3 #define VERSION_MAJOR 3
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 49 #define VERSION_REVISION 51
// generated by configure, only macros. // The macros generated by configure script.
#include <srs_auto_headers.hpp> #include <srs_auto_headers.hpp>
// provider info. // To convert macro values to string.
// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define SRS_INTERNAL_STR(v) #v
#define SRS_XSTR(v) SRS_INTERNAL_STR(v)
// The project informations, may sent to client in HTTP header or RTMP metadata.
#define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_KEY "SRS"
#define RTMP_SIG_SRS_CODE "OuXuli" #define RTMP_SIG_SRS_CODE "OuXuli"
#define RTMP_SIG_SRS_AUTHROS "winlin,wenjie.zhao"
// contact info.
#define RTMP_SIG_SRS_WEB "http://ossrs.net"
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
// debug info.
#define RTMP_SIG_SRS_ROLE "cluster"
#define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs" #define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs"
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2019 " RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_AUTHROS ")"
#define RTMP_SIG_SRS_PRIMARY RTMP_SIG_SRS_KEY "/" VERSION_STABLE_BRANCH
#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_VERSION ")"
#define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION) #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION)
#define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")" #define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")"
// stable major version // The current stable release.
#define VERSION_STABLE 2 #define VERSION_STABLE 2
#define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release" #define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release"
// internal macros, covert macro values to str, // For 32bit os, 2G big file limit for unistd io,
// see: read https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification
#define SRS_XSTR(v) SRS_INTERNAL_STR(v)
#define SRS_INTERNAL_STR(v) #v
/**
* the core provides the common defined macros, utilities,
* user must include the srs_core.hpp before any header, or maybe
* build failed.
*/
// for 32bit os, 2G big file limit for unistd io,
// ie. read/write/lseek to use 64bits size for huge file. // ie. read/write/lseek to use 64bits size for huge file.
#ifndef _FILE_OFFSET_BITS #ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#endif #endif
// for int64_t print using PRId64 format. // For int64_t print using PRId64 format.
#ifndef __STDC_FORMAT_MACROS #ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS
#endif #endif
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 // For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32 #ifndef _WIN32
#include <inttypes.h> #include <inttypes.h>
#endif #endif
@ -86,22 +71,21 @@
#include <stddef.h> #include <stddef.h>
#include <sys/types.h> #include <sys/types.h>
// Time defines. // The time unit for timeout, interval or duration.
#include <srs_core_time.hpp> #include <srs_core_time.hpp>
// Some important performance options. // Some important performance options.
#include <srs_core_performance.hpp> #include <srs_core_performance.hpp>
// free the p and set to NULL. // To free the p and set to NULL.
// p must be a T*. // @remark The p must be a pointer T*.
#define srs_freep(p) \ #define srs_freep(p) \
if (p) { \ if (p) { \
delete p; \ delete p; \
p = NULL; \ p = NULL; \
} \ } \
(void)0 (void)0
// please use the freepa(T[]) to free an array, // Please use the freepa(T[]) to free an array, otherwise the behavior is undefined.
// or the behavior is undefined.
#define srs_freepa(pa) \ #define srs_freepa(pa) \
if (pa) { \ if (pa) { \
delete[] pa; \ delete[] pa; \
@ -109,11 +93,8 @@
} \ } \
(void)0 (void)0
/** // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm
* important check for st(state-threads), // @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
* only support the following cpus: i386/amd64/x86_64/arm
* @reamrk to patch ST for arm, read https://github.com/ossrs/state-threads/issues/1
*/
#if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__)
#error "only support i386/amd64/x86_64/arm cpu" #error "only support i386/amd64/x86_64/arm cpu"
#endif #endif

View file

@ -27,7 +27,7 @@
#include <srs_core.hpp> #include <srs_core.hpp>
/** /**
* auto free the instance in the current scope, for instance, MyClass* ptr, * To free the instance in the current scope, for instance, MyClass* ptr,
* which is a ptr and this class will: * which is a ptr and this class will:
* 1. free the ptr. * 1. free the ptr.
* 2. set ptr to NULL. * 2. set ptr to NULL.
@ -56,9 +56,6 @@ private:
T** ptr; T** ptr;
bool is_array; bool is_array;
public: public:
/**
* auto delete the ptr.
*/
impl_SrsAutoFree(T** p, bool array) { impl_SrsAutoFree(T** p, bool array) {
ptr = p; ptr = p;
is_array = array; is_array = array;

View file

@ -28,15 +28,17 @@
#ifdef SRS_AUTO_MEM_WATCH #ifdef SRS_AUTO_MEM_WATCH
#warning "MemoryWatch is deprecated."
#include <string> #include <string>
// watch the specified memory. // Watch the specified memory.
extern void srs_memory_watch(void* ptr, std::string category, int size); extern void srs_memory_watch(void* ptr, std::string category, int size);
// unwatch the specified memory. // Unwatch the specified memory.
extern void srs_memory_unwatch(void* ptr); extern void srs_memory_unwatch(void* ptr);
// report the memory watch. // Report the memory watch.
extern void srs_memory_report(); extern void srs_memory_report();
#endif #endif

View file

@ -35,9 +35,7 @@
class SrsBuffer; class SrsBuffer;
class ISrsStreamWriter; class ISrsStreamWriter;
/** // Transmux the RTMP packets to AAC stream.
* Transmux the RTMP packets to AAC stream.
*/
class SrsAacTransmuxer class SrsAacTransmuxer
{ {
private: private:
@ -51,17 +49,13 @@ public:
SrsAacTransmuxer(); SrsAacTransmuxer();
virtual ~SrsAacTransmuxer(); virtual ~SrsAacTransmuxer();
public: public:
/** // Initialize the underlayer file stream.
* initialize the underlayer file stream. // @remark User can initialize multiple times to encode multiple aac files.
* @remark user can initialize multiple times to encode multiple aac files. // @remark User must free the fs, aac encoder never close/free it.
* @remark, user must free the fs, aac encoder never close/free it.
*/
virtual srs_error_t initialize(ISrsStreamWriter* fs); virtual srs_error_t initialize(ISrsStreamWriter* fs);
public: public:
/** // Write audio/video packet.
* write audio/video packet. // @remark The assert data should not be NULL.
* @remark assert data is not NULL.
*/
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size); virtual srs_error_t write_audio(int64_t timestamp, char* data, int size);
}; };

View file

@ -36,82 +36,72 @@
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// RTMP consts values // RTMP consts values
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// default vhost of rtmp // Default vhost of rtmp
#define SRS_CONSTS_RTMP_DEFAULT_VHOST "__defaultVhost__" #define SRS_CONSTS_RTMP_DEFAULT_VHOST "__defaultVhost__"
#define SRS_CONSTS_RTMP_DEFAULT_APP "__defaultApp__" #define SRS_CONSTS_RTMP_DEFAULT_APP "__defaultApp__"
// default port of rtmp // Default port of rtmp
#define SRS_CONSTS_RTMP_DEFAULT_PORT 1935 #define SRS_CONSTS_RTMP_DEFAULT_PORT 1935
// the default chunk size for system. // The default chunk size for system.
#define SRS_CONSTS_RTMP_SRS_CHUNK_SIZE 60000 #define SRS_CONSTS_RTMP_SRS_CHUNK_SIZE 60000
// 6. Chunking, RTMP protocol default chunk size. // 6. Chunking, RTMP protocol default chunk size.
#define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128 #define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128
/** // 6. Chunking
* 6. Chunking // The chunk size is configurable. It can be set using a control
* The chunk size is configurable. It can be set using a control // message(Set Chunk Size) as described in section 7.1. The maximum
* message(Set Chunk Size) as described in section 7.1. The maximum // chunk size can be 65536 bytes and minimum 128 bytes. Larger values
* chunk size can be 65536 bytes and minimum 128 bytes. Larger values // reduce CPU usage, but also commit to larger writes that can delay
* reduce CPU usage, but also commit to larger writes that can delay // other content on lower bandwidth connections. Smaller chunks are not
* other content on lower bandwidth connections. Smaller chunks are not // good for high-bit rate streaming. Chunk size is maintained
* good for high-bit rate streaming. Chunk size is maintained // independently for each direction.
* independently for each direction.
*/
#define SRS_CONSTS_RTMP_MIN_CHUNK_SIZE 128 #define SRS_CONSTS_RTMP_MIN_CHUNK_SIZE 128
#define SRS_CONSTS_RTMP_MAX_CHUNK_SIZE 65536 #define SRS_CONSTS_RTMP_MAX_CHUNK_SIZE 65536
// the following is the timeout for rtmp protocol, // The following is the timeout for rtmp protocol,
// to avoid death connection. // to avoid death connection.
// the common io timeout, for connect, recv or send. // The common io timeout, for connect, recv or send.
// TODO: FIXME: Maybe change to smaller value, such as 3s? // TODO: FIXME: Maybe change to smaller value, such as 3s?
#define SRS_CONSTS_RTMP_TIMEOUT (30 * SRS_UTIME_SECONDS) #define SRS_CONSTS_RTMP_TIMEOUT (30 * SRS_UTIME_SECONDS)
// the timeout to wait for client control message, // The timeout to wait for client control message,
// if timeout, we generally ignore and send the data to client, // if timeout, we generally ignore and send the data to client,
// generally, it's the pulse time for data seding. // generally, it's the pulse time for data seding.
// @remark, recomment to 500ms. // @remark, recomment to 500ms.
#define SRS_CONSTS_RTMP_PULSE (500 * SRS_UTIME_MILLISECONDS) #define SRS_CONSTS_RTMP_PULSE (500 * SRS_UTIME_MILLISECONDS)
/** // The max rtmp header size:
* max rtmp header size: // 1bytes basic header,
* 1bytes basic header, // 11bytes message header,
* 11bytes message header, // 4bytes timestamp header,
* 4bytes timestamp header, // that is, 1+11+4=16bytes.
* that is, 1+11+4=16bytes.
*/
#define SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE 16 #define SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE 16
/** // The max rtmp header size:
* max rtmp header size: // 1bytes basic header,
* 1bytes basic header, // 4bytes timestamp header,
* 4bytes timestamp header, // that is, 1+4=5bytes.
* that is, 1+4=5bytes.
*/
// always use fmt0 as cache. // always use fmt0 as cache.
#define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5 #define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5
/** // For performance issue,
* for performance issue, // the iovs cache, @see https://github.com/ossrs/srs/issues/194
* the iovs cache, @see https://github.com/ossrs/srs/issues/194 // iovs cache for multiple messages for each connections.
* iovs cache for multiple messages for each connections. // suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec,
* suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec, // so the iovs max should be (SRS_PERF_MW_MSGS * 2)
* so the iovs max should be (SRS_PERF_MW_MSGS * 2) //
* // @remark, SRS will realloc when the iovs not enough.
* @remark, SRS will realloc when the iovs not enough.
*/
#define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2) #define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2)
/** // For performance issue,
* for performance issue, // the c0c3 cache, @see https://github.com/ossrs/srs/issues/194
* the c0c3 cache, @see https://github.com/ossrs/srs/issues/194 // c0c3 cache for multiple messages for each connections.
* c0c3 cache for multiple messages for each connections. // each c0 <= 16byes, suppose the chunk size is 64k,
* each c0 <= 16byes, suppose the chunk size is 64k, // each message send in a chunk which needs only a c0 header,
* each message send in a chunk which needs only a c0 header, // so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16)
* so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16) //
* // @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it.
* @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it. // so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32)
* so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32)
*/
#define SRS_CONSTS_C0C3_HEADERS_MAX (SRS_PERF_MW_MSGS * 32) #define SRS_CONSTS_C0C3_HEADERS_MAX (SRS_PERF_MW_MSGS * 32)
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -127,16 +117,16 @@
#define SRS_CONSTS_NULL_FILE "/dev/null" #define SRS_CONSTS_NULL_FILE "/dev/null"
#define SRS_CONSTS_LOCALHOST "127.0.0.1" #define SRS_CONSTS_LOCALHOST "127.0.0.1"
// signal defines. // The signal defines.
// reload the config file and apply new config. // To reload the config file and apply new config.
#define SRS_SIGNAL_RELOAD SIGHUP #define SRS_SIGNAL_RELOAD SIGHUP
// reopen the log file. // Reopen the log file.
#define SRS_SIGNAL_REOPEN_LOG SIGUSR1 #define SRS_SIGNAL_REOPEN_LOG SIGUSR1
// srs should gracefully quit, do dispose then exit. // The signal for srs to gracefully quit, do dispose then exit.
#define SRS_SIGNAL_GRACEFULLY_QUIT SIGTERM #define SRS_SIGNAL_GRACEFULLY_QUIT SIGTERM
// application level signals. // The application level signals.
// persistence the config in memory to config file. // Persistence the config in memory to config file.
// @see https://github.com/ossrs/srs/issues/319#issuecomment-134993922 // @see https://github.com/ossrs/srs/issues/319#issuecomment-134993922
// @remark we actually don't handle the signal for it's not a valid os signal. // @remark we actually don't handle the signal for it's not a valid os signal.
#define SRS_SIGNAL_PERSISTENCE_CONFIG 1000 #define SRS_SIGNAL_PERSISTENCE_CONFIG 1000
@ -149,33 +139,33 @@
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// log consts values // The log consts values
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// downloading speed-up, play to edge, ingest from origin // Downloading speed-up, play to edge, ingest from origin
#define SRS_CONSTS_LOG_EDGE_PLAY "EIG" #define SRS_CONSTS_LOG_EDGE_PLAY "EIG"
// uploading speed-up, publish to edge, foward to origin // Uploading speed-up, publish to edge, foward to origin
#define SRS_CONSTS_LOG_EDGE_PUBLISH "EFW" #define SRS_CONSTS_LOG_EDGE_PUBLISH "EFW"
// edge/origin forwarder. // The edge/origin forwarder.
#define SRS_CONSTS_LOG_FOWARDER "FWR" #define SRS_CONSTS_LOG_FOWARDER "FWR"
// play stream on edge/origin. // Play stream on edge/origin.
#define SRS_CONSTS_LOG_PLAY "PLA" #define SRS_CONSTS_LOG_PLAY "PLA"
// client publish to edge/origin // Client publish to edge/origin
#define SRS_CONSTS_LOG_CLIENT_PUBLISH "CPB" #define SRS_CONSTS_LOG_CLIENT_PUBLISH "CPB"
// web/flash publish to edge/origin // The web/flash publish to edge/origin
#define SRS_CONSTS_LOG_WEB_PUBLISH "WPB" #define SRS_CONSTS_LOG_WEB_PUBLISH "WPB"
// ingester for edge(play)/origin // Ingester for edge(play)/origin
#define SRS_CONSTS_LOG_INGESTER "IGS" #define SRS_CONSTS_LOG_INGESTER "IGS"
// hls log id. // The hls log id.
#define SRS_CONSTS_LOG_HLS "HLS" #define SRS_CONSTS_LOG_HLS "HLS"
// encoder log id. // The encoder log id.
#define SRS_CONSTS_LOG_ENCODER "ENC" #define SRS_CONSTS_LOG_ENCODER "ENC"
// http stream log id. // The http stream log id.
#define SRS_CONSTS_LOG_HTTP_STREAM "HTS" #define SRS_CONSTS_LOG_HTTP_STREAM "HTS"
// http stream cache log id. // The http stream cache log id.
#define SRS_CONSTS_LOG_HTTP_STREAM_CACHE "HTC" #define SRS_CONSTS_LOG_HTTP_STREAM_CACHE "HTC"
// stream caster log id. // The stream caster log id.
#define SRS_CONSTS_LOG_STREAM_CASTER "SCS" #define SRS_CONSTS_LOG_STREAM_CASTER "SCS"
// the nginx exec log id. // The nginx exec log id.
#define SRS_CONSTS_LOG_EXEC "EXE" #define SRS_CONSTS_LOG_EXEC "EXE"
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -213,14 +203,14 @@
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// HTTP consts values // HTTP consts values
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// the default http port. // The default http port.
#define SRS_CONSTS_HTTP_DEFAULT_PORT 80 #define SRS_CONSTS_HTTP_DEFAULT_PORT 80
// linux path seprator // The linux path seprator
#define SRS_CONSTS_HTTP_PATH_SEP '/' #define SRS_CONSTS_HTTP_PATH_SEP '/'
// query string seprator // Query string seprator
#define SRS_CONSTS_HTTP_QUERY_SEP '?' #define SRS_CONSTS_HTTP_QUERY_SEP '?'
// the default recv timeout. // The default recv timeout.
#define SRS_HTTP_RECV_TIMEOUT (60 * SRS_UTIME_SECONDS) #define SRS_HTTP_RECV_TIMEOUT (60 * SRS_UTIME_SECONDS)
// 6.1.1 Status Code and Reason Phrase // 6.1.1 Status Code and Reason Phrase
@ -405,7 +395,7 @@
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
#define SRS_CONSTS_KAFKA_DEFAULT_PORT 9092 #define SRS_CONSTS_KAFKA_DEFAULT_PORT 9092
// the common io timeout, for both recv and send. // The common io timeout, for both recv and send.
#define SRS_CONSTS_KAFKA_TIMEOUT (30 * SRS_UTIME_MILLISECONDS) #define SRS_CONSTS_KAFKA_TIMEOUT (30 * SRS_UTIME_MILLISECONDS)
#endif #endif

View file

@ -28,13 +28,13 @@
#include <string> #include <string>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 // For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32 #ifndef _WIN32
#define ERROR_SUCCESS 0 #define ERROR_SUCCESS 0
#endif #endif
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// system error. // The system error.
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
#define ERROR_SOCKET_CREATE 1000 #define ERROR_SOCKET_CREATE 1000
#define ERROR_SOCKET_SETREUSE 1001 #define ERROR_SOCKET_SETREUSE 1001
@ -173,18 +173,18 @@
#define ERROR_RTMP_STREAM_NAME_EMPTY 2051 #define ERROR_RTMP_STREAM_NAME_EMPTY 2051
#define ERROR_HTTP_HIJACK 2052 #define ERROR_HTTP_HIJACK 2052
// //
// system control message, // The system control message,
// not an error, but special control logic. // It's not an error, but special control logic.
// //
// connection is redirect to another server. // When connection is redirect to another server.
#define ERROR_CONTROL_REDIRECT 2997 #define ERROR_CONTROL_REDIRECT 2997
// sys ctl: rtmp close stream, support replay. // For sys ctl: rtmp close stream, support replay.
#define ERROR_CONTROL_RTMP_CLOSE 2998 #define ERROR_CONTROL_RTMP_CLOSE 2998
// FMLE stop publish and republish. // When FMLE stop publish and republish.
#define ERROR_CONTROL_REPUBLISH 2999 #define ERROR_CONTROL_REPUBLISH 2999
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// application level // The application level errors.
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
#define ERROR_HLS_METADATA 3000 #define ERROR_HLS_METADATA 3000
#define ERROR_HLS_DECODE_ERROR 3001 #define ERROR_HLS_DECODE_ERROR 3001
@ -329,23 +329,23 @@
//#define ERROR_API_METHOD_NOT_ALLOWD //#define ERROR_API_METHOD_NOT_ALLOWD
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
// user-define error. // For user-define error.
/////////////////////////////////////////////////////// ///////////////////////////////////////////////////////
#define ERROR_USER_START 9000 #define ERROR_USER_START 9000
//#define ERROR_USER_DISCONNECT 9001 //#define ERROR_USER_DISCONNECT 9001
#define ERROR_SOURCE_NOT_FOUND 9002 #define ERROR_SOURCE_NOT_FOUND 9002
#define ERROR_USER_END 9999 #define ERROR_USER_END 9999
/** // Whether the error code is an system control error.
* whether the error code is an system control error.
*/
// TODO: FIXME: Remove it from underlayer for confused with error and logger. // TODO: FIXME: Remove it from underlayer for confused with error and logger.
extern bool srs_is_system_control_error(int error_code); extern bool srs_is_system_control_error(int error_code);
extern bool srs_is_system_control_error(srs_error_t err); extern bool srs_is_system_control_error(srs_error_t err);
extern bool srs_is_client_gracefully_close(int error_code); extern bool srs_is_client_gracefully_close(int error_code);
extern bool srs_is_client_gracefully_close(srs_error_t err); extern bool srs_is_client_gracefully_close(srs_error_t err);
// Use complex errors, @read https://github.com/ossrs/srs/issues/913 // The complex error carries code, message, callstack and instant variables,
// which is more strong and easy to locate problem by log,
// please @read https://github.com/ossrs/srs/issues/913
class SrsCplxError class SrsCplxError
{ {
private: private:

View file

@ -28,7 +28,7 @@
#include <string> #include <string>
// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 // For srs-librtmp, @see https://github.com/ossrs/srs/issues/213
#ifndef _WIN32 #ifndef _WIN32
#include <sys/uio.h> #include <sys/uio.h>
#endif #endif
@ -40,19 +40,13 @@ class SrsFileReader;
#define SRS_FLV_TAG_HEADER_SIZE 11 #define SRS_FLV_TAG_HEADER_SIZE 11
#define SRS_FLV_PREVIOUS_TAG_SIZE 4 #define SRS_FLV_PREVIOUS_TAG_SIZE 4
// 5. Protocol Control Messages
/**************************************************************************** // RTMP reserves message type IDs 1-7 for protocol control messages.
***************************************************************************** // These messages contain information needed by the RTM Chunk Stream
****************************************************************************/ // protocol or RTMP itself. Protocol messages with IDs 1 & 2 are
/** // reserved for usage with RTM Chunk Stream protocol. Protocol messages
5. Protocol Control Messages // with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID
RTMP reserves message type IDs 1-7 for protocol control messages. // 7 is used between edge server and origin server.
These messages contain information needed by the RTM Chunk Stream
protocol or RTMP itself. Protocol messages with IDs 1 & 2 are
reserved for usage with RTM Chunk Stream protocol. Protocol messages
with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID
7 is used between edge server and origin server.
*/
#define RTMP_MSG_SetChunkSize 0x01 #define RTMP_MSG_SetChunkSize 0x01
#define RTMP_MSG_AbortMessage 0x02 #define RTMP_MSG_AbortMessage 0x02
#define RTMP_MSG_Acknowledgement 0x03 #define RTMP_MSG_Acknowledgement 0x03
@ -60,167 +54,121 @@ class SrsFileReader;
#define RTMP_MSG_WindowAcknowledgementSize 0x05 #define RTMP_MSG_WindowAcknowledgementSize 0x05
#define RTMP_MSG_SetPeerBandwidth 0x06 #define RTMP_MSG_SetPeerBandwidth 0x06
#define RTMP_MSG_EdgeAndOriginServerCommand 0x07 #define RTMP_MSG_EdgeAndOriginServerCommand 0x07
/** // 3. Types of messages
3. Types of messages // The server and the client send messages over the network to
The server and the client send messages over the network to // communicate with each other. The messages can be of any type which
communicate with each other. The messages can be of any type which // includes audio messages, video messages, command messages, shared
includes audio messages, video messages, command messages, shared // object messages, data messages, and user control messages.
object messages, data messages, and user control messages. // 3.1. Command message
3.1. Command message // Command messages carry the AMF-encoded commands between the client
Command messages carry the AMF-encoded commands between the client // and the server. These messages have been assigned message type value
and the server. These messages have been assigned message type value // of 20 for AMF0 encoding and message type value of 17 for AMF3
of 20 for AMF0 encoding and message type value of 17 for AMF3 // encoding. These messages are sent to perform some operations like
encoding. These messages are sent to perform some operations like // connect, createStream, publish, play, pause on the peer. Command
connect, createStream, publish, play, pause on the peer. Command // messages like onstatus, result etc. are used to inform the sender
messages like onstatus, result etc. are used to inform the sender // about the status of the requested commands. A command message
about the status of the requested commands. A command message // consists of command name, transaction ID, and command object that
consists of command name, transaction ID, and command object that // contains related parameters. A client or a server can request Remote
contains related parameters. A client or a server can request Remote // Procedure Calls (RPC) over streams that are communicated using the
Procedure Calls (RPC) over streams that are communicated using the // command messages to the peer.
command messages to the peer.
*/
#define RTMP_MSG_AMF3CommandMessage 17 // 0x11 #define RTMP_MSG_AMF3CommandMessage 17 // 0x11
#define RTMP_MSG_AMF0CommandMessage 20 // 0x14 #define RTMP_MSG_AMF0CommandMessage 20 // 0x14
/** // 3.2. Data message
3.2. Data message // The client or the server sends this message to send Metadata or any
The client or the server sends this message to send Metadata or any // user data to the peer. Metadata includes details about the
user data to the peer. Metadata includes details about the // data(audio, video etc.) like creation time, duration, theme and so
data(audio, video etc.) like creation time, duration, theme and so // on. These messages have been assigned message type value of 18 for
on. These messages have been assigned message type value of 18 for // AMF0 and message type value of 15 for AMF3.
AMF0 and message type value of 15 for AMF3.
*/
#define RTMP_MSG_AMF0DataMessage 18 // 0x12 #define RTMP_MSG_AMF0DataMessage 18 // 0x12
#define RTMP_MSG_AMF3DataMessage 15 // 0x0F #define RTMP_MSG_AMF3DataMessage 15 // 0x0F
/** // 3.3. Shared object message
3.3. Shared object message // A shared object is a Flash object (a collection of name value pairs)
A shared object is a Flash object (a collection of name value pairs) // that are in synchronization across multiple clients, instances, and
that are in synchronization across multiple clients, instances, and // so on. The message types kMsgContainer=19 for AMF0 and
so on. The message types kMsgContainer=19 for AMF0 and // kMsgContainerEx=16 for AMF3 are reserved for shared object events.
kMsgContainerEx=16 for AMF3 are reserved for shared object events. // Each message can contain multiple events.
Each message can contain multiple events.
*/
#define RTMP_MSG_AMF3SharedObject 16 // 0x10 #define RTMP_MSG_AMF3SharedObject 16 // 0x10
#define RTMP_MSG_AMF0SharedObject 19 // 0x13 #define RTMP_MSG_AMF0SharedObject 19 // 0x13
/** // 3.4. Audio message
3.4. Audio message // The client or the server sends this message to send audio data to the
The client or the server sends this message to send audio data to the // peer. The message type value of 8 is reserved for audio messages.
peer. The message type value of 8 is reserved for audio messages.
*/
#define RTMP_MSG_AudioMessage 8 // 0x08 #define RTMP_MSG_AudioMessage 8 // 0x08
/* * // 3.5. Video message
3.5. Video message // The client or the server sends this message to send video data to the
The client or the server sends this message to send video data to the // peer. The message type value of 9 is reserved for video messages.
peer. The message type value of 9 is reserved for video messages. // These messages are large and can delay the sending of other type of
These messages are large and can delay the sending of other type of // messages. To avoid such a situation, the video message is assigned
messages. To avoid such a situation, the video message is assigned // The lowest priority.
the lowest priority.
*/
#define RTMP_MSG_VideoMessage 9 // 0x09 #define RTMP_MSG_VideoMessage 9 // 0x09
/** // 3.6. Aggregate message
3.6. Aggregate message // An aggregate message is a single message that contains a list of submessages.
An aggregate message is a single message that contains a list of submessages. // The message type value of 22 is reserved for aggregate
The message type value of 22 is reserved for aggregate // messages.
messages.
*/
#define RTMP_MSG_AggregateMessage 22 // 0x16 #define RTMP_MSG_AggregateMessage 22 // 0x16
// The chunk stream id used for some under-layer message,
/**************************************************************************** // For example, the PC(protocol control) message.
*****************************************************************************
****************************************************************************/
/**
* the chunk stream id used for some under-layer message,
* for example, the PC(protocol control) message.
*/
#define RTMP_CID_ProtocolControl 0x02 #define RTMP_CID_ProtocolControl 0x02
/** // The AMF0/AMF3 command message, invoke method and return the result, over NetConnection.
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection. // generally use 0x03.
* generally use 0x03.
*/
#define RTMP_CID_OverConnection 0x03 #define RTMP_CID_OverConnection 0x03
/** // The AMF0/AMF3 command message, invoke method and return the result, over NetConnection,
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection, // The midst state(we guess).
* the midst state(we guess). // rarely used, e.g. onStatus(NetStream.Play.Reset).
* rarely used, e.g. onStatus(NetStream.Play.Reset).
*/
#define RTMP_CID_OverConnection2 0x04 #define RTMP_CID_OverConnection2 0x04
/** // The stream message(amf0/amf3), over NetStream.
* the stream message(amf0/amf3), over NetStream. // generally use 0x05.
* generally use 0x05.
*/
#define RTMP_CID_OverStream 0x05 #define RTMP_CID_OverStream 0x05
/** // The stream message(amf0/amf3), over NetStream, the midst state(we guess).
* the stream message(amf0/amf3), over NetStream, the midst state(we guess). // rarely used, e.g. play("mp4:mystram.f4v")
* rarely used, e.g. play("mp4:mystram.f4v")
*/
#define RTMP_CID_OverStream2 0x08 #define RTMP_CID_OverStream2 0x08
/** // The stream message(video), over NetStream
* the stream message(video), over NetStream // generally use 0x06.
* generally use 0x06.
*/
#define RTMP_CID_Video 0x06 #define RTMP_CID_Video 0x06
/** // The stream message(audio), over NetStream.
* the stream message(audio), over NetStream. // generally use 0x07.
* generally use 0x07.
*/
#define RTMP_CID_Audio 0x07 #define RTMP_CID_Audio 0x07
/** // 6.1. Chunk Format
* 6.1. Chunk Format // Extended timestamp: 0 or 4 bytes
* Extended timestamp: 0 or 4 bytes // This field MUST be sent when the normal timsestamp is set to
* This field MUST be sent when the normal timsestamp is set to // 0xffffff, it MUST NOT be sent if the normal timestamp is set to
* 0xffffff, it MUST NOT be sent if the normal timestamp is set to // anything else. So for values less than 0xffffff the normal
* anything else. So for values less than 0xffffff the normal // timestamp field SHOULD be used in which case the extended timestamp
* timestamp field SHOULD be used in which case the extended timestamp // MUST NOT be present. For values greater than or equal to 0xffffff
* MUST NOT be present. For values greater than or equal to 0xffffff // The normal timestamp field MUST NOT be used and MUST be set to
* the normal timestamp field MUST NOT be used and MUST be set to // 0xffffff and the extended timestamp MUST be sent.
* 0xffffff and the extended timestamp MUST be sent.
*/
#define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF #define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF
/** // 4.1. Message Header
* 4.1. Message Header
*/
class SrsMessageHeader class SrsMessageHeader
{ {
public: public:
/** // 3bytes.
* 3bytes. // Three-byte field that contains a timestamp delta of the message.
* Three-byte field that contains a timestamp delta of the message. // @remark, only used for decoding message from chunk stream.
* @remark, only used for decoding message from chunk stream.
*/
int32_t timestamp_delta; int32_t timestamp_delta;
/** // 3bytes.
* 3bytes. // Three-byte field that represents the size of the payload in bytes.
* Three-byte field that represents the size of the payload in bytes. // It is set in big-endian format.
* It is set in big-endian format.
*/
int32_t payload_length; int32_t payload_length;
/** // 1byte.
* 1byte. // One byte field to represent the message type. A range of type IDs
* One byte field to represent the message type. A range of type IDs // (1-7) are reserved for protocol control messages.
* (1-7) are reserved for protocol control messages.
*/
int8_t message_type; int8_t message_type;
/** // 4bytes.
* 4bytes. // Four-byte field that identifies the stream of the message. These
* Four-byte field that identifies the stream of the message. These // bytes are set in little-endian format.
* bytes are set in little-endian format.
*/
int32_t stream_id; int32_t stream_id;
/** // Four-byte field that contains a timestamp of the message.
* Four-byte field that contains a timestamp of the message. // The 4 bytes are packed in the big-endian order.
* The 4 bytes are packed in the big-endian order. // @remark, used as calc timestamp when decode and encode time.
* @remark, used as calc timestamp when decode and encode time. // @remark, we use 64bits for large time for jitter detect and hls.
* @remark, we use 64bits for large time for jitter detect and hls.
*/
int64_t timestamp; int64_t timestamp;
public: public:
/** // Get the perfered cid(chunk stream id) which sendout over.
* get the perfered cid(chunk stream id) which sendout over. // set at decoding, and canbe used for directly send message,
* set at decoding, and canbe used for directly send message, // For example, dispatch to all connections.
* for example, dispatch to all connections.
*/
int perfer_cid; int perfer_cid;
public: public:
SrsMessageHeader(); SrsMessageHeader();
@ -239,149 +187,114 @@ public:
bool is_set_peer_bandwidth(); bool is_set_peer_bandwidth();
bool is_aggregate(); bool is_aggregate();
public: public:
/** // Create a amf0 script header, set the size and stream_id.
* create a amf0 script header, set the size and stream_id.
*/
void initialize_amf0_script(int size, int stream); void initialize_amf0_script(int size, int stream);
/** // Create a audio header, set the size, timestamp and stream_id.
* create a audio header, set the size, timestamp and stream_id.
*/
void initialize_audio(int size, uint32_t time, int stream); void initialize_audio(int size, uint32_t time, int stream);
/** // Create a video header, set the size, timestamp and stream_id.
* create a video header, set the size, timestamp and stream_id.
*/
void initialize_video(int size, uint32_t time, int stream); void initialize_video(int size, uint32_t time, int stream);
}; };
/** // The message is raw data RTMP message, bytes oriented,
* message is raw data RTMP message, bytes oriented, // protcol always recv RTMP message, and can send RTMP message or RTMP packet.
* protcol always recv RTMP message, and can send RTMP message or RTMP packet. // The common message is read from underlay protocol sdk.
* the common message is read from underlay protocol sdk. // while the shared ptr message used to copy and send.
* while the shared ptr message used to copy and send.
*/
class SrsCommonMessage class SrsCommonMessage
{ {
// 4.1. Message Header // 4.1. Message Header
public: public:
SrsMessageHeader header; SrsMessageHeader header;
// 4.2. Message Payload // 4.2. Message Payload
public: public:
/** // The current message parsed size,
* current message parsed size, // size <= header.payload_length
* size <= header.payload_length // For the payload maybe sent in multiple chunks.
* for the payload maybe sent in multiple chunks.
*/
int size; int size;
/** // The payload of message, the SrsCommonMessage never know about the detail of payload,
* the payload of message, the SrsCommonMessage never know about the detail of payload, // user must use SrsProtocol.decode_message to get concrete packet.
* user must use SrsProtocol.decode_message to get concrete packet. // @remark, not all message payload can be decoded to packet. for example,
* @remark, not all message payload can be decoded to packet. for example, // video/audio packet use raw bytes, no video/audio packet.
* video/audio packet use raw bytes, no video/audio packet.
*/
char* payload; char* payload;
public: public:
SrsCommonMessage(); SrsCommonMessage();
virtual ~SrsCommonMessage(); virtual ~SrsCommonMessage();
public: public:
/** // Alloc the payload to specified size of bytes.
* alloc the payload to specified size of bytes.
*/
virtual void create_payload(int size); virtual void create_payload(int size);
public: public:
/** // Create common message,
* create common message, // from the header and body.
* from the header and body. // @remark user should never free the body.
* @remark user should never free the body. // @param pheader, the header to copy to the message. NULL to ignore.
* @param pheader, the header to copy to the message. NULL to ignore.
*/
virtual srs_error_t create(SrsMessageHeader* pheader, char* body, int size); virtual srs_error_t create(SrsMessageHeader* pheader, char* body, int size);
}; };
/** // The message header for shared ptr message.
* the message header for shared ptr message. // only the message for all msgs are same.
* only the message for all msgs are same.
*/
struct SrsSharedMessageHeader struct SrsSharedMessageHeader
{ {
/** // 3bytes.
* 3bytes. // Three-byte field that represents the size of the payload in bytes.
* Three-byte field that represents the size of the payload in bytes. // It is set in big-endian format.
* It is set in big-endian format.
*/
int32_t payload_length; int32_t payload_length;
/** // 1byte.
* 1byte. // One byte field to represent the message type. A range of type IDs
* One byte field to represent the message type. A range of type IDs // (1-7) are reserved for protocol control messages.
* (1-7) are reserved for protocol control messages.
*/
int8_t message_type; int8_t message_type;
/** // Get the perfered cid(chunk stream id) which sendout over.
* get the perfered cid(chunk stream id) which sendout over. // set at decoding, and canbe used for directly send message,
* set at decoding, and canbe used for directly send message, // For example, dispatch to all connections.
* for example, dispatch to all connections.
*/
int perfer_cid; int perfer_cid;
SrsSharedMessageHeader(); SrsSharedMessageHeader();
virtual ~SrsSharedMessageHeader(); virtual ~SrsSharedMessageHeader();
}; };
/** // The shared ptr message.
* shared ptr message. // For audio/video/data message that need less memory copy.
* for audio/video/data message that need less memory copy. // and only for output.
* and only for output. //
* // Create first object by constructor and create(),
* create first object by constructor and create(), // use copy if need reference count message.
* use copy if need reference count message.
*
*/
class SrsSharedPtrMessage class SrsSharedPtrMessage
{ {
// 4.1. Message Header // 4.1. Message Header
public: public:
// the header can shared, only set the timestamp and stream id. // The header can shared, only set the timestamp and stream id.
// @see https://github.com/ossrs/srs/issues/251 // @see https://github.com/ossrs/srs/issues/251
//SrsSharedMessageHeader header; //SrsSharedMessageHeader header;
/** // Four-byte field that contains a timestamp of the message.
* Four-byte field that contains a timestamp of the message. // The 4 bytes are packed in the big-endian order.
* The 4 bytes are packed in the big-endian order. // @remark, used as calc timestamp when decode and encode time.
* @remark, used as calc timestamp when decode and encode time. // @remark, we use 64bits for large time for jitter detect and hls.
* @remark, we use 64bits for large time for jitter detect and hls.
*/
int64_t timestamp; int64_t timestamp;
/** // 4bytes.
* 4bytes. // Four-byte field that identifies the stream of the message. These
* Four-byte field that identifies the stream of the message. These // bytes are set in big-endian format.
* bytes are set in big-endian format.
*/
int32_t stream_id; int32_t stream_id;
// 4.2. Message Payload // 4.2. Message Payload
public: public:
/** // The current message parsed size,
* current message parsed size, // size <= header.payload_length
* size <= header.payload_length // For the payload maybe sent in multiple chunks.
* for the payload maybe sent in multiple chunks.
*/
int size; int size;
/** // The payload of message, the SrsCommonMessage never know about the detail of payload,
* the payload of message, the SrsCommonMessage never know about the detail of payload, // user must use SrsProtocol.decode_message to get concrete packet.
* user must use SrsProtocol.decode_message to get concrete packet. // @remark, not all message payload can be decoded to packet. for example,
* @remark, not all message payload can be decoded to packet. for example, // video/audio packet use raw bytes, no video/audio packet.
* video/audio packet use raw bytes, no video/audio packet.
*/
char* payload; char* payload;
private: private:
class SrsSharedPtrPayload class SrsSharedPtrPayload
{ {
public: public:
// shared message header. // The shared message header.
// @see https://github.com/ossrs/srs/issues/251 // @see https://github.com/ossrs/srs/issues/251
SrsSharedMessageHeader header; SrsSharedMessageHeader header;
// actual shared payload. // The actual shared payload.
char* payload; char* payload;
// size of payload. // The size of payload.
int size; int size;
// the reference count // The reference count
int shared_count; int shared_count;
public: public:
SrsSharedPtrPayload(); SrsSharedPtrPayload();
@ -392,54 +305,40 @@ public:
SrsSharedPtrMessage(); SrsSharedPtrMessage();
virtual ~SrsSharedPtrMessage(); virtual ~SrsSharedPtrMessage();
public: public:
/** // Create shared ptr message,
* create shared ptr message, // copy header, manage the payload of msg,
* copy header, manage the payload of msg, // set the payload to NULL to prevent double free.
* set the payload to NULL to prevent double free. // @remark payload of msg set to NULL if success.
* @remark payload of msg set to NULL if success.
*/
virtual srs_error_t create(SrsCommonMessage* msg); virtual srs_error_t create(SrsCommonMessage* msg);
/** // Create shared ptr message,
* create shared ptr message, // from the header and payload.
* from the header and payload. // @remark user should never free the payload.
* @remark user should never free the payload. // @param pheader, the header to copy to the message. NULL to ignore.
* @param pheader, the header to copy to the message. NULL to ignore.
*/
virtual srs_error_t create(SrsMessageHeader* pheader, char* payload, int size); virtual srs_error_t create(SrsMessageHeader* pheader, char* payload, int size);
/** // Get current reference count.
* get current reference count. // when this object created, count set to 0.
* when this object created, count set to 0. // if copy() this object, count increase 1.
* if copy() this object, count increase 1. // if this or copy deleted, free payload when count is 0, or count--.
* if this or copy deleted, free payload when count is 0, or count--. // @remark, assert object is created.
* @remark, assert object is created.
*/
virtual int count(); virtual int count();
/** // check perfer cid and stream id.
* check perfer cid and stream id. // @return whether stream id already set.
* @return whether stream id already set.
*/
virtual bool check(int stream_id); virtual bool check(int stream_id);
public: public:
virtual bool is_av(); virtual bool is_av();
virtual bool is_audio(); virtual bool is_audio();
virtual bool is_video(); virtual bool is_video();
public: public:
/** // generate the chunk header to cache.
* generate the chunk header to cache. // @return the size of header.
* @return the size of header.
*/
virtual int chunk_header(char* cache, int nb_cache, bool c0); virtual int chunk_header(char* cache, int nb_cache, bool c0);
public: public:
/** // copy current shared ptr message, use ref-count.
* copy current shared ptr message, use ref-count. // @remark, assert object is created.
* @remark, assert object is created.
*/
virtual SrsSharedPtrMessage* copy(); virtual SrsSharedPtrMessage* copy();
}; };
/** // Transmux RTMP packets to FLV stream.
* Transmux RTMP packets to FLV stream.
*/
class SrsFlvTransmuxer class SrsFlvTransmuxer
{ {
private: private:
@ -450,60 +349,48 @@ public:
SrsFlvTransmuxer(); SrsFlvTransmuxer();
virtual ~SrsFlvTransmuxer(); virtual ~SrsFlvTransmuxer();
public: public:
/** // Initialize the underlayer file stream.
* initialize the underlayer file stream. // @remark user can initialize multiple times to encode multiple flv files.
* @remark user can initialize multiple times to encode multiple flv files. // @remark, user must free the @param fw, flv encoder never close/free it.
* @remark, user must free the @param fw, flv encoder never close/free it.
*/
virtual srs_error_t initialize(ISrsWriter* fw); virtual srs_error_t initialize(ISrsWriter* fw);
public: public:
/** // Write flv header.
* write flv header. // Write following:
* write following: // 1. E.2 The FLV header
* 1. E.2 The FLV header // 2. PreviousTagSize0 UI32 Always 0
* 2. PreviousTagSize0 UI32 Always 0 // that is, 9+4=13bytes.
* that is, 9+4=13bytes.
*/
virtual srs_error_t write_header(); virtual srs_error_t write_header();
virtual srs_error_t write_header(char flv_header[9]); virtual srs_error_t write_header(char flv_header[9]);
/** // Write flv metadata.
* write flv metadata. // @param type, the type of data, or other message type.
* @param type, the type of data, or other message type. // @see SrsFrameType
* @see SrsFrameType // @param data, the amf0 metadata which serialize from:
* @param data, the amf0 metadata which serialize from: // AMF0 string: onMetaData,
* AMF0 string: onMetaData, // AMF0 object: the metadata object.
* AMF0 object: the metadata object. // @remark assert data is not NULL.
* @remark assert data is not NULL.
*/
virtual srs_error_t write_metadata(char type, char* data, int size); virtual srs_error_t write_metadata(char type, char* data, int size);
/** // Write audio/video packet.
* write audio/video packet. // @remark assert data is not NULL.
* @remark assert data is not NULL.
*/
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size); virtual srs_error_t write_audio(int64_t timestamp, char* data, int size);
virtual srs_error_t write_video(int64_t timestamp, char* data, int size); virtual srs_error_t write_video(int64_t timestamp, char* data, int size);
public: public:
/** // Get the tag size,
* get the tag size, // including the tag header, body, and 4bytes previous tag size.
* including the tag header, body, and 4bytes previous tag size. // @remark assert data_size is not negative.
* @remark assert data_size is not negative.
*/
static int size_tag(int data_size); static int size_tag(int data_size);
#ifdef SRS_PERF_FAST_FLV_ENCODER #ifdef SRS_PERF_FAST_FLV_ENCODER
private: private:
// cache tag header. // The cache tag header.
int nb_tag_headers; int nb_tag_headers;
char* tag_headers; char* tag_headers;
// cache pps(previous tag size) // The cache pps(previous tag size)
int nb_ppts; int nb_ppts;
char* ppts; char* ppts;
// cache iovss. // The cache iovss.
int nb_iovss_cache; int nb_iovss_cache;
iovec* iovss_cache; iovec* iovss_cache;
public: public:
/** // Write the tags in a time.
* write the tags in a time.
*/
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count); virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
#endif #endif
private: private:
@ -514,9 +401,7 @@ private:
virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size); virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size);
}; };
/** // Decode flv file.
* decode flv file.
*/
class SrsFlvDecoder class SrsFlvDecoder
{ {
private: private:
@ -525,40 +410,28 @@ public:
SrsFlvDecoder(); SrsFlvDecoder();
virtual ~SrsFlvDecoder(); virtual ~SrsFlvDecoder();
public: public:
/** // Initialize the underlayer file stream
* initialize the underlayer file stream // @remark user can initialize multiple times to decode multiple flv files.
* @remark user can initialize multiple times to decode multiple flv files. // @remark user must free the @param fr, flv decoder never close/free it
* @remark user must free the @param fr, flv decoder never close/free it
*/
virtual srs_error_t initialize(ISrsReader* fr); virtual srs_error_t initialize(ISrsReader* fr);
public: public:
/** // Read the flv header, donot including the 4bytes previous tag size.
* read the flv header, donot including the 4bytes previous tag size. // @remark assert header not NULL.
* @remark assert header not NULL.
*/
virtual srs_error_t read_header(char header[9]); virtual srs_error_t read_header(char header[9]);
/** // Read the tag header infos.
* read the tag header infos. // @remark assert ptype/pdata_size/ptime not NULL.
* @remark assert ptype/pdata_size/ptime not NULL.
*/
virtual srs_error_t read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* ptime); virtual srs_error_t read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* ptime);
/** // Read the tag data.
* read the tag data. // @remark assert data not NULL.
* @remark assert data not NULL.
*/
virtual srs_error_t read_tag_data(char* data, int32_t size); virtual srs_error_t read_tag_data(char* data, int32_t size);
/** // Read the 4bytes previous tag size.
* read the 4bytes previous tag size. // @remark assert previous_tag_size not NULL.
* @remark assert previous_tag_size not NULL.
*/
virtual srs_error_t read_previous_tag_size(char previous_tag_size[4]); virtual srs_error_t read_previous_tag_size(char previous_tag_size[4]);
}; };
/** // Decode flv fast by only decoding the header and tag.
* decode flv fast by only decoding the header and tag. // used for vod flv stream to read the header and sequence header,
* used for vod flv stream to read the header and sequence header, // then seek to specified offset.
* then seek to specified offset.
*/
class SrsFlvVodStreamDecoder class SrsFlvVodStreamDecoder
{ {
private: private:
@ -567,31 +440,23 @@ public:
SrsFlvVodStreamDecoder(); SrsFlvVodStreamDecoder();
virtual ~SrsFlvVodStreamDecoder(); virtual ~SrsFlvVodStreamDecoder();
public: public:
/** // Initialize the underlayer file stream
* initialize the underlayer file stream // @remark user can initialize multiple times to decode multiple flv files.
* @remark user can initialize multiple times to decode multiple flv files. // @remark user must free the @param fr, flv decoder never close/free it.
* @remark user must free the @param fr, flv decoder never close/free it.
*/
virtual srs_error_t initialize(ISrsReader* fr); virtual srs_error_t initialize(ISrsReader* fr);
public: public:
/** // Read the flv header and its size.
* read the flv header and its size. // @param header, fill it 13bytes(9bytes header, 4bytes previous tag size).
* @param header, fill it 13bytes(9bytes header, 4bytes previous tag size). // @remark assert header not NULL.
* @remark assert header not NULL.
*/
virtual srs_error_t read_header_ext(char header[13]); virtual srs_error_t read_header_ext(char header[13]);
/** // Read the sequence header tags offset and its size.
* read the sequence header tags offset and its size. // @param pstart, the start offset of sequence header.
* @param pstart, the start offset of sequence header. // @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size).
* @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size). // @remark we think the first audio/video is sequence header.
* @remark we think the first audio/video is sequence header. // @remark assert pstart/psize not NULL.
* @remark assert pstart/psize not NULL.
*/
virtual srs_error_t read_sequence_header_summary(int64_t* pstart, int* psize); virtual srs_error_t read_sequence_header_summary(int64_t* pstart, int* psize);
public: public:
/** // For start offset, seed to this position and response flv stream.
* for start offset, seed to this position and response flv stream.
*/
virtual srs_error_t seek2(int64_t offset); virtual srs_error_t seek2(int64_t offset);
}; };

View file

@ -33,15 +33,13 @@
#include <srs_kernel_consts.hpp> #include <srs_kernel_consts.hpp>
/** // The log level, for example:
* the log level, for example: // if specified Debug level, all level messages will be logged.
* if specified Debug level, all level messages will be logged. // if specified Warn level, only Warn/Error/Fatal level messages will be logged.
* if specified Warn level, only Warn/Error/Fatal level messages will be logged.
*/
enum SrsLogLevel enum SrsLogLevel
{ {
SrsLogLevelForbidden = 0x00, SrsLogLevelForbidden = 0x00,
// only used for very verbose debug, generally, // Only used for very verbose debug, generally,
// we compile without this level for high performance. // we compile without this level for high performance.
SrsLogLevelVerbose = 0x01, SrsLogLevelVerbose = 0x01,
SrsLogLevelInfo = 0x02, SrsLogLevelInfo = 0x02,
@ -51,85 +49,63 @@ enum SrsLogLevel
SrsLogLevelDisabled = 0x20, SrsLogLevelDisabled = 0x20,
}; };
/** // The log interface provides method to write log.
* the log interface provides method to write log. // but we provides some macro, which enable us to disable the log when compile.
* but we provides some macro, which enable us to disable the log when compile. // @see also SmtDebug/SmtTrace/SmtWarn/SmtError which is corresponding to Debug/Trace/Warn/Fatal.
* @see also SmtDebug/SmtTrace/SmtWarn/SmtError which is corresponding to Debug/Trace/Warn/Fatal.
*/
class ISrsLog class ISrsLog
{ {
public: public:
ISrsLog(); ISrsLog();
virtual ~ISrsLog(); virtual ~ISrsLog();
public: public:
/** // Initialize log utilities.
* initialize log utilities.
*/
virtual srs_error_t initialize(); virtual srs_error_t initialize();
/** // Reopen the log file for log rotate.
* reopen the log file for log rotate.
*/
virtual void reopen(); virtual void reopen();
public: public:
/** // The log for verbose, very verbose information.
* log for verbose, very verbose information.
*/
virtual void verbose(const char* tag, int context_id, const char* fmt, ...); virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
/** // The log for debug, detail information.
* log for debug, detail information.
*/
virtual void info(const char* tag, int context_id, const char* fmt, ...); virtual void info(const char* tag, int context_id, const char* fmt, ...);
/** // The log for trace, important information.
* log for trace, important information.
*/
virtual void trace(const char* tag, int context_id, const char* fmt, ...); virtual void trace(const char* tag, int context_id, const char* fmt, ...);
/** // The log for warn, warn is something should take attention, but not a error.
* log for warn, warn is something should take attention, but not a error.
*/
virtual void warn(const char* tag, int context_id, const char* fmt, ...); virtual void warn(const char* tag, int context_id, const char* fmt, ...);
/** // The log for error, something error occur, do something about the error, ie. close the connection,
* log for error, something error occur, do something about the error, ie. close the connection, // but we will donot abort the program.
* but we will donot abort the program.
*/
virtual void error(const char* tag, int context_id, const char* fmt, ...); virtual void error(const char* tag, int context_id, const char* fmt, ...);
}; };
/** // The context id manager to identify context, for instance, the green-thread.
* the context id manager to identify context, for instance, the green-thread. // Usage:
* usage: // _srs_context->generate_id(); // when thread start.
* _srs_context->generate_id(); // when thread start. // _srs_context->get_id(); // get current generated id.
* _srs_context->get_id(); // get current generated id. // int old_id = _srs_context->set_id(1000); // set context id if need to merge thread context.
* int old_id = _srs_context->set_id(1000); // set context id if need to merge thread context. // The context for multiple clients.
*/
// the context for multiple clients.
class ISrsThreadContext class ISrsThreadContext
{ {
public: public:
ISrsThreadContext(); ISrsThreadContext();
virtual ~ISrsThreadContext(); virtual ~ISrsThreadContext();
public: public:
/** // Generate the id for current context.
* generate the id for current context.
*/
virtual int generate_id(); virtual int generate_id();
/** // Get the generated id of current context.
* get the generated id of current context.
*/
virtual int get_id(); virtual int get_id();
/** // Set the id of current context.
* set the id of current context. // @return the previous id value; 0 if no context.
* @return the previous id value; 0 if no context.
*/
virtual int set_id(int v); virtual int set_id(int v);
}; };
// @global user must provides a log object // @global User must provides a log object
extern ISrsLog* _srs_log; extern ISrsLog* _srs_log;
// @global user must implements the LogContext and define a global instance. // @global User must implements the LogContext and define a global instance.
extern ISrsThreadContext* _srs_context; extern ISrsThreadContext* _srs_context;
// donot print method // Log style.
// Use __FUNCTION__ to print c method
// Use __PRETTY_FUNCTION__ to print c++ class:method
#if 1 #if 1
#define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
@ -137,7 +113,6 @@ extern ISrsThreadContext* _srs_context;
#define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
#endif #endif
// use __FUNCTION__ to print c method
#if 0 #if 0
#define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
@ -145,7 +120,6 @@ extern ISrsThreadContext* _srs_context;
#define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#endif #endif
// use __PRETTY_FUNCTION__ to print c++ class:method
#if 0 #if 0
#define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
@ -154,7 +128,7 @@ extern ISrsThreadContext* _srs_context;
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
#endif #endif
// TODO: FIXME: add more verbose and info logs. // TODO: FIXME: Add more verbose and info logs.
#ifndef SRS_AUTO_VERBOSE #ifndef SRS_AUTO_VERBOSE
#undef srs_verbose #undef srs_verbose
#define srs_verbose(msg, ...) (void)0 #define srs_verbose(msg, ...) (void)0

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -33,160 +33,132 @@
class SrsBuffer; class SrsBuffer;
class SrsBitBuffer; class SrsBitBuffer;
// compare // Basic compare function.
#define srs_min(a, b) (((a) < (b))? (a) : (b)) #define srs_min(a, b) (((a) < (b))? (a) : (b))
#define srs_max(a, b) (((a) < (b))? (b) : (a)) #define srs_max(a, b) (((a) < (b))? (b) : (a))
// read nalu uev. // To read H.264 NALU uev.
extern srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer* stream, int32_t& v); extern srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer* stream, int32_t& v);
extern srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v); extern srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v);
// get current system time in srs_utime_t, use cache to avoid performance problem // Get current system time in srs_utime_t, use cache to avoid performance problem
extern srs_utime_t srs_get_system_time(); extern srs_utime_t srs_get_system_time();
extern srs_utime_t srs_get_system_startup_time(); extern srs_utime_t srs_get_system_startup_time();
// the deamon st-thread will update it. // A daemon st-thread updates it.
extern srs_utime_t srs_update_system_time(); extern srs_utime_t srs_update_system_time();
// the any address for listener, // The "ANY" address to listen, it's "0.0.0.0" for ipv4, and "::" for ipv6.
// it's "0.0.0.0" for ipv4, and "::" for ipv6.
extern std::string srs_any_address4listener(); extern std::string srs_any_address4listener();
// dns resolve utility, return the resolved ip address. // The dns resolve utility, return the resolved ip address.
extern std::string srs_dns_resolve(std::string host, int& family); extern std::string srs_dns_resolve(std::string host, int& family);
// split the host:port to host and port. // Split the host:port to host and port.
// @remark the hostport format in <host[:port]>, where port is optional. // @remark the hostport format in <host[:port]>, where port is optional.
extern void srs_parse_hostport(const std::string& hostport, std::string& host, int& port); extern void srs_parse_hostport(const std::string& hostport, std::string& host, int& port);
// parse the endpoint to ip and port. // Parse the endpoint to ip and port.
// @remark hostport format in <[ip:]port>, where ip is default to "0.0.0.0". // @remark The hostport format in <[ip:]port>, where ip is default to "0.0.0.0".
extern void srs_parse_endpoint(std::string hostport, std::string& ip, int& port); extern void srs_parse_endpoint(std::string hostport, std::string& ip, int& port);
// parse the int64 value to string. // Parse the int64 value to string.
extern std::string srs_int2str(int64_t value); extern std::string srs_int2str(int64_t value);
// parse the float value to string, precise is 2. // Parse the float value to string, precise is 2.
extern std::string srs_float2str(double value); extern std::string srs_float2str(double value);
// convert bool to switch value, true to "on", false to "off". // Convert bool to switch value, true to "on", false to "off".
extern std::string srs_bool2switch(bool v); extern std::string srs_bool2switch(bool v);
// whether system is little endian // Whether system is little endian
extern bool srs_is_little_endian(); extern bool srs_is_little_endian();
// replace old_str to new_str of str // Replace old_str to new_str of str
extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str); extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str);
// trim char in trim_chars of str // Trim char in trim_chars of str
extern std::string srs_string_trim_end(std::string str, std::string trim_chars); extern std::string srs_string_trim_end(std::string str, std::string trim_chars);
// trim char in trim_chars of str // Trim char in trim_chars of str
extern std::string srs_string_trim_start(std::string str, std::string trim_chars); extern std::string srs_string_trim_start(std::string str, std::string trim_chars);
// remove char in remove_chars of str // Remove char in remove_chars of str
extern std::string srs_string_remove(std::string str, std::string remove_chars); extern std::string srs_string_remove(std::string str, std::string remove_chars);
// remove first substring from str // Remove first substring from str
extern std::string srs_erase_first_substr(std::string str, std::string erase_string); extern std::string srs_erase_first_substr(std::string str, std::string erase_string);
// remove last substring from str // Remove last substring from str
extern std::string srs_erase_last_substr(std::string str, std::string erase_string); extern std::string srs_erase_last_substr(std::string str, std::string erase_string);
// whether string end with // Whether string end with
extern bool srs_string_ends_with(std::string str, std::string flag); extern bool srs_string_ends_with(std::string str, std::string flag);
extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1);
extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2);
extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3);
// whether string starts with // Whether string starts with
extern bool srs_string_starts_with(std::string str, std::string flag); extern bool srs_string_starts_with(std::string str, std::string flag);
extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1);
extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2);
extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3);
// whether string contains with // Whether string contains with
extern bool srs_string_contains(std::string str, std::string flag); extern bool srs_string_contains(std::string str, std::string flag);
extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1); extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1);
extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1, std::string flag2); extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1, std::string flag2);
// find the min match in str for flags. // Find the min match in str for flags.
extern std::string srs_string_min_match(std::string str, std::vector<std::string> flags); extern std::string srs_string_min_match(std::string str, std::vector<std::string> flags);
// split the string by flag to array. // Split the string by flag to array.
extern std::vector<std::string> srs_string_split(std::string str, std::string flag); extern std::vector<std::string> srs_string_split(std::string str, std::string flag);
extern std::vector<std::string> srs_string_split(std::string str, std::vector<std::string> flags); extern std::vector<std::string> srs_string_split(std::string str, std::vector<std::string> flags);
/** // Compare the memory in bytes.
* compare the memory in bytes. // @return true if completely equal; otherwise, false.
* @return true if completely equal; otherwise, false.
*/
extern bool srs_bytes_equals(void* pa, void* pb, int size); extern bool srs_bytes_equals(void* pa, void* pb, int size);
// create dir recursively // Create dir recursively
extern srs_error_t srs_create_dir_recursively(std::string dir); extern srs_error_t srs_create_dir_recursively(std::string dir);
// whether path exists. // Whether path exists.
extern bool srs_path_exists(std::string path); extern bool srs_path_exists(std::string path);
// get the dirname of path, for instance, dirname("/live/livestream")="/live" // Get the dirname of path, for instance, dirname("/live/livestream")="/live"
extern std::string srs_path_dirname(std::string path); extern std::string srs_path_dirname(std::string path);
// get the basename of path, for instance, basename("/live/livestream")="livestream" // Get the basename of path, for instance, basename("/live/livestream")="livestream"
extern std::string srs_path_basename(std::string path); extern std::string srs_path_basename(std::string path);
// get the filename of path, for instance, filename("livestream.flv")="livestream" // Get the filename of path, for instance, filename("livestream.flv")="livestream"
extern std::string srs_path_filename(std::string path); extern std::string srs_path_filename(std::string path);
// get the file extension of path, for instance, filext("live.flv")=".flv" // Get the file extension of path, for instance, filext("live.flv")=".flv"
extern std::string srs_path_filext(std::string path); extern std::string srs_path_filext(std::string path);
/** // Whether stream starts with the avc NALU in "AnnexB" from ISO_IEC_14496-10-AVC-2003.pdf, page 211.
* whether stream starts with the avc NALU in "AnnexB" // The start code must be "N[00] 00 00 01" where N>=0
* from ISO_IEC_14496-10-AVC-2003.pdf, page 211. // @param pnb_start_code output the size of start code, must >=3. NULL to ignore.
* start code must be "N[00] 00 00 01" where N>=0
* @param pnb_start_code output the size of start code, must >=3.
* NULL to ignore.
*/
extern bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code = NULL); extern bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code = NULL);
/** // Whether stream starts with the aac ADTS from ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS.
* whether stream starts with the aac ADTS // The start code must be '1111 1111 1111'B, that is 0xFFF
* from ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS.
* start code must be '1111 1111 1111'B, that is 0xFFF
*/
extern bool srs_aac_startswith_adts(SrsBuffer* stream); extern bool srs_aac_startswith_adts(SrsBuffer* stream);
/** // Cacl the crc32 of bytes in buf, for ffmpeg.
* cacl the crc32 of bytes in buf, for ffmpeg.
*/
extern uint32_t srs_crc32_mpegts(const void* buf, int size); extern uint32_t srs_crc32_mpegts(const void* buf, int size);
/** // Calc the crc32 of bytes in buf by IEEE, for zip.
* calc the crc32 of bytes in buf by IEEE, for zip.
*/
extern uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous = 0); extern uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous = 0);
/** // Decode a base64-encoded string.
* Decode a base64-encoded string.
*/
extern srs_error_t srs_av_base64_decode(std::string cipher, std::string& plaintext); extern srs_error_t srs_av_base64_decode(std::string cipher, std::string& plaintext);
/** // Calculate the output size needed to base64-encode x bytes to a null-terminated string.
* Calculate the output size needed to base64-encode x bytes to a
* null-terminated string.
*/
#define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) #define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
/** // Convert hex string to data, for example, p=config='139056E5A0'
* convert hex string to data. // The output data in hex {0x13, 0x90, 0x56, 0xe5, 0xa0} as such.
* for example, p=config='139056E5A0'
* output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0}
*/
extern int srs_hex_to_data(uint8_t* data, const char* p, int size); extern int srs_hex_to_data(uint8_t* data, const char* p, int size);
/** // Convert data string to hex.
* convert data string to hex.
*/
extern char *srs_data_to_hex(char *des, const uint8_t *src, int len); extern char *srs_data_to_hex(char *des, const uint8_t *src, int len);
/** // Generate the c0 chunk header for msg.
* generate the c0 chunk header for msg. // @param cache, the cache to write header.
* @param cache, the cache to write header. // @param nb_cache, the size of cache.
* @param nb_cache, the size of cache. // @return The size of header. 0 if cache not enough.
* @return the size of header. 0 if cache not enough.
*/
extern int srs_chunk_header_c0(int perfer_cid, uint32_t timestamp, int32_t payload_length, int8_t message_type, int32_t stream_id, char* cache, int nb_cache); extern int srs_chunk_header_c0(int perfer_cid, uint32_t timestamp, int32_t payload_length, int8_t message_type, int32_t stream_id, char* cache, int nb_cache);
/** // Generate the c3 chunk header for msg.
* generate the c3 chunk header for msg. // @param cache, the cache to write header.
* @param cache, the cache to write header. // @param nb_cache, the size of cache.
* @param nb_cache, the size of cache. // @return the size of header. 0 if cache not enough.
* @return the size of header. 0 if cache not enough.
*/
extern int srs_chunk_header_c3(int perfer_cid, uint32_t timestamp, char* cache, int nb_cache); extern int srs_chunk_header_c3(int perfer_cid, uint32_t timestamp, char* cache, int nb_cache);
#endif #endif

View file

@ -365,7 +365,7 @@ int SimpleSocketStream::connect(const char* server_ip, int port)
return srs_hijack_io_connect(io, server_ip, port); return srs_hijack_io_connect(io, server_ip, port);
} }
// ISrsReader // Interface ISrsReader
srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
{ {
srs_assert(io); srs_assert(io);
@ -376,7 +376,7 @@ srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
return srs_success; return srs_success;
} }
// ISrsProtocolReader // Interface ISrsProtocolReader
void SimpleSocketStream::set_recv_timeout(srs_utime_t tm) void SimpleSocketStream::set_recv_timeout(srs_utime_t tm)
{ {
srs_assert(io); srs_assert(io);
@ -395,7 +395,7 @@ int64_t SimpleSocketStream::get_recv_bytes()
return srs_hijack_io_get_recv_bytes(io); return srs_hijack_io_get_recv_bytes(io);
} }
// ISrsProtocolWriter // Interface ISrsProtocolWriter
void SimpleSocketStream::set_send_timeout(srs_utime_t tm) void SimpleSocketStream::set_send_timeout(srs_utime_t tm)
{ {
srs_assert(io); srs_assert(io);
@ -424,7 +424,7 @@ srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t*
return srs_success; return srs_success;
} }
// ISrsProtocolReadWriter // Interface ISrsProtocolReadWriter
bool SimpleSocketStream::is_never_timeout(srs_utime_t tm) bool SimpleSocketStream::is_never_timeout(srs_utime_t tm)
{ {
srs_assert(io); srs_assert(io);

View file

@ -49,21 +49,21 @@ public:
virtual srs_hijack_io_t hijack_io(); virtual srs_hijack_io_t hijack_io();
virtual int create_socket(srs_rtmp_t owner); virtual int create_socket(srs_rtmp_t owner);
virtual int connect(const char* server, int port); virtual int connect(const char* server, int port);
// ISrsReader // Interface ISrsReader
public: public:
virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); virtual srs_error_t read(void* buf, size_t size, ssize_t* nread);
// ISrsProtocolReader // Interface ISrsProtocolReader
public: public:
virtual void set_recv_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm);
virtual srs_utime_t get_recv_timeout(); virtual srs_utime_t get_recv_timeout();
virtual int64_t get_recv_bytes(); virtual int64_t get_recv_bytes();
// ISrsProtocolWriter // Interface ISrsProtocolWriter
public: public:
virtual void set_send_timeout(srs_utime_t tm); virtual void set_send_timeout(srs_utime_t tm);
virtual srs_utime_t get_send_timeout(); virtual srs_utime_t get_send_timeout();
virtual int64_t get_send_bytes(); virtual int64_t get_send_bytes();
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
// ISrsProtocolReadWriter // Interface ISrsProtocolReadWriter
public: public:
virtual bool is_never_timeout(srs_utime_t tm); virtual bool is_never_timeout(srs_utime_t tm);
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);

View file

@ -662,10 +662,10 @@ private:
public: public:
SrsIngestHlsOutput(SrsHttpUri* rtmp); SrsIngestHlsOutput(SrsHttpUri* rtmp);
virtual ~SrsIngestHlsOutput(); virtual ~SrsIngestHlsOutput();
// interface ISrsTsHandler // Interface ISrsTsHandler
public: public:
virtual srs_error_t on_ts_message(SrsTsMessage* msg); virtual srs_error_t on_ts_message(SrsTsMessage* msg);
// interface IAacHandler // Interface IAacHandler
public: public:
virtual int on_aac_frame(char* frame, int frame_size, double duration); virtual int on_aac_frame(char* frame, int frame_size, double duration);
private: private:

View file

@ -118,9 +118,8 @@ srs_error_t do_main(int argc, char** argv)
} }
// config already applied to log. // config already applied to log.
srs_trace(RTMP_SIG_SRS_SERVER ", stable is " RTMP_SIG_SRS_PRIMARY); srs_trace(RTMP_SIG_SRS_SERVER);
srs_trace("license: " RTMP_SIG_SRS_LICENSE ", " RTMP_SIG_SRS_COPYRIGHT); srs_trace("license: " RTMP_SIG_SRS_LICENSE);
srs_trace("authors: " RTMP_SIG_SRS_AUTHROS);
srs_trace("contributors: " SRS_AUTO_CONSTRIBUTORS); srs_trace("contributors: " SRS_AUTO_CONSTRIBUTORS);
srs_trace("build: %s, configure:%s, uname: %s", SRS_AUTO_BUILD_DATE, SRS_AUTO_USER_CONFIGURE, SRS_AUTO_UNAME); srs_trace("build: %s, configure:%s, uname: %s", SRS_AUTO_BUILD_DATE, SRS_AUTO_USER_CONFIGURE, SRS_AUTO_UNAME);
srs_trace("configure detail: " SRS_AUTO_CONFIGURE); srs_trace("configure detail: " SRS_AUTO_CONFIGURE);
@ -374,16 +373,12 @@ srs_error_t run(SrsServer* svr)
{ {
srs_error_t err = srs_success; srs_error_t err = srs_success;
/** // Initialize the whole system, set hooks to handle server level events.
* we do nothing in the constructor of server,
* and use initialize to create members, set hooks for instance the reload handler,
* all initialize will done in this stage.
*/
if ((err = svr->initialize(NULL)) != srs_success) { if ((err = svr->initialize(NULL)) != srs_success) {
return srs_error_wrap(err, "server initialize"); return srs_error_wrap(err, "server initialize");
} }
// if not deamon, directly run master. // If not deamon, directly run master.
if (!_srs_config->get_deamon()) { if (!_srs_config->get_deamon()) {
if ((err = run_master(svr)) != srs_success) { if ((err = run_master(svr)) != srs_success) {
return srs_error_wrap(err, "run master"); return srs_error_wrap(err, "run master");

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -77,7 +77,7 @@ public:
virtual bool empty(); virtual bool empty();
virtual std::string to_str(); virtual std::string to_str();
virtual void set_value(std::string v); virtual void set_value(std::string v);
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -106,7 +106,7 @@ public:
virtual void set_value(std::string v); virtual void set_value(std::string v);
virtual void set_value(const char* v, int nb_v); virtual void set_value(const char* v, int nb_v);
virtual uint32_t crc32(uint32_t previous); virtual uint32_t crc32(uint32_t previous);
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -164,7 +164,7 @@ public:
{ {
return elems.at(index); return elems.at(index);
} }
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes() virtual int nb_bytes()
{ {
@ -251,7 +251,7 @@ public:
{ {
return elems.at(index); return elems.at(index);
} }
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes() virtual int nb_bytes()
{ {
@ -400,7 +400,7 @@ public:
virtual bool is_offset_commit_request(); virtual bool is_offset_commit_request();
virtual bool is_offset_fetch_request(); virtual bool is_offset_fetch_request();
virtual bool is_consumer_metadata_request(); virtual bool is_consumer_metadata_request();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -466,7 +466,7 @@ public:
* get the correlation id of response message. * get the correlation id of response message.
*/ */
virtual int32_t correlation_id(); virtual int32_t correlation_id();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -533,7 +533,7 @@ private:
* get the raw message, bytes after the message_size. * get the raw message, bytes after the message_size.
*/ */
virtual int raw_message_size(); virtual int raw_message_size();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -554,7 +554,7 @@ public:
virtual ~SrsKafkaRawMessageSet(); virtual ~SrsKafkaRawMessageSet();
public: public:
virtual void append(SrsKafkaRawMessage* msg); virtual void append(SrsKafkaRawMessage* msg);
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -585,7 +585,7 @@ public:
* get the api key of request. * get the api key of request.
*/ */
virtual SrsKafkaApiKey api_key(); virtual SrsKafkaApiKey api_key();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -608,7 +608,7 @@ public:
* @param s an int value specifies the size of message in header. * @param s an int value specifies the size of message in header.
*/ */
virtual void update_header(int s); virtual void update_header(int s);
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -638,7 +638,7 @@ public:
virtual ~SrsKafkaTopicMetadataRequest(); virtual ~SrsKafkaTopicMetadataRequest();
public: public:
virtual void add_topic(std::string topic); virtual void add_topic(std::string topic);
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -658,7 +658,7 @@ public:
public: public:
SrsKafkaBroker(); SrsKafkaBroker();
virtual ~SrsKafkaBroker(); virtual ~SrsKafkaBroker();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -675,7 +675,7 @@ public:
public: public:
SrsKafkaPartitionMetadata(); SrsKafkaPartitionMetadata();
virtual ~SrsKafkaPartitionMetadata(); virtual ~SrsKafkaPartitionMetadata();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -690,7 +690,7 @@ public:
public: public:
SrsKafkaTopicMetadata(); SrsKafkaTopicMetadata();
virtual ~SrsKafkaTopicMetadata(); virtual ~SrsKafkaTopicMetadata();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -713,7 +713,7 @@ public:
public: public:
SrsKafkaTopicMetadataResponse(); SrsKafkaTopicMetadataResponse();
virtual ~SrsKafkaTopicMetadataResponse(); virtual ~SrsKafkaTopicMetadataResponse();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -740,7 +740,7 @@ public:
* messages in set. * messages in set.
*/ */
SrsKafkaRawMessageSet messages; SrsKafkaRawMessageSet messages;
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -757,7 +757,7 @@ public:
* messages of partitions. * messages of partitions.
*/ */
SrsKafkaArray<SrsKafkaProducerPartitionMessages> partitions; SrsKafkaArray<SrsKafkaProducerPartitionMessages> partitions;
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);
@ -801,7 +801,7 @@ public:
public: public:
SrsKafkaProducerRequest(); SrsKafkaProducerRequest();
virtual ~SrsKafkaProducerRequest(); virtual ~SrsKafkaProducerRequest();
// interface ISrsCodec // Interface ISrsCodec
public: public:
virtual int nb_bytes(); virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf); virtual srs_error_t encode(SrsBuffer* buf);

View file

@ -32,7 +32,7 @@
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// json decode // JSON decode
// 1. SrsJsonAny: read any from str:char* // 1. SrsJsonAny: read any from str:char*
// SrsJsonAny* any = NULL; // SrsJsonAny* any = NULL;
// if ((any = SrsJsonAny::loads(str)) == NULL) { // if ((any = SrsJsonAny::loads(str)) == NULL) {
@ -45,7 +45,7 @@
// string v = any->to_str(); // string v = any->to_str();
// } // }
// //
// for detail usage, see interfaces of each object. // For detail usage, see interfaces of each object.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@ -59,8 +59,8 @@ class SrsJsonAny
{ {
public: public:
char marker; char marker;
// donot directly create this object, // Don't directly create this object,
// instead, for examle, use SrsJsonAny::str() to create a concreated one. // please use SrsJsonAny::str() to create a concreated one.
protected: protected:
SrsJsonAny(); SrsJsonAny();
public: public:
@ -74,35 +74,23 @@ public:
virtual bool is_array(); virtual bool is_array();
virtual bool is_null(); virtual bool is_null();
public: public:
/** // Get the string of any when is_string() indicates true.
* get the string of any when is_string() indicates true. // user must ensure the type is a string, or assert failed.
* user must ensure the type is a string, or assert failed.
*/
virtual std::string to_str(); virtual std::string to_str();
/** // Get the boolean of any when is_boolean() indicates true.
* get the boolean of any when is_boolean() indicates true. // user must ensure the type is a boolean, or assert failed.
* user must ensure the type is a boolean, or assert failed.
*/
virtual bool to_boolean(); virtual bool to_boolean();
/** // Get the integer of any when is_integer() indicates true.
* get the integer of any when is_integer() indicates true. // user must ensure the type is a integer, or assert failed.
* user must ensure the type is a integer, or assert failed.
*/
virtual int64_t to_integer(); virtual int64_t to_integer();
/** // Get the number of any when is_number() indicates true.
* get the number of any when is_number() indicates true. // user must ensure the type is a number, or assert failed.
* user must ensure the type is a number, or assert failed.
*/
virtual double to_number(); virtual double to_number();
/** // Get the object of any when is_object() indicates true.
* get the object of any when is_object() indicates true. // user must ensure the type is a object, or assert failed.
* user must ensure the type is a object, or assert failed.
*/
virtual SrsJsonObject* to_object(); virtual SrsJsonObject* to_object();
/** // Get the ecma array of any when is_ecma_array() indicates true.
* get the ecma array of any when is_ecma_array() indicates true. // user must ensure the type is a ecma array, or assert failed.
* user must ensure the type is a ecma array, or assert failed.
*/
virtual SrsJsonArray* to_array(); virtual SrsJsonArray* to_array();
public: public:
virtual std::string dumps(); virtual std::string dumps();
@ -117,10 +105,8 @@ public:
static SrsJsonObject* object(); static SrsJsonObject* object();
static SrsJsonArray* array(); static SrsJsonArray* array();
public: public:
/** // Read json tree from string.
* read json tree from string. // @return json object. NULL if error.
* @return json object. NULL if error.
*/
static SrsJsonAny* loads(const std::string& str); static SrsJsonAny* loads(const std::string& str);
}; };
@ -130,7 +116,7 @@ private:
typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType; typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType;
std::vector<SrsJsonObjectPropertyType> properties; std::vector<SrsJsonObjectPropertyType> properties;
private: private:
// use SrsJsonAny::object() to create it. // Use SrsJsonAny::object() to create it.
friend class SrsJsonAny; friend class SrsJsonAny;
SrsJsonObject(); SrsJsonObject();
public: public:
@ -161,7 +147,7 @@ private:
std::vector<SrsJsonAny*> properties; std::vector<SrsJsonAny*> properties;
private: private:
// use SrsJsonAny::array() to create it. // Use SrsJsonAny::array() to create it.
friend class SrsJsonAny; friend class SrsJsonAny;
SrsJsonArray(); SrsJsonArray();
public: public:
@ -181,6 +167,6 @@ public:
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// json encode, please use JSON.dumps() to encode json object. // JSON encode, please use JSON.dumps() to encode json object.
#endif #endif

View file

@ -221,14 +221,14 @@ public:
* use the add_delta() is better solutions. * use the add_delta() is better solutions.
*/ */
virtual void sample(); virtual void sample();
// interface ISrsProtocolStatistic // Interface ISrsProtocolStatistic
public: public:
virtual int64_t get_send_bytes(); virtual int64_t get_send_bytes();
virtual int64_t get_recv_bytes(); virtual int64_t get_recv_bytes();
// interface ISrsKbpsDelta // Interface ISrsKbpsDelta
public: public:
virtual void remark(int64_t* in, int64_t* out); virtual void remark(int64_t* in, int64_t* out);
// interface ISrsMemorySizer // Interface ISrsMemorySizer
public: public:
virtual int size_memory(); virtual int size_memory();
}; };

View file

@ -32,61 +32,45 @@
class SrsBuffer; class SrsBuffer;
/** // The raw h.264 stream, in annexb.
* the raw h.264 stream, in annexb.
*/
class SrsRawH264Stream class SrsRawH264Stream
{ {
public: public:
SrsRawH264Stream(); SrsRawH264Stream();
virtual ~SrsRawH264Stream(); virtual ~SrsRawH264Stream();
public: public:
/** // Demux the stream in annexb format.
* demux the stream in annexb format. // @param stream the input stream bytes.
* @param stream the input stream bytes. // @param pframe the output h.264 frame in stream. user should never free it.
* @param pframe the output h.264 frame in stream. user should never free it. // @param pnb_frame the output h.264 frame size.
* @param pnb_frame the output h.264 frame size.
*/
virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame); virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame);
/** // whether the frame is sps or pps.
* whether the frame is sps or pps.
*/
virtual bool is_sps(char* frame, int nb_frame); virtual bool is_sps(char* frame, int nb_frame);
virtual bool is_pps(char* frame, int nb_frame); virtual bool is_pps(char* frame, int nb_frame);
/** // Demux the sps or pps to string.
* demux the sps or pps to string. // @param sps/pps output the sps/pps.
* @param sps/pps output the sps/pps.
*/
virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps); virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps);
virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps); virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps);
public: public:
/** // The h264 raw data to h264 packet, without flv payload header.
* h264 raw data to h264 packet, without flv payload header. // Mux the sps/pps to flv sequence header packet.
* mux the sps/pps to flv sequence header packet. // @param sh output the sequence header.
* @param sh output the sequence header.
*/
virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh); virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh);
/** // The h264 raw data to h264 packet, without flv payload header.
* h264 raw data to h264 packet, without flv payload header. // Mux the ibp to flv ibp packet.
* mux the ibp to flv ibp packet. // @param ibp output the packet.
* @param ibp output the packet. // @param frame_type output the frame type.
* @param frame_type output the frame type.
*/
virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp); virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
/** // Mux the avc video packet to flv video packet.
* mux the avc video packet to flv video packet. // @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
* @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame. // @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
* @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU. // @param video the h.264 raw data.
* @param video the h.264 raw data. // @param flv output the muxed flv packet.
* @param flv output the muxed flv packet. // @param nb_flv output the muxed flv size.
* @param nb_flv output the muxed flv size.
*/
virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv); virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv);
}; };
/** // The header of adts sample.
* the header of adts sample.
*/
struct SrsRawAacStreamCodec struct SrsRawAacStreamCodec
{ {
int8_t protection_absent; int8_t protection_absent;
@ -103,37 +87,29 @@ struct SrsRawAacStreamCodec
int8_t aac_packet_type; int8_t aac_packet_type;
}; };
/** // The raw aac stream, in adts.
* the raw aac stream, in adts.
*/
class SrsRawAacStream class SrsRawAacStream
{ {
public: public:
SrsRawAacStream(); SrsRawAacStream();
virtual ~SrsRawAacStream(); virtual ~SrsRawAacStream();
public: public:
/** // Demux the stream in adts format.
* demux the stream in adts format. // @param stream the input stream bytes.
* @param stream the input stream bytes. // @param pframe the output aac frame in stream. user should never free it.
* @param pframe the output aac frame in stream. user should never free it. // @param pnb_frame the output aac frame size.
* @param pnb_frame the output aac frame size. // @param codec the output codec info.
* @param codec the output codec info.
*/
virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec); virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
/** // Mux aac raw data to aac packet, without flv payload header.
* aac raw data to aac packet, without flv payload header. // Mux the aac specific config to flv sequence header packet.
* mux the aac specific config to flv sequence header packet. // @param sh output the sequence header.
* @param sh output the sequence header.
*/
virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh); virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
/** // Mux the aac audio packet to flv audio packet.
* mux the aac audio packet to flv audio packet. // @param frame the aac raw data.
* @param frame the aac raw data. // @param nb_frame the count of aac frame.
* @param nb_frame the count of aac frame. // @param codec the codec info of aac.
* @param codec the codec info of aac. // @param flv output the muxed flv packet.
* @param flv output the muxed flv packet. // @param nb_flv output the muxed flv size.
* @param nb_flv output the muxed flv size.
*/
virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv); virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv);
}; };

View file

@ -42,6 +42,9 @@ using namespace _srs_internal;
// for openssl_generate_key // for openssl_generate_key
#include <openssl/dh.h> #include <openssl/dh.h>
// For randomly generate the handshake bytes.
#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_VERSION ")"
#if OPENSSL_VERSION_NUMBER < 0x10100000L #if OPENSSL_VERSION_NUMBER < 0x10100000L
static HMAC_CTX *HMAC_CTX_new(void) static HMAC_CTX *HMAC_CTX_new(void)

View file

@ -31,21 +31,19 @@ class SrsComplexHandshake;
class SrsHandshakeBytes; class SrsHandshakeBytes;
class SrsBuffer; class SrsBuffer;
// for openssl. // For openssl.
#include <openssl/hmac.h> #include <openssl/hmac.h>
namespace _srs_internal namespace _srs_internal
{ {
// the digest key generate size. // The digest key generate size.
#define SRS_OpensslHashSize 512 #define SRS_OpensslHashSize 512
extern uint8_t SrsGenuineFMSKey[]; extern uint8_t SrsGenuineFMSKey[];
extern uint8_t SrsGenuineFPKey[]; extern uint8_t SrsGenuineFPKey[];
srs_error_t openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest); srs_error_t openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest);
srs_error_t openssl_generate_key(char* public_key, int32_t size); srs_error_t openssl_generate_key(char* public_key, int32_t size);
/** // The DH wrapper.
* the DH wrapper.
*/
class SrsDH class SrsDH
{ {
private: private:
@ -56,62 +54,48 @@ namespace _srs_internal
private: private:
virtual void close(); virtual void close();
public: public:
/** // Initialize dh, generate the public and private key.
* initialize dh, generate the public and private key. // @param ensure_128bytes_public_key whether ensure public key is 128bytes,
* @param ensure_128bytes_public_key whether ensure public key is 128bytes, // sometimes openssl generate 127bytes public key.
* sometimes openssl generate 127bytes public key. // default to false to donot ensure.
* default to false to donot ensure.
*/
virtual srs_error_t initialize(bool ensure_128bytes_public_key = false); virtual srs_error_t initialize(bool ensure_128bytes_public_key = false);
/** // Copy the public key.
* copy the public key. // @param pkey the bytes to copy the public key.
* @param pkey the bytes to copy the public key. // @param pkey_size the max public key size, output the actual public key size.
* @param pkey_size the max public key size, output the actual public key size. // user should never ignore this size.
* user should never ignore this size. // @remark, when ensure_128bytes_public_key, the size always 128.
* @remark, when ensure_128bytes_public_key, the size always 128.
*/
virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size); virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size);
/** // Generate and copy the shared key.
* generate and copy the shared key. // Generate the shared key with peer public key.
* generate the shared key with peer public key. // @param ppkey peer public key.
* @param ppkey peer public key. // @param ppkey_size the size of ppkey.
* @param ppkey_size the size of ppkey. // @param skey the computed shared key.
* @param skey the computed shared key. // @param skey_size the max shared key size, output the actual shared key size.
* @param skey_size the max shared key size, output the actual shared key size. // user should never ignore this size.
* user should never ignore this size.
*/
virtual srs_error_t copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size); virtual srs_error_t copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size);
private: private:
virtual srs_error_t do_initialize(); virtual srs_error_t do_initialize();
}; };
/** // The schema type.
* the schema type.
*/
enum srs_schema_type enum srs_schema_type
{ {
srs_schema_invalid = 2, srs_schema_invalid = 2,
/** // The key-digest sequence
* key-digest sequence
*/
srs_schema0 = 0, srs_schema0 = 0,
/** // The digest-key sequence
* digest-key sequence // @remark, FMS requires the schema1(digest-key), or connect failed.
* @remark, FMS requires the schema1(digest-key), or connect failed.
*/
// //
srs_schema1 = 1, srs_schema1 = 1,
}; };
/** // The 764bytes key structure
* 764bytes key structure // random-data: (offset)bytes
* random-data: (offset)bytes // key-data: 128bytes
* key-data: 128bytes // random-data: (764-offset-128-4)bytes
* random-data: (764-offset-128-4)bytes // offset: 4bytes
* offset: 4bytes // @see also: http://blog.csdn.net/win_lin/article/details/13006803
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
class key_block class key_block
{ {
public: public:
@ -132,24 +116,22 @@ namespace _srs_internal
key_block(); key_block();
virtual ~key_block(); virtual ~key_block();
public: public:
// parse key block from c1s1. // Parse key block from c1s1.
// if created, user must free it by srs_key_block_free // if created, user must free it by srs_key_block_free
// @stream contains c1s1_key_bytes the key start bytes // @stream contains c1s1_key_bytes the key start bytes
srs_error_t parse(SrsBuffer* stream); srs_error_t parse(SrsBuffer* stream);
private: private:
// calc the offset of key, // Calculate the offset of key,
// the key->offset cannot be used as the offset of key. // The key->offset cannot be used as the offset of key.
int calc_valid_offset(); int calc_valid_offset();
}; };
/** // The 764bytes digest structure
* 764bytes digest structure // offset: 4bytes
* offset: 4bytes // random-data: (offset)bytes
* random-data: (offset)bytes // digest-data: 32bytes
* digest-data: 32bytes // random-data: (764-4-offset-32)bytes
* random-data: (764-4-offset-32)bytes // @see also: http://blog.csdn.net/win_lin/article/details/13006803
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
class digest_block class digest_block
{ {
public: public:
@ -170,23 +152,21 @@ namespace _srs_internal
digest_block(); digest_block();
virtual ~digest_block(); virtual ~digest_block();
public: public:
// parse digest block from c1s1. // Parse digest block from c1s1.
// if created, user must free it by srs_digest_block_free // if created, user must free it by srs_digest_block_free
// @stream contains c1s1_digest_bytes the digest start bytes // @stream contains c1s1_digest_bytes the digest start bytes
srs_error_t parse(SrsBuffer* stream); srs_error_t parse(SrsBuffer* stream);
private: private:
// calc the offset of digest, // Calculate the offset of digest,
// the key->offset cannot be used as the offset of digest. // The key->offset cannot be used as the offset of digest.
int calc_valid_offset(); int calc_valid_offset();
}; };
class c1s1; class c1s1;
/** // The c1s1 strategy, use schema0 or schema1.
* the c1s1 strategy, use schema0 or schema1. // The template method class to defines common behaviors,
* the template method class to defines common behaviors, // while the concrete class to implements in schema0 or schema1.
* while the concrete class to implements in schema0 or schema1.
*/
class c1s1_strategy class c1s1_strategy
{ {
protected: protected:
@ -196,114 +176,82 @@ namespace _srs_internal
c1s1_strategy(); c1s1_strategy();
virtual ~c1s1_strategy(); virtual ~c1s1_strategy();
public: public:
/** // Get the scema.
* get the scema.
*/
virtual srs_schema_type schema() = 0; virtual srs_schema_type schema() = 0;
/** // Get the digest.
* get the digest.
*/
virtual char* get_digest(); virtual char* get_digest();
/** // Get the key.
* get the key.
*/
virtual char* get_key(); virtual char* get_key();
/** // Copy to bytes.
* copy to bytes. // @param size must be 1536.
* @param size must be 1536.
*/
virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size); virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size);
/** // For server: parse the c1s1, discovery the key and digest by schema.
* server: parse the c1s1, discovery the key and digest by schema. // use the c1_validate_digest() to valid the digest of c1.
* use the c1_validate_digest() to valid the digest of c1.
*/
virtual srs_error_t parse(char* _c1s1, int size) = 0; virtual srs_error_t parse(char* _c1s1, int size) = 0;
public: public:
/** // For client: create and sign c1 by schema.
* client: create and sign c1 by schema. // sign the c1, generate the digest.
* sign the c1, generate the digest. // calc_c1_digest(c1, schema) {
* calc_c1_digest(c1, schema) { // get c1s1-joined from c1 by specified schema
* get c1s1-joined from c1 by specified schema // digest-data = HMACsha256(c1s1-joined, FPKey, 30)
* digest-data = HMACsha256(c1s1-joined, FPKey, 30) // return digest-data;
* return digest-data; // }
* } // random fill 1536bytes c1 // also fill the c1-128bytes-key
* random fill 1536bytes c1 // also fill the c1-128bytes-key // time = time() // c1[0-3]
* time = time() // c1[0-3] // version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] // schema = choose schema0 or schema1
* schema = choose schema0 or schema1 // digest-data = calc_c1_digest(c1, schema)
* digest-data = calc_c1_digest(c1, schema) // copy digest-data to c1
* copy digest-data to c1
*/
virtual srs_error_t c1_create(c1s1* owner); virtual srs_error_t c1_create(c1s1* owner);
/** // For server: validate the parsed c1 schema
* server: validate the parsed c1 schema
*/
virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid); virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid);
/** // For server: create and sign the s1 from c1.
* server: create and sign the s1 from c1. // // decode c1 try schema0 then schema1
* // decode c1 try schema0 then schema1 // c1-digest-data = get-c1-digest-data(schema0)
* c1-digest-data = get-c1-digest-data(schema0) // if c1-digest-data equals to calc_c1_digest(c1, schema0) {
* if c1-digest-data equals to calc_c1_digest(c1, schema0) { // c1-key-data = get-c1-key-data(schema0)
* c1-key-data = get-c1-key-data(schema0) // schema = schema0
* schema = schema0 // } else {
* } else { // c1-digest-data = get-c1-digest-data(schema1)
* c1-digest-data = get-c1-digest-data(schema1) // if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) { // switch to simple handshake.
* switch to simple handshake. // return
* return // }
* } // c1-key-data = get-c1-key-data(schema1)
* c1-key-data = get-c1-key-data(schema1) // schema = schema1
* schema = schema1 // }
* } //
* // // Generate s1
* // generate s1 // random fill 1536bytes s1
* random fill 1536bytes s1 // time = time() // c1[0-3]
* time = time() // c1[0-3] // version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] // s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) // get c1s1-joined by specified schema
* get c1s1-joined by specified schema // s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) // copy s1-digest-data and s1-key-data to s1.
* copy s1-digest-data and s1-key-data to s1. // @param c1, to get the peer_pub_key of client.
* @param c1, to get the peer_pub_key of client.
*/
virtual srs_error_t s1_create(c1s1* owner, c1s1* c1); virtual srs_error_t s1_create(c1s1* owner, c1s1* c1);
/** // For server: validate the parsed s1 schema
* server: validate the parsed s1 schema
*/
virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid); virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid);
public: public:
/** // Calculate the digest for c1
* calc the digest for c1
*/
virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest); virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest);
/** // Calculate the digest for s1
* calc the digest for s1
*/
virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest); virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest);
/** // Copy whole c1s1 to bytes.
* copy whole c1s1 to bytes. // @param size must always be 1536 with digest, and 1504 without digest.
* @param size must always be 1536 with digest, and 1504 without digest.
*/
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0; virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0;
/** // Copy time and version to stream.
* copy time and version to stream.
*/
virtual void copy_time_version(SrsBuffer* stream, c1s1* owner); virtual void copy_time_version(SrsBuffer* stream, c1s1* owner);
/** // Copy key to stream.
* copy key to stream.
*/
virtual void copy_key(SrsBuffer* stream); virtual void copy_key(SrsBuffer* stream);
/** // Copy digest to stream.
* copy digest to stream.
*/
virtual void copy_digest(SrsBuffer* stream, bool with_digest); virtual void copy_digest(SrsBuffer* stream, bool with_digest);
}; };
/** // The c1s1 schema0
* c1s1 schema0 // key: 764bytes
* key: 764bytes // digest: 764bytes
* digest: 764bytes
*/
class c1s1_strategy_schema0 : public c1s1_strategy class c1s1_strategy_schema0 : public c1s1_strategy
{ {
public: public:
@ -316,11 +264,9 @@ namespace _srs_internal
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest); virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
}; };
/** // The c1s1 schema1
* c1s1 schema1 // digest: 764bytes
* digest: 764bytes // key: 764bytes
* key: 764bytes
*/
class c1s1_strategy_schema1 : public c1s1_strategy class c1s1_strategy_schema1 : public c1s1_strategy
{ {
public: public:
@ -333,19 +279,17 @@ namespace _srs_internal
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest); virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
}; };
/** // The c1s1 schema0
* c1s1 schema0 // time: 4bytes
* time: 4bytes // version: 4bytes
* version: 4bytes // key: 764bytes
* key: 764bytes // digest: 764bytes
* digest: 764bytes // The c1s1 schema1
* c1s1 schema1 // time: 4bytes
* time: 4bytes // version: 4bytes
* version: 4bytes // digest: 764bytes
* digest: 764bytes // key: 764bytes
* key: 764bytes // @see also: http://blog.csdn.net/win_lin/article/details/13006803
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
class c1s1 class c1s1
{ {
public: public:
@ -359,92 +303,72 @@ namespace _srs_internal
c1s1(); c1s1();
virtual ~c1s1(); virtual ~c1s1();
public: public:
/** // Get the scema.
* get the scema.
*/
virtual srs_schema_type schema(); virtual srs_schema_type schema();
/** // Get the digest key.
* get the digest key.
*/
virtual char* get_digest(); virtual char* get_digest();
/** // Get the key.
* get the key.
*/
virtual char* get_key(); virtual char* get_key();
public: public:
/** // Copy to bytes.
* copy to bytes. // @param size, must always be 1536.
* @param size, must always be 1536.
*/
virtual srs_error_t dump(char* _c1s1, int size); virtual srs_error_t dump(char* _c1s1, int size);
/** // For server: parse the c1s1, discovery the key and digest by schema.
* server: parse the c1s1, discovery the key and digest by schema. // @param size, must always be 1536.
* @param size, must always be 1536. // use the c1_validate_digest() to valid the digest of c1.
* use the c1_validate_digest() to valid the digest of c1. // use the s1_validate_digest() to valid the digest of s1.
* use the s1_validate_digest() to valid the digest of s1.
*/
virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema); virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema);
public: public:
/** // For client: create and sign c1 by schema.
* client: create and sign c1 by schema. // sign the c1, generate the digest.
* sign the c1, generate the digest. // calc_c1_digest(c1, schema) {
* calc_c1_digest(c1, schema) { // get c1s1-joined from c1 by specified schema
* get c1s1-joined from c1 by specified schema // digest-data = HMACsha256(c1s1-joined, FPKey, 30)
* digest-data = HMACsha256(c1s1-joined, FPKey, 30) // return digest-data;
* return digest-data; // }
* } // random fill 1536bytes c1 // also fill the c1-128bytes-key
* random fill 1536bytes c1 // also fill the c1-128bytes-key // time = time() // c1[0-3]
* time = time() // c1[0-3] // version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] // schema = choose schema0 or schema1
* schema = choose schema0 or schema1 // digest-data = calc_c1_digest(c1, schema)
* digest-data = calc_c1_digest(c1, schema) // copy digest-data to c1
* copy digest-data to c1
*/
virtual srs_error_t c1_create(srs_schema_type _schema); virtual srs_error_t c1_create(srs_schema_type _schema);
/** // For server: validate the parsed c1 schema
* server: validate the parsed c1 schema
*/
virtual srs_error_t c1_validate_digest(bool& is_valid); virtual srs_error_t c1_validate_digest(bool& is_valid);
public: public:
/** // For server: create and sign the s1 from c1.
* server: create and sign the s1 from c1. // // decode c1 try schema0 then schema1
* // decode c1 try schema0 then schema1 // c1-digest-data = get-c1-digest-data(schema0)
* c1-digest-data = get-c1-digest-data(schema0) // if c1-digest-data equals to calc_c1_digest(c1, schema0) {
* if c1-digest-data equals to calc_c1_digest(c1, schema0) { // c1-key-data = get-c1-key-data(schema0)
* c1-key-data = get-c1-key-data(schema0) // schema = schema0
* schema = schema0 // } else {
* } else { // c1-digest-data = get-c1-digest-data(schema1)
* c1-digest-data = get-c1-digest-data(schema1) // if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) { // switch to simple handshake.
* switch to simple handshake. // return
* return // }
* } // c1-key-data = get-c1-key-data(schema1)
* c1-key-data = get-c1-key-data(schema1) // schema = schema1
* schema = schema1 // }
* } //
* // // Generate s1
* // generate s1 // random fill 1536bytes s1
* random fill 1536bytes s1 // time = time() // c1[0-3]
* time = time() // c1[0-3] // version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] // s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) // get c1s1-joined by specified schema
* get c1s1-joined by specified schema // s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) // copy s1-digest-data and s1-key-data to s1.
* copy s1-digest-data and s1-key-data to s1.
*/
virtual srs_error_t s1_create(c1s1* c1); virtual srs_error_t s1_create(c1s1* c1);
/** // For server: validate the parsed s1 schema
* server: validate the parsed s1 schema
*/
virtual srs_error_t s1_validate_digest(bool& is_valid); virtual srs_error_t s1_validate_digest(bool& is_valid);
}; };
/** // The c2s2 complex handshake structure.
* the c2s2 complex handshake structure. // random-data: 1504bytes
* random-data: 1504bytes // digest-data: 32bytes
* digest-data: 32bytes // @see also: http://blog.csdn.net/win_lin/article/details/13006803
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
class c2s2 class c2s2
{ {
public: public:
@ -454,85 +378,65 @@ namespace _srs_internal
c2s2(); c2s2();
virtual ~c2s2(); virtual ~c2s2();
public: public:
/** // Copy to bytes.
* copy to bytes. // @param size, must always be 1536.
* @param size, must always be 1536.
*/
virtual srs_error_t dump(char* _c2s2, int size); virtual srs_error_t dump(char* _c2s2, int size);
/** // Parse the c2s2
* parse the c2s2 // @param size, must always be 1536.
* @param size, must always be 1536.
*/
virtual srs_error_t parse(char* _c2s2, int size); virtual srs_error_t parse(char* _c2s2, int size);
public: public:
/** // Create c2.
* create c2. // random fill c2s2 1536 bytes
* random fill c2s2 1536 bytes //
* // // client generate C2, or server valid C2
* // client generate C2, or server valid C2 // temp-key = HMACsha256(s1-digest, FPKey, 62)
* temp-key = HMACsha256(s1-digest, FPKey, 62) // c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
* c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
*/
virtual srs_error_t c2_create(c1s1* s1); virtual srs_error_t c2_create(c1s1* s1);
/** // Validate the c2 from client.
* validate the c2 from client.
*/
virtual srs_error_t c2_validate(c1s1* s1, bool& is_valid); virtual srs_error_t c2_validate(c1s1* s1, bool& is_valid);
public: public:
/** // Create s2.
* create s2. // random fill c2s2 1536 bytes
* random fill c2s2 1536 bytes //
* // For server generate S2, or client valid S2
* // server generate S2, or client valid S2 // temp-key = HMACsha256(c1-digest, FMSKey, 68)
* temp-key = HMACsha256(c1-digest, FMSKey, 68) // s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
* s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
*/
virtual srs_error_t s2_create(c1s1* c1); virtual srs_error_t s2_create(c1s1* c1);
/** // Validate the s2 from server.
* validate the s2 from server.
*/
virtual srs_error_t s2_validate(c1s1* c1, bool& is_valid); virtual srs_error_t s2_validate(c1s1* c1, bool& is_valid);
}; };
} }
/** // Simple handshake.
* simple handshake. // user can try complex handshake first,
* user can try complex handshake first, // rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
*/
class SrsSimpleHandshake class SrsSimpleHandshake
{ {
public: public:
SrsSimpleHandshake(); SrsSimpleHandshake();
virtual ~SrsSimpleHandshake(); virtual ~SrsSimpleHandshake();
public: public:
/** // Simple handshake.
* simple handshake.
*/
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
}; };
/** // Complex handshake,
* rtmp complex handshake, // @see also crtmp(crtmpserver) or librtmp,
* @see also crtmp(crtmpserver) or librtmp, // @see also: http://blog.csdn.net/win_lin/article/details/13006803
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
*/
class SrsComplexHandshake class SrsComplexHandshake
{ {
public: public:
SrsComplexHandshake(); SrsComplexHandshake();
virtual ~SrsComplexHandshake(); virtual ~SrsComplexHandshake();
public: public:
/** // Complex hanshake.
* complex hanshake. // @return user must:
* @return user must: // continue connect app if success,
* continue connect app if success, // try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
* try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS, // otherwise, disconnect
* otherwise, disconnect
*/
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
}; };

View file

@ -28,43 +28,31 @@
class SrsSharedPtrMessage; class SrsSharedPtrMessage;
/** // The class to auto free the shared ptr message array.
* the class to auto free the shared ptr message array. // When need to get some messages, for instance, from Consumer queue,
* when need to get some messages, for instance, from Consumer queue, // create a message array, whose msgs can used to accept the msgs,
* create a message array, whose msgs can used to accept the msgs, // then send each message and set to NULL.
* then send each message and set to NULL. //
* // @remark: user must free all msgs in array, for the SRS2.0 protocol stack
* @remark: user must free all msgs in array, for the SRS2.0 protocol stack // provides an api to send messages, @see send_and_free_messages
* provides an api to send messages, @see send_and_free_messages
*/
class SrsMessageArray class SrsMessageArray
{ {
public: public:
/** // When user already send all msgs, please set to NULL,
* when user already send all msgs, please set to NULL, // for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
* for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg), // where send(msg) will always send and free it.
* where send(msg) will always send and free it.
*/
SrsSharedPtrMessage** msgs; SrsSharedPtrMessage** msgs;
int max; int max;
public: public:
/** // Create msg array, initialize array to NULL ptrs.
* create msg array, initialize array to NULL ptrs.
*/
SrsMessageArray(int max_msgs); SrsMessageArray(int max_msgs);
/** // Free the msgs not sent out(not NULL).
* free the msgs not sent out(not NULL).
*/
virtual ~SrsMessageArray(); virtual ~SrsMessageArray();
public: public:
/** // Free specified count of messages.
* free specified count of messages.
*/
virtual void free(int count); virtual void free(int count);
private: private:
/** // Zero initialize the message array.
* zero initialize the message array.
*/
virtual void zero(int count); virtual void zero(int count);
}; };

View file

@ -2385,14 +2385,8 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser
data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY)); data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE));
data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE));
data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL));
data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB));
data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL));
data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT));
data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));
data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));
if (server_ip) { if (server_ip) {
data->set("srs_server_ip", SrsAmf0Any::str(server_ip)); data->set("srs_server_ip", SrsAmf0Any::str(server_ip));

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ class SrsSimpleStream;
class SrsAudioFrame; class SrsAudioFrame;
class ISrsProtocolReadWriter; class ISrsProtocolReadWriter;
// rtsp specification // From rtsp specification
// CR = <US-ASCII CR, carriage return (13)> // CR = <US-ASCII CR, carriage return (13)>
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D #define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
// LF = <US-ASCII LF, linefeed (10)> // LF = <US-ASCII LF, linefeed (10)>
@ -78,38 +78,28 @@ class ISrsProtocolReadWriter;
// RTSP-Version // RTSP-Version
#define SRS_RTSP_VERSION "RTSP/1.0" #define SRS_RTSP_VERSION "RTSP/1.0"
/** // The rtsp sdp parse state.
* the rtsp sdp parse state.
*/
enum SrsRtspSdpState enum SrsRtspSdpState
{ {
/** // Other sdp properties.
* other sdp properties.
*/
SrsRtspSdpStateOthers, SrsRtspSdpStateOthers,
/** // Parse sdp audio state.
* parse sdp audio state.
*/
SrsRtspSdpStateAudio, SrsRtspSdpStateAudio,
/** // Parse sdp video state.
* parse sdp video state.
*/
SrsRtspSdpStateVideo, SrsRtspSdpStateVideo,
}; };
/** // 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
* 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57 // The method token indicates the method to be performed on the resource
* The method token indicates the method to be performed on the resource // identified by the Request-URI. The method is case-sensitive. New
* identified by the Request-URI. The method is case-sensitive. New // methods may be defined in the future. Method names may not start with
* methods may be defined in the future. Method names may not start with // a $ character (decimal 24) and must be a token. Methods are
* a $ character (decimal 24) and must be a token. Methods are // summarized in Table 2.
* summarized in Table 2. // Notes on Table 2: PAUSE is recommended, but not required in that a
* Notes on Table 2: PAUSE is recommended, but not required in that a // fully functional server can be built that does not support this
* fully functional server can be built that does not support this // method, for example, for live feeds. If a server does not support a
* method, for example, for live feeds. If a server does not support a // particular method, it MUST return "501 Not Implemented" and a client
* particular method, it MUST return "501 Not Implemented" and a client // SHOULD not try this method again for this server.
* SHOULD not try this method again for this server.
*/
enum SrsRtspMethod enum SrsRtspMethod
{ {
SrsRtspMethodDescribe = 0x0001, SrsRtspMethodDescribe = 0x0001,
@ -125,237 +115,187 @@ enum SrsRtspMethod
SrsRtspMethodTeardown = 0x0400, SrsRtspMethodTeardown = 0x0400,
}; };
/** // The state of rtsp token.
* the state of rtsp token.
*/
enum SrsRtspTokenState enum SrsRtspTokenState
{ {
/** // Parse token failed, default state.
* parse token failed, default state.
*/
SrsRtspTokenStateError = 100, SrsRtspTokenStateError = 100,
/** // When SP follow the token.
* when SP follow the token.
*/
SrsRtspTokenStateNormal = 101, SrsRtspTokenStateNormal = 101,
/** // When CRLF follow the token.
* when CRLF follow the token.
*/
SrsRtspTokenStateEOF = 102, SrsRtspTokenStateEOF = 102,
}; };
/** // The rtp packet.
* the rtp packet. // 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
* 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
*/
class SrsRtpPacket class SrsRtpPacket
{ {
public: public:
/** // The version (V): 2 bits
* version (V): 2 bits // This field identifies the version of RTP. The version defined by this specification is two (2).
* This field identifies the version of RTP. The version defined by this specification is two (2). // (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol
* (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol // initially implemented in the \vat" audio tool.)
* initially implemented in the \vat" audio tool.)
*/
int8_t version; //2bits int8_t version; //2bits
/** // The padding (P): 1 bit
* padding (P): 1 bit // If the padding bit is set, the packet contains one or more additional padding octets at the
* If the padding bit is set, the packet contains one or more additional padding octets at the // end which are not part of the payload. The last octet of the padding contains a count of
* end which are not part of the payload. The last octet of the padding contains a count of // how many padding octets should be ignored, including itself. Padding may be needed by
* how many padding octets should be ignored, including itself. Padding may be needed by // some encryption algorithms with fixed block sizes or for carrying several RTP packets in a
* some encryption algorithms with fixed block sizes or for carrying several RTP packets in a // lower-layer protocol data unit.
* lower-layer protocol data unit.
*/
int8_t padding; //1bit int8_t padding; //1bit
/** // The extension (X): 1 bit
* extension (X): 1 bit // If the extension bit is set, the fixed header must be followed by exactly one header extension,
* If the extension bit is set, the fixed header must be followed by exactly one header extension, // with a format defined in Section 5.3.1.
* with a format defined in Section 5.3.1.
*/
int8_t extension; //1bit int8_t extension; //1bit
/** // The CSRC count (CC): 4 bits
* CSRC count (CC): 4 bits // The CSRC count contains the number of CSRC identifiers that follow the fixed header.
* The CSRC count contains the number of CSRC identifiers that follow the fixed header.
*/
int8_t csrc_count; //4bits int8_t csrc_count; //4bits
/** // The marker (M): 1 bit
* marker (M): 1 bit // The interpretation of the marker is defined by a profile. It is intended to allow significant
* The interpretation of the marker is defined by a profile. It is intended to allow significant // events such as frame boundaries to be marked in the packet stream. A profile may define
* events such as frame boundaries to be marked in the packet stream. A profile may define // additional marker bits or specify that there is no marker bit by changing the number of bits
* additional marker bits or specify that there is no marker bit by changing the number of bits // in the payload type field (see Section 5.3).
* in the payload type field (see Section 5.3).
*/
int8_t marker; //1bit int8_t marker; //1bit
/** // The payload type (PT): 7 bits
* payload type (PT): 7 bits // This field identifies the format of the RTP payload and determines its interpretation by the
* This field identifies the format of the RTP payload and determines its interpretation by the // application. A profile may specify a default static mapping of payload type codes to payload
* application. A profile may specify a default static mapping of payload type codes to payload // formats. Additional payload type codes may be defined dynamically through non-RTP means
* formats. Additional payload type codes may be defined dynamically through non-RTP means // (see Section 3). A set of default mappings for audio and video is specified in the companion
* (see Section 3). A set of default mappings for audio and video is specified in the companion // RFC 3551 [1]. An RTP source may change the payload type during a session, but this field
* RFC 3551 [1]. An RTP source may change the payload type during a session, but this field // should not be used for multiplexing separate media streams (see Section 5.2).
* should not be used for multiplexing separate media streams (see Section 5.2). // A receiver must ignore packets with payload types that it does not understand.
* A receiver must ignore packets with payload types that it does not understand.
*/
int8_t payload_type; //7bits int8_t payload_type; //7bits
/** // The sequence number: 16 bits
* sequence number: 16 bits // The sequence number increments by one for each RTP data packet sent, and may be used
* The sequence number increments by one for each RTP data packet sent, and may be used // by the receiver to detect packet loss and to restore packet sequence. The initial value of the
* by the receiver to detect packet loss and to restore packet sequence. The initial value of the // sequence number should be random (unpredictable) to make known-plaintext attacks on
* sequence number should be random (unpredictable) to make known-plaintext attacks on // encryption more dicult, even if the source itself does not encrypt according to the method
* encryption more dicult, even if the source itself does not encrypt according to the method // in Section 9.1, because the packets may flow through a translator that does. Techniques for
* in Section 9.1, because the packets may flow through a translator that does. Techniques for // choosing unpredictable numbers are discussed in [17].
* choosing unpredictable numbers are discussed in [17].
*/
uint16_t sequence_number; //16bits uint16_t sequence_number; //16bits
/** // The timestamp: 32 bits
* timestamp: 32 bits // The timestamp reflects the sampling instant of the first octet in the RTP data packet. The
* The timestamp reflects the sampling instant of the first octet in the RTP data packet. The // sampling instant must be derived from a clock that increments monotonically and linearly
* sampling instant must be derived from a clock that increments monotonically and linearly // in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution
* in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution // of the clock must be sucient for the desired synchronization accuracy and for measuring
* of the clock must be sucient for the desired synchronization accuracy and for measuring // packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency
* packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency // is dependent on the format of data carried as payload and is specified statically in the profile
* is dependent on the format of data carried as payload and is specified statically in the profile // or payload format specification that defines the format, or may be specified dynamically for
* or payload format specification that defines the format, or may be specified dynamically for // payload formats defined through non-RTP means. If RTP packets are generated periodically,
* payload formats defined through non-RTP means. If RTP packets are generated periodically, // The nominal sampling instant as determined from the sampling clock is to be used, not a
* the nominal sampling instant as determined from the sampling clock is to be used, not a // reading of the system clock. As an example, for fixed-rate audio the timestamp clock would
* reading of the system clock. As an example, for fixed-rate audio the timestamp clock would // likely increment by one for each sampling period. If an audio application reads blocks covering
* likely increment by one for each sampling period. If an audio application reads blocks covering // 160 sampling periods from the input device, the timestamp would be increased by 160 for
* 160 sampling periods from the input device, the timestamp would be increased by 160 for // each such block, regardless of whether the block is transmitted in a packet or dropped as
* each such block, regardless of whether the block is transmitted in a packet or dropped as // silent.
* silent. //
* // The initial value of the timestamp should be random, as for the sequence number. Several
* The initial value of the timestamp should be random, as for the sequence number. Several // consecutive RTP packets will have equal timestamps if they are (logically) generated at once,
* consecutive RTP packets will have equal timestamps if they are (logically) generated at once, // e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that
* e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that // are not monotonic if the data is not transmitted in the order it was sampled, as in the case
* are not monotonic if the data is not transmitted in the order it was sampled, as in the case // of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
* of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted // will still be monotonic.)
* will still be monotonic.) //
* // RTP timestamps from different media streams may advance at different rates and usually
* RTP timestamps from different media streams may advance at different rates and usually // have independent, random offsets. Therefore, although these timestamps are sucient to
* have independent, random offsets. Therefore, although these timestamps are sucient to // reconstruct the timing of a single stream, directly comparing RTP timestamps from different
* reconstruct the timing of a single stream, directly comparing RTP timestamps from different // media is not effective for synchronization. Instead, for each medium the RTP timestamp
* media is not effective for synchronization. Instead, for each medium the RTP timestamp // is related to the sampling instant by pairing it with a timestamp from a reference clock
* is related to the sampling instant by pairing it with a timestamp from a reference clock // (wallclock) that represents the time when the data corresponding to the RTP timestamp was
* (wallclock) that represents the time when the data corresponding to the RTP timestamp was // sampled. The reference clock is shared by all media to be synchronized. The timestamp
* sampled. The reference clock is shared by all media to be synchronized. The timestamp // pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as
* pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as // described in Section 6.4.
* described in Section 6.4. //
* // The sampling instant is chosen as the point of reference for the RTP timestamp because it is
* The sampling instant is chosen as the point of reference for the RTP timestamp because it is // known to the transmitting endpoint and has a common definition for all media, independent
* known to the transmitting endpoint and has a common definition for all media, independent // of encoding delays or other processing. The purpose is to allow synchronized presentation of
* of encoding delays or other processing. The purpose is to allow synchronized presentation of // all media sampled at the same time.
* all media sampled at the same time. //
* // Applications transmitting stored data rather than data sampled in real time typically use a
* Applications transmitting stored data rather than data sampled in real time typically use a // virtual presentation timeline derived from wallclock time to determine when the next frame
* virtual presentation timeline derived from wallclock time to determine when the next frame // or other unit of each medium in the stored data should be presented. In this case, the RTP
* or other unit of each medium in the stored data should be presented. In this case, the RTP // timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for
* timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for // each unit would be related to the wallclock time at which the unit becomes current on the
* each unit would be related to the wallclock time at which the unit becomes current on the // virtual presentation timeline. Actual presentation occurs some time later as determined by
* virtual presentation timeline. Actual presentation occurs some time later as determined by // The receiver.
* the receiver. //
* // An example describing live audio narration of prerecorded video illustrates the significance
* An example describing live audio narration of prerecorded video illustrates the significance // of choosing the sampling instant as the reference point. In this scenario, the video would
* of choosing the sampling instant as the reference point. In this scenario, the video would // be presented locally for the narrator to view and would be simultaneously transmitted using
* be presented locally for the narrator to view and would be simultaneously transmitted using // RTP. The sampling instant" of a video frame transmitted in RTP would be established by
* RTP. The sampling instant" of a video frame transmitted in RTP would be established by // referencing its timestamp to the wallclock time when that video frame was presented to the
* referencing its timestamp to the wallclock time when that video frame was presented to the // narrator. The sampling instant for the audio RTP packets containing the narrator's speech
* narrator. The sampling instant for the audio RTP packets containing the narrator's speech // would be established by referencing the same wallclock time when the audio was sampled.
* would be established by referencing the same wallclock time when the audio was sampled. // The audio and video may even be transmitted by different hosts if the reference clocks on
* The audio and video may even be transmitted by different hosts if the reference clocks on // The two hosts are synchronized by some means such as NTP. A receiver can then synchronize
* the two hosts are synchronized by some means such as NTP. A receiver can then synchronize // presentation of the audio and video packets by relating their RTP timestamps using the
* presentation of the audio and video packets by relating their RTP timestamps using the // timestamp pairs in RTCP SR packets.
* timestamp pairs in RTCP SR packets.
*/
uint32_t timestamp; //32bits uint32_t timestamp; //32bits
/** // The SSRC: 32 bits
* SSRC: 32 bits // The SSRC field identifies the synchronization source. This identifier should be chosen
* The SSRC field identifies the synchronization source. This identifier should be chosen // randomly, with the intent that no two synchronization sources within the same RTP session
* randomly, with the intent that no two synchronization sources within the same RTP session // will have the same SSRC identifier. An example algorithm for generating a random identifier
* will have the same SSRC identifier. An example algorithm for generating a random identifier // is presented in Appendix A.6. Although the probability of multiple sources choosing the same
* is presented in Appendix A.6. Although the probability of multiple sources choosing the same // identifier is low, all RTP implementations must be prepared to detect and resolve collisions.
* identifier is low, all RTP implementations must be prepared to detect and resolve collisions. // Section 8 describes the probability of collision along with a mechanism for resolving collisions
* Section 8 describes the probability of collision along with a mechanism for resolving collisions // and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If
* and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If // a source changes its source transport address, it must also choose a new SSRC identifier to
* a source changes its source transport address, it must also choose a new SSRC identifier to // avoid being interpreted as a looped source (see Section 8.2).
* avoid being interpreted as a looped source (see Section 8.2).
*/
uint32_t ssrc; //32bits uint32_t ssrc; //32bits
// the payload. // The payload.
SrsSimpleStream* payload; SrsSimpleStream* payload;
// whether transport in chunked payload. // Whether transport in chunked payload.
bool chunked; bool chunked;
// whether message is completed. // Whether message is completed.
// normal message always completed. // normal message always completed.
// while chunked completed when the last chunk arriaved. // while chunked completed when the last chunk arriaved.
bool completed; bool completed;
/** // The audio samples, one rtp packets may contains multiple audio samples.
* the audio samples, one rtp packets may contains multiple audio samples.
*/
SrsAudioFrame* audio; SrsAudioFrame* audio;
public: public:
SrsRtpPacket(); SrsRtpPacket();
virtual ~SrsRtpPacket(); virtual ~SrsRtpPacket();
public: public:
/** // copy the header from src.
* copy the header from src.
*/
virtual void copy(SrsRtpPacket* src); virtual void copy(SrsRtpPacket* src);
/** // reap the src to this packet, reap the payload.
* reap the src to this packet, reap the payload.
*/
virtual void reap(SrsRtpPacket* src); virtual void reap(SrsRtpPacket* src);
/** // decode rtp packet from stream.
* decode rtp packet from stream.
*/
virtual srs_error_t decode(SrsBuffer* stream); virtual srs_error_t decode(SrsBuffer* stream);
private: private:
virtual srs_error_t decode_97(SrsBuffer* stream); virtual srs_error_t decode_97(SrsBuffer* stream);
virtual srs_error_t decode_96(SrsBuffer* stream); virtual srs_error_t decode_96(SrsBuffer* stream);
}; };
/** // The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
* the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159 // Appendix C: Use of SDP for RTSP Session Descriptions
* Appendix C: Use of SDP for RTSP Session Descriptions // The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
* The Session Description Protocol (SDP, RFC 2327 [6]) may be used to // describe streams or presentations in RTSP.
* describe streams or presentations in RTSP.
*/
class SrsRtspSdp class SrsRtspSdp
{ {
private: private:
SrsRtspSdpState state; SrsRtspSdpState state;
public: public:
/** // The version of sdp.
* the version of sdp.
*/
std::string version; std::string version;
/** // The owner/creator of sdp.
* the owner/creator of sdp.
*/
std::string owner_username; std::string owner_username;
std::string owner_session_id; std::string owner_session_id;
std::string owner_session_version; std::string owner_session_version;
std::string owner_network_type; std::string owner_network_type;
std::string owner_address_type; std::string owner_address_type;
std::string owner_address; std::string owner_address;
/** // The session name of sdp.
* the session name of sdp.
*/
std::string session_name; std::string session_name;
/** // The connection info of sdp.
* the connection info of sdp.
*/
std::string connection_network_type; std::string connection_network_type;
std::string connection_address_type; std::string connection_address_type;
std::string connection_address; std::string connection_address;
/** // The tool attribute of sdp.
* the tool attribute of sdp.
*/
std::string tool; std::string tool;
/** // The video attribute of sdp.
* the video attribute of sdp.
*/
std::string video_port; std::string video_port;
std::string video_protocol; std::string video_protocol;
std::string video_transport_format; std::string video_transport_format;
@ -363,13 +303,11 @@ public:
std::string video_codec; std::string video_codec;
std::string video_sample_rate; std::string video_sample_rate;
std::string video_stream_id; std::string video_stream_id;
// fmtp // The fmtp
std::string video_packetization_mode; std::string video_packetization_mode;
std::string video_sps; // sequence header: sps. std::string video_sps; // sequence header: sps.
std::string video_pps; // sequence header: pps. std::string video_pps; // sequence header: pps.
/** // The audio attribute of sdp.
* the audio attribute of sdp.
*/
std::string audio_port; std::string audio_port;
std::string audio_protocol; std::string audio_protocol;
std::string audio_transport_format; std::string audio_transport_format;
@ -378,7 +316,7 @@ public:
std::string audio_sample_rate; std::string audio_sample_rate;
std::string audio_channel; std::string audio_channel;
std::string audio_stream_id; std::string audio_stream_id;
// fmtp // The fmtp
std::string audio_profile_level_id; std::string audio_profile_level_id;
std::string audio_mode; std::string audio_mode;
std::string audio_size_length; std::string audio_size_length;
@ -389,34 +327,24 @@ public:
SrsRtspSdp(); SrsRtspSdp();
virtual ~SrsRtspSdp(); virtual ~SrsRtspSdp();
public: public:
/** // Parse a line of token for sdp.
* parse a line of token for sdp.
*/
virtual srs_error_t parse(std::string token); virtual srs_error_t parse(std::string token);
private: private:
/** // generally, the fmtp is the sequence header for video or audio.
* generally, the fmtp is the sequence header for video or audio.
*/
virtual srs_error_t parse_fmtp_attribute(std::string attr); virtual srs_error_t parse_fmtp_attribute(std::string attr);
/** // generally, the control is the stream info for video or audio.
* generally, the control is the stream info for video or audio.
*/
virtual srs_error_t parse_control_attribute(std::string attr); virtual srs_error_t parse_control_attribute(std::string attr);
/** // decode the string by base64.
* decode the string by base64.
*/
virtual std::string base64_decode(std::string value); virtual std::string base64_decode(std::string value);
}; };
/** // The rtsp transport.
* the rtsp transport. // 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
* 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115 // This request header indicates which transport protocol is to be used
* This request header indicates which transport protocol is to be used // and configures its parameters such as destination address,
* and configures its parameters such as destination address, // compression, multicast time-to-live and destination port for a single
* compression, multicast time-to-live and destination port for a single // stream. It sets those values not already determined by a presentation
* stream. It sets those values not already determined by a presentation // description.
* description.
*/
class SrsRtspTransport class SrsRtspTransport
{ {
public: public:
@ -431,7 +359,7 @@ public:
// Clients that are capable of handling both unicast and // Clients that are capable of handling both unicast and
// multicast transmission MUST indicate such capability by // multicast transmission MUST indicate such capability by
// including two full transport-specs with separate parameters // including two full transport-specs with separate parameters
// for each. // For each.
std::string cast_type; std::string cast_type;
// The mode parameter indicates the methods to be supported for // The mode parameter indicates the methods to be supported for
// this session. Valid values are PLAY and RECORD. If not // this session. Valid values are PLAY and RECORD. If not
@ -449,79 +377,59 @@ public:
SrsRtspTransport(); SrsRtspTransport();
virtual ~SrsRtspTransport(); virtual ~SrsRtspTransport();
public: public:
/** // Parse a line of token for transport.
* parse a line of token for transport.
*/
virtual srs_error_t parse(std::string attr); virtual srs_error_t parse(std::string attr);
}; };
/** // The rtsp request message.
* the rtsp request message. // 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
* 6 Request, @see rfc2326-1998-rtsp.pdf, page 39 // A request message from a client to a server or vice versa includes,
* A request message from a client to a server or vice versa includes, // within the first line of that message, the method to be applied to
* within the first line of that message, the method to be applied to // The resource, the identifier of the resource, and the protocol
* the resource, the identifier of the resource, and the protocol // version in use.
* version in use. // Request = Request-Line ; Section 6.1
* Request = Request-Line ; Section 6.1 // // ( general-header ; Section 5
* *( general-header ; Section 5 // | request-header ; Section 6.2
* | request-header ; Section 6.2 // | entity-header ) ; Section 8.1
* | entity-header ) ; Section 8.1 // CRLF
* CRLF // [ message-body ] ; Section 4.3
* [ message-body ] ; Section 4.3
*/
class SrsRtspRequest class SrsRtspRequest
{ {
public: public:
/** // 6.1 Request Line
* 6.1 Request Line // Request-Line = Method SP Request-URI SP RTSP-Version CRLF
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
*/
std::string method; std::string method;
std::string uri; std::string uri;
std::string version; std::string version;
/** // 12.17 CSeq
* 12.17 CSeq // The CSeq field specifies the sequence number for an RTSP requestresponse
* The CSeq field specifies the sequence number for an RTSP requestresponse // pair. This field MUST be present in all requests and
* pair. This field MUST be present in all requests and // responses. For every RTSP request containing the given sequence
* responses. For every RTSP request containing the given sequence // number, there will be a corresponding response having the same
* number, there will be a corresponding response having the same // number. Any retransmitted request must contain the same sequence
* number. Any retransmitted request must contain the same sequence // number as the original (i.e. the sequence number is not incremented
* number as the original (i.e. the sequence number is not incremented // For retransmissions of the same request).
* for retransmissions of the same request).
*/
long seq; long seq;
/** // 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
* 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99 // See [H14.18]. Note that the content types suitable for RTSP are
* See [H14.18]. Note that the content types suitable for RTSP are // likely to be restricted in practice to presentation descriptions and
* likely to be restricted in practice to presentation descriptions and // parameter-value types.
* parameter-value types.
*/
std::string content_type; std::string content_type;
/** // 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
* 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99 // This field contains the length of the content of the method (i.e.
* This field contains the length of the content of the method (i.e. // after the double CRLF following the last header). Unlike HTTP, it
* after the double CRLF following the last header). Unlike HTTP, it // MUST be included in all messages that carry content beyond the header
* MUST be included in all messages that carry content beyond the header // portion of the message. If it is missing, a default value of zero is
* portion of the message. If it is missing, a default value of zero is // assumed. It is interpreted according to [H14.14].
* assumed. It is interpreted according to [H14.14].
*/
long content_length; long content_length;
/** // The session id.
* the session id.
*/
std::string session; std::string session;
/** // The sdp in announce, NULL for no sdp.
* the sdp in announce, NULL for no sdp.
*/
SrsRtspSdp* sdp; SrsRtspSdp* sdp;
/** // The transport in setup, NULL for no transport.
* the transport in setup, NULL for no transport.
*/
SrsRtspTransport* transport; SrsRtspTransport* transport;
/** // For setup message, parse the stream id from uri.
* for setup message, parse the stream id from uri.
*/
int stream_id; int stream_id;
public: public:
SrsRtspRequest(); SrsRtspRequest();
@ -533,79 +441,63 @@ public:
virtual bool is_record(); virtual bool is_record();
}; };
/** // The rtsp response message.
* the rtsp response message. // 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
* 7 Response, @see rfc2326-1998-rtsp.pdf, page 43 // [H6] applies except that HTTP-Version is replaced by RTSP-Version.
* [H6] applies except that HTTP-Version is replaced by RTSP-Version. // Also, RTSP defines additional status codes and does not define some
* Also, RTSP defines additional status codes and does not define some // HTTP codes. The valid response codes and the methods they can be used
* HTTP codes. The valid response codes and the methods they can be used // with are defined in Table 1.
* with are defined in Table 1. // After receiving and interpreting a request message, the recipient
* After receiving and interpreting a request message, the recipient // responds with an RTSP response message.
* responds with an RTSP response message. // Response = Status-Line ; Section 7.1
* Response = Status-Line ; Section 7.1 // // ( general-header ; Section 5
* *( general-header ; Section 5 // | response-header ; Section 7.1.2
* | response-header ; Section 7.1.2 // | entity-header ) ; Section 8.1
* | entity-header ) ; Section 8.1 // CRLF
* CRLF // [ message-body ] ; Section 4.3
* [ message-body ] ; Section 4.3
*/
class SrsRtspResponse class SrsRtspResponse
{ {
public: public:
/** // 7.1 Status-Line
* 7.1 Status-Line // The first line of a Response message is the Status-Line, consisting
* The first line of a Response message is the Status-Line, consisting // of the protocol version followed by a numeric status code, and the
* of the protocol version followed by a numeric status code, and the // textual phrase associated with the status code, with each element
* textual phrase associated with the status code, with each element // separated by SP characters. No CR or LF is allowed except in the
* separated by SP characters. No CR or LF is allowed except in the // final CRLF sequence.
* final CRLF sequence. // Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
*/
// @see about the version of rtsp, see SRS_RTSP_VERSION // @see about the version of rtsp, see SRS_RTSP_VERSION
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK // @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
int status; int status;
/** // 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
* 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99 // The CSeq field specifies the sequence number for an RTSP requestresponse
* The CSeq field specifies the sequence number for an RTSP requestresponse // pair. This field MUST be present in all requests and
* pair. This field MUST be present in all requests and // responses. For every RTSP request containing the given sequence
* responses. For every RTSP request containing the given sequence // number, there will be a corresponding response having the same
* number, there will be a corresponding response having the same // number. Any retransmitted request must contain the same sequence
* number. Any retransmitted request must contain the same sequence // number as the original (i.e. the sequence number is not incremented
* number as the original (i.e. the sequence number is not incremented // For retransmissions of the same request).
* for retransmissions of the same request).
*/
long seq; long seq;
/** // The session id.
* the session id.
*/
std::string session; std::string session;
public: public:
SrsRtspResponse(int cseq); SrsRtspResponse(int cseq);
virtual ~SrsRtspResponse(); virtual ~SrsRtspResponse();
public: public:
/** // Encode message to string.
* encode message to string.
*/
virtual srs_error_t encode(std::stringstream& ss); virtual srs_error_t encode(std::stringstream& ss);
protected: protected:
/** // Sub classes override this to encode the headers.
* sub classes override this to encode the headers.
*/
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
* 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59 // The behavior is equivalent to that described in [H9.2]. An OPTIONS
* The behavior is equivalent to that described in [H9.2]. An OPTIONS // request may be issued at any time, e.g., if the client is about to
* request may be issued at any time, e.g., if the client is about to // try a nonstandard request. It does not influence server state.
* try a nonstandard request. It does not influence server state.
*/
class SrsRtspOptionsResponse : public SrsRtspResponse class SrsRtspOptionsResponse : public SrsRtspResponse
{ {
public: public:
/** // Join of SrsRtspMethod
* join of SrsRtspMethod
*/
SrsRtspMethod methods; SrsRtspMethod methods;
public: public:
SrsRtspOptionsResponse(int cseq); SrsRtspOptionsResponse(int cseq);
@ -614,28 +506,26 @@ protected:
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
* 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65 // The SETUP request for a URI specifies the transport mechanism to be
* The SETUP request for a URI specifies the transport mechanism to be // used for the streamed media. A client can issue a SETUP request for a
* used for the streamed media. A client can issue a SETUP request for a // stream that is already playing to change transport parameters, which
* stream that is already playing to change transport parameters, which // a server MAY allow. If it does not allow this, it MUST respond with
* a server MAY allow. If it does not allow this, it MUST respond with // error "455 Method Not Valid In This State". For the benefit of any
* error "455 Method Not Valid In This State". For the benefit of any // intervening firewalls, a client must indicate the transport
* intervening firewalls, a client must indicate the transport // parameters even if it has no influence over these parameters, for
* parameters even if it has no influence over these parameters, for // example, where the server advertises a fixed multicast address.
* example, where the server advertises a fixed multicast address.
*/
class SrsRtspSetupResponse : public SrsRtspResponse class SrsRtspSetupResponse : public SrsRtspResponse
{ {
public: public:
// the client specified port. // The client specified port.
int client_port_min; int client_port_min;
int client_port_max; int client_port_max;
// client will use the port in: // The client will use the port in:
// [local_port_min, local_port_max) // [local_port_min, local_port_max)
int local_port_min; int local_port_min;
int local_port_max; int local_port_max;
// session. // The session.
std::string session; std::string session;
public: public:
SrsRtspSetupResponse(int cseq); SrsRtspSetupResponse(int cseq);
@ -644,65 +534,45 @@ protected:
virtual srs_error_t encode_header(std::stringstream& ss); virtual srs_error_t encode_header(std::stringstream& ss);
}; };
/** // The rtsp protocol stack to parse the rtsp packets.
* the rtsp protocol stack to parse the rtsp packets.
*/
class SrsRtspStack class SrsRtspStack
{ {
private: private:
/** // The cached bytes buffer.
* cached bytes buffer.
*/
SrsSimpleStream* buf; SrsSimpleStream* buf;
/** // The underlayer socket object, send/recv bytes.
* underlayer socket object, send/recv bytes.
*/
ISrsProtocolReadWriter* skt; ISrsProtocolReadWriter* skt;
public: public:
SrsRtspStack(ISrsProtocolReadWriter* s); SrsRtspStack(ISrsProtocolReadWriter* s);
virtual ~SrsRtspStack(); virtual ~SrsRtspStack();
public: public:
/** // Recv rtsp message from underlayer io.
* recv rtsp message from underlayer io. // @param preq the output rtsp request message, which user must free it.
* @param preq the output rtsp request message, which user must free it. // @return an int error code.
* @return an int error code. // ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
*/
virtual srs_error_t recv_message(SrsRtspRequest** preq); virtual srs_error_t recv_message(SrsRtspRequest** preq);
/** // Send rtsp message over underlayer io.
* send rtsp message over underlayer io. // @param res the rtsp response message, which user should never free it.
* @param res the rtsp response message, which user should never free it. // @return an int error code.
* @return an int error code.
*/
virtual srs_error_t send_message(SrsRtspResponse* res); virtual srs_error_t send_message(SrsRtspResponse* res);
private: private:
/** // Recv the rtsp message.
* recv the rtsp message.
*/
virtual srs_error_t do_recv_message(SrsRtspRequest* req); virtual srs_error_t do_recv_message(SrsRtspRequest* req);
/** // Read a normal token from io, error when token state is not normal.
* read a normal token from io, error when token state is not normal.
*/
virtual srs_error_t recv_token_normal(std::string& token); virtual srs_error_t recv_token_normal(std::string& token);
/** // Read a normal token from io, error when token state is not eof.
* read a normal token from io, error when token state is not eof.
*/
virtual srs_error_t recv_token_eof(std::string& token); virtual srs_error_t recv_token_eof(std::string& token);
/** // Read the token util got eof, for example, to read the response status Reason-Phrase
* read the token util got eof, for example, to read the response status Reason-Phrase // @param pconsumed, output the token parsed length. NULL to ignore.
* @param pconsumed, output the token parsed length. NULL to ignore.
*/
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL); virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
/** // Read a token from io, split by SP, endswith CRLF:
* read a token from io, split by SP, endswith CRLF: // token1 SP token2 SP ... tokenN CRLF
* token1 SP token2 SP ... tokenN CRLF // @param token, output the read token.
* @param token, output the read token. // @param state, output the token parse state.
* @param state, output the token parse state. // @param normal_ch, the char to indicates the normal token.
* @param normal_ch, the char to indicates the normal token. // the SP use to indicates the normal token, @see SRS_RTSP_SP
* the SP use to indicates the normal token, @see SRS_RTSP_SP // the 0x00 use to ignore normal token flag. @see recv_token_util_eof
* the 0x00 use to ignore normal token flag. @see recv_token_util_eof // @param pconsumed, output the token parsed length. NULL to ignore.
* @param pconsumed, output the token parsed length. NULL to ignore.
*/
virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL); virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL);
}; };

View file

@ -26,9 +26,7 @@
#include <srs_core.hpp> #include <srs_core.hpp>
/** // The connection interface for all HTTP/RTMP/RTSP object.
* The connection interface for all HTTP/RTMP/RTSP object.
*/
class ISrsConnection class ISrsConnection
{ {
public: public:
@ -36,18 +34,14 @@ public:
virtual ~ISrsConnection(); virtual ~ISrsConnection();
}; };
/** // The manager for connection.
* the manager for connection.
*/
class IConnectionManager class IConnectionManager
{ {
public: public:
IConnectionManager(); IConnectionManager();
virtual ~IConnectionManager(); virtual ~IConnectionManager();
public: public:
/** // Remove then free the specified connection.
* Remove then free the specified connection.
*/
virtual void remove(ISrsConnection* c) = 0; virtual void remove(ISrsConnection* c) = 0;
}; };

View file

@ -40,18 +40,16 @@ class SrsKbps;
class SrsWallClock; class SrsWallClock;
class SrsTcpClient; class SrsTcpClient;
// the default timeout for http client. // The default timeout for http client.
#define SRS_HTTP_CLIENT_TIMEOUT (30 * SRS_UTIME_SECONDS) #define SRS_HTTP_CLIENT_TIMEOUT (30 * SRS_UTIME_SECONDS)
/** // The client to GET/POST/PUT/DELETE over HTTP.
* The client to GET/POST/PUT/DELETE over HTTP. // @remark We will reuse the TCP transport until initialize or channel error,
* @remark We will reuse the TCP transport until initialize or channel error, // such as send/recv failed.
* such as send/recv failed. // Usage:
* Usage: // SrsHttpClient hc;
* SrsHttpClient hc; // hc.initialize("127.0.0.1", 80, 9000);
* hc.initialize("127.0.0.1", 80, 9000); // hc.post("/api/v1/version", "Hello world!", NULL);
* hc.post("/api/v1/version", "Hello world!", NULL);
*/
class SrsHttpClient class SrsHttpClient
{ {
private: private:
@ -72,33 +70,25 @@ public:
SrsHttpClient(); SrsHttpClient();
virtual ~SrsHttpClient(); virtual ~SrsHttpClient();
public: public:
/** // Initliaze the client, disconnect the transport, renew the HTTP parser.
* Initliaze the client, disconnect the transport, renew the HTTP parser. // @param tm The underlayer TCP transport timeout in srs_utime_t.
* @param tm The underlayer TCP transport timeout in srs_utime_t. // @remark we will set default values in headers, which can be override by set_header.
* @remark we will set default values in headers, which can be override by set_header.
*/
virtual srs_error_t initialize(std::string h, int p, srs_utime_t tm = SRS_HTTP_CLIENT_TIMEOUT); virtual srs_error_t initialize(std::string h, int p, srs_utime_t tm = SRS_HTTP_CLIENT_TIMEOUT);
/** // Set HTTP request header in header[k]=v.
* Set HTTP request header in header[k]=v. // @return the HTTP client itself.
* @return the HTTP client itself.
*/
virtual SrsHttpClient* set_header(std::string k, std::string v); virtual SrsHttpClient* set_header(std::string k, std::string v);
public: public:
/** // Post data to the uri.
* to post data to the uri. // @param the path to request on.
* @param the path to request on. // @param req the data post to uri. empty string to ignore.
* @param req the data post to uri. empty string to ignore. // @param ppmsg output the http message to read the response.
* @param ppmsg output the http message to read the response. // @remark user must free the ppmsg if not NULL.
* @remark user must free the ppmsg if not NULL.
*/
virtual srs_error_t post(std::string path, std::string req, ISrsHttpMessage** ppmsg); virtual srs_error_t post(std::string path, std::string req, ISrsHttpMessage** ppmsg);
/** // Get data from the uri.
* to get data from the uri. // @param the path to request on.
* @param the path to request on. // @param req the data post to uri. empty string to ignore.
* @param req the data post to uri. empty string to ignore. // @param ppmsg output the http message to read the response.
* @param ppmsg output the http message to read the response. // @remark user must free the ppmsg if not NULL.
* @remark user must free the ppmsg if not NULL.
*/
virtual srs_error_t get(std::string path, std::string req, ISrsHttpMessage** ppmsg); virtual srs_error_t get(std::string path, std::string req, ISrsHttpMessage** ppmsg);
private: private:
virtual void set_recv_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm);

View file

@ -82,7 +82,7 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
header = http_parser(); header = http_parser();
url = ""; url = "";
headers.clear(); headers.clear();
header_parsed = 0; pbody = NULL;
// do parse // do parse
if ((err = parse_message_imp(reader)) != srs_success) { if ((err = parse_message_imp(reader)) != srs_success) {
@ -109,40 +109,34 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader)
srs_error_t err = srs_success; srs_error_t err = srs_success;
while (true) { while (true) {
ssize_t nparsed = 0; if (buffer->size() > 0) {
ssize_t nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size());
if (buffer->size() != nparsed) {
return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse failed, nparsed=%d, size=%d", nparsed, buffer->size());
}
// when got entire http header, parse it. // The consumed size, does not include the body.
// @see https://github.com/ossrs/srs/issues/400 ssize_t consumed = nparsed;
char* start = buffer->bytes(); if (pbody && buffer->bytes() < pbody) {
char* end = start + buffer->size(); consumed = pbody - buffer->bytes();
for (char* p = start; p <= end - 4; p++) { }
// SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A srs_info("size=%d, nparsed=%d, consumed=%d", buffer->size(), (int)nparsed, consumed);
if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) {
nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); // Only consume the header bytes.
srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed); buffer->read_slice(consumed);
// Done when header completed, never wait for body completed, because it maybe chunked.
if (state >= SrsHttpParseStateHeaderComplete) {
break; break;
} }
} }
// consume the parsed bytes.
if (nparsed && header_parsed) {
buffer->read_slice(header_parsed);
}
// ok atleast header completed,
// never wait for body completed, for maybe chunked.
if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) {
break;
}
// when nothing parsed, read more to parse. // when nothing parsed, read more to parse.
if (nparsed == 0) {
// when requires more, only grow 1bytes, but the buffer will cache more. // when requires more, only grow 1bytes, but the buffer will cache more.
if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) { if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) {
return srs_error_wrap(err, "grow buffer"); return srs_error_wrap(err, "grow buffer");
} }
} }
}
// parse last header. // parse last header.
if (!field_name.empty() && !field_value.empty()) { if (!field_name.empty() && !field_value.empty()) {
@ -172,7 +166,6 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
obj->header = *parser; obj->header = *parser;
// save the parser when header parse completed. // save the parser when header parse completed.
obj->state = SrsHttpParseStateHeaderComplete; obj->state = SrsHttpParseStateHeaderComplete;
obj->header_parsed = (int)parser->nread;
srs_info("***HEADERS COMPLETE***"); srs_info("***HEADERS COMPLETE***");
@ -249,6 +242,12 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
SrsHttpParser* obj = (SrsHttpParser*)parser->data; SrsHttpParser* obj = (SrsHttpParser*)parser->data;
srs_assert(obj); srs_assert(obj);
// save the parser when body parsed.
obj->state = SrsHttpParseStateBody;
// Save the body position.
obj->pbody = at;
srs_info("Body: %.*s", (int)length, at); srs_info("Body: %.*s", (int)length, at);
return 0; return 0;

View file

@ -37,18 +37,16 @@ class ISrsReader;
class SrsHttpResponseReader; class SrsHttpResponseReader;
class SrsStSocket; class SrsStSocket;
/** // A wrapper for http-parser,
* wrapper for http-parser, // provides HTTP message originted service.
* provides HTTP message originted service.
*/
class SrsHttpParser class SrsHttpParser
{ {
private: private:
http_parser_settings settings; http_parser_settings settings;
http_parser parser; http_parser parser;
// the global parse buffer. // The global parse buffer.
SrsFastStream* buffer; SrsFastStream* buffer;
// whether allow jsonp parse. // Whether allow jsonp parse.
bool jsonp; bool jsonp;
private: private:
// http parse data, reset before parse message. // http parse data, reset before parse message.
@ -59,29 +57,23 @@ private:
http_parser header; http_parser header;
std::string url; std::string url;
std::vector<SrsHttpHeaderField> headers; std::vector<SrsHttpHeaderField> headers;
int header_parsed; const char* pbody;
public: public:
SrsHttpParser(); SrsHttpParser();
virtual ~SrsHttpParser(); virtual ~SrsHttpParser();
public: public:
/** // initialize the http parser with specified type,
* initialize the http parser with specified type, // one parser can only parse request or response messages.
* one parser can only parse request or response messages. // @param allow_jsonp whether allow jsonp parser, which indicates the method in query string.
* @param allow_jsonp whether allow jsonp parser, which indicates the method in query string. virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp = false);
*/ // always parse a http message,
virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp); // that is, the *ppmsg always NOT-NULL when return success.
/** // or error and *ppmsg must be NULL.
* always parse a http message, // @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
* that is, the *ppmsg always NOT-NULL when return success. // @remark user must free the ppmsg if not NULL.
* or error and *ppmsg must be NULL.
* @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete().
* @remark user must free the ppmsg if not NULL.
*/
virtual srs_error_t parse_message(ISrsReader* reader, ISrsHttpMessage** ppmsg); virtual srs_error_t parse_message(ISrsReader* reader, ISrsHttpMessage** ppmsg);
private: private:
/** // parse the HTTP message to member field: msg.
* parse the HTTP message to member field: msg.
*/
virtual srs_error_t parse_message_imp(ISrsReader* reader); virtual srs_error_t parse_message_imp(ISrsReader* reader);
private: private:
static int on_message_begin(http_parser* parser); static int on_message_begin(http_parser* parser);
@ -105,62 +97,41 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
class SrsHttpMessage : public ISrsHttpMessage class SrsHttpMessage : public ISrsHttpMessage
{ {
private: private:
/** // The parsed url.
* parsed url.
*/
std::string _url; std::string _url;
/** // The extension of file, for example, .flv
* the extension of file, for example, .flv
*/
std::string _ext; std::string _ext;
/** // parsed http header.
* parsed http header.
*/
http_parser _header; http_parser _header;
/** // The body object, reader object.
* body object, reader object. // @remark, user can get body in string by get_body().
* @remark, user can get body in string by get_body().
*/
SrsHttpResponseReader* _body; SrsHttpResponseReader* _body;
/** // Whether the body is chunked.
* whether the body is chunked.
*/
bool chunked; bool chunked;
/** // Whether the body is infinite chunked.
* whether the body is infinite chunked.
*/
bool infinite_chunked; bool infinite_chunked;
/** // Whether the request indicates should keep alive for the http connection.
* whether the request indicates should keep alive
* for the http connection.
*/
bool keep_alive; bool keep_alive;
/** // The uri parser
* uri parser
*/
SrsHttpUri* _uri; SrsHttpUri* _uri;
/** // Use a buffer to read and send ts file.
* use a buffer to read and send ts file.
*/
// TODO: FIXME: remove it. // TODO: FIXME: remove it.
char* _http_ts_send_buffer; char* _http_ts_send_buffer;
// http headers // The http headers
std::vector<SrsHttpHeaderField> _headers; std::vector<SrsHttpHeaderField> _headers;
// the query map // The query map
std::map<std::string, std::string> _query; std::map<std::string, std::string> _query;
// the transport connection, can be NULL. // The transport connection, can be NULL.
SrsConnection* owner_conn; SrsConnection* owner_conn;
// whether request is jsonp. // Whether request is jsonp.
bool jsonp; bool jsonp;
// the method in QueryString will override the HTTP method. // The method in QueryString will override the HTTP method.
std::string jsonp_method; std::string jsonp_method;
public: public:
SrsHttpMessage(ISrsReader* io); SrsHttpMessage(ISrsReader* io);
virtual ~SrsHttpMessage(); virtual ~SrsHttpMessage();
public: public:
/** // set the original messages, then update the message.
* set the original messages, then update the message.
*/
virtual srs_error_t update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers); virtual srs_error_t update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector<SrsHttpHeaderField>& headers);
public: public:
// Get the owner connection, maybe NULL. // Get the owner connection, maybe NULL.
@ -169,91 +140,62 @@ public:
public: public:
virtual uint8_t method(); virtual uint8_t method();
virtual uint16_t status_code(); virtual uint16_t status_code();
/** // The method helpers.
* method helpers.
*/
virtual std::string method_str(); virtual std::string method_str();
virtual bool is_http_get(); virtual bool is_http_get();
virtual bool is_http_put(); virtual bool is_http_put();
virtual bool is_http_post(); virtual bool is_http_post();
virtual bool is_http_delete(); virtual bool is_http_delete();
virtual bool is_http_options(); virtual bool is_http_options();
/** // Whether body is chunked encoding, for reader only.
* whether body is chunked encoding, for reader only.
*/
virtual bool is_chunked(); virtual bool is_chunked();
/** // Whether body is infinite chunked encoding.
* whether body is infinite chunked encoding. // @remark set by enter_infinite_chunked.
* @remark set by enter_infinite_chunked.
*/
virtual bool is_infinite_chunked(); virtual bool is_infinite_chunked();
/** // Whether should keep the connection alive.
* whether should keep the connection alive.
*/
virtual bool is_keep_alive(); virtual bool is_keep_alive();
/** // The uri contains the host and path.
* the uri contains the host and path.
*/
virtual std::string uri(); virtual std::string uri();
/** // The url maybe the path.
* the url maybe the path.
*/
virtual std::string url(); virtual std::string url();
virtual std::string host(); virtual std::string host();
virtual std::string path(); virtual std::string path();
virtual std::string query(); virtual std::string query();
virtual std::string ext(); virtual std::string ext();
/** // Get the RESTful matched id.
* get the RESTful matched id.
*/
virtual int parse_rest_id(std::string pattern); virtual int parse_rest_id(std::string pattern);
public: public:
virtual srs_error_t enter_infinite_chunked(); virtual srs_error_t enter_infinite_chunked();
public: public:
/** // Read body to string.
* read body to string. // @remark for small http body.
* @remark for small http body.
*/
virtual srs_error_t body_read_all(std::string& body); virtual srs_error_t body_read_all(std::string& body);
/** // Get the body reader, to read one by one.
* get the body reader, to read one by one. // @remark when body is very large, or chunked, use this.
* @remark when body is very large, or chunked, use this.
*/
virtual ISrsHttpResponseReader* body_reader(); virtual ISrsHttpResponseReader* body_reader();
/** // The content length, -1 for chunked or not set.
* the content length, -1 for chunked or not set.
*/
virtual int64_t content_length(); virtual int64_t content_length();
/** // Get the param in query string, for instance, query is "start=100&end=200",
* get the param in query string, // then query_get("start") is "100", and query_get("end") is "200"
* for instance, query is "start=100&end=200",
* then query_get("start") is "100", and query_get("end") is "200"
*/
virtual std::string query_get(std::string key); virtual std::string query_get(std::string key);
/** // Get the headers.
* get the headers.
*/
virtual int request_header_count(); virtual int request_header_count();
virtual std::string request_header_key_at(int index); virtual std::string request_header_key_at(int index);
virtual std::string request_header_value_at(int index); virtual std::string request_header_value_at(int index);
virtual std::string get_request_header(std::string name); virtual std::string get_request_header(std::string name);
public: public:
/** // Convert the http message to a request.
* convert the http message to a request. // @remark user must free the return request.
* @remark user must free the return request.
*/
virtual SrsRequest* to_request(std::string vhost); virtual SrsRequest* to_request(std::string vhost);
public: public:
virtual bool is_jsonp(); virtual bool is_jsonp();
}; };
// the http chunked header size, // The http chunked header size,
// for writev, there always one chunk to send it. // for writev, there always one chunk to send it.
#define SRS_HTTP_HEADER_CACHE_SIZE 64 #define SRS_HTTP_HEADER_CACHE_SIZE 64
/** // Response writer use st socket
* response writer use st socket
*/
class SrsHttpResponseWriter : public ISrsHttpResponseWriter class SrsHttpResponseWriter : public ISrsHttpResponseWriter
{ {
private: private:
@ -264,17 +206,17 @@ private:
iovec* iovss_cache; iovec* iovss_cache;
int nb_iovss_cache; int nb_iovss_cache;
private: private:
// reply header has been (logically) written // Reply header has been (logically) written
bool header_wrote; bool header_wrote;
// status code passed to WriteHeader // The status code passed to WriteHeader
int status; int status;
private: private:
// explicitly-declared Content-Length; or -1 // The explicitly-declared Content-Length; or -1
int64_t content_length; int64_t content_length;
// number of bytes written in body // The number of bytes written in body
int64_t written; int64_t written;
private: private:
// wroteHeader tells whether the header's been written to "the // The wroteHeader tells whether the header's been written to "the
// wire" (or rather: w.conn.buf). this is unlike // wire" (or rather: w.conn.buf). this is unlike
// (*response).wroteHeader, which tells only whether it was // (*response).wroteHeader, which tells only whether it was
// logically written. // logically written.
@ -291,9 +233,7 @@ public:
virtual srs_error_t send_header(char* data, int size); virtual srs_error_t send_header(char* data, int size);
}; };
/** // Response reader use st socket.
* response reader use st socket.
*/
class SrsHttpResponseReader : virtual public ISrsHttpResponseReader class SrsHttpResponseReader : virtual public ISrsHttpResponseReader
{ {
private: private:
@ -301,21 +241,19 @@ private:
SrsHttpMessage* owner; SrsHttpMessage* owner;
SrsFastStream* buffer; SrsFastStream* buffer;
bool is_eof; bool is_eof;
// the left bytes in chunk. // The left bytes in chunk.
int nb_left_chunk; int nb_left_chunk;
// the number of bytes of current chunk. // The number of bytes of current chunk.
int nb_chunk; int nb_chunk;
// already read total bytes. // Already read total bytes.
int64_t nb_total_read; int64_t nb_total_read;
public: public:
SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader); SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader);
virtual ~SrsHttpResponseReader(); virtual ~SrsHttpResponseReader();
public: public:
/** // Initialize the response reader with buffer.
* initialize the response reader with buffer.
*/
virtual srs_error_t initialize(SrsFastStream* buffer); virtual srs_error_t initialize(SrsFastStream* buffer);
// interface ISrsHttpResponseReader // Interface ISrsHttpResponseReader
public: public:
virtual bool eof(); virtual bool eof();
virtual srs_error_t read(char* data, int nb_data, int* nb_read); virtual srs_error_t read(char* data, int nb_data, int* nb_read);

View file

@ -31,10 +31,8 @@
#include <srs_service_st.hpp> #include <srs_service_st.hpp>
#include <srs_kernel_log.hpp> #include <srs_kernel_log.hpp>
/** // The st thread context, get_id will get the st-thread id,
* st thread context, get_id will get the st-thread id, // which identify the client.
* which identify the client.
*/
class SrsThreadContext : public ISrsThreadContext class SrsThreadContext : public ISrsThreadContext
{ {
private: private:
@ -50,9 +48,7 @@ public:
virtual void clear_cid(); virtual void clear_cid();
}; };
/** // The basic console log, which write log to console.
* The basic console log, which write log to console.
*/
class SrsConsoleLog : public ISrsLog class SrsConsoleLog : public ISrsLog
{ {
private: private:
@ -63,7 +59,7 @@ private:
public: public:
SrsConsoleLog(SrsLogLevel l, bool u); SrsConsoleLog(SrsLogLevel l, bool u);
virtual ~SrsConsoleLog(); virtual ~SrsConsoleLog();
// interface ISrsLog // Interface ISrsLog
public: public:
virtual srs_error_t initialize(); virtual srs_error_t initialize();
virtual void reopen(); virtual void reopen();
@ -74,13 +70,11 @@ public:
virtual void error(const char* tag, int context_id, const char* fmt, ...); virtual void error(const char* tag, int context_id, const char* fmt, ...);
}; };
/** // Generate the log header.
* Generate the log header. // @param dangerous Whether log is warning or error, log the errno if true.
* @param dangerous Whether log is warning or error, log the errno if true. // @param utc Whether use UTC time format in the log header.
* @param utc Whether use UTC time format in the log header. // @param psize Output the actual header size.
* @param psize Output the actual header size. // @remark It's a internal API.
* @remark It's a internal API.
*/
bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize); bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize);
#endif #endif

View file

@ -118,14 +118,8 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY)); data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE));
data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE));
data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL));
data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB));
data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL));
data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT));
data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));
data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));
// for edge to directly get the id of client. // for edge to directly get the id of client.
data->set("srs_pid", SrsAmf0Any::number(getpid())); data->set("srs_pid", SrsAmf0Any::number(getpid()));
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id())); data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));

View file

@ -37,15 +37,13 @@ class SrsPacket;
class SrsKbps; class SrsKbps;
class SrsWallClock; class SrsWallClock;
/** // The simple RTMP client, provides friendly APIs.
* The simple RTMP client, provides friendly APIs. // @remark Should never use client when closed.
* @remark Should never use client when closed. // Usage:
* Usage: // SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000);
* SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000); // client.connect();
* client.connect(); // client.play();
* client.play(); // client.close();
* client.close();
*/
class SrsBasicRtmpClient class SrsBasicRtmpClient
{ {
private: private:

View file

@ -36,10 +36,10 @@ typedef void* srs_thread_t;
typedef void* srs_cond_t; typedef void* srs_cond_t;
typedef void* srs_mutex_t; typedef void* srs_mutex_t;
// initialize st, requires epoll. // Initialize st, requires epoll.
extern srs_error_t srs_st_init(); extern srs_error_t srs_st_init();
// close the netfd, and close the underlayer fd. // Close the netfd, and close the underlayer fd.
// @remark when close, user must ensure io completed. // @remark when close, user must ensure io completed.
extern void srs_close_stfd(srs_netfd_t& stfd); extern void srs_close_stfd(srs_netfd_t& stfd);
@ -81,9 +81,7 @@ extern srs_netfd_t srs_accept(srs_netfd_t stfd, struct sockaddr *addr, int *addr
extern ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout); extern ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout);
/** // The mutex locker.
* The mutex locker.
*/
#define SrsLocker(instance) \ #define SrsLocker(instance) \
impl__SrsLocker _srs_auto_free_##instance(&instance) impl__SrsLocker _srs_auto_free_##instance(&instance)
@ -102,10 +100,8 @@ public:
} }
}; };
/** // the socket provides TCP socket over st,
* the socket provides TCP socket over st, // that is, the sync socket mechanism.
* that is, the sync socket mechanism.
*/
class SrsStSocket : public ISrsProtocolReadWriter class SrsStSocket : public ISrsProtocolReadWriter
{ {
private: private:
@ -133,28 +129,22 @@ public:
virtual int64_t get_recv_bytes(); virtual int64_t get_recv_bytes();
virtual int64_t get_send_bytes(); virtual int64_t get_send_bytes();
public: public:
/** // @param nread, the actual read bytes, ignore if NULL.
* @param nread, the actual read bytes, ignore if NULL.
*/
virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); virtual srs_error_t read(void* buf, size_t size, ssize_t* nread);
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
/** // @param nwrite, the actual write bytes, ignore if NULL.
* @param nwrite, the actual write bytes, ignore if NULL.
*/
virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite); virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite);
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
}; };
/** // The client to connect to server over TCP.
* The client to connect to server over TCP. // User must never reuse the client when close it.
* User must never reuse the client when close it. // Usage:
* Usage: // SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS);
* SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS); // client.connect();
* client.connect(); // client.write("Hello world!", 12, NULL);
* client.write("Hello world!", 12, NULL); // client.read(buf, 4096, NULL);
* client.read(buf, 4096, NULL); // @remark User can directly free the object, which will close the fd.
* @remark User can directly free the object, which will close the fd.
*/
class SrsTcpClient : public ISrsProtocolReadWriter class SrsTcpClient : public ISrsProtocolReadWriter
{ {
private: private:
@ -166,27 +156,21 @@ private:
// The timeout in srs_utime_t. // The timeout in srs_utime_t.
srs_utime_t timeout; srs_utime_t timeout;
public: public:
/** // Constructor.
* Constructor. // @param h the ip or hostname of server.
* @param h the ip or hostname of server. // @param p the port to connect to.
* @param p the port to connect to. // @param tm the timeout in srs_utime_t.
* @param tm the timeout in srs_utime_t.
*/
SrsTcpClient(std::string h, int p, srs_utime_t tm); SrsTcpClient(std::string h, int p, srs_utime_t tm);
virtual ~SrsTcpClient(); virtual ~SrsTcpClient();
public: public:
/** // Connect to server over TCP.
* Connect to server over TCP. // @remark We will close the exists connection before do connect.
* @remark We will close the exists connection before do connect.
*/
virtual srs_error_t connect(); virtual srs_error_t connect();
private: private:
/** // Close the connection to server.
* Close the connection to server. // @remark User should never use the client when close it.
* @remark User should never use the client when close it.
*/
virtual void close(); virtual void close();
// interface ISrsProtocolReadWriter // Interface ISrsProtocolReadWriter
public: public:
virtual bool is_never_timeout(srs_utime_t tm); virtual bool is_never_timeout(srs_utime_t tm);
virtual void set_recv_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm);

View file

@ -32,17 +32,17 @@
#include <srs_service_st.hpp> #include <srs_service_st.hpp>
// whether the url is starts with http:// or https:// // Whether the url is starts with http:// or https://
extern bool srs_string_is_http(std::string url); extern bool srs_string_is_http(std::string url);
extern bool srs_string_is_rtmp(std::string url); extern bool srs_string_is_rtmp(std::string url);
// get local ip, fill to @param ips // Get local ip, fill to @param ips
extern std::vector<std::string>& srs_get_local_ips(); extern std::vector<std::string>& srs_get_local_ips();
// get local public ip, empty string if no public internet address found. // Get local public ip, empty string if no public internet address found.
extern std::string srs_get_public_internet_address(); extern std::string srs_get_public_internet_address();
// detect whether specified device is internet public address. // Detect whether specified device is internet public address.
extern bool srs_net_device_is_internet(std::string ifname); extern bool srs_net_device_is_internet(std::string ifname);
extern bool srs_net_device_is_internet(const sockaddr* addr); extern bool srs_net_device_is_internet(const sockaddr* addr);

View file

@ -40,6 +40,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// we add an empty macro for upp to show the smart tips. // we add an empty macro for upp to show the smart tips.
#define VOID #define VOID
// For errors.
#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err)
#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err)
// the asserts of gtest: // the asserts of gtest:
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2

View file

@ -5597,6 +5597,443 @@ VOID TEST(ProtocolRTMPTest, RTMPHandshakeBytes)
EXPECT_TRUE(bytes.s0s1s2 != NULL); EXPECT_TRUE(bytes.s0s1s2 != NULL);
} }
struct MockStage
{
http_parser parser;
const char* at;
size_t length;
MockStage(http_parser* from);
};
MockStage::MockStage(http_parser* from)
{
parser = *from;
at = NULL;
length = 0;
}
class MockParser
{
private:
http_parser_settings settings;
http_parser* parser;
size_t parsed;
public:
MockStage* message_begin;
MockStage* url;
MockStage* status;
MockStage* header_field;
MockStage* header_value;
MockStage* headers_complete;
MockStage* body;
MockStage* message_complete;
MockStage* chunk_header;
MockStage* chunk_complete;
public:
MockParser();
virtual ~MockParser();
public:
srs_error_t parse(string data);
private:
static int on_message_begin(http_parser* parser);
static int on_url(http_parser* parser, const char* at, size_t length);
static int on_status(http_parser* parser, const char* at, size_t length);
static int on_header_field(http_parser* parser, const char* at, size_t length);
static int on_header_value(http_parser* parser, const char* at, size_t length);
static int on_headers_complete(http_parser* parser);
static int on_body(http_parser* parser, const char* at, size_t length);
static int on_message_complete(http_parser* parser);
static int on_chunk_header(http_parser* parser);
static int on_chunk_complete(http_parser* parser);
};
MockParser::MockParser()
{
parser = new http_parser();
http_parser_init(parser, HTTP_REQUEST);
parser->data = (void*)this;
parsed = 0;
memset(&settings, 0, sizeof(settings));
settings.on_message_begin = on_message_begin;
settings.on_url = on_url;
settings.on_status = on_status;
settings.on_header_field = on_header_field;
settings.on_header_value = on_header_value;
settings.on_headers_complete = on_headers_complete;
settings.on_body = on_body;
settings.on_message_complete = on_message_complete;
settings.on_chunk_header = on_chunk_header;
settings.on_chunk_complete = on_chunk_complete;
message_begin = NULL;
url = NULL;
status = NULL;
header_field = NULL;
header_value = NULL;
headers_complete = NULL;
body = NULL;
message_complete = NULL;
chunk_header = NULL;
chunk_complete = NULL;
}
MockParser::~MockParser()
{
srs_freep(parser);
srs_freep(message_begin);
srs_freep(url);
srs_freep(status);
srs_freep(header_field);
srs_freep(header_value);
srs_freep(headers_complete);
srs_freep(body);
srs_freep(message_complete);
srs_freep(chunk_header);
srs_freep(chunk_complete);
}
int MockParser::on_message_begin(http_parser* parser)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->message_begin);
obj->message_begin = new MockStage(parser);
return 0;
}
int MockParser::on_url(http_parser* parser, const char* at, size_t length)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->url);
obj->url = new MockStage(parser);
obj->url->at = at;
obj->url->length = length;
return 0;
}
int MockParser::on_status(http_parser* parser, const char* at, size_t length)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->status);
obj->status = new MockStage(parser);
obj->status->at = at;
obj->status->length = length;
return 0;
}
int MockParser::on_header_field(http_parser* parser, const char* at, size_t length)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->header_field);
obj->header_field = new MockStage(parser);
obj->header_field->at = at;
obj->header_field->length = length;
return 0;
}
int MockParser::on_header_value(http_parser* parser, const char* at, size_t length)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->header_value);
obj->header_value = new MockStage(parser);
obj->header_value->at = at;
obj->header_value->length = length;
return 0;
}
int MockParser::on_headers_complete(http_parser* parser)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->headers_complete);
obj->headers_complete = new MockStage(parser);
return 0;
}
int MockParser::on_body(http_parser* parser, const char* at, size_t length)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->body);
obj->body = new MockStage(parser);
obj->body->at = at;
obj->body->length = length;
return 0;
}
int MockParser::on_message_complete(http_parser* parser)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->message_complete);
obj->message_complete = new MockStage(parser);
return 0;
}
int MockParser::on_chunk_header(http_parser* parser)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->chunk_header);
obj->chunk_header = new MockStage(parser);
return 0;
}
int MockParser::on_chunk_complete(http_parser* parser)
{
MockParser* obj = (MockParser*)parser->data;
srs_assert(obj);
srs_freep(obj->chunk_complete);
obj->chunk_complete = new MockStage(parser);
return 0;
}
srs_error_t MockParser::parse(string data)
{
srs_error_t err = srs_success;
const char* buf = (const char*)data.data();
size_t size = (size_t)data.length();
size_t nparsed = http_parser_execute(parser, &settings, buf, size);
parsed = nparsed;
if (nparsed != size) {
return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size);
}
return err;
}
VOID TEST(ProtocolHTTPTest, HTTPParser)
{
srs_error_t err;
if (true) {
MockParser parser;
// size = 70, nparsed = 70, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_TRUE(!parser.body);
EXPECT_TRUE(parser.headers_complete);
EXPECT_TRUE(!parser.message_complete);
}
if (true) {
MockParser parser;
// size = 75, nparsed = 75, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_TRUE(parser.body && 5 == parser.body->length);
EXPECT_TRUE(parser.headers_complete);
EXPECT_TRUE(parser.message_complete);
}
if (true) {
MockParser parser;
// size = 150, nparsed = 150, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
EXPECT_EQ(150, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(5, parser.parser->content_length);
// size = 79, nparsed = 5, nread = 1, content_length = -1, Header("Content-Length", 5)
HELPER_EXPECT_FAILED(parser.parse("elloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(5, parser.parsed);
EXPECT_EQ(1, parser.parser->nread);
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
}
if (true) {
MockParser parser;
// size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n"));
EXPECT_EQ(70, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(5, parser.parser->content_length);
// size = 80, nparsed = 70, nread = 0, content_length = 0, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("HelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld"));
EXPECT_EQ(80, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(0, parser.parser->content_length);
}
if (true) {
MockParser parser;
// size = 73, nparsed = 73, nread = 0, content_length = 2, Header("Content-Length", 5)
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHel"));
EXPECT_EQ(73, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
EXPECT_EQ(2, parser.parser->content_length);
}
if (true) {
MockParser parser;
// size = 82, nparsed = 75, nread = 1, content_length = -1, Header("Content-Length", 5)
HELPER_EXPECT_FAILED(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello World!"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(1, parser.parser->nread);
EXPECT_EQ(-1, (int64_t)parser.parser->content_length);
}
if (true) {
MockParser parser;
// size = 34, nparsed = 34, nread = 34
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHo"));
EXPECT_EQ(34, parser.parsed);
EXPECT_EQ(34, parser.parser->nread);
// size = 41, nparsed = 41, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("st: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(41, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 41, nparsed = 41, nread = 41
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: oss"));
EXPECT_EQ(41, parser.parsed);
EXPECT_EQ(41, parser.parser->nread);
// size = 34, nparsed = 34, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("rs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(34, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 48, nparsed = 48, nread = 48
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r"));
EXPECT_EQ(48, parser.parsed);
EXPECT_EQ(48, parser.parser->nread);
// size = 27, nparsed = 27, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(27, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 68, nparsed = 68, nread = 68
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n"));
EXPECT_EQ(68, parser.parsed);
EXPECT_EQ(68, parser.parser->nread);
// size = 7, nparsed = 7, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\r\nHello"));
EXPECT_EQ(7, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 69, nparsed = 69, nread = 69
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r"));
EXPECT_EQ(69, parser.parsed);
EXPECT_EQ(69, parser.parser->nread);
// size = 6, nparsed = 6, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("\nHello"));
EXPECT_EQ(6, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 75, nparsed = 75, nread = 0
HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello"));
EXPECT_EQ(75, parser.parsed);
EXPECT_EQ(0, parser.parser->nread);
}
if (true) {
MockParser parser;
// nparsed = 2, size = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 0, nparsed = 1, nread=2
HELPER_EXPECT_FAILED(parser.parse(""));
EXPECT_EQ(1, parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 2, nparsed = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 1, nparsed = 0, nread = 3
HELPER_EXPECT_FAILED(parser.parse("X"));
EXPECT_EQ(0, parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 2, nparsed = 2, nread = 2
HELPER_EXPECT_SUCCESS(parser.parse("GE"));
EXPECT_EQ(2, parser.parsed);
EXPECT_EQ(2, parser.parser->nread);
// size = 1, nparsed = 1, nread = 3
HELPER_EXPECT_SUCCESS(parser.parse("T"));
EXPECT_EQ(1, parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
if (true) {
MockParser parser;
// size = 3, nparsed = 3, nread = 3
HELPER_EXPECT_SUCCESS(parser.parse("GET"));
EXPECT_EQ(3, parser.parsed);
EXPECT_EQ(3, parser.parser->nread);
}
}
VOID TEST(ProtocolHTTPTest, ParseHTTPMessage) VOID TEST(ProtocolHTTPTest, ParseHTTPMessage)
{ {
if (true) { if (true) {
@ -5606,26 +6043,34 @@ VOID TEST(ProtocolHTTPTest, ParseHTTPMessage)
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false));
if (true) {
ISrsHttpMessage* req = NULL; ISrsHttpMessage* req = NULL;
SrsAutoFree(ISrsHttpMessage, req);
ASSERT_TRUE(0 == hp.parse_message(&bio, &req)); ASSERT_TRUE(0 == hp.parse_message(&bio, &req));
// We should read body, or next parsing message will fail. // We should read body, or next parsing message will fail.
// @see https://github.com/ossrs/srs/issues/1181 // @see https://github.com/ossrs/srs/issues/1181
EXPECT_FALSE(req->body_reader()->eof()); EXPECT_FALSE(req->body_reader()->eof());
} srs_freep(req);
if (true) { // Got new packet, notice that previous body still exists in bio.
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); bio.append("GET /gslb/v2/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
// Should fail because there is body which not read. // Should fail because there is body which not read.
// @see https://github.com/ossrs/srs/issues/1181 // @see https://github.com/ossrs/srs/issues/1181
ISrsHttpMessage* req = NULL;
SrsAutoFree(ISrsHttpMessage, req);
ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); ASSERT_FALSE(0 == hp.parse_message(&bio, &req));
srs_freep(req);
} }
if (true) {
MockBufferIO bio;
SrsHttpParser hp;
bio.append("GET");
EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false));
// Should fail if not completed message.
ISrsHttpMessage* req = NULL;
ASSERT_FALSE(0 == hp.parse_message(&bio, &req));
srs_freep(req);
} }
if (true) { if (true) {