mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 11:51:57 +00:00
Merge branch 3.0release into develop
This commit is contained in:
commit
7c002308e9
87 changed files with 7840 additions and 9677 deletions
|
@ -147,9 +147,9 @@ Please select according to languages:
|
|||
- [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] 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.
|
||||
- [ ] Enhanced forwarding with vhost and variables.
|
||||
- [ ] Support listen at IPv4 and IPv6, read [#460][bug #460].
|
||||
- [ ] Support source cleanup for idle streams.
|
||||
- [ ] 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].
|
||||
|
@ -164,6 +164,8 @@ Please select according to languages:
|
|||
|
||||
### 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-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
|
||||
|
|
|
@ -200,12 +200,16 @@ echo "" >> $SRS_AUTO_HEADERS_H
|
|||
#####################################################################################
|
||||
# generated the contributors from AUTHORS.txt
|
||||
#####################################################################################
|
||||
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
||||
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
||||
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
||||
done
|
||||
echo "\"" >> $SRS_AUTO_HEADERS_H
|
||||
if [[ -f ../AUTHORS.txt ]]; then
|
||||
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
||||
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
||||
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
||||
done
|
||||
echo "\"" >> $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"ossrs\"" >> $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# new empty line to auto headers file.
|
||||
echo "" >> $SRS_AUTO_HEADERS_H
|
||||
|
|
|
@ -428,15 +428,15 @@ SED="sed_utility" && echo "SED is $SED"
|
|||
#####################################################################################
|
||||
# check the os.
|
||||
#####################################################################################
|
||||
# user must specifies something what a fuck, we suppport following os:
|
||||
# centos/ubuntu/osx,
|
||||
# Only supports:
|
||||
# linux, centos/ubuntu as such,
|
||||
# cross build for embeded system, for example, mips or arm,
|
||||
# directly build on arm/mips, for example, pi or cubie,
|
||||
# export srs-librtmp
|
||||
# others is invalid.
|
||||
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
|
||||
echo "What a fuck, your OS `uname -s` is not supported."
|
||||
echo "Your OS `uname -s` is not supported."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -31,38 +31,29 @@
|
|||
|
||||
#include <srs_app_thread.hpp>
|
||||
|
||||
/**
|
||||
* the async call for http hooks,
|
||||
* for the http hooks will switch st-thread,
|
||||
* so we must use isolate thread to avoid the thread corrupt,
|
||||
* for example, when dvr call http hooks, the video receive thread got
|
||||
* a video and pass it to the dvr again.
|
||||
* futhurmore, the aync call never block the main worker thread.
|
||||
*/
|
||||
// The async call for http hooks, for the http hooks will switch st-thread,
|
||||
// so we must use isolate thread to avoid the thread corrupt,
|
||||
// for example, when dvr call http hooks, the video receive thread got
|
||||
// a video and pass it to the dvr again.
|
||||
// Futhurmore, the aync call never block the main worker thread.
|
||||
class ISrsAsyncCallTask
|
||||
{
|
||||
public:
|
||||
ISrsAsyncCallTask();
|
||||
virtual ~ISrsAsyncCallTask();
|
||||
public:
|
||||
/**
|
||||
* execute the task async.
|
||||
* this method is the actual execute method of task,
|
||||
* for example, to notify callback server.
|
||||
*/
|
||||
// Execute the task async.
|
||||
// This method is the actual execute method of task,
|
||||
// for example, to notify callback server.
|
||||
virtual srs_error_t call() = 0;
|
||||
/**
|
||||
* convert task to string to describe it.
|
||||
* used for logger.
|
||||
*/
|
||||
// Convert task to string to describe it.
|
||||
// It's used for logger.
|
||||
virtual std::string to_string() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* the async callback for dvr, callback and other async worker.
|
||||
* when worker call with the task, the worker will do it in isolate thread.
|
||||
* that is, the task is execute/call in async mode.
|
||||
*/
|
||||
// The async callback for dvr, callback and other async worker.
|
||||
// When worker call with the task, the worker will do it in isolate thread.
|
||||
// That is, the task is execute/call in async mode.
|
||||
class SrsAsyncCallWorker : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -79,7 +70,7 @@ public:
|
|||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
// interface ISrsReusableThreadHandler
|
||||
// Interface ISrsReusableThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
};
|
||||
|
|
|
@ -36,85 +36,69 @@ class SrsRtmpServer;
|
|||
class SrsKbpsLimit;
|
||||
class ISrsProtocolStatistic;
|
||||
|
||||
/**
|
||||
* bandwidth check/test sample.
|
||||
*/
|
||||
// The bandwidth check/test sample.
|
||||
class SrsBandwidthSample
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* the plan, how long to do the test, in ms,
|
||||
* if exceed the duration, abort the test.
|
||||
*/
|
||||
// The plan, how long to do the test, in ms,
|
||||
// if exceed the duration, abort the test.
|
||||
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;
|
||||
public:
|
||||
/**
|
||||
* the actual test duration, in ms.
|
||||
*/
|
||||
// The actual test duration, in ms.
|
||||
int actual_duration_ms;
|
||||
/**
|
||||
* the actual test bytes
|
||||
*/
|
||||
// The actual test bytes
|
||||
int bytes;
|
||||
/**
|
||||
* the actual test kbps
|
||||
*/
|
||||
// The actual test kbps
|
||||
int kbps;
|
||||
public:
|
||||
SrsBandwidthSample();
|
||||
virtual ~SrsBandwidthSample();
|
||||
public:
|
||||
/**
|
||||
* update the bytes and actual duration, then calc the kbps.
|
||||
* @param _bytes update the sample bytes.
|
||||
* @param _duration update the actual duration, in ms.
|
||||
*/
|
||||
// Update the bytes and actual duration, then calc the kbps.
|
||||
// @param _bytes update the sample bytes.
|
||||
// @param _duration update the actual duration, in ms.
|
||||
virtual void calc_kbps(int _bytes, int _duration);
|
||||
};
|
||||
|
||||
/**
|
||||
* bandwidth test agent which provides the interfaces for bandwidth check.
|
||||
* 1. if vhost disabled bandwidth check, ignore.
|
||||
* 2. otherwise, check the key, error if verify failed.
|
||||
* 3. check the interval limit, error if bandwidth in the interval window.
|
||||
* 4. check the bandwidth under the max kbps.
|
||||
* 5. send the bandwidth data to client.
|
||||
* bandwidth workflow:
|
||||
* +------------+ +----------+
|
||||
* | Client | | Server |
|
||||
* +-----+------+ +-----+----+
|
||||
* | |
|
||||
* | connect vhost------> | if vhost enable bandwidth,
|
||||
* | <-----result(success) | do bandwidth check.
|
||||
* | |
|
||||
* | <----call(start play) | onSrsBandCheckStartPlayBytes
|
||||
* | result(playing)-----> | onSrsBandCheckStartingPlayBytes
|
||||
* | <-------data(playing) | onSrsBandCheckStartingPlayBytes
|
||||
* | <-----call(stop play) | onSrsBandCheckStopPlayBytes
|
||||
* | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes
|
||||
* | |
|
||||
* | <-call(start publish) | onSrsBandCheckStartPublishBytes
|
||||
* | result(publishing)--> | onSrsBandCheckStartingPublishBytes
|
||||
* | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
|
||||
* | <--call(stop publish) | onSrsBandCheckStopPublishBytes
|
||||
* | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
|
||||
* | |
|
||||
* | <--------------report |
|
||||
* | final(2)------------> | finalClientPacket
|
||||
* | <END> |
|
||||
*
|
||||
* 1. when flash client, server never wait the stop publish response,
|
||||
* for the flash client queue is fullfill with other packets.
|
||||
* 2. when flash client, server never wait the final 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,
|
||||
* for the linux client donot know when to stop the publish.
|
||||
* when server got publishing and stop publish, stop publish.
|
||||
*/
|
||||
// The bandwidth test agent which provides the interfaces for bandwidth check.
|
||||
// 1. if vhost disabled bandwidth check, ignore.
|
||||
// 2. otherwise, check the key, error if verify failed.
|
||||
// 3. check the interval limit, error if bandwidth in the interval window.
|
||||
// 4. check the bandwidth under the max kbps.
|
||||
// 5. send the bandwidth data to client.
|
||||
// bandwidth workflow:
|
||||
// +------------+ +----------+
|
||||
// | Client | | Server |
|
||||
// +-----+------+ +-----+----+
|
||||
// | |
|
||||
// | connect vhost------> | if vhost enable bandwidth,
|
||||
// | <-----result(success) | do bandwidth check.
|
||||
// | |
|
||||
// | <----call(start play) | onSrsBandCheckStartPlayBytes
|
||||
// | result(playing)-----> | onSrsBandCheckStartingPlayBytes
|
||||
// | <-------data(playing) | onSrsBandCheckStartingPlayBytes
|
||||
// | <-----call(stop play) | onSrsBandCheckStopPlayBytes
|
||||
// | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes
|
||||
// | |
|
||||
// | <-call(start publish) | onSrsBandCheckStartPublishBytes
|
||||
// | result(publishing)--> | onSrsBandCheckStartingPublishBytes
|
||||
// | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
|
||||
// | <--call(stop publish) | onSrsBandCheckStopPublishBytes
|
||||
// | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
|
||||
// | |
|
||||
// | <--------------report |
|
||||
// | final(2)------------> | finalClientPacket
|
||||
// | <END> |
|
||||
//
|
||||
// 1. when flash client, server never wait the stop publish response,
|
||||
// for the flash client queue is fullfill with other packets.
|
||||
// 2. when flash client, server never wait the final 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,
|
||||
// for the linux client donot know when to stop the publish.
|
||||
// when server got publishing and stop publish, stop publish.
|
||||
class SrsBandwidth
|
||||
{
|
||||
private:
|
||||
|
@ -124,81 +108,61 @@ public:
|
|||
SrsBandwidth();
|
||||
virtual ~SrsBandwidth();
|
||||
public:
|
||||
/**
|
||||
* do the bandwidth check.
|
||||
* @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 req, client request object, specifies the request info from client.
|
||||
* @param local_ip, the ip of server which client connected at
|
||||
*/
|
||||
// Do the bandwidth check.
|
||||
// @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 req, client request object, specifies the request info from client.
|
||||
// @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);
|
||||
private:
|
||||
/**
|
||||
* used to process band width check from client.
|
||||
* @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
|
||||
*/
|
||||
// Used to process band width check from client.
|
||||
// @param limit, the bandwidth limit object, to slowdown if exceed the kbps.
|
||||
virtual srs_error_t do_bandwidth_check(SrsKbpsLimit* limit);
|
||||
// play check/test, downloading bandwidth kbps.
|
||||
private:
|
||||
/**
|
||||
* start play/download bandwidth check/test,
|
||||
* send start-play command to client, client must response starting-play
|
||||
* to start the test.
|
||||
*/
|
||||
// Start play/download bandwidth check/test,
|
||||
// send start-play command to client, client must response starting-play
|
||||
// to start the test.
|
||||
virtual srs_error_t play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
/**
|
||||
* do play/download bandwidth check/test,
|
||||
* server send call messages to client in specified time,
|
||||
* calc the time and bytes sent, then we got the kbps.
|
||||
*/
|
||||
// Do play/download bandwidth check/test,
|
||||
// server send call messages to client in specified time,
|
||||
// calc the time and bytes sent, then we got the kbps.
|
||||
virtual srs_error_t play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
/**
|
||||
* stop play/download bandwidth check/test,
|
||||
* send stop-play command to client, client must response stopped-play
|
||||
* to stop the test.
|
||||
*/
|
||||
// stop play/download bandwidth check/test,
|
||||
// send stop-play command to client, client must response stopped-play
|
||||
// to stop the test.
|
||||
virtual srs_error_t play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
// publish check/test, publishing bandwidth kbps.
|
||||
private:
|
||||
/**
|
||||
* start publish/upload bandwidth check/test,
|
||||
* send start-publish command to client, client must response starting-publish
|
||||
* to start the test.
|
||||
*/
|
||||
// Start publish/upload bandwidth check/test,
|
||||
// send start-publish command to client, client must response starting-publish
|
||||
// to start the test.
|
||||
virtual srs_error_t publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
/**
|
||||
* do publish/upload bandwidth check/test,
|
||||
* client send call messages to client in specified time,
|
||||
* 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.
|
||||
* then enter the publish-stop stage with client.
|
||||
* @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
|
||||
* response message in the publish-stop stage.
|
||||
*/
|
||||
// Do publish/upload bandwidth check/test,
|
||||
// client send call messages to client in specified time,
|
||||
// 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.
|
||||
// then enter the publish-stop stage with client.
|
||||
// @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
|
||||
// response message in the publish-stop stage.
|
||||
virtual srs_error_t publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
/**
|
||||
* stop publish/upload bandwidth check/test,
|
||||
* send stop-publish command to client,
|
||||
* for linux client, always expect a stopped-publish response from client,
|
||||
* for flash client, the sent queue is fullfill with publishing call messages,
|
||||
* so server never expect the stopped-publish from it.
|
||||
*/
|
||||
// Stop publish/upload bandwidth check/test,
|
||||
// send stop-publish command to client,
|
||||
// for linux client, always expect a stopped-publish response from client,
|
||||
// for flash client, the sent queue is fullfill with publishing call messages,
|
||||
// so server never expect the stopped-publish from it.
|
||||
virtual srs_error_t publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit);
|
||||
private:
|
||||
/**
|
||||
* report and final packet
|
||||
* 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 flash client, the sent queue is fullfill with publishing call messages,
|
||||
* so server never expect the final packet from it.
|
||||
*/
|
||||
// Report and final packet
|
||||
// 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 flash client, the sent queue is fullfill with publishing call messages,
|
||||
// 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* the kbps limit, if exceed the kbps, slow down.
|
||||
*/
|
||||
// The kbps limit, if exceed the kbps, slow down.
|
||||
class SrsKbpsLimit
|
||||
{
|
||||
private:
|
||||
|
@ -208,17 +172,11 @@ public:
|
|||
SrsKbpsLimit(SrsKbps* kbps, int limit_kbps);
|
||||
virtual ~SrsKbpsLimit();
|
||||
public:
|
||||
/**
|
||||
* get the system limit kbps.
|
||||
*/
|
||||
// Get the system limit kbps.
|
||||
virtual int limit_kbps();
|
||||
/**
|
||||
* limit the recv bandwidth.
|
||||
*/
|
||||
// Limit the recv bandwidth.
|
||||
virtual void recv_limit();
|
||||
/**
|
||||
* limit the send bandwidth.
|
||||
*/
|
||||
// Limit the send bandwidth.
|
||||
virtual void send_limit();
|
||||
};
|
||||
|
||||
|
|
|
@ -46,9 +46,7 @@ class SrsSimpleRtmpClient;
|
|||
#include <srs_app_http_conn.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
|
||||
, virtual public IConnectionManager, virtual public ISrsHttpHandler
|
||||
{
|
||||
|
@ -62,20 +60,18 @@ public:
|
|||
virtual ~SrsAppCasterFlv();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
// ISrsTcpHandler
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
// IConnectionManager
|
||||
// Interface IConnectionManager
|
||||
public:
|
||||
virtual void remove(ISrsConnection* c);
|
||||
// ISrsHttpHandler
|
||||
// Interface ISrsHttpHandler
|
||||
public:
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -93,10 +89,7 @@ private:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -105,9 +98,7 @@ public:
|
|||
SrsHttpFileReader(ISrsHttpResponseReader* h);
|
||||
virtual ~SrsHttpFileReader();
|
||||
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 void close();
|
||||
public:
|
||||
|
|
|
@ -3433,25 +3433,16 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv)
|
|||
void SrsConfig::print_help(char** argv)
|
||||
{
|
||||
printf(
|
||||
RTMP_SIG_SRS_SERVER " " RTMP_SIG_SRS_COPYRIGHT "\n"
|
||||
"License: " RTMP_SIG_SRS_LICENSE "\n"
|
||||
"Primary: " RTMP_SIG_SRS_PRIMARY "\n"
|
||||
"Authors: " RTMP_SIG_SRS_AUTHROS "\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"
|
||||
RTMP_SIG_SRS_SERVER ", " RTMP_SIG_SRS_URL ", licensed under " RTMP_SIG_SRS_LICENSE
|
||||
", built at " SRS_AUTO_BUILD_DATE ", configured by " SRS_AUTO_USER_CONFIGURE
|
||||
", which means " SRS_AUTO_CONFIGURE "\n""\n"
|
||||
"Usage: %s <-h?vVgG>|<[-t] -c filename>\n"
|
||||
"Options:\n"
|
||||
" -?, -h : show this help and exit(0)\n"
|
||||
" -v, -V : show version and exit(0)\n"
|
||||
" -g, -G : show server signature and exit(0)\n"
|
||||
" -t : test configuration file, exit(error_code).\n"
|
||||
" -c filename : use configuration file for SRS\n"
|
||||
"\n"
|
||||
RTMP_SIG_SRS_WEB "\n"
|
||||
RTMP_SIG_SRS_URL "\n"
|
||||
"Email: " RTMP_SIG_SRS_EMAIL "\n"
|
||||
"\n"
|
||||
" -?, -h : Show this help and exit 0.\n"
|
||||
" -v, -V : Show version and exit 0.\n"
|
||||
" -g, -G : Show server signature and exit 0.\n"
|
||||
" -t : Test configuration file, exit with error code(0 for success).\n"
|
||||
" -c filename : Use config file to start server.\n"
|
||||
"For example:\n"
|
||||
" %s -v\n"
|
||||
" %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -36,95 +36,67 @@
|
|||
|
||||
class SrsWallClock;
|
||||
|
||||
/**
|
||||
* the basic connection of SRS,
|
||||
* all connections accept from listener must extends from this base class,
|
||||
* server will add the connection to manager, and delete it when remove.
|
||||
*/
|
||||
// The basic connection of SRS,
|
||||
// all connections accept from listener must extends from this base class,
|
||||
// server will add the connection to manager, and delete it when remove.
|
||||
class SrsConnection : virtual public ISrsConnection, virtual public ISrsCoroutineHandler
|
||||
, virtual public ISrsKbpsDelta, virtual public ISrsReloadHandler
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* each connection start a green thread,
|
||||
* when thread stop, the connection will be delete by server.
|
||||
*/
|
||||
// Each connection start a green thread,
|
||||
// when thread stop, the connection will be delete by server.
|
||||
SrsCoroutine* trd;
|
||||
/**
|
||||
* the manager object to manage the connection.
|
||||
*/
|
||||
// The manager object to manage the connection.
|
||||
IConnectionManager* manager;
|
||||
/**
|
||||
* the underlayer st fd handler.
|
||||
*/
|
||||
// The underlayer st fd handler.
|
||||
srs_netfd_t stfd;
|
||||
/**
|
||||
* the ip of client.
|
||||
*/
|
||||
// The ip of client.
|
||||
std::string ip;
|
||||
/**
|
||||
* the underlayer socket.
|
||||
*/
|
||||
// The underlayer socket.
|
||||
SrsStSocket* skt;
|
||||
/**
|
||||
* connection total kbps.
|
||||
* not only the rtmp or http connection, all type of connection are
|
||||
* need to statistic the kbps of io.
|
||||
* the SrsStatistic will use it indirectly to statistic the bytes delta of current connection.
|
||||
*/
|
||||
// The connection total kbps.
|
||||
// not only the rtmp or http connection, all type of connection are
|
||||
// need to statistic the kbps of io.
|
||||
// The SrsStatistic will use it indirectly to statistic the bytes delta of current connection.
|
||||
SrsKbps* kbps;
|
||||
SrsWallClock* clk;
|
||||
/**
|
||||
* the create time in milliseconds.
|
||||
* for current connection to log self create time and calculate the living time.
|
||||
*/
|
||||
// The create time in milliseconds.
|
||||
// for current connection to log self create time and calculate the living time.
|
||||
int64_t create_time;
|
||||
public:
|
||||
SrsConnection(IConnectionManager* cm, srs_netfd_t c, std::string cip);
|
||||
virtual ~SrsConnection();
|
||||
// interface ISrsKbpsDelta
|
||||
// Interface ISrsKbpsDelta
|
||||
public:
|
||||
virtual void remark(int64_t* in, int64_t* out);
|
||||
public:
|
||||
/**
|
||||
* to dipose the connection.
|
||||
*/
|
||||
// To dipose the connection.
|
||||
virtual void dispose();
|
||||
/**
|
||||
* start the client green thread.
|
||||
* when server get a client from listener,
|
||||
* 1. server will create an concrete connection(for instance, RTMP connection),
|
||||
* 2. then add connection to its connection manager,
|
||||
* 3. start the client thread by invoke this start()
|
||||
* when client cycle thread stop, invoke the on_thread_stop(), which will use server
|
||||
* to remove the client by server->remove(this).
|
||||
*/
|
||||
// Start the client green thread.
|
||||
// when server get a client from listener,
|
||||
// 1. server will create an concrete connection(for instance, RTMP connection),
|
||||
// 2. then add connection to its connection manager,
|
||||
// 3. start the client thread by invoke this start()
|
||||
// when client cycle thread stop, invoke the on_thread_stop(), which will use server
|
||||
// To remove the client by server->remove(this).
|
||||
virtual srs_error_t start();
|
||||
// Set socket option TCP_NODELAY.
|
||||
virtual srs_error_t set_tcp_nodelay(bool v);
|
||||
// Set socket option SO_SNDBUF in srs_utime_t.
|
||||
virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v);
|
||||
// interface ISrsOneCycleThreadHandler
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
/**
|
||||
* the thread cycle function,
|
||||
* when serve connection completed, terminate the loop which will terminate the thread,
|
||||
* thread will invoke the on_thread_stop() when it terminated.
|
||||
*/
|
||||
// The thread cycle function,
|
||||
// when serve connection completed, terminate the loop which will terminate the thread,
|
||||
// thread will invoke the on_thread_stop() when it terminated.
|
||||
virtual srs_error_t cycle();
|
||||
public:
|
||||
/**
|
||||
* get the srs id which identify the client.
|
||||
*/
|
||||
// Get the srs id which identify the client.
|
||||
virtual int srs_id();
|
||||
/**
|
||||
* set connection to expired.
|
||||
*/
|
||||
// Set connection to expired.
|
||||
virtual void expire();
|
||||
protected:
|
||||
/**
|
||||
* for concrete connection to do the cycle.
|
||||
*/
|
||||
// For concrete connection to do the cycle.
|
||||
virtual srs_error_t do_cycle() = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class SrsJsonAny;
|
|||
class SrsRequest;
|
||||
class SrsSource;
|
||||
|
||||
// For origin cluster.
|
||||
class SrsCoWorkers
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -40,9 +40,7 @@ class SrsMpdWriter;
|
|||
class SrsMp4M2tsInitEncoder;
|
||||
class SrsMp4M2tsSegmentEncoder;
|
||||
|
||||
/**
|
||||
* The init mp4 for FMP4.
|
||||
*/
|
||||
// The init mp4 for FMP4.
|
||||
class SrsInitMp4 : public SrsFragment
|
||||
{
|
||||
private:
|
||||
|
@ -56,9 +54,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -76,9 +72,7 @@ public:
|
|||
virtual srs_error_t reap(uint64_t& dts);
|
||||
};
|
||||
|
||||
/**
|
||||
* The writer to write MPD for DASH.
|
||||
*/
|
||||
// The writer to write MPD for DASH.
|
||||
class SrsMpdWriter
|
||||
{
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* The controller for DASH, control the MPD and FMP4 generating system.
|
||||
*/
|
||||
// The controller for DASH, control the MPD and FMP4 generating system.
|
||||
class SrsDashController
|
||||
{
|
||||
private:
|
||||
|
@ -149,9 +141,7 @@ private:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -49,9 +49,7 @@ class SrsFormat;
|
|||
#include <srs_app_reload.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
|
||||
{
|
||||
protected:
|
||||
|
@ -105,14 +103,12 @@ private:
|
|||
virtual std::string generate_path();
|
||||
// When update the duration of segment by rtmp msg.
|
||||
virtual srs_error_t on_update_duration(SrsSharedPtrMessage* msg);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -140,9 +136,7 @@ protected:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -161,9 +155,7 @@ protected:
|
|||
virtual srs_error_t close_encoder();
|
||||
};
|
||||
|
||||
/**
|
||||
* the dvr async call.
|
||||
*/
|
||||
// the dvr async call.
|
||||
class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
|
@ -178,9 +170,7 @@ public:
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
@ -208,9 +198,7 @@ public:
|
|||
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
|
||||
{
|
||||
public:
|
||||
|
@ -221,9 +209,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -241,14 +227,12 @@ public:
|
|||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
private:
|
||||
virtual srs_error_t update_duration(SrsSharedPtrMessage* msg);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -264,38 +248,26 @@ public:
|
|||
SrsDvr();
|
||||
virtual ~SrsDvr();
|
||||
public:
|
||||
/**
|
||||
* initialize dvr, create dvr plan.
|
||||
* when system initialize(encoder publish at first time, or reload),
|
||||
* initialize the dvr will reinitialize the plan, the whole dvr framework.
|
||||
*/
|
||||
// initialize dvr, create dvr plan.
|
||||
// when system initialize(encoder publish at first time, or reload),
|
||||
// initialize the dvr will reinitialize the plan, the whole dvr framework.
|
||||
virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r);
|
||||
/**
|
||||
* publish stream event,
|
||||
* when encoder start to publish RTMP stream.
|
||||
* @param fetch_sequence_header whether fetch sequence from source.
|
||||
*/
|
||||
// publish stream event,
|
||||
// when encoder start to publish RTMP stream.
|
||||
// @param fetch_sequence_header whether fetch sequence from source.
|
||||
virtual srs_error_t on_publish();
|
||||
/**
|
||||
* the unpublish event.,
|
||||
* when encoder stop(unpublish) to publish RTMP stream.
|
||||
*/
|
||||
// the unpublish event.,
|
||||
// when encoder stop(unpublish) to publish RTMP stream.
|
||||
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);
|
||||
/**
|
||||
* mux the audio packets to dvr.
|
||||
* @param shared_audio, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// mux the audio packets to dvr.
|
||||
// @param shared_audio, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* foramt);
|
||||
/**
|
||||
* mux the video packets to dvr.
|
||||
* @param shared_video, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// mux the video packets to dvr.
|
||||
// @param shared_video, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_dvr_apply(std::string vhost);
|
||||
};
|
||||
|
|
|
@ -47,34 +47,28 @@ class SrsTcpClient;
|
|||
class SrsSimpleRtmpClient;
|
||||
class SrsPacket;
|
||||
|
||||
/**
|
||||
* the state of edge, auto machine
|
||||
*/
|
||||
// The state of edge, auto machine
|
||||
enum SrsEdgeState
|
||||
{
|
||||
SrsEdgeStateInit = 0,
|
||||
|
||||
// for play edge
|
||||
// For play edge
|
||||
SrsEdgeStatePlay = 100,
|
||||
// play stream from origin, ingest stream
|
||||
SrsEdgeStateIngestConnected = 101,
|
||||
|
||||
// for publish edge
|
||||
// For publish edge
|
||||
SrsEdgeStatePublish = 200,
|
||||
};
|
||||
|
||||
/**
|
||||
* the state of edge from user, manual machine
|
||||
*/
|
||||
// The state of edge from user, manual machine
|
||||
enum SrsEdgeUserState
|
||||
{
|
||||
SrsEdgeUserStateInit = 0,
|
||||
SrsEdgeUserStateReloading = 100,
|
||||
};
|
||||
|
||||
/**
|
||||
* the upstream of edge, can be rtmp or http.
|
||||
*/
|
||||
// The upstream of edge, can be rtmp or http.
|
||||
class SrsEdgeUpstream
|
||||
{
|
||||
public:
|
||||
|
@ -93,7 +87,7 @@ public:
|
|||
class SrsEdgeRtmpUpstream : public SrsEdgeUpstream
|
||||
{
|
||||
private:
|
||||
// for RTMP 302, if not empty,
|
||||
// For RTMP 302, if not empty,
|
||||
// use this <ip[:port]> as upstream.
|
||||
std::string redirect;
|
||||
SrsSimpleRtmpClient* sdk;
|
||||
|
@ -111,9 +105,7 @@ public:
|
|||
virtual void kbps_sample(const char* label, int64_t age);
|
||||
};
|
||||
|
||||
/**
|
||||
* edge used to ingest stream from origin.
|
||||
*/
|
||||
// The edge used to ingest stream from origin.
|
||||
class SrsEdgeIngester : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -123,7 +115,7 @@ private:
|
|||
SrsCoroutine* trd;
|
||||
SrsLbRoundRobin* lb;
|
||||
SrsEdgeUpstream* upstream;
|
||||
// for RTMP 302 redirect.
|
||||
// For RTMP 302 redirect.
|
||||
std::string redirect;
|
||||
public:
|
||||
SrsEdgeIngester();
|
||||
|
@ -133,7 +125,7 @@ public:
|
|||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
virtual std::string get_curr_origin();
|
||||
// interface ISrsReusableThread2Handler
|
||||
// Interface ISrsReusableThread2Handler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
@ -143,9 +135,7 @@ private:
|
|||
virtual srs_error_t process_publish_message(SrsCommonMessage* msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* edge used to forward stream to origin.
|
||||
*/
|
||||
// The edge used to forward stream to origin.
|
||||
class SrsEdgeForwarder : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -155,16 +145,12 @@ private:
|
|||
SrsCoroutine* trd;
|
||||
SrsSimpleRtmpClient* sdk;
|
||||
SrsLbRoundRobin* lb;
|
||||
/**
|
||||
* we must ensure one thread one fd principle,
|
||||
* that is, a fd must be write/read by the one 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.
|
||||
*/
|
||||
// we must ensure one thread one fd principle,
|
||||
// that is, a fd must be write/read by the one 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.
|
||||
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;
|
||||
public:
|
||||
SrsEdgeForwarder();
|
||||
|
@ -175,7 +161,7 @@ public:
|
|||
virtual srs_error_t initialize(SrsSource* s, SrsPublishEdge* e, SrsRequest* r);
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
// interface ISrsReusableThread2Handler
|
||||
// Interface ISrsReusableThread2Handler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
@ -184,10 +170,7 @@ public:
|
|||
virtual srs_error_t proxy(SrsCommonMessage* msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* play edge control service.
|
||||
* downloading edge speed-up.
|
||||
*/
|
||||
// The play edge control service.
|
||||
class SrsPlayEdge
|
||||
{
|
||||
private:
|
||||
|
@ -197,32 +180,21 @@ public:
|
|||
SrsPlayEdge();
|
||||
virtual ~SrsPlayEdge();
|
||||
public:
|
||||
/**
|
||||
* always use the req of source,
|
||||
* for we assume all client to edge is invalid,
|
||||
* if auth open, edge must valid it from origin, then service it.
|
||||
*/
|
||||
// Always use the req of source,
|
||||
// For we assume all client to edge is invalid,
|
||||
// if auth open, edge must valid it from origin, then service it.
|
||||
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();
|
||||
/**
|
||||
* when all client stopped play, disconnect to origin.
|
||||
*/
|
||||
// When all client stopped play, disconnect to origin.
|
||||
virtual void on_all_client_stop();
|
||||
virtual std::string get_curr_origin();
|
||||
public:
|
||||
/**
|
||||
* when ingester start to play stream.
|
||||
*/
|
||||
// When ingester start to play stream.
|
||||
virtual srs_error_t on_ingest_play();
|
||||
};
|
||||
|
||||
/**
|
||||
* publish edge control service.
|
||||
* uploading edge speed-up.
|
||||
*/
|
||||
// The publish edge control service.
|
||||
class SrsPublishEdge
|
||||
{
|
||||
private:
|
||||
|
@ -236,17 +208,11 @@ public:
|
|||
public:
|
||||
virtual srs_error_t initialize(SrsSource* source, SrsRequest* req);
|
||||
virtual bool can_publish();
|
||||
/**
|
||||
* when client publish stream on edge.
|
||||
*/
|
||||
// When client publish stream on edge.
|
||||
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);
|
||||
/**
|
||||
* proxy unpublish stream to edge.
|
||||
*/
|
||||
// Proxy unpublish stream to edge.
|
||||
virtual void on_proxy_unpublish();
|
||||
};
|
||||
|
||||
|
|
|
@ -36,10 +36,8 @@ class SrsRequest;
|
|||
class SrsPithyPrint;
|
||||
class SrsFFMPEG;
|
||||
|
||||
/**
|
||||
* the encoder for a stream,
|
||||
* may use multiple ffmpegs to transcode the specified stream.
|
||||
*/
|
||||
// The encoder for a stream, may use multiple
|
||||
// ffmpegs to transcode the specified stream.
|
||||
class SrsEncoder : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -54,7 +52,7 @@ public:
|
|||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest* req);
|
||||
virtual void on_unpublish();
|
||||
// interface ISrsReusableThreadHandler.
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
|
|
@ -35,10 +35,7 @@ class SrsConfDirective;
|
|||
class SrsPithyPrint;
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -43,14 +43,11 @@ class SrsOriginHub;
|
|||
class SrsKbps;
|
||||
class SrsSimpleRtmpClient;
|
||||
|
||||
/**
|
||||
* forward the stream to other servers.
|
||||
*/
|
||||
// TODO: FIXME: refine the error log, comments it.
|
||||
// Forward the stream to other servers.
|
||||
class SrsForwarder : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
// the ep to forward, server[:port].
|
||||
// The ep to forward, server[:port].
|
||||
std::string ep_forward;
|
||||
SrsRequest* req;
|
||||
private:
|
||||
|
@ -60,10 +57,8 @@ private:
|
|||
SrsSimpleRtmpClient* sdk;
|
||||
SrsRtmpJitter* jitter;
|
||||
SrsMessageQueue* queue;
|
||||
/**
|
||||
* cache the sequence header for retry when slave is failed.
|
||||
* @see https://github.com/ossrs/srs/issues/150
|
||||
*/
|
||||
// Cache the sequence header for retry when slave is failed.
|
||||
// @see https://github.com/ossrs/srs/issues/150
|
||||
SrsSharedPtrMessage* sh_audio;
|
||||
SrsSharedPtrMessage* sh_video;
|
||||
public:
|
||||
|
@ -75,22 +70,16 @@ public:
|
|||
public:
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
/**
|
||||
* forward the audio packet.
|
||||
* @param shared_metadata, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// Forward the audio packet.
|
||||
// @param shared_metadata, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata);
|
||||
/**
|
||||
* forward the audio packet.
|
||||
* @param shared_audio, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// Forward the audio packet.
|
||||
// @param shared_audio, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio);
|
||||
/**
|
||||
* forward the video packet.
|
||||
* @param shared_video, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// Forward the video packet.
|
||||
// @param shared_video, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video);
|
||||
// interface ISrsReusableThread2Handler.
|
||||
// Interface ISrsReusableThread2Handler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
|
|
@ -29,10 +29,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* Represent a fragment, such as HLS segment, DVR segment or DASH segment.
|
||||
* It's a media file, for example FLV or MP4, with duration.
|
||||
*/
|
||||
// Represent a fragment, such as HLS segment, DVR segment or DASH segment.
|
||||
// It's a media file, for example FLV or MP4, with duration.
|
||||
class SrsFragment
|
||||
{
|
||||
private:
|
||||
|
@ -75,9 +73,7 @@ public:
|
|||
virtual srs_error_t rename();
|
||||
};
|
||||
|
||||
/**
|
||||
* The fragment window manage a series of fragment.
|
||||
*/
|
||||
// The fragment window manage a series of fragment.
|
||||
class SrsFragmentWindow
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -35,6 +35,7 @@ class SrsSharedPtrMessage;
|
|||
class SrsHdsFragment;
|
||||
class SrsSource;
|
||||
|
||||
// Mux RTMP to Adobe HDS streaming.
|
||||
class SrsHds
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -50,12 +50,10 @@ class SrsTsMessageCache;
|
|||
class SrsHlsSegment;
|
||||
class SrsTsContext;
|
||||
|
||||
/**
|
||||
* the wrapper of m3u8 segment from specification:
|
||||
*
|
||||
* 3.3.2. EXTINF
|
||||
* The EXTINF tag specifies the duration of a media segment.
|
||||
*/
|
||||
// The wrapper of m3u8 segment from specification:
|
||||
//
|
||||
// 3.3.2. EXTINF
|
||||
// The EXTINF tag specifies the duration of a media segment.
|
||||
class SrsHlsSegment : public SrsFragment
|
||||
{
|
||||
public:
|
||||
|
@ -63,7 +61,7 @@ public:
|
|||
int sequence_no;
|
||||
// ts uri in m3u8.
|
||||
std::string uri;
|
||||
// the underlayer file writer.
|
||||
// The underlayer file writer.
|
||||
SrsFileWriter* writer;
|
||||
// The TS context writer to write TS to file.
|
||||
SrsTsContextWriter* tscw;
|
||||
|
@ -78,9 +76,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -101,9 +97,7 @@ public:
|
|||
virtual std::string to_string();
|
||||
};
|
||||
|
||||
/**
|
||||
* the hls async call: on_hls_notify
|
||||
*/
|
||||
// The hls async call: on_hls_notify
|
||||
class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
|
@ -118,14 +112,12 @@ public:
|
|||
virtual std::string to_string();
|
||||
};
|
||||
|
||||
/**
|
||||
* muxer the HLS stream(m3u8 and ts files).
|
||||
* generally, the m3u8 muxer only provides methods to open/close segments,
|
||||
* to flush video/audio, without any mechenisms.
|
||||
*
|
||||
* that is, user must use HlsCache, which will control the methods of muxer,
|
||||
* and provides HLS mechenisms.
|
||||
*/
|
||||
// Mux the HLS stream(m3u8 and ts files).
|
||||
// Generally, the m3u8 muxer only provides methods to open/close segments,
|
||||
// to flush video/audio, without any mechenisms.
|
||||
//
|
||||
// That is, user must use HlsCache, which will control the methods of muxer,
|
||||
// and provides HLS mechenisms.
|
||||
class SrsHlsMuxer
|
||||
{
|
||||
private:
|
||||
|
@ -143,26 +135,26 @@ private:
|
|||
srs_utime_t hls_window;
|
||||
SrsAsyncCallWorker* async;
|
||||
private:
|
||||
// whether use floor algorithm for timestamp.
|
||||
// Whether use floor algorithm for timestamp.
|
||||
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.
|
||||
int deviation_ts;
|
||||
// the previous reap floor timestamp,
|
||||
// The previous reap floor timestamp,
|
||||
// used to detect the dup or jmp or ts.
|
||||
int64_t accept_floor_ts;
|
||||
int64_t previous_floor_ts;
|
||||
private:
|
||||
// encrypted or not
|
||||
// Whether encrypted or not
|
||||
bool hls_keys;
|
||||
int hls_fragments_per_key;
|
||||
// key file name
|
||||
// The key file name
|
||||
std::string hls_key_file;
|
||||
// key file path
|
||||
// The key file path
|
||||
std::string hls_key_file_path;
|
||||
// key file url
|
||||
// The key file url
|
||||
std::string hls_key_url;
|
||||
// key and iv.
|
||||
// The key and iv.
|
||||
unsigned char key[16];
|
||||
unsigned char iv[16];
|
||||
SrsFileWriter *writer;
|
||||
|
@ -176,10 +168,8 @@ private:
|
|||
SrsFragmentWindow* segments;
|
||||
// The current writing segment.
|
||||
SrsHlsSegment* current;
|
||||
/**
|
||||
* the ts context, to keep cc continous between ts.
|
||||
* @see https://github.com/ossrs/srs/issues/375
|
||||
*/
|
||||
// The ts context, to keep cc continous between ts.
|
||||
// @see https://github.com/ossrs/srs/issues/375
|
||||
SrsTsContext* context;
|
||||
public:
|
||||
SrsHlsMuxer();
|
||||
|
@ -192,48 +182,32 @@ public:
|
|||
virtual srs_utime_t duration();
|
||||
virtual int deviation();
|
||||
public:
|
||||
/**
|
||||
* initialize the hls muxer.
|
||||
*/
|
||||
// Initialize the hls muxer.
|
||||
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,
|
||||
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,
|
||||
bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key,
|
||||
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 on_sequence_header();
|
||||
/**
|
||||
* whether segment overflow,
|
||||
* that is whether the current segment duration>=(the segment in config)
|
||||
*/
|
||||
// Whether segment overflow,
|
||||
// that is whether the current segment duration>=(the segment in config)
|
||||
virtual bool is_segment_overflow();
|
||||
/**
|
||||
* whether wait keyframe to reap the ts.
|
||||
*/
|
||||
// Whether wait keyframe to reap the ts.
|
||||
virtual bool wait_keyframe();
|
||||
/**
|
||||
* whether segment absolutely overflow, for pure audio to reap segment,
|
||||
* that is whether the current segment duration>=2*(the segment in config)
|
||||
* @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
|
||||
*/
|
||||
// Whether segment absolutely overflow, for pure audio to reap segment,
|
||||
// that is whether the current segment duration>=2*(the segment in config)
|
||||
// @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184
|
||||
virtual bool is_segment_absolutely_overflow();
|
||||
public:
|
||||
/**
|
||||
* whether current hls muxer is pure audio mode.
|
||||
*/
|
||||
// Whether current hls muxer is pure audio mode.
|
||||
virtual bool pure_audio();
|
||||
virtual srs_error_t flush_audio(SrsTsMessageCache* cache);
|
||||
virtual srs_error_t flush_video(SrsTsMessageCache* cache);
|
||||
/**
|
||||
* Close segment(ts).
|
||||
*/
|
||||
// Close segment(ts).
|
||||
virtual srs_error_t segment_close();
|
||||
private:
|
||||
virtual srs_error_t do_segment_close();
|
||||
|
@ -242,23 +216,21 @@ private:
|
|||
virtual srs_error_t _refresh_m3u8(std::string m3u8_file);
|
||||
};
|
||||
|
||||
/**
|
||||
* hls stream cache,
|
||||
* use to cache hls stream and flush to hls muxer.
|
||||
*
|
||||
* when write stream to ts file:
|
||||
* video frame will directly flush to M3u8Muxer,
|
||||
* audio frame need to cache, because it's small and flv tbn problem.
|
||||
*
|
||||
* whatever, the Hls cache used to cache video/audio,
|
||||
* and flush video/audio to m3u8 muxer if needed.
|
||||
*
|
||||
* about the flv tbn problem:
|
||||
* flv tbn is 1/1000, ts tbn is 1/90000,
|
||||
* when timestamp convert to flv tbn, it will loose precise,
|
||||
* so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter,
|
||||
* we use a aac jitter to correct the audio pts.
|
||||
*/
|
||||
// The hls stream cache,
|
||||
// use to cache hls stream and flush to hls muxer.
|
||||
//
|
||||
// When write stream to ts file:
|
||||
// video frame will directly flush to M3u8Muxer,
|
||||
// audio frame need to cache, because it's small and flv tbn problem.
|
||||
//
|
||||
// Whatever, the Hls cache used to cache video/audio,
|
||||
// and flush video/audio to m3u8 muxer if needed.
|
||||
//
|
||||
// About the flv tbn problem:
|
||||
// flv tbn is 1/1000, ts tbn is 1/90000,
|
||||
// when timestamp convert to flv tbn, it will loose precise,
|
||||
// so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter,
|
||||
// we use a aac jitter to correct the audio pts.
|
||||
class SrsHlsController
|
||||
{
|
||||
private:
|
||||
|
@ -278,40 +250,28 @@ public:
|
|||
virtual srs_utime_t duration();
|
||||
virtual int deviation();
|
||||
public:
|
||||
/**
|
||||
* when publish or unpublish stream.
|
||||
*/
|
||||
// When publish or unpublish stream.
|
||||
virtual srs_error_t on_publish(SrsRequest* req);
|
||||
virtual srs_error_t on_unpublish();
|
||||
/**
|
||||
* when get sequence header,
|
||||
* must write a #EXT-X-DISCONTINUITY to m3u8.
|
||||
* @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt
|
||||
* @see: 3.4.11. EXT-X-DISCONTINUITY
|
||||
*/
|
||||
// When get sequence header,
|
||||
// must write a #EXT-X-DISCONTINUITY to m3u8.
|
||||
// @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt
|
||||
// @see: 3.4.11. EXT-X-DISCONTINUITY
|
||||
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);
|
||||
/**
|
||||
* write video to muxer.
|
||||
*/
|
||||
// write video to muxer.
|
||||
virtual srs_error_t write_video(SrsVideoFrame* frame, int64_t dts);
|
||||
private:
|
||||
/**
|
||||
* reopen the muxer for a new hls segment,
|
||||
* close current segment, open a new segment,
|
||||
* then write the key frame to the new segment.
|
||||
* so, user must reap_segment then flush_video to hls muxer.
|
||||
*/
|
||||
// Reopen the muxer for a new hls segment,
|
||||
// close current segment, open a new segment,
|
||||
// then write the key frame to the new segment.
|
||||
// so, user must reap_segment then flush_video to hls muxer.
|
||||
virtual srs_error_t reap_segment();
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmux RTMP stream to HLS(m3u8 and ts).
|
||||
* TODO: FIXME: add utest for hls.
|
||||
*/
|
||||
// Transmux RTMP stream to HLS(m3u8 and ts).
|
||||
// TODO: FIXME: add utest for hls.
|
||||
class SrsHls
|
||||
{
|
||||
private:
|
||||
|
@ -338,31 +298,21 @@ public:
|
|||
virtual void dispose();
|
||||
virtual srs_error_t cycle();
|
||||
public:
|
||||
/**
|
||||
* initialize the hls by handler and source.
|
||||
*/
|
||||
// Initialize the hls by handler and source.
|
||||
virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r);
|
||||
/**
|
||||
* publish stream event, continue to write the m3u8,
|
||||
* for the muxer object not destroyed.
|
||||
* @param fetch_sequence_header whether fetch sequence from source.
|
||||
*/
|
||||
// Publish stream event, continue to write the m3u8,
|
||||
// for the muxer object not destroyed.
|
||||
// @param fetch_sequence_header whether fetch sequence from source.
|
||||
virtual srs_error_t on_publish();
|
||||
/**
|
||||
* the unpublish event, only close the muxer, donot destroy the
|
||||
* muxer, for when we continue to publish, the m3u8 will continue.
|
||||
*/
|
||||
// The unpublish event, only close the muxer, donot destroy the
|
||||
// muxer, for when we continue to publish, the m3u8 will continue.
|
||||
virtual void on_unpublish();
|
||||
/**
|
||||
* mux the audio packets to ts.
|
||||
* @param shared_audio, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// Mux the audio packets to ts.
|
||||
// @param shared_audio, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format);
|
||||
/**
|
||||
* mux the video packets to ts.
|
||||
* @param shared_video, directly ptr, copy it if need to save it.
|
||||
* @param is_sps_pps whether the video is h.264 sps/pps.
|
||||
*/
|
||||
// Mux the video packets to ts.
|
||||
// @param shared_video, directly ptr, copy it if need to save it.
|
||||
// @param is_sps_pps whether the video is h.264 sps/pps.
|
||||
// TODO: FIXME: Remove param is_sps_pps.
|
||||
virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format);
|
||||
private:
|
||||
|
|
|
@ -28,68 +28,63 @@
|
|||
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* the handler for the tick.
|
||||
*/
|
||||
// The handler for the tick.
|
||||
class ISrsHourGlass
|
||||
{
|
||||
public:
|
||||
ISrsHourGlass();
|
||||
virtual ~ISrsHourGlass();
|
||||
public:
|
||||
/**
|
||||
* notify the handler, the type and tick.
|
||||
*/
|
||||
// When time is ticked, this function is called.
|
||||
virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* the hourglass used to do some specieal task,
|
||||
* while these task is cycle when some interval, for example,
|
||||
* there are N=3 tasks to do:
|
||||
* 1. heartbeat every 3s.
|
||||
* 2. print message every 5s.
|
||||
* 3. notify backend every 7s.
|
||||
* the hourglass will call back when ticks:
|
||||
* 1. notify(type=1, time=3)
|
||||
* 2. notify(type=2, time=5)
|
||||
* 3. notify(type=1, time=6)
|
||||
* 4. notify(type=3, time=7)
|
||||
* 5. notify(type=1, time=9)
|
||||
* 6. notify(type=2, time=10)
|
||||
* this is used for server and bocar server and other manager.
|
||||
*
|
||||
* Usage:
|
||||
* SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS);
|
||||
* hg->tick(1, 3 * SRS_UTIME_MILLISECONDS);
|
||||
* hg->tick(2, 5 * SRS_UTIME_MILLISECONDS);
|
||||
* hg->tick(3, 7 * SRS_UTIME_MILLISECONDS);
|
||||
* // create a thread to cycle, which will call handerl when ticked.
|
||||
* while (true) {
|
||||
* hg->cycle();
|
||||
* }
|
||||
*/
|
||||
// he hourglass used to do some specieal task,
|
||||
// while these task is cycle when some interval, for example,
|
||||
// there are N=3 tasks to do:
|
||||
// 1. heartbeat every 3s.
|
||||
// 2. print message every 5s.
|
||||
// 3. notify backend every 7s.
|
||||
// The hourglass will call back when ticks:
|
||||
// 1. notify(type=1, time=3)
|
||||
// 2. notify(type=2, time=5)
|
||||
// 3. notify(type=1, time=6)
|
||||
// 4. notify(type=3, time=7)
|
||||
// 5. notify(type=1, time=9)
|
||||
// 6. notify(type=2, time=10)
|
||||
// This is used for server and bocar server and other manager.
|
||||
//
|
||||
// Usage:
|
||||
// SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS);
|
||||
// hg->tick(1, 3 * SRS_UTIME_MILLISECONDS);
|
||||
// hg->tick(2, 5 * SRS_UTIME_MILLISECONDS);
|
||||
// hg->tick(3, 7 * SRS_UTIME_MILLISECONDS);
|
||||
// // create a thread to cycle, which will call handerl when ticked.
|
||||
// while (true) {
|
||||
// hg->cycle();
|
||||
// }
|
||||
class SrsHourGlass
|
||||
{
|
||||
private:
|
||||
ISrsHourGlass* handler;
|
||||
srs_utime_t _resolution;
|
||||
// key: the type of tick.
|
||||
// value: the interval of tick.
|
||||
// The ticks:
|
||||
// key: the type of tick.
|
||||
// value: the interval of tick.
|
||||
std::map<int, srs_utime_t> ticks;
|
||||
// the total elapsed time,
|
||||
// The total elapsed time,
|
||||
// for each cycle, we increase it with a resolution.
|
||||
srs_utime_t total_elapse;
|
||||
public:
|
||||
SrsHourGlass(ISrsHourGlass* h, srs_utime_t resolution);
|
||||
virtual ~SrsHourGlass();
|
||||
public:
|
||||
// add a pair of tick(type, interval).
|
||||
// Add a pair of tick(type, interval).
|
||||
// @param type the type of tick.
|
||||
// @param interval the interval in srs_utime_t of tick.
|
||||
virtual srs_error_t tick(int type, srs_utime_t interval);
|
||||
public:
|
||||
// cycle the hourglass, which will sleep resolution every time.
|
||||
// Cycle the hourglass, which will sleep resolution every time.
|
||||
// and call handler when ticked.
|
||||
virtual srs_error_t cycle();
|
||||
};
|
||||
|
|
|
@ -550,10 +550,7 @@ srs_error_t SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa
|
|||
SrsJsonObject* data = SrsJsonAny::object();
|
||||
obj->set("data", data);
|
||||
|
||||
data->set("primary", SrsJsonAny::str(RTMP_SIG_SRS_PRIMARY));
|
||||
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));
|
||||
|
||||
return srs_api_response(w, r, obj->dumps());
|
||||
|
|
|
@ -37,7 +37,7 @@ class SrsServer;
|
|||
#include <srs_http_stack.hpp>
|
||||
#include <srs_app_reload.hpp>
|
||||
|
||||
// for http root.
|
||||
// For http root.
|
||||
class SrsGoApiRoot : public ISrsHttpHandler
|
||||
{
|
||||
public:
|
||||
|
@ -187,7 +187,7 @@ public:
|
|||
virtual ~SrsGoApiRaw();
|
||||
public:
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_http_api_raw_api();
|
||||
};
|
||||
|
@ -219,14 +219,14 @@ private:
|
|||
public:
|
||||
SrsHttpApi(IConnectionManager* cm, srs_netfd_t fd, SrsHttpServeMux* m, std::string cip);
|
||||
virtual ~SrsHttpApi();
|
||||
// interface ISrsKbpsDelta
|
||||
// Interface ISrsKbpsDelta
|
||||
public:
|
||||
virtual void remark(int64_t* in, int64_t* out);
|
||||
protected:
|
||||
virtual srs_error_t do_cycle();
|
||||
private:
|
||||
virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_http_api_crossdomain();
|
||||
};
|
||||
|
|
|
@ -55,9 +55,7 @@ class SrsHttpMessage;
|
|||
class SrsHttpStreamServer;
|
||||
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
|
||||
{
|
||||
protected:
|
||||
|
@ -67,32 +65,28 @@ protected:
|
|||
public:
|
||||
SrsHttpConn(IConnectionManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, std::string cip);
|
||||
virtual ~SrsHttpConn();
|
||||
// interface ISrsKbpsDelta
|
||||
// Interface ISrsKbpsDelta
|
||||
public:
|
||||
virtual void remark(int64_t* in, int64_t* out);
|
||||
protected:
|
||||
virtual srs_error_t do_cycle();
|
||||
protected:
|
||||
// when got http message,
|
||||
// When got http message,
|
||||
// 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.
|
||||
virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg) = 0;
|
||||
private:
|
||||
virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
/**
|
||||
* when the connection disconnect, call this method.
|
||||
* e.g. log msg of connection and report to other system.
|
||||
* @param request: request which is converted by the last http message.
|
||||
*/
|
||||
// When the connection disconnect, call this method.
|
||||
// e.g. log msg of connection and report to other system.
|
||||
// @param request: request which is converted by the last http message.
|
||||
virtual srs_error_t on_disconnect(SrsRequest* req);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
|
@ -109,9 +103,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -123,10 +115,9 @@ public:
|
|||
virtual ~SrsHttpServer();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
// ISrsHttpServeMux
|
||||
// Interface ISrsHttpServeMux
|
||||
public:
|
||||
virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
|
||||
// http flv/ts/mp3/aac stream
|
||||
public:
|
||||
virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r);
|
||||
virtual void http_unmount(SrsSource* s, SrsRequest* r);
|
||||
|
|
|
@ -34,11 +34,10 @@ class SrsRequest;
|
|||
class SrsHttpParser;
|
||||
class SrsHttpClient;
|
||||
|
||||
/**
|
||||
* the http hooks, http callback api,
|
||||
* for some event, such as on_connect, call
|
||||
* a http api(hooks).
|
||||
*/
|
||||
// the http hooks, http callback api,
|
||||
// for some event, such as on_connect, call
|
||||
// a http api(hooks).
|
||||
// TODO: Refine to global variable.
|
||||
class SrsHttpHooks
|
||||
{
|
||||
private:
|
||||
|
@ -46,76 +45,56 @@ private:
|
|||
public:
|
||||
virtual ~SrsHttpHooks();
|
||||
public:
|
||||
/**
|
||||
* on_connect hook, when client connect to srs.
|
||||
* @param url the api server url, to valid the client.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The on_connect hook, when client connect to srs.
|
||||
// @param url the api server url, to valid the client.
|
||||
// ignore if empty.
|
||||
static srs_error_t on_connect(std::string url, SrsRequest* req);
|
||||
/**
|
||||
* 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.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The 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.
|
||||
// ignore if empty.
|
||||
static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes);
|
||||
/**
|
||||
* on_publish hook, when client(encoder) start to publish stream
|
||||
* @param url the api server url, to valid the client.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The on_publish hook, when client(encoder) start to publish stream
|
||||
// @param url the api server url, to valid the client.
|
||||
// ignore if empty.
|
||||
static srs_error_t on_publish(std::string url, SrsRequest* req);
|
||||
/**
|
||||
* on_unpublish hook, when client(encoder) stop publish stream.
|
||||
* @param url the api server url, to process the event.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The on_unpublish hook, when client(encoder) stop publish stream.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
static void on_unpublish(std::string url, SrsRequest* req);
|
||||
/**
|
||||
* on_play hook, when client start to play stream.
|
||||
* @param url the api server url, to valid the client.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The on_play hook, when client start to play stream.
|
||||
// @param url the api server url, to valid the client.
|
||||
// ignore if empty.
|
||||
static srs_error_t on_play(std::string url, SrsRequest* req);
|
||||
/**
|
||||
* on_stop hook, when client stop to play the stream.
|
||||
* @param url the api server url, to process the event.
|
||||
* ignore if empty.
|
||||
*/
|
||||
// The on_stop hook, when client stop to play the stream.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
static void on_stop(std::string url, SrsRequest* req);
|
||||
/**
|
||||
* on_dvr hook, when reap a dvr file.
|
||||
* @param url the api server url, to process the event.
|
||||
* ignore if empty.
|
||||
* @param file the file path, can be relative or absolute path.
|
||||
* @param cid the source connection cid, for the on_dvr is async call.
|
||||
*/
|
||||
// The on_dvr hook, when reap a dvr file.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
// @param file the file path, can be relative or absolute path.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file);
|
||||
/**
|
||||
* when hls reap segment, callback.
|
||||
* @param url the api server url, to process the event.
|
||||
* ignore if empty.
|
||||
* @param file the ts file path, can be relative or absolute path.
|
||||
* @param ts_url the ts url, which used for m3u8.
|
||||
* @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 sn the seq_no, the sequence number of ts in hls/m3u8.
|
||||
* @param duration the segment duration in srs_utime_t.
|
||||
* @param cid the source connection cid, for the on_dvr is async call.
|
||||
*/
|
||||
// When hls reap segment, callback.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
// @param file the ts file path, can be relative or absolute path.
|
||||
// @param ts_url the ts url, which used for m3u8.
|
||||
// @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 sn the seq_no, the sequence number of ts in hls/m3u8.
|
||||
// @param duration the segment duration in srs_utime_t.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url,
|
||||
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration);
|
||||
/**
|
||||
* when hls reap segment, callback.
|
||||
* @param url the api server url, to process the event.
|
||||
* ignore if empty.
|
||||
* @param ts_url the ts uri, used to replace the variable [ts_url] in url.
|
||||
* @param nb_notify the max bytes to read from notify server.
|
||||
* @param cid the source connection cid, for the on_dvr is async call.
|
||||
*/
|
||||
// When hls reap segment, callback.
|
||||
// @param url the api server url, to process the event.
|
||||
// ignore if empty.
|
||||
// @param ts_url the ts uri, used to replace the variable [ts_url] in url.
|
||||
// @param nb_notify the max bytes to read from notify server.
|
||||
// @param cid the source connection cid, for the on_dvr is async call.
|
||||
static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify);
|
||||
/**
|
||||
* 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);
|
||||
private:
|
||||
static srs_error_t do_post(SrsHttpClient* hc, std::string url, std::string req, int& code, std::string& res);
|
||||
|
|
|
@ -28,12 +28,10 @@
|
|||
|
||||
#include <srs_app_http_conn.hpp>
|
||||
|
||||
/**
|
||||
* the flv vod stream supports flv?start=offset-bytes.
|
||||
* for example, http://server/file.flv?start=10240
|
||||
* server will write flv header and sequence header,
|
||||
* then seek(10240) and response flv tag data.
|
||||
*/
|
||||
// The flv vod stream supports flv?start=offset-bytes.
|
||||
// For example, http://server/file.flv?start=10240
|
||||
// server will write flv header and sequence header,
|
||||
// then seek(10240) and response flv tag data.
|
||||
class SrsVodStream : public SrsHttpFileServer
|
||||
{
|
||||
public:
|
||||
|
@ -44,10 +42,8 @@ protected:
|
|||
virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end);
|
||||
};
|
||||
|
||||
/**
|
||||
* the http static server instance,
|
||||
* serve http static file and flv/mp4 vod stream.
|
||||
*/
|
||||
// The http static server instance,
|
||||
// serve http static file and flv/mp4 vod stream.
|
||||
class SrsHttpStaticServer : virtual public ISrsReloadHandler
|
||||
{
|
||||
private:
|
||||
|
@ -61,7 +57,7 @@ public:
|
|||
virtual srs_error_t initialize();
|
||||
private:
|
||||
virtual srs_error_t mount_vhost(std::string vhost, std::string& pmount);
|
||||
// interface ISrsReloadHandler.
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_added(std::string vhost);
|
||||
virtual srs_error_t on_reload_vhost_http_updated();
|
||||
|
|
|
@ -33,9 +33,7 @@ class SrsMp3Transmuxer;
|
|||
class SrsFlvTransmuxer;
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -52,48 +50,36 @@ public:
|
|||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
// interface ISrsEndlessThreadHandler.
|
||||
// Interface ISrsEndlessThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
};
|
||||
|
||||
/**
|
||||
* The encoder to transmux RTMP stream.
|
||||
*/
|
||||
// The encoder to transmux RTMP stream.
|
||||
class ISrsBufferEncoder
|
||||
{
|
||||
public:
|
||||
ISrsBufferEncoder();
|
||||
virtual ~ISrsBufferEncoder();
|
||||
public:
|
||||
/**
|
||||
* initialize the encoder with file writer(to http response) and stream cache.
|
||||
* @param w the writer to write to http response.
|
||||
* @param c the stream cache for audio stream fast startup.
|
||||
*/
|
||||
// Initialize the encoder with file writer(to http response) and stream cache.
|
||||
// @param w the writer to write to http response.
|
||||
// @param c the stream cache for audio stream fast startup.
|
||||
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_video(int64_t timestamp, char* data, int size) = 0;
|
||||
virtual srs_error_t write_metadata(int64_t timestamp, char* data, int size) = 0;
|
||||
public:
|
||||
/**
|
||||
* 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.
|
||||
* @return true to use gop cache of encoder; otherwise, use SrsSource.
|
||||
*/
|
||||
// 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.
|
||||
// @return true to use gop cache of encoder; otherwise, use SrsSource.
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmux RTMP to HTTP Live Streaming.
|
||||
*/
|
||||
// Transmux RTMP to HTTP Live Streaming.
|
||||
class SrsFlvStreamEncoder : public ISrsBufferEncoder
|
||||
{
|
||||
protected:
|
||||
|
@ -112,26 +98,20 @@ public:
|
|||
};
|
||||
|
||||
#ifdef SRS_PERF_FAST_FLV_ENCODER
|
||||
/**
|
||||
* A Fast HTTP FLV Live Streaming, to write multiple tags by writev.
|
||||
* @see https://github.com/ossrs/srs/issues/405
|
||||
*/
|
||||
// A Fast HTTP FLV Live Streaming, to write multiple tags by writev.
|
||||
// @see https://github.com/ossrs/srs/issues/405
|
||||
class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder
|
||||
{
|
||||
public:
|
||||
SrsFastFlvStreamEncoder();
|
||||
virtual ~SrsFastFlvStreamEncoder();
|
||||
public:
|
||||
/**
|
||||
* write the tags in a time.
|
||||
*/
|
||||
// Write the tags in a time.
|
||||
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Transmux RTMP to HTTP TS Streaming.
|
||||
*/
|
||||
// Transmux RTMP to HTTP TS Streaming.
|
||||
class SrsTsStreamEncoder : public ISrsBufferEncoder
|
||||
{
|
||||
private:
|
||||
|
@ -149,9 +129,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -170,9 +148,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -191,9 +167,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -212,9 +186,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -234,9 +206,7 @@ private:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -248,8 +218,8 @@ public:
|
|||
SrsRequest* req;
|
||||
SrsSource* source;
|
||||
public:
|
||||
// for template, the mount contains variables.
|
||||
// for concrete stream, the mount is url to access.
|
||||
// For template, the mount contains variables.
|
||||
// For concrete stream, the mount is url to access.
|
||||
std::string mount;
|
||||
|
||||
SrsLiveStream* stream;
|
||||
|
@ -263,9 +233,7 @@ public:
|
|||
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.
|
||||
class SrsHttpStreamServer : virtual public ISrsReloadHandler
|
||||
, virtual public ISrsHttpMatchHijacker
|
||||
|
@ -274,24 +242,24 @@ private:
|
|||
SrsServer* server;
|
||||
public:
|
||||
SrsHttpServeMux mux;
|
||||
// the http live streaming template, to create streams.
|
||||
// The http live streaming template, to create streams.
|
||||
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;
|
||||
public:
|
||||
SrsHttpStreamServer(SrsServer* svr);
|
||||
virtual ~SrsHttpStreamServer();
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
// http flv/ts/mp3/aac stream
|
||||
public:
|
||||
// HTTP flv/ts/mp3/aac stream
|
||||
virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r);
|
||||
virtual void http_unmount(SrsSource* s, SrsRequest* r);
|
||||
// interface ISrsReloadHandler.
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_added(std::string vhost);
|
||||
virtual srs_error_t on_reload_vhost_http_remux_updated(std::string vhost);
|
||||
// interface ISrsHttpMatchHijacker
|
||||
// Interface ISrsHttpMatchHijacker
|
||||
public:
|
||||
virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph);
|
||||
private:
|
||||
|
|
|
@ -35,9 +35,7 @@ class SrsFFMPEG;
|
|||
class SrsConfDirective;
|
||||
class SrsPithyPrint;
|
||||
|
||||
/**
|
||||
* ingester ffmpeg object.
|
||||
*/
|
||||
// Ingester ffmpeg object.
|
||||
class SrsIngesterFFMPEG
|
||||
{
|
||||
private:
|
||||
|
@ -50,9 +48,9 @@ public:
|
|||
virtual ~SrsIngesterFFMPEG();
|
||||
public:
|
||||
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();
|
||||
// the alive in srs_utime_t.
|
||||
// The alive in srs_utime_t.
|
||||
virtual srs_utime_t alive();
|
||||
virtual bool equals(std::string v, std::string i);
|
||||
virtual bool equals(std::string v);
|
||||
|
@ -64,11 +62,9 @@ public:
|
|||
virtual void fast_stop();
|
||||
};
|
||||
|
||||
/**
|
||||
* ingest file/stream/device,
|
||||
* encode with FFMPEG(optional),
|
||||
* push to SRS(or any RTMP server) over RTMP.
|
||||
*/
|
||||
// Ingest file/stream/device,
|
||||
// encode with FFMPEG(optional),
|
||||
// push to SRS(or any RTMP server) over RTMP.
|
||||
class SrsIngester : public ISrsCoroutineHandler, public ISrsReloadHandler
|
||||
{
|
||||
private:
|
||||
|
@ -76,8 +72,7 @@ private:
|
|||
private:
|
||||
SrsCoroutine* trd;
|
||||
SrsPithyPrint* pprint;
|
||||
// whether the ingesters are expired,
|
||||
// for example, the listen port changed,
|
||||
// Whether the ingesters are expired, for example, the listen port changed,
|
||||
// all ingesters must be restart.
|
||||
bool expired;
|
||||
public:
|
||||
|
@ -90,7 +85,7 @@ public:
|
|||
virtual void stop();
|
||||
private:
|
||||
virtual void fast_stop();
|
||||
// interface ISrsReusableThreadHandler.
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
@ -102,7 +97,7 @@ private:
|
|||
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 void show_ingest_log_message();
|
||||
// interface ISrsReloadHandler.
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_removed(std::string vhost);
|
||||
virtual srs_error_t on_reload_vhost_added(std::string vhost);
|
||||
|
|
|
@ -42,14 +42,10 @@ class SrsKafkaProducer;
|
|||
|
||||
#ifdef SRS_AUTO_KAFKA
|
||||
|
||||
/**
|
||||
* the partition messages cache.
|
||||
*/
|
||||
// The partition messages cache.
|
||||
typedef std::vector<SrsJsonObject*> SrsKafkaPartitionCache;
|
||||
|
||||
/**
|
||||
* the kafka partition info.
|
||||
*/
|
||||
// The kafka partition info.
|
||||
struct SrsKafkaPartition
|
||||
{
|
||||
private:
|
||||
|
@ -75,9 +71,7 @@ private:
|
|||
virtual void disconnect();
|
||||
};
|
||||
|
||||
/**
|
||||
* the following is all types of kafka messages.
|
||||
*/
|
||||
// The following is all types of kafka messages.
|
||||
class SrsKafkaMessage : public ISrsAsyncCallTask
|
||||
{
|
||||
private:
|
||||
|
@ -87,25 +81,23 @@ private:
|
|||
public:
|
||||
SrsKafkaMessage(SrsKafkaProducer* p, int k, SrsJsonObject* j);
|
||||
virtual ~SrsKafkaMessage();
|
||||
// interface ISrsAsyncCallTask
|
||||
// Interface ISrsAsyncCallTask
|
||||
public:
|
||||
virtual srs_error_t call();
|
||||
virtual std::string to_string();
|
||||
};
|
||||
|
||||
/**
|
||||
* a message cache for kafka.
|
||||
*/
|
||||
// A message cache for kafka.
|
||||
class SrsKafkaCache
|
||||
{
|
||||
public:
|
||||
// the total partitions,
|
||||
// The total partitions,
|
||||
// for the key to map to the parition by key%nb_partitions.
|
||||
int nb_partitions;
|
||||
private:
|
||||
// total messages for all partitions.
|
||||
// Total messages for all partitions.
|
||||
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,
|
||||
// so maybe some message will dispatch to new partition.
|
||||
std::map< int32_t, SrsKafkaPartitionCache*> cache;
|
||||
|
@ -115,37 +107,27 @@ public:
|
|||
public:
|
||||
virtual void append(int key, SrsJsonObject* obj);
|
||||
virtual int size();
|
||||
/**
|
||||
* fetch out a available partition cache.
|
||||
* @return true when got a key and pc; otherwise, false.
|
||||
*/
|
||||
// Fetch out a available partition cache.
|
||||
// @return true when got a key and pc; otherwise, false.
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* the kafka cluster interface.
|
||||
*/
|
||||
// The kafka cluster interface.
|
||||
class ISrsKafkaCluster
|
||||
{
|
||||
public:
|
||||
ISrsKafkaCluster();
|
||||
virtual ~ISrsKafkaCluster();
|
||||
public:
|
||||
/**
|
||||
* when got any client connect to SRS, notify kafka.
|
||||
* @param key the partition map key, the client id or hash(ip).
|
||||
* @param type the type of client.
|
||||
* @param ip the peer ip of client.
|
||||
*/
|
||||
// When got any client connect to SRS, notify kafka.
|
||||
// @param key the partition map key, the client id or hash(ip).
|
||||
// @param type the type of client.
|
||||
// @param ip the peer ip of client.
|
||||
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip) = 0;
|
||||
/**
|
||||
* when client close or disconnect for error.
|
||||
* @param key the partition map key, the client id or hash(ip).
|
||||
*/
|
||||
// When client close or disconnect for error.
|
||||
// @param key the partition map key, the client id or hash(ip).
|
||||
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 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
|
||||
{
|
||||
private:
|
||||
|
@ -183,25 +163,23 @@ public:
|
|||
virtual void stop();
|
||||
// internal: for worker to call task to send object.
|
||||
public:
|
||||
/**
|
||||
* send json object to kafka cluster.
|
||||
* 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 obj the json object; user must never free it again.
|
||||
*/
|
||||
// Send json object to kafka cluster.
|
||||
// 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 obj the json object; user must never free it again.
|
||||
virtual srs_error_t send(int key, SrsJsonObject* obj);
|
||||
// interface ISrsKafkaCluster
|
||||
// Interface ISrsKafkaCluster
|
||||
public:
|
||||
virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip);
|
||||
virtual srs_error_t on_close(int key);
|
||||
// interface ISrsReusableThreadHandler
|
||||
// Interface ISrsReusableThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
virtual void clear_metadata();
|
||||
virtual srs_error_t do_cycle();
|
||||
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 srs_error_t flush();
|
||||
};
|
||||
|
|
|
@ -33,51 +33,39 @@
|
|||
|
||||
struct sockaddr;
|
||||
|
||||
/**
|
||||
* the udp packet handler.
|
||||
*/
|
||||
// The udp packet handler.
|
||||
class ISrsUdpHandler
|
||||
{
|
||||
public:
|
||||
ISrsUdpHandler();
|
||||
virtual ~ISrsUdpHandler();
|
||||
public:
|
||||
/**
|
||||
* when fd changed, for instance, reload the listen port,
|
||||
* notify the handler and user can do something.
|
||||
*/
|
||||
// When fd changed, for instance, reload the listen port,
|
||||
// notify the handler and user can do something.
|
||||
virtual srs_error_t on_stfd_change(srs_netfd_t fd);
|
||||
public:
|
||||
/**
|
||||
* when udp listener got a udp packet, notice server to process it.
|
||||
* @param type, the client type, used to create concrete connection,
|
||||
* for instance RTMP connection to serve client.
|
||||
* @param from, the udp packet from address.
|
||||
* @param buf, the udp packet bytes, user should copy if need to use.
|
||||
* @param nb_buf, the size of udp packet bytes.
|
||||
* @remark user should never use the buf, for it's a shared memory bytes.
|
||||
*/
|
||||
// When udp listener got a udp packet, notice server to process it.
|
||||
// @param type, the client type, used to create concrete connection,
|
||||
// for instance RTMP connection to serve client.
|
||||
// @param from, the udp packet from address.
|
||||
// @param buf, the udp packet bytes, user should copy if need to use.
|
||||
// @param nb_buf, the size of udp packet 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;
|
||||
};
|
||||
|
||||
/**
|
||||
* the tcp connection handler.
|
||||
*/
|
||||
// The tcp connection handler.
|
||||
class ISrsTcpHandler
|
||||
{
|
||||
public:
|
||||
ISrsTcpHandler();
|
||||
virtual ~ISrsTcpHandler();
|
||||
public:
|
||||
/**
|
||||
* when got tcp client.
|
||||
*/
|
||||
// When got tcp client.
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -99,14 +87,12 @@ public:
|
|||
virtual srs_netfd_t stfd();
|
||||
public:
|
||||
virtual srs_error_t listen();
|
||||
// interface ISrsReusableThreadHandler.
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -124,7 +110,7 @@ public:
|
|||
virtual int fd();
|
||||
public:
|
||||
virtual srs_error_t listen();
|
||||
// interface ISrsReusableThreadHandler.
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
};
|
||||
|
|
|
@ -32,29 +32,26 @@
|
|||
#include <srs_app_reload.hpp>
|
||||
#include <srs_service_log.hpp>
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* when you want to use different level, override this classs, set the protected _level.
|
||||
*/
|
||||
// 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.
|
||||
// when you want to use different level, override this classs, set the protected _level.
|
||||
class SrsFastLog : public ISrsLog, public ISrsReloadHandler
|
||||
{
|
||||
// for utest to override
|
||||
protected:
|
||||
// defined in SrsLogLevel.
|
||||
private:
|
||||
// Defined in SrsLogLevel.
|
||||
SrsLogLevel level;
|
||||
private:
|
||||
char* log_data;
|
||||
// log to file if specified srs_log_file
|
||||
// Log to file if specified srs_log_file
|
||||
int fd;
|
||||
// whether log to file tank
|
||||
// Whether log to file tank
|
||||
bool log_to_file_tank;
|
||||
// whether use utc time.
|
||||
// Whether use utc time.
|
||||
bool utc;
|
||||
public:
|
||||
SrsFastLog();
|
||||
virtual ~SrsFastLog();
|
||||
// interface ISrsLog
|
||||
// Interface ISrsLog
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual void reopen();
|
||||
|
@ -63,7 +60,7 @@ public:
|
|||
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void warn(const char* tag, int context_id, const char* fmt, ...);
|
||||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
// interface ISrsReloadHandler.
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_utc_time();
|
||||
virtual srs_error_t on_reload_log_tank();
|
||||
|
|
|
@ -48,15 +48,13 @@ class SrsSimpleRtmpClient;
|
|||
#include <srs_kernel_ts.hpp>
|
||||
#include <srs_app_listener.hpp>
|
||||
|
||||
/**
|
||||
* the queue for mpegts over udp to send packets.
|
||||
* for the aac in mpegts contains many flv packets in a pes packet,
|
||||
* we must recalc the timestamp.
|
||||
*/
|
||||
// The queue for mpegts over udp to send packets.
|
||||
// For the aac in mpegts contains many flv packets in a pes packet,
|
||||
// we must recalc the timestamp.
|
||||
class SrsMpegtsQueue
|
||||
{
|
||||
private:
|
||||
// key: dts, value: msg.
|
||||
// The key: dts, value: msg.
|
||||
std::map<int64_t, SrsSharedPtrMessage*> msgs;
|
||||
int nb_audios;
|
||||
int nb_videos;
|
||||
|
@ -68,11 +66,8 @@ public:
|
|||
virtual SrsSharedPtrMessage* dequeue();
|
||||
};
|
||||
|
||||
/**
|
||||
* the mpegts over udp stream caster.
|
||||
*/
|
||||
class SrsMpegtsOverUdp : virtual public ISrsTsHandler
|
||||
, virtual public ISrsUdpHandler
|
||||
// The mpegts over udp stream caster.
|
||||
class SrsMpegtsOverUdp : virtual public ISrsTsHandler, virtual public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
SrsTsContext* context;
|
||||
|
@ -96,12 +91,12 @@ private:
|
|||
public:
|
||||
SrsMpegtsOverUdp(SrsConfDirective* c);
|
||||
virtual ~SrsMpegtsOverUdp();
|
||||
// interface ISrsUdpHandler
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
private:
|
||||
virtual srs_error_t on_udp_bytes(std::string host, int port, char* buf, int nb_buf);
|
||||
// interface ISrsTsHandler
|
||||
// Interface ISrsTsHandler
|
||||
public:
|
||||
virtual srs_error_t on_ts_message(SrsTsMessage* msg);
|
||||
private:
|
||||
|
|
|
@ -35,11 +35,9 @@ class SrsRequest;
|
|||
class SrsPithyPrint;
|
||||
class SrsProcess;
|
||||
|
||||
/**
|
||||
* 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/ossrs/srs/issues/367
|
||||
*/
|
||||
// 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/ossrs/srs/issues/367
|
||||
class SrsNgExec : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -53,7 +51,7 @@ public:
|
|||
public:
|
||||
virtual srs_error_t on_publish(SrsRequest* req);
|
||||
virtual void on_unpublish();
|
||||
// interface ISrsReusableThreadHandler.
|
||||
// Interface ISrsReusableThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
|
||||
#include <srs_app_reload.hpp>
|
||||
|
||||
/**
|
||||
* the stage info to calc the age.
|
||||
*/
|
||||
// The stage info to calc the age.
|
||||
class SrsStageInfo : public ISrsReloadHandler
|
||||
{
|
||||
public:
|
||||
|
@ -50,26 +48,24 @@ public:
|
|||
virtual srs_error_t on_reload_pithy_print();
|
||||
};
|
||||
|
||||
/**
|
||||
* the stage is used for a collection of object to do print,
|
||||
* the print time in a stage is constant and not changed,
|
||||
* that is, we always got one message to print every specified time.
|
||||
*
|
||||
* for example, stage #1 for all play clients, print time is 3s,
|
||||
* if there is 1client, it will print every 3s.
|
||||
* if there is 10clients, random select one to print every 3s.
|
||||
* Usage:
|
||||
* SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play();
|
||||
* SrsAutoFree(SrsPithyPrint, pprint);
|
||||
* while (true) {
|
||||
* pprint->elapse();
|
||||
* if (pprint->can_print()) {
|
||||
* // print pithy message.
|
||||
* // user can get the elapse time by: pprint->age()
|
||||
* }
|
||||
* // read and write RTMP messages.
|
||||
* }
|
||||
*/
|
||||
// The stage is used for a collection of object to do print,
|
||||
// the print time in a stage is constant and not changed,
|
||||
// that is, we always got one message to print every specified time.
|
||||
//
|
||||
// For example, stage #1 for all play clients, print time is 3s,
|
||||
// if there is 1client, it will print every 3s.
|
||||
// if there is 10clients, random select one to print every 3s.
|
||||
// Usage:
|
||||
// SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play();
|
||||
// SrsAutoFree(SrsPithyPrint, pprint);
|
||||
// while (true) {
|
||||
// pprint->elapse();
|
||||
// if (pprint->can_print()) {
|
||||
// // print pithy message.
|
||||
// // user can get the elapse time by: pprint->age()
|
||||
// }
|
||||
// // read and write RTMP messages.
|
||||
// }
|
||||
class SrsPithyPrint
|
||||
{
|
||||
private:
|
||||
|
@ -93,26 +89,16 @@ public:
|
|||
static SrsPithyPrint* create_http_stream_cache();
|
||||
virtual ~SrsPithyPrint();
|
||||
private:
|
||||
/**
|
||||
* enter the specified stage, return the client id.
|
||||
*/
|
||||
// Enter the specified stage, return the client id.
|
||||
virtual int enter_stage();
|
||||
/**
|
||||
* leave the specified stage, release the client id.
|
||||
*/
|
||||
// Leave the specified stage, release the client id.
|
||||
virtual void leave_stage();
|
||||
public:
|
||||
/**
|
||||
* auto calc the elapse time
|
||||
*/
|
||||
// Auto calc the elapse time
|
||||
virtual void elapse();
|
||||
/**
|
||||
* whether current client can print.
|
||||
*/
|
||||
// Whether current client 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();
|
||||
};
|
||||
|
||||
|
|
|
@ -29,26 +29,24 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* to start and stop a process, cycle to restart the process when terminated.
|
||||
* the usage:
|
||||
* // the binary is the process to fork.
|
||||
* binary = "./objs/ffmpeg/bin/ffmpeg";
|
||||
* // where argv is a array contains each params.
|
||||
* argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"];
|
||||
*
|
||||
* process = new SrsProcess();
|
||||
* if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; }
|
||||
* if ((ret = process->start()) != ERROR_SUCCESS) { return ret; }
|
||||
* if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; }
|
||||
* process->fast_stop();
|
||||
* process->stop();
|
||||
*/
|
||||
// Start and stop a process. Call cycle to restart the process when terminated.
|
||||
// The usage:
|
||||
// // the binary is the process to fork.
|
||||
// binary = "./objs/ffmpeg/bin/ffmpeg";
|
||||
// // where argv is a array contains each params.
|
||||
// argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"];
|
||||
//
|
||||
// process = new SrsProcess();
|
||||
// if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; }
|
||||
// if ((ret = process->start()) != ERROR_SUCCESS) { return ret; }
|
||||
// if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; }
|
||||
// process->fast_stop();
|
||||
// process->stop();
|
||||
class SrsProcess
|
||||
{
|
||||
private:
|
||||
bool is_started;
|
||||
// whether SIGTERM send but need to wait or SIGKILL.
|
||||
// Whether SIGTERM send but need to wait or SIGKILL.
|
||||
bool fast_stopped;
|
||||
pid_t pid;
|
||||
private:
|
||||
|
@ -56,56 +54,42 @@ private:
|
|||
std::string stdout_file;
|
||||
std::string stderr_file;
|
||||
std::vector<std::string> params;
|
||||
// the cli to fork process.
|
||||
// The cli to fork process.
|
||||
std::string cli;
|
||||
std::string actual_cli;
|
||||
public:
|
||||
SrsProcess();
|
||||
virtual ~SrsProcess();
|
||||
public:
|
||||
/**
|
||||
* get pid of process.
|
||||
*/
|
||||
// Get pid of process.
|
||||
virtual int get_pid();
|
||||
/**
|
||||
* whether process is already started.
|
||||
*/
|
||||
// whether process is already started.
|
||||
virtual bool started();
|
||||
/**
|
||||
* initialize the process with binary and argv.
|
||||
* @param binary the binary path to exec.
|
||||
* @param argv the argv for binary path, the argv[0] generally is the binary.
|
||||
* @remark the argv[0] must be the binary.
|
||||
*/
|
||||
// Initialize the process with binary and argv.
|
||||
// @param binary the binary path to exec.
|
||||
// @param argv the argv for binary path, the argv[0] generally is the binary.
|
||||
// @remark the argv[0] must be the binary.
|
||||
virtual srs_error_t initialize(std::string binary, std::vector<std::string> argv);
|
||||
public:
|
||||
/**
|
||||
* start the process, ignore when already started.
|
||||
*/
|
||||
// Start the process, ignore when already started.
|
||||
virtual srs_error_t start();
|
||||
/**
|
||||
* cycle check the process, update the state of process.
|
||||
* @remark when process terminated(not started), user can restart it again by start().
|
||||
*/
|
||||
// cycle check the process, update the state of process.
|
||||
// @remark when process terminated(not started), user can restart it again by start().
|
||||
virtual srs_error_t cycle();
|
||||
/**
|
||||
* send SIGTERM then SIGKILL to ensure the process stopped.
|
||||
* the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the
|
||||
* process quit timeout.
|
||||
* @remark use fast_stop before stop one by one, when got lots of process to quit.
|
||||
*/
|
||||
// Send SIGTERM then SIGKILL to ensure the process stopped.
|
||||
// the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the
|
||||
// process quit timeout.
|
||||
// @remark use fast_stop before stop one by one, when got lots of process to quit.
|
||||
virtual void stop();
|
||||
public:
|
||||
/**
|
||||
* the fast stop is to send a SIGTERM.
|
||||
* 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
|
||||
* wait one by one to stop, it's more faster.
|
||||
* @remark user must use stop() to ensure the ffmpeg to stopped.
|
||||
* @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]
|
||||
* but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
|
||||
*/
|
||||
// The fast stop is to send a SIGTERM.
|
||||
// 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
|
||||
// wait one by one to stop, it's more faster.
|
||||
// @remark user must use stop() to ensure the ffmpeg to stopped.
|
||||
// @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]
|
||||
// but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS].
|
||||
virtual void fast_stop();
|
||||
};
|
||||
|
||||
|
|
|
@ -42,54 +42,38 @@ class SrsConsumer;
|
|||
class SrsHttpConn;
|
||||
class SrsResponseOnlyHttpConn;
|
||||
|
||||
/**
|
||||
* The message consumer which consume a message.
|
||||
*/
|
||||
// The message consumer which consume a message.
|
||||
class ISrsMessageConsumer
|
||||
{
|
||||
public:
|
||||
ISrsMessageConsumer();
|
||||
virtual ~ISrsMessageConsumer();
|
||||
public:
|
||||
/**
|
||||
* Consume the received message.
|
||||
* @remark user must free this message.
|
||||
*/
|
||||
// Consume the received message.
|
||||
// @remark user must free this message.
|
||||
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
|
||||
{
|
||||
public:
|
||||
ISrsMessagePumper();
|
||||
virtual ~ISrsMessagePumper();
|
||||
public:
|
||||
/**
|
||||
* Whether the pumper is interrupted.
|
||||
* For example, when pumpter is busy, it's interrupted,
|
||||
* please wait for a while then try to feed the pumper.
|
||||
*/
|
||||
// Whether the pumper is interrupted.
|
||||
// For example, when pumpter is busy, it's interrupted,
|
||||
// please wait for a while then try to feed the pumper.
|
||||
virtual bool interrupted() = 0;
|
||||
/**
|
||||
* Interrupt the pumper for a error.
|
||||
*/
|
||||
// Interrupt the pumper for a error.
|
||||
virtual void interrupt(srs_error_t error) = 0;
|
||||
/**
|
||||
* When start the pumper.
|
||||
*/
|
||||
// When start the pumper.
|
||||
virtual void on_start() = 0;
|
||||
/**
|
||||
* When stop the pumper.
|
||||
*/
|
||||
// When stop the pumper.
|
||||
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
|
||||
{
|
||||
protected:
|
||||
|
@ -110,26 +94,24 @@ public:
|
|||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
virtual void stop_loop();
|
||||
// interface ISrsReusableThread2Handler
|
||||
// Interface ISrsReusableThread2Handler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
virtual srs_error_t do_cycle();
|
||||
};
|
||||
|
||||
/**
|
||||
* the recv thread used to replace the timeout recv,
|
||||
* which hurt performance for the epoll_ctrl is frequently used.
|
||||
* @see: SrsRtmpConn::playing
|
||||
* @see: https://github.com/ossrs/srs/issues/217
|
||||
*/
|
||||
// The recv thread used to replace the timeout recv,
|
||||
// which hurt performance for the epoll_ctrl is frequently used.
|
||||
// @see: SrsRtmpConn::playing
|
||||
// @see: https://github.com/ossrs/srs/issues/217
|
||||
class SrsQueueRecvThread : public ISrsMessagePumper
|
||||
{
|
||||
private:
|
||||
std::vector<SrsCommonMessage*> queue;
|
||||
SrsRecvThread trd;
|
||||
SrsRtmpServer* rtmp;
|
||||
// the recv thread error code.
|
||||
// The recv thread error code.
|
||||
srs_error_t recv_error;
|
||||
SrsConsumer* _consumer;
|
||||
public:
|
||||
|
@ -144,7 +126,7 @@ public:
|
|||
virtual int size();
|
||||
virtual SrsCommonMessage* pump();
|
||||
virtual srs_error_t error_code();
|
||||
// interface ISrsMessagePumper
|
||||
// Interface ISrsMessagePumper
|
||||
public:
|
||||
virtual srs_error_t consume(SrsCommonMessage* msg);
|
||||
virtual bool interrupted();
|
||||
|
@ -153,10 +135,8 @@ public:
|
|||
virtual void on_stop();
|
||||
};
|
||||
|
||||
/**
|
||||
* the publish recv thread got message and callback the source method to process message.
|
||||
* @see: https://github.com/ossrs/srs/issues/237
|
||||
*/
|
||||
// The publish recv thread got message and callback the source method to process message.
|
||||
// @see: https://github.com/ossrs/srs/issues/237
|
||||
class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler
|
||||
#ifdef SRS_PERF_MERGED_READ
|
||||
, virtual public IMergeReadHandler
|
||||
|
@ -166,27 +146,27 @@ private:
|
|||
SrsRecvThread trd;
|
||||
SrsRtmpServer* rtmp;
|
||||
SrsRequest* req;
|
||||
// the msgs already got.
|
||||
// The msgs already got.
|
||||
int64_t _nb_msgs;
|
||||
// The video frames we got.
|
||||
uint64_t video_frames;
|
||||
// for mr(merged read),
|
||||
// For mr(merged read),
|
||||
// @see https://github.com/ossrs/srs/issues/241
|
||||
bool mr;
|
||||
int mr_fd;
|
||||
srs_utime_t mr_sleep;
|
||||
// for realtime
|
||||
// For realtime
|
||||
// @see https://github.com/ossrs/srs/issues/257
|
||||
bool realtime;
|
||||
// the recv thread error code.
|
||||
// The recv thread error code.
|
||||
srs_error_t recv_error;
|
||||
SrsRtmpConn* _conn;
|
||||
// the params for conn callback.
|
||||
// The params for conn callback.
|
||||
SrsSource* _source;
|
||||
// the error timeout cond
|
||||
// The error timeout cond
|
||||
// @see https://github.com/ossrs/srs/issues/244
|
||||
srs_cond_t error;
|
||||
// merged context id.
|
||||
// The merged context id.
|
||||
int cid;
|
||||
int ncid;
|
||||
public:
|
||||
|
@ -194,9 +174,7 @@ public:
|
|||
int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid);
|
||||
virtual ~SrsPublishRecvThread();
|
||||
public:
|
||||
/**
|
||||
* wait for error for some timeout.
|
||||
*/
|
||||
// Wait for error for some timeout.
|
||||
virtual srs_error_t wait(srs_utime_t tm);
|
||||
virtual int64_t nb_msgs();
|
||||
virtual uint64_t nb_video_frames();
|
||||
|
@ -206,19 +184,19 @@ public:
|
|||
public:
|
||||
virtual srs_error_t start();
|
||||
virtual void stop();
|
||||
// interface ISrsMessagePumper
|
||||
// Interface ISrsMessagePumper
|
||||
public:
|
||||
virtual srs_error_t consume(SrsCommonMessage* msg);
|
||||
virtual bool interrupted();
|
||||
virtual void interrupt(srs_error_t err);
|
||||
virtual void on_start();
|
||||
virtual void on_stop();
|
||||
// interface IMergeReadHandler
|
||||
// Interface IMergeReadHandler
|
||||
public:
|
||||
#ifdef SRS_PERF_MERGED_READ
|
||||
virtual void on_read(ssize_t nread);
|
||||
#endif
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_publish(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);
|
||||
};
|
||||
|
||||
/**
|
||||
* The HTTP receive thread, try to read messages util EOF.
|
||||
* For example, the HTTP FLV serving thread will use the receive thread to break
|
||||
* when client closed the request, to avoid FD leak.
|
||||
* @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
|
||||
*/
|
||||
// The HTTP receive thread, try to read messages util EOF.
|
||||
// For example, the HTTP FLV serving thread will use the receive thread to break
|
||||
// when client closed the request, to avoid FD leak.
|
||||
// @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427
|
||||
class SrsHttpRecvThread : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -244,7 +220,7 @@ public:
|
|||
virtual srs_error_t start();
|
||||
public:
|
||||
virtual srs_error_t pull();
|
||||
// interface ISrsOneCycleThreadHandler
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
};
|
||||
|
|
|
@ -36,11 +36,9 @@ public:
|
|||
SrsRefer();
|
||||
virtual ~SrsRefer();
|
||||
public:
|
||||
/**
|
||||
* to check the refer.
|
||||
* @param page_url the client page url.
|
||||
* @param refer the refer in config.
|
||||
*/
|
||||
// Check the refer.
|
||||
// @param page_url the client page url.
|
||||
// @param refer the refer in config.
|
||||
virtual srs_error_t check(std::string page_url, SrsConfDirective* refer);
|
||||
private:
|
||||
virtual srs_error_t check_single_refer(std::string page_url, std::string refer);
|
||||
|
|
|
@ -28,13 +28,11 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* the handler for config reload.
|
||||
* when reload callback, the config is updated yet.
|
||||
*
|
||||
* features not support reload,
|
||||
* @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
|
||||
*/
|
||||
// The handler for config reload.
|
||||
// When reload callback, the config is updated yet.
|
||||
//
|
||||
// Features not support reload,
|
||||
// @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
|
||||
class ISrsReloadHandler
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -58,9 +58,7 @@ class SrsPacket;
|
|||
class ISrsKafkaCluster;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* The simple rtmp client for SRS.
|
||||
*/
|
||||
// The simple rtmp client for SRS.
|
||||
class SrsSimpleRtmpClient : public SrsBasicRtmpClient
|
||||
{
|
||||
public:
|
||||
|
@ -70,9 +68,7 @@ protected:
|
|||
virtual srs_error_t connect_app();
|
||||
};
|
||||
|
||||
/**
|
||||
* Some information of client.
|
||||
*/
|
||||
// Some information of client.
|
||||
class SrsClientInfo
|
||||
{
|
||||
public:
|
||||
|
@ -89,12 +85,10 @@ public:
|
|||
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
|
||||
{
|
||||
// for the thread to directly access any field of connection.
|
||||
// For the thread to directly access any field of connection.
|
||||
friend class SrsPublishRecvThread;
|
||||
private:
|
||||
SrsServer* server;
|
||||
|
@ -102,27 +96,27 @@ private:
|
|||
SrsRefer* refer;
|
||||
SrsBandwidth* bandwidth;
|
||||
SrsSecurity* security;
|
||||
// the wakable handler, maybe NULL.
|
||||
// The wakable handler, maybe NULL.
|
||||
// TODO: FIXME: Should refine the state for receiving thread.
|
||||
ISrsWakable* wakable;
|
||||
// elapse duration in srs_utime_t
|
||||
// for live play duration, for instance, rtmpdump to record.
|
||||
// The elapsed duration in srs_utime_t
|
||||
// For live play duration, for instance, rtmpdump to record.
|
||||
// @see https://github.com/ossrs/srs/issues/47
|
||||
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;
|
||||
// the MR(merged-write) only enabled for play.
|
||||
// The MR(merged-write) only enabled for play.
|
||||
int mw_enabled;
|
||||
// for realtime
|
||||
// For realtime
|
||||
// @see https://github.com/ossrs/srs/issues/257
|
||||
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;
|
||||
// publish 1st packet timeout in srs_utime_t
|
||||
// The publish 1st packet timeout in srs_utime_t
|
||||
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;
|
||||
// whether enable the tcp_nodelay.
|
||||
// Whether enable the tcp_nodelay.
|
||||
bool tcp_nodelay;
|
||||
// About the rtmp client.
|
||||
SrsClientInfo* info;
|
||||
|
@ -133,20 +127,20 @@ public:
|
|||
virtual void dispose();
|
||||
protected:
|
||||
virtual srs_error_t do_cycle();
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
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_tcp_nodelay(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);
|
||||
// interface ISrsKbpsDelta
|
||||
// Interface ISrsKbpsDelta
|
||||
public:
|
||||
virtual void remark(int64_t* in, int64_t* out);
|
||||
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();
|
||||
// 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 check_vhost(bool try_default_vhost);
|
||||
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 do_token_traverse_auth(SrsRtmpClient* client);
|
||||
private:
|
||||
/**
|
||||
* when the connection disconnect, call this method.
|
||||
* e.g. log msg of connection and report to other system.
|
||||
*/
|
||||
// When the connection disconnect, call this method.
|
||||
// e.g. log msg of connection and report to other system.
|
||||
virtual srs_error_t on_disconnect();
|
||||
private:
|
||||
virtual srs_error_t http_hooks_on_connect();
|
||||
|
|
|
@ -52,9 +52,7 @@ class SrsSimpleStream;
|
|||
class SrsPithyPrint;
|
||||
class SrsSimpleRtmpClient;
|
||||
|
||||
/**
|
||||
* a rtp connection which transport a stream.
|
||||
*/
|
||||
// A rtp connection which transport a stream.
|
||||
class SrsRtpConn: public ISrsUdpHandler
|
||||
{
|
||||
private:
|
||||
|
@ -70,14 +68,12 @@ public:
|
|||
public:
|
||||
virtual int port();
|
||||
virtual srs_error_t listen();
|
||||
// interface ISrsUdpHandler
|
||||
// Interface ISrsUdpHandler
|
||||
public:
|
||||
virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf);
|
||||
};
|
||||
|
||||
/**
|
||||
* audio is group by frames.
|
||||
*/
|
||||
// The audio cache, audio is grouped by frames.
|
||||
struct SrsRtspAudioCache
|
||||
{
|
||||
int64_t dts;
|
||||
|
@ -88,9 +84,7 @@ struct SrsRtspAudioCache
|
|||
virtual ~SrsRtspAudioCache();
|
||||
};
|
||||
|
||||
/**
|
||||
* the time jitter correct for rtsp.
|
||||
*/
|
||||
// The time jitter correct for rtsp.
|
||||
class SrsRtspJitter
|
||||
{
|
||||
private:
|
||||
|
@ -105,9 +99,7 @@ public:
|
|||
virtual srs_error_t correct(int64_t& ts);
|
||||
};
|
||||
|
||||
/**
|
||||
* the rtsp connection serve the fd.
|
||||
*/
|
||||
// The rtsp connection serve the fd.
|
||||
class SrsRtspConn : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
|
@ -156,7 +148,7 @@ private:
|
|||
// internal methods
|
||||
public:
|
||||
virtual srs_error_t on_rtp_packet(SrsRtpPacket* pkt, int stream_id);
|
||||
// interface ISrsOneCycleThreadHandler
|
||||
// Interface ISrsOneCycleThreadHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
|
@ -176,16 +168,14 @@ private:
|
|||
virtual void close();
|
||||
};
|
||||
|
||||
/**
|
||||
* the caster for rtsp.
|
||||
*/
|
||||
// The caster for rtsp.
|
||||
class SrsRtspCaster : public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
std::string output;
|
||||
int local_port_min;
|
||||
int local_port_max;
|
||||
// key: port, value: whether used.
|
||||
// The key: port, value: whether used.
|
||||
std::map<int, bool> used_ports;
|
||||
private:
|
||||
std::vector<SrsRtspConn*> clients;
|
||||
|
@ -193,19 +183,15 @@ public:
|
|||
SrsRtspCaster(SrsConfDirective* c);
|
||||
virtual ~SrsRtspCaster();
|
||||
public:
|
||||
/**
|
||||
* alloc a rtp port from local ports pool.
|
||||
* @param pport output the rtp port.
|
||||
*/
|
||||
// Alloc a rtp port from local ports pool.
|
||||
// @param pport output the rtp port.
|
||||
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);
|
||||
// interface ISrsTcpHandler
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
// internal methods.
|
||||
// internal methods.
|
||||
public:
|
||||
virtual void remove(SrsRtspConn* conn);
|
||||
};
|
||||
|
|
|
@ -32,33 +32,25 @@
|
|||
|
||||
class SrsConfDirective;
|
||||
|
||||
/**
|
||||
* the security apply on vhost.
|
||||
* @see https://github.com/ossrs/srs/issues/211
|
||||
*/
|
||||
// The security apply on vhost.
|
||||
// @see https://github.com/ossrs/srs/issues/211
|
||||
class SrsSecurity
|
||||
{
|
||||
public:
|
||||
SrsSecurity();
|
||||
virtual ~SrsSecurity();
|
||||
public:
|
||||
/**
|
||||
* security check the client apply by vhost security strategy
|
||||
* @param type the client type, publish or play.
|
||||
* @param ip the ip address of client.
|
||||
* @param req the request object of client.
|
||||
*/
|
||||
// Security check the client apply by vhost security strategy
|
||||
// @param type the client type, publish or play.
|
||||
// @param ip the ip address of client.
|
||||
// @param req the request object of client.
|
||||
virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest* req);
|
||||
private:
|
||||
/**
|
||||
* security check the allow,
|
||||
* @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
|
||||
*/
|
||||
// Security check the allow,
|
||||
// @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW.
|
||||
virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
|
||||
/**
|
||||
* security check the deny,
|
||||
* @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
|
||||
*/
|
||||
// Security check the deny,
|
||||
// @return, if denied, ERROR_SYSTEM_SECURITY_DENY.
|
||||
virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip);
|
||||
};
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class SrsKafkaProducer;
|
|||
#endif
|
||||
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.
|
||||
enum SrsListenerType
|
||||
{
|
||||
|
@ -73,9 +73,7 @@ enum SrsListenerType
|
|||
SrsListenerFlv = 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* the common tcp listener, for RTMP/HTTP server.
|
||||
*/
|
||||
// A common tcp listener, for RTMP/HTTP server.
|
||||
class SrsListener
|
||||
{
|
||||
protected:
|
||||
|
@ -92,9 +90,7 @@ public:
|
|||
virtual srs_error_t listen(std::string i, int p) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* tcp listener.
|
||||
*/
|
||||
// A buffered TCP listener.
|
||||
class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
|
@ -104,14 +100,12 @@ public:
|
|||
virtual ~SrsBufferListener();
|
||||
public:
|
||||
virtual srs_error_t listen(std::string ip, int port);
|
||||
// ISrsTcpHandler
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
};
|
||||
|
||||
/**
|
||||
* the tcp listener, for rtsp server.
|
||||
*/
|
||||
// A TCP listener, for rtsp server.
|
||||
class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
|
@ -122,14 +116,12 @@ public:
|
|||
virtual ~SrsRtspListener();
|
||||
public:
|
||||
virtual srs_error_t listen(std::string i, int p);
|
||||
// ISrsTcpHandler
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
};
|
||||
|
||||
/**
|
||||
* the tcp listener, for flv stream server.
|
||||
*/
|
||||
// A TCP listener, for flv stream server.
|
||||
class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler
|
||||
{
|
||||
private:
|
||||
|
@ -140,14 +132,12 @@ public:
|
|||
virtual ~SrsHttpFlvListener();
|
||||
public:
|
||||
virtual srs_error_t listen(std::string i, int p);
|
||||
// ISrsTcpHandler
|
||||
// Interface ISrsTcpHandler
|
||||
public:
|
||||
virtual srs_error_t on_tcp_client(srs_netfd_t stfd);
|
||||
};
|
||||
|
||||
/**
|
||||
* the udp listener, for udp server.
|
||||
*/
|
||||
// A UDP listener, for udp server.
|
||||
class SrsUdpStreamListener : public SrsListener
|
||||
{
|
||||
protected:
|
||||
|
@ -160,9 +150,7 @@ public:
|
|||
virtual srs_error_t listen(std::string i, int p);
|
||||
};
|
||||
|
||||
/**
|
||||
* the udp listener, for udp stream caster server.
|
||||
*/
|
||||
// A UDP listener, for udp stream caster server.
|
||||
class SrsUdpCasterListener : public SrsUdpStreamListener
|
||||
{
|
||||
public:
|
||||
|
@ -170,15 +158,13 @@ public:
|
|||
virtual ~SrsUdpCasterListener();
|
||||
};
|
||||
|
||||
/**
|
||||
* convert signal to io,
|
||||
* @see: st-1.9/docs/notes.html
|
||||
*/
|
||||
// Convert signal to io,
|
||||
// @see: st-1.9/docs/notes.html
|
||||
class SrsSignalManager : public ISrsCoroutineHandler
|
||||
{
|
||||
private:
|
||||
/* Per-process pipe which is used as a signal queue. */
|
||||
/* Up to PIPE_BUF/sizeof(int) signals can be queued up. */
|
||||
// Per-process pipe which is used as a signal queue.
|
||||
// Up to PIPE_BUF/sizeof(int) signals can be queued up.
|
||||
int sig_pipe[2];
|
||||
srs_netfd_t signal_read_stfd;
|
||||
private:
|
||||
|
@ -190,47 +176,34 @@ public:
|
|||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual srs_error_t start();
|
||||
// interface ISrsEndlessThreadHandler.
|
||||
// Interface ISrsEndlessThreadHandler.
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
private:
|
||||
// global singleton instance
|
||||
// Global singleton instance
|
||||
static SrsSignalManager* instance;
|
||||
/* Signal catching function. */
|
||||
/* Converts signal event to I/O event. */
|
||||
// Signal catching function.
|
||||
// Converts signal event to I/O event.
|
||||
static void sig_catcher(int signo);
|
||||
};
|
||||
|
||||
/**
|
||||
* the handler to the handle cycle in SRS RTMP server.
|
||||
*/
|
||||
// A handler to the handle cycle in SRS RTMP server.
|
||||
class ISrsServerCycle
|
||||
{
|
||||
public:
|
||||
ISrsServerCycle();
|
||||
virtual ~ISrsServerCycle();
|
||||
public:
|
||||
/**
|
||||
* initialize the cycle handler.
|
||||
*/
|
||||
// Initialize the cycle handler.
|
||||
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;
|
||||
/**
|
||||
* callback the handler when got client.
|
||||
*/
|
||||
// Callback the handler when got client.
|
||||
virtual srs_error_t on_accept_client(int max, int cur) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* SRS RTMP server, initialize and listen,
|
||||
* start connection service thread, destroy client.
|
||||
*/
|
||||
class SrsServer : virtual public ISrsReloadHandler
|
||||
, virtual public ISrsSourceHandler
|
||||
, virtual public IConnectionManager
|
||||
// SRS RTMP server, initialize and listen, start connection service thread, destroy client.
|
||||
class SrsServer : virtual public ISrsReloadHandler, virtual public ISrsSourceHandler, virtual public IConnectionManager
|
||||
{
|
||||
private:
|
||||
// TODO: FIXME: rename to http_api
|
||||
|
@ -240,59 +213,41 @@ private:
|
|||
SrsIngester* ingester;
|
||||
SrsCoroutineManager* conn_manager;
|
||||
private:
|
||||
/**
|
||||
* 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,
|
||||
* 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.
|
||||
*/
|
||||
// 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,
|
||||
// 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.
|
||||
int pid_fd;
|
||||
/**
|
||||
* all connections, connection manager
|
||||
*/
|
||||
// All connections, connection manager
|
||||
std::vector<SrsConnection*> conns;
|
||||
/**
|
||||
* all listners, listener manager.
|
||||
*/
|
||||
// All listners, listener manager.
|
||||
std::vector<SrsListener*> listeners;
|
||||
/**
|
||||
* signal manager which convert gignal to io message.
|
||||
*/
|
||||
// Signal manager which convert gignal to io message.
|
||||
SrsSignalManager* signal_manager;
|
||||
/**
|
||||
* handle in server cycle.
|
||||
*/
|
||||
// Handle in server cycle.
|
||||
ISrsServerCycle* handler;
|
||||
/**
|
||||
* user send the signal, convert to variable.
|
||||
*/
|
||||
// User send the signal, convert to variable.
|
||||
bool signal_reload;
|
||||
bool signal_persistence_config;
|
||||
bool signal_gmc_stop;
|
||||
bool signal_gracefully_quit;
|
||||
// parent pid for asprocess.
|
||||
// Parent pid for asprocess.
|
||||
int ppid;
|
||||
public:
|
||||
SrsServer();
|
||||
virtual ~SrsServer();
|
||||
private:
|
||||
/**
|
||||
* the destroy is for gmc to analysis the memory leak,
|
||||
* if not destroy global/static data, the gmc will warning memory leak.
|
||||
* in service, server never destroy, directly exit when restart.
|
||||
*/
|
||||
// The destroy is for gmc to analysis the memory leak,
|
||||
// if not destroy global/static data, the gmc will warning memory leak.
|
||||
// In service, server never destroy, directly exit when restart.
|
||||
virtual void destroy();
|
||||
/**
|
||||
* when SIGTERM, SRS should do cleanup, for example,
|
||||
* to stop all ingesters, cleanup HLS and dvr.
|
||||
*/
|
||||
// When SIGTERM, SRS should do cleanup, for example,
|
||||
// to stop all ingesters, cleanup HLS and dvr.
|
||||
virtual void dispose();
|
||||
// server startup workflow, @see run_master()
|
||||
public:
|
||||
/**
|
||||
* initialize server with callback handler ch.
|
||||
* @remark user must free the handler.
|
||||
*/
|
||||
// Initialize server with callback handler ch.
|
||||
// @remark user must free the handler.
|
||||
virtual srs_error_t initialize(ISrsServerCycle* ch);
|
||||
virtual srs_error_t initialize_st();
|
||||
virtual srs_error_t initialize_signal();
|
||||
|
@ -304,64 +259,50 @@ public:
|
|||
virtual srs_error_t cycle();
|
||||
// server utilities.
|
||||
public:
|
||||
/**
|
||||
* callback for signal manager got a signal.
|
||||
* the signal manager convert signal to io message,
|
||||
* whatever, we will got the signo like the orignal signal(int signo) handler.
|
||||
* @param signo the signal number from user, where:
|
||||
* SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit.
|
||||
* SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file.
|
||||
* SRS_SIGNAL_RELOAD, the SIGHUP, reload the config.
|
||||
* SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file.
|
||||
* @remark, for SIGINT:
|
||||
* no gmc, directly exit.
|
||||
* 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.
|
||||
*/
|
||||
// The callback for signal manager got a signal.
|
||||
// The signal manager convert signal to io message,
|
||||
// whatever, we will got the signo like the orignal signal(int signo) handler.
|
||||
// @param signo the signal number from user, where:
|
||||
// SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit.
|
||||
// SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file.
|
||||
// SRS_SIGNAL_RELOAD, the SIGHUP, reload the config.
|
||||
// SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file.
|
||||
// @remark, for SIGINT:
|
||||
// no gmc, directly exit.
|
||||
// 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.
|
||||
virtual void on_signal(int signo);
|
||||
private:
|
||||
/**
|
||||
* the server thread main cycle,
|
||||
* update the global static data, for instance, the current time,
|
||||
* the cpu/mem/network statistic.
|
||||
*/
|
||||
// The server thread main cycle,
|
||||
// update the global static data, for instance, the current time,
|
||||
// the cpu/mem/network statistic.
|
||||
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_http_api();
|
||||
virtual srs_error_t listen_http_stream();
|
||||
virtual srs_error_t listen_stream_caster();
|
||||
/**
|
||||
* close the listeners for specified type,
|
||||
* remove the listen object from manager.
|
||||
*/
|
||||
// Close the listeners for specified type,
|
||||
// Remove the listen object from manager.
|
||||
virtual void close_listeners(SrsListenerType type);
|
||||
/**
|
||||
* resample the server kbs.
|
||||
*/
|
||||
// Resample the server kbs.
|
||||
virtual void resample_kbps();
|
||||
// internal only
|
||||
// For internal only
|
||||
public:
|
||||
/**
|
||||
* when listener got a fd, notice server to accept it.
|
||||
* @param type, the client type, used to create concrete connection,
|
||||
* for instance RTMP connection to serve client.
|
||||
* @param stfd, the client fd in st boxed, the underlayer fd.
|
||||
*/
|
||||
// When listener got a fd, notice server to accept it.
|
||||
// @param type, the client type, used to create concrete connection,
|
||||
// for instance RTMP connection to serve client.
|
||||
// @param stfd, the client fd in st boxed, the underlayer fd.
|
||||
virtual srs_error_t accept_client(SrsListenerType type, srs_netfd_t stfd);
|
||||
private:
|
||||
virtual srs_error_t fd2conn(SrsListenerType type, srs_netfd_t stfd, SrsConnection** pconn);
|
||||
// IConnectionManager
|
||||
// Interface IConnectionManager
|
||||
public:
|
||||
/**
|
||||
* callback for connection to remove itself.
|
||||
* when connection thread cycle terminated, callback this to delete connection.
|
||||
* @see SrsConnection.on_thread_stop().
|
||||
*/
|
||||
// A callback for connection to remove itself.
|
||||
// When connection thread cycle terminated, callback this to delete connection.
|
||||
// @see SrsConnection.on_thread_stop().
|
||||
virtual void remove(ISrsConnection* c);
|
||||
// interface ISrsReloadHandler.
|
||||
// Interface ISrsReloadHandler.
|
||||
public:
|
||||
virtual srs_error_t on_reload_listen();
|
||||
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_disabled();
|
||||
virtual srs_error_t on_reload_http_stream_updated();
|
||||
// interface ISrsSourceHandler
|
||||
// Interface ISrsSourceHandler
|
||||
public:
|
||||
virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r);
|
||||
virtual void on_unpublish(SrsSource* s, SrsRequest* r);
|
||||
|
|
|
@ -1590,9 +1590,7 @@ srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPac
|
|||
|
||||
// add server info to metadata
|
||||
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
|
||||
// add version to metadata, please donot remove it, for debug.
|
||||
metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
|
||||
|
|
|
@ -61,12 +61,10 @@ class SrsBuffer;
|
|||
class SrsHds;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* the time jitter algorithm:
|
||||
* 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
|
||||
* 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
|
||||
* 3. off, disable the time jitter algorithm, like atc.
|
||||
*/
|
||||
// The time jitter algorithm:
|
||||
// 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
|
||||
// 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
|
||||
// 3. off, disable the time jitter algorithm, like atc.
|
||||
enum SrsRtmpJitterAlgorithm
|
||||
{
|
||||
SrsRtmpJitterAlgorithmFULL = 0x01,
|
||||
|
@ -75,10 +73,7 @@ enum SrsRtmpJitterAlgorithm
|
|||
};
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
@ -88,23 +83,16 @@ public:
|
|||
SrsRtmpJitter();
|
||||
virtual ~SrsRtmpJitter();
|
||||
public:
|
||||
/**
|
||||
* detect the time jitter and correct it.
|
||||
* @param ag the algorithm to use for time jitter.
|
||||
*/
|
||||
// detect the time jitter and correct it.
|
||||
// @param ag the algorithm to use for time jitter.
|
||||
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();
|
||||
};
|
||||
|
||||
#ifdef SRS_PERF_QUEUE_FAST_VECTOR
|
||||
/**
|
||||
* to alloc and increase fixed space,
|
||||
* fast remove and insert for msgs sender.
|
||||
* @see https://github.com/ossrs/srs/issues/251
|
||||
*/
|
||||
// To alloc and increase fixed space, fast remove and insert for msgs sender.
|
||||
// @see https://github.com/ossrs/srs/issues/251
|
||||
class SrsFastVector
|
||||
{
|
||||
private:
|
||||
|
@ -127,10 +115,8 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* the message queue for the consumer(client), forwarder.
|
||||
* we limit the size in seconds, drop old messages(the whole gop) if full.
|
||||
*/
|
||||
// The message queue for the consumer(client), forwarder.
|
||||
// We limit the size in seconds, drop old messages(the whole gop) if full.
|
||||
class SrsMessageQueue
|
||||
{
|
||||
private:
|
||||
|
@ -151,85 +137,63 @@ public:
|
|||
SrsMessageQueue(bool ignore_shrink = false);
|
||||
virtual ~SrsMessageQueue();
|
||||
public:
|
||||
/**
|
||||
* get the size of queue.
|
||||
*/
|
||||
// Get the size of queue.
|
||||
virtual int size();
|
||||
/**
|
||||
* get the duration of queue.
|
||||
*/
|
||||
// Get the duration of queue.
|
||||
virtual srs_utime_t duration();
|
||||
/**
|
||||
* set the queue size
|
||||
* @param queue_size the queue size in srs_utime_t.
|
||||
*/
|
||||
// Set the queue size
|
||||
// @param queue_size the queue size in srs_utime_t.
|
||||
virtual void set_queue_size(srs_utime_t queue_size);
|
||||
public:
|
||||
/**
|
||||
* enqueue the message, the timestamp always monotonically.
|
||||
* @param msg, the msg to enqueue, user never free it whatever the return code.
|
||||
* @param is_overflow, whether overflow and shrinked. NULL to ignore.
|
||||
*/
|
||||
// Enqueue the message, the timestamp always monotonically.
|
||||
// @param msg, the msg to enqueue, user never free it whatever the return code.
|
||||
// @param is_overflow, whether overflow and shrinked. NULL to ignore.
|
||||
virtual srs_error_t enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL);
|
||||
/**
|
||||
* get packets in consumer queue.
|
||||
* @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it.
|
||||
* @count the count in array, output param.
|
||||
* @max_count the max count to dequeue, must be positive.
|
||||
*/
|
||||
// Get packets in consumer queue.
|
||||
// @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it.
|
||||
// @count the count in array, output param.
|
||||
// @max_count the max count to dequeue, must be positive.
|
||||
virtual srs_error_t dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count);
|
||||
/**
|
||||
* dumps packets to consumer, use specified args.
|
||||
* @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
|
||||
*/
|
||||
// Dumps packets to consumer, use specified args.
|
||||
// @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
|
||||
virtual srs_error_t dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag);
|
||||
private:
|
||||
/**
|
||||
* remove a gop from the front.
|
||||
* if no iframe found, clear it.
|
||||
*/
|
||||
// Remove a gop from the front.
|
||||
// if no iframe found, clear it.
|
||||
virtual void shrink();
|
||||
public:
|
||||
/**
|
||||
* clear all messages in queue.
|
||||
*/
|
||||
// clear all messages in queue.
|
||||
virtual void clear();
|
||||
};
|
||||
|
||||
/**
|
||||
* the wakable used for some object
|
||||
* which is waiting on cond.
|
||||
*/
|
||||
// The wakable used for some object
|
||||
// which is waiting on cond.
|
||||
class ISrsWakable
|
||||
{
|
||||
public:
|
||||
ISrsWakable();
|
||||
virtual ~ISrsWakable();
|
||||
public:
|
||||
/**
|
||||
* when the consumer(for player) got msg from recv thread,
|
||||
* it must be processed for maybe it's a close msg, so the cond
|
||||
* wait must be wakeup.
|
||||
*/
|
||||
// when the consumer(for player) got msg from recv thread,
|
||||
// it must be processed for maybe it's a close msg, so the cond
|
||||
// wait must be wakeup.
|
||||
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
|
||||
{
|
||||
private:
|
||||
SrsRtmpJitter* jitter;
|
||||
SrsSource* source;
|
||||
SrsMessageQueue* queue;
|
||||
// the owner connection for debug, maybe NULL.
|
||||
// The owner connection for debug, maybe NULL.
|
||||
SrsConnection* conn;
|
||||
bool paused;
|
||||
// when source id changed, notice all consumers
|
||||
bool should_update_source_id;
|
||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||
// the cond wait for mw.
|
||||
// The cond wait for mw.
|
||||
// @see https://github.com/ossrs/srs/issues/251
|
||||
srs_cond_t mw_wait;
|
||||
bool mw_waiting;
|
||||
|
@ -240,159 +204,109 @@ public:
|
|||
SrsConsumer(SrsSource* s, SrsConnection* c);
|
||||
virtual ~SrsConsumer();
|
||||
public:
|
||||
/**
|
||||
* set the size of queue.
|
||||
*/
|
||||
// Set the size of queue.
|
||||
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();
|
||||
public:
|
||||
/**
|
||||
* get current client time, the last packet time.
|
||||
*/
|
||||
// Get current client time, the last packet time.
|
||||
virtual int64_t get_time();
|
||||
/**
|
||||
* enqueue an shared ptr message.
|
||||
* @param shared_msg, directly ptr, copy it if need to save it.
|
||||
* @param whether atc, donot use jitter correct if true.
|
||||
* @param ag the algorithm of time jitter.
|
||||
*/
|
||||
// Enqueue an shared ptr message.
|
||||
// @param shared_msg, directly ptr, copy it if need to save it.
|
||||
// @param whether atc, donot use jitter correct if true.
|
||||
// @param ag the algorithm of time jitter.
|
||||
virtual srs_error_t enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag);
|
||||
/**
|
||||
* get packets in consumer queue.
|
||||
* @param msgs the msgs array to dump packets to send.
|
||||
* @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.
|
||||
*/
|
||||
// Get packets in consumer queue.
|
||||
// @param msgs the msgs array to dump packets to send.
|
||||
// @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.
|
||||
virtual srs_error_t dump_packets(SrsMessageArray* msgs, int& count);
|
||||
#ifdef SRS_PERF_QUEUE_COND_WAIT
|
||||
/**
|
||||
* wait for messages incomming, atleast nb_msgs and in duration.
|
||||
* @param nb_msgs the messages count to wait.
|
||||
* @param msgs_duration the messages duration to wait.
|
||||
*/
|
||||
// wait for messages incomming, atleast nb_msgs and in duration.
|
||||
// @param nb_msgs the messages count to wait.
|
||||
// @param msgs_duration the messages duration to wait.
|
||||
virtual void wait(int nb_msgs, srs_utime_t msgs_duration);
|
||||
#endif
|
||||
/**
|
||||
* when client send the pause message.
|
||||
*/
|
||||
// when client send the pause message.
|
||||
virtual srs_error_t on_play_client_pause(bool is_pause);
|
||||
// ISrsWakable
|
||||
// Interface ISrsWakable
|
||||
public:
|
||||
/**
|
||||
* when the consumer(for player) got msg from recv thread,
|
||||
* it must be processed for maybe it's a close msg, so the cond
|
||||
* wait must be wakeup.
|
||||
*/
|
||||
// when the consumer(for player) got msg from recv thread,
|
||||
// it must be processed for maybe it's a close msg, so the cond
|
||||
// wait must be wakeup.
|
||||
virtual void wakeup();
|
||||
};
|
||||
|
||||
/**
|
||||
* cache a gop of video/audio data,
|
||||
* delivery at the connect of flash player,
|
||||
* to enable it to fast startup.
|
||||
*/
|
||||
// cache a gop of video/audio data,
|
||||
// delivery at the connect of flash player,
|
||||
// To enable it to fast startup.
|
||||
class SrsGopCache
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* if disabled the gop cache,
|
||||
* the client will wait for the next keyframe for h264,
|
||||
* and will be black-screen.
|
||||
*/
|
||||
// if disabled the gop cache,
|
||||
// The client will wait for the next keyframe for h264,
|
||||
// and will be black-screen.
|
||||
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;
|
||||
/**
|
||||
* when user disabled video when publishing, and gop cache enalbed,
|
||||
* 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,
|
||||
* so we must guess whether user disabled the video.
|
||||
* when we got some audios after laster video, for instance, 600 audio packets,
|
||||
* about 3s(26ms per packet) 115 audio packets, clear gop cache.
|
||||
*
|
||||
* @remark, it is ok for performance, for when we clear the gop cache,
|
||||
* gop cache is disabled for pure audio stream.
|
||||
* @see: https://github.com/ossrs/srs/issues/124
|
||||
*/
|
||||
// when user disabled video when publishing, and gop cache enalbed,
|
||||
// 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,
|
||||
// so we must guess whether user disabled the video.
|
||||
// when we got some audios after laster video, for instance, 600 audio packets,
|
||||
// about 3s(26ms per packet) 115 audio packets, clear gop cache.
|
||||
//
|
||||
// @remark, it is ok for performance, for when we clear the gop cache,
|
||||
// gop cache is disabled for pure audio stream.
|
||||
// @see: https://github.com/ossrs/srs/issues/124
|
||||
int audio_after_last_video_count;
|
||||
/**
|
||||
* cached gop.
|
||||
*/
|
||||
// cached gop.
|
||||
std::vector<SrsSharedPtrMessage*> gop_cache;
|
||||
public:
|
||||
SrsGopCache();
|
||||
virtual ~SrsGopCache();
|
||||
public:
|
||||
/**
|
||||
* cleanup when system quit.
|
||||
*/
|
||||
// cleanup when system quit.
|
||||
virtual void dispose();
|
||||
/**
|
||||
* to enable or disable the gop cache.
|
||||
*/
|
||||
// To enable or disable the gop cache.
|
||||
virtual void set(bool v);
|
||||
virtual bool enabled();
|
||||
/**
|
||||
* only for h264 codec
|
||||
* 1. cache the gop when got h264 video packet.
|
||||
* 2. clear gop when got keyframe.
|
||||
* @param shared_msg, directly ptr, copy it if need to save it.
|
||||
*/
|
||||
// only for h264 codec
|
||||
// 1. cache the gop when got h264 video packet.
|
||||
// 2. clear gop when got keyframe.
|
||||
// @param shared_msg, directly ptr, copy it if need to save it.
|
||||
virtual srs_error_t cache(SrsSharedPtrMessage* shared_msg);
|
||||
/**
|
||||
* clear the gop cache.
|
||||
*/
|
||||
// clear the gop cache.
|
||||
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);
|
||||
/**
|
||||
* used for atc to get the time of gop cache,
|
||||
* the atc will adjust the sequence header timestamp to gop cache.
|
||||
*/
|
||||
// used for atc to get the time of gop cache,
|
||||
// The atc will adjust the sequence header timestamp to gop cache.
|
||||
virtual bool empty();
|
||||
/**
|
||||
* get the start time of gop cache, in srs_utime_t.
|
||||
* @return 0 if no packets.
|
||||
*/
|
||||
// Get the start time of gop cache, in srs_utime_t.
|
||||
// @return 0 if no packets.
|
||||
virtual srs_utime_t start_time();
|
||||
/**
|
||||
* whether current stream is pure audio,
|
||||
* when no video in gop cache, the stream is pure audio right now.
|
||||
*/
|
||||
// whether current stream is pure audio,
|
||||
// when no video in gop cache, the stream is pure audio right now.
|
||||
virtual bool pure_audio();
|
||||
};
|
||||
|
||||
/**
|
||||
* the handler to handle the event of srs source.
|
||||
* for example, the http flv streaming module handle the event and
|
||||
* mount http when rtmp start publishing.
|
||||
*/
|
||||
// The handler to handle the event of srs source.
|
||||
// For example, the http flv streaming module handle the event and
|
||||
// mount http when rtmp start publishing.
|
||||
class ISrsSourceHandler
|
||||
{
|
||||
public:
|
||||
ISrsSourceHandler();
|
||||
virtual ~ISrsSourceHandler();
|
||||
public:
|
||||
/**
|
||||
* when stream start publish, mount stream.
|
||||
*/
|
||||
// when stream start publish, mount stream.
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* the mix queue to correct the timestamp for mix_correct algorithm.
|
||||
*/
|
||||
// The mix queue to correct the timestamp for mix_correct algorithm.
|
||||
class SrsMixQueue
|
||||
{
|
||||
private:
|
||||
|
@ -408,11 +322,9 @@ public:
|
|||
virtual SrsSharedPtrMessage* pop();
|
||||
};
|
||||
|
||||
/**
|
||||
* The hub for origin is a collection of utilities for origin only,
|
||||
* for example, DVR, HLS, Forward and Transcode are only available for origin,
|
||||
* they are meanless for edge server.
|
||||
*/
|
||||
// The hub for origin is a collection of utilities for origin only,
|
||||
// For example, DVR, HLS, Forward and Transcode are only available for origin,
|
||||
// they are meanless for edge server.
|
||||
class SrsOriginHub : public ISrsReloadHandler
|
||||
{
|
||||
private:
|
||||
|
@ -437,7 +349,7 @@ private:
|
|||
#endif
|
||||
// nginx-rtmp exec feature.
|
||||
SrsNgExec* ng_exec;
|
||||
// to forward stream to other servers
|
||||
// To forward stream to other servers
|
||||
std::vector<SrsForwarder*> forwarders;
|
||||
public:
|
||||
SrsOriginHub();
|
||||
|
@ -447,10 +359,10 @@ public:
|
|||
// @param r The request object, managed by source.
|
||||
virtual srs_error_t initialize(SrsSource* s, SrsRequest* r);
|
||||
// Dispose the hub, release utilities resource,
|
||||
// for example, delete all HLS pieces.
|
||||
// For example, delete all HLS pieces.
|
||||
virtual void dispose();
|
||||
// Cycle the hub, process some regular events,
|
||||
// for example, dispose hls in cycle.
|
||||
// For example, dispose hls in cycle.
|
||||
virtual srs_error_t cycle();
|
||||
public:
|
||||
// When got a parsed metadata.
|
||||
|
@ -466,11 +378,11 @@ public:
|
|||
virtual void on_unpublish();
|
||||
// Internal callback.
|
||||
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);
|
||||
// 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();
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_forward(std::string vhost);
|
||||
virtual srs_error_t on_reload_vhost_dash(std::string vhost);
|
||||
|
@ -484,10 +396,8 @@ private:
|
|||
virtual void destroy_forwarders();
|
||||
};
|
||||
|
||||
/**
|
||||
* Each stream have optional meta(sps/pps in sequence header and metadata).
|
||||
* This class cache and update the meta.
|
||||
*/
|
||||
// Each stream have optional meta(sps/pps in sequence header and metadata).
|
||||
// This class cache and update the meta.
|
||||
class SrsMetaCache
|
||||
{
|
||||
private:
|
||||
|
@ -528,46 +438,35 @@ public:
|
|||
virtual srs_error_t update_vsh(SrsSharedPtrMessage* msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* live streaming source.
|
||||
*/
|
||||
// live streaming source.
|
||||
class SrsSource : public ISrsReloadHandler
|
||||
{
|
||||
friend class SrsOriginHub;
|
||||
private:
|
||||
static std::map<std::string, SrsSource*> pool;
|
||||
public:
|
||||
/**
|
||||
* create source when fetch from cache failed.
|
||||
* @param r the client request.
|
||||
* @param h the event handler for source.
|
||||
* @param pps the matched source, if success never be NULL.
|
||||
*/
|
||||
// create source when fetch from cache failed.
|
||||
// @param r the client request.
|
||||
// @param h the event handler for source.
|
||||
// @param pps the matched source, if success never be NULL.
|
||||
static srs_error_t fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps);
|
||||
private:
|
||||
/**
|
||||
* get the exists source, NULL when not exists.
|
||||
* update the request and return the exists source.
|
||||
*/
|
||||
// Get the exists source, NULL when not exists.
|
||||
// update the request and return the exists source.
|
||||
static SrsSource* fetch(SrsRequest* r);
|
||||
public:
|
||||
/**
|
||||
* dispose and cycle all sources.
|
||||
*/
|
||||
// dispose and cycle all sources.
|
||||
static void dispose_all();
|
||||
static srs_error_t cycle_all();
|
||||
private:
|
||||
static srs_error_t do_cycle_all();
|
||||
public:
|
||||
/**
|
||||
* when system exit, destroy the sources,
|
||||
* for gmc to analysis mem leaks.
|
||||
*/
|
||||
// when system exit, destroy the sources,
|
||||
// For gmc to analysis mem leaks.
|
||||
static void destroy();
|
||||
private:
|
||||
// source id,
|
||||
// for publish, it's the publish client id.
|
||||
// for edge, it's the edge ingest id.
|
||||
// For publish, it's the publish client id.
|
||||
// For edge, it's the edge ingest id.
|
||||
// when source id changed, for example, the edge reconnect,
|
||||
// invoke the on_source_id_changed() to let all clients know.
|
||||
int _source_id;
|
||||
|
@ -575,31 +474,29 @@ private:
|
|||
int _pre_source_id;
|
||||
// deep copy of client request.
|
||||
SrsRequest* req;
|
||||
// to delivery stream to clients.
|
||||
// To delivery stream to clients.
|
||||
std::vector<SrsConsumer*> consumers;
|
||||
// the time jitter algorithm for vhost.
|
||||
// The time jitter algorithm for vhost.
|
||||
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;
|
||||
// the mix queue to implements the mix correct algorithm.
|
||||
// The mix queue to implements the mix correct algorithm.
|
||||
SrsMixQueue* mix_queue;
|
||||
/**
|
||||
* for play, whether enabled atc.
|
||||
* atc whether atc(use absolute time and donot adjust time),
|
||||
* directly use msg time and donot adjust if atc is true,
|
||||
* otherwise, adjust msg time to start from 0 to make flash happy.
|
||||
*/
|
||||
// For play, whether enabled atc.
|
||||
// The atc(use absolute time and donot adjust time),
|
||||
// directly use msg time and donot adjust if atc is true,
|
||||
// otherwise, adjust msg time to start from 0 to make flash happy.
|
||||
bool atc;
|
||||
// whether stream 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;
|
||||
// the event handler.
|
||||
// The event handler.
|
||||
ISrsSourceHandler* handler;
|
||||
// edge control service
|
||||
// The edge control service
|
||||
SrsPlayEdge* play_edge;
|
||||
SrsPublishEdge* publish_edge;
|
||||
// gop cache for client fast startup.
|
||||
// The gop cache for client fast startup.
|
||||
SrsGopCache* gop_cache;
|
||||
// The hub for origin server.
|
||||
SrsOriginHub* hub;
|
||||
|
@ -609,7 +506,7 @@ private:
|
|||
// Whether source is avaiable for publishing.
|
||||
bool _can_publish;
|
||||
// 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;
|
||||
public:
|
||||
SrsSource();
|
||||
|
@ -617,26 +514,23 @@ public:
|
|||
public:
|
||||
virtual void dispose();
|
||||
virtual srs_error_t cycle();
|
||||
// remove source when expired.
|
||||
// Remove source when expired.
|
||||
virtual bool expired();
|
||||
// initialize, get and setter.
|
||||
public:
|
||||
// initialize the hls with handlers.
|
||||
// Initialize the hls with handlers.
|
||||
virtual srs_error_t initialize(SrsRequest* r, ISrsSourceHandler* h);
|
||||
// interface ISrsReloadHandler
|
||||
// Interface ISrsReloadHandler
|
||||
public:
|
||||
virtual srs_error_t on_reload_vhost_play(std::string vhost);
|
||||
// for the tools callback
|
||||
public:
|
||||
// source id changed.
|
||||
// The source id changed.
|
||||
virtual srs_error_t on_source_id_changed(int id);
|
||||
// get current source id.
|
||||
// Get current source id.
|
||||
virtual int source_id();
|
||||
virtual int pre_source_id();
|
||||
// Whether source is inactive, which means there is no publishing stream source.
|
||||
// @remark For edge, it's inactive util stream has been pulled from origin.
|
||||
virtual bool inactive();
|
||||
// logic data methods
|
||||
public:
|
||||
virtual bool can_publish(bool is_edge);
|
||||
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);
|
||||
public:
|
||||
virtual srs_error_t on_aggregate(SrsCommonMessage* msg);
|
||||
/**
|
||||
* publish stream event notify.
|
||||
* @param _req the request from client, the source will deep copy it,
|
||||
* for when reload the request of client maybe invalid.
|
||||
*/
|
||||
// Publish stream event notify.
|
||||
// @param _req the request from client, the source will deep copy it,
|
||||
// for when reload the request of client maybe invalid.
|
||||
virtual srs_error_t on_publish();
|
||||
virtual void on_unpublish();
|
||||
// consumer methods
|
||||
public:
|
||||
/**
|
||||
* create consumer and dumps packets in cache.
|
||||
* @param consumer, output the create consumer.
|
||||
* @param ds, whether dumps the sequence header.
|
||||
* @param dm, whether dumps the metadata.
|
||||
* @param dg, whether dumps the gop cache.
|
||||
*/
|
||||
// Create consumer and dumps packets in cache.
|
||||
// @param consumer, output the create consumer.
|
||||
// @param ds, whether dumps the sequence header.
|
||||
// @param dm, whether dumps the metadata.
|
||||
// @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 void on_consumer_destroy(SrsConsumer* consumer);
|
||||
virtual void set_cache(bool enabled);
|
||||
virtual SrsRtmpJitterAlgorithm jitter();
|
||||
// internal
|
||||
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();
|
||||
// for edge, proxy the publish
|
||||
// For edge, proxy the publish
|
||||
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();
|
||||
public:
|
||||
virtual std::string get_curr_origin();
|
||||
|
|
|
@ -31,49 +31,43 @@
|
|||
#include <srs_service_st.hpp>
|
||||
#include <srs_protocol_io.hpp>
|
||||
|
||||
/**
|
||||
* Each ST-coroutine must implements this interface,
|
||||
* to do the cycle job and handle some events.
|
||||
*
|
||||
* Thread do a job then terminated normally, it's a SrsOneCycleThread:
|
||||
* class SrsOneCycleThread : public ISrsCoroutineHandler {
|
||||
* public: SrsCoroutine trd;
|
||||
* public: virtual srs_error_t cycle() {
|
||||
* // Do something, then return this cycle and thread terminated normally.
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* Thread has its inside loop, such as the RTMP receive thread:
|
||||
* class SrsReceiveThread : public ISrsCoroutineHandler {
|
||||
* public: SrsCoroutine* trd;
|
||||
* public: virtual srs_error_t cycle() {
|
||||
* while (true) {
|
||||
* // Check whether thread interrupted.
|
||||
* if ((err = trd->pull()) != srs_success) {
|
||||
* return err;
|
||||
* }
|
||||
* // Do something, such as st_read() packets, it'll be wakeup
|
||||
* // when user stop or interrupt the thread.
|
||||
* }
|
||||
* }
|
||||
* };
|
||||
*/
|
||||
// Each ST-coroutine must implements this interface,
|
||||
// to do the cycle job and handle some events.
|
||||
//
|
||||
// Thread do a job then terminated normally, it's a SrsOneCycleThread:
|
||||
// class SrsOneCycleThread : public ISrsCoroutineHandler {
|
||||
// public: SrsCoroutine trd;
|
||||
// public: virtual srs_error_t cycle() {
|
||||
// // Do something, then return this cycle and thread terminated normally.
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// Thread has its inside loop, such as the RTMP receive thread:
|
||||
// class SrsReceiveThread : public ISrsCoroutineHandler {
|
||||
// public: SrsCoroutine* trd;
|
||||
// public: virtual srs_error_t cycle() {
|
||||
// while (true) {
|
||||
// // Check whether thread interrupted.
|
||||
// if ((err = trd->pull()) != srs_success) {
|
||||
// return err;
|
||||
// }
|
||||
// // Do something, such as st_read() packets, it'll be wakeup
|
||||
// // when user stop or interrupt the thread.
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
class ISrsCoroutineHandler
|
||||
{
|
||||
public:
|
||||
ISrsCoroutineHandler();
|
||||
virtual ~ISrsCoroutineHandler();
|
||||
public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
// 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.
|
||||
virtual srs_error_t cycle() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The corotine object.
|
||||
*/
|
||||
// The corotine object.
|
||||
class SrsCoroutine
|
||||
{
|
||||
public:
|
||||
|
@ -89,10 +83,8 @@ public:
|
|||
virtual int cid() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* An empty coroutine, user can default to this object before create any real coroutine.
|
||||
* @see https://github.com/ossrs/srs/pull/908
|
||||
*/
|
||||
// An empty coroutine, user can default to this object before create any real coroutine.
|
||||
// @see https://github.com/ossrs/srs/pull/908
|
||||
class SrsDummyCoroutine : public SrsCoroutine
|
||||
{
|
||||
public:
|
||||
|
@ -110,20 +102,18 @@ public:
|
|||
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;
|
||||
|
||||
/**
|
||||
* A ST-coroutine is a lightweight thread, just like the goroutine.
|
||||
* 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
|
||||
* problem in multiple threads. For SRS, we only use single thread module,
|
||||
* like NGINX to get very high performance, with asynchronous and non-blocking
|
||||
* sockets.
|
||||
* @reamrk For multiple processes, please use go-oryx to fork many SRS processes.
|
||||
* Please read https://github.com/ossrs/go-oryx
|
||||
* @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
|
||||
* @remark We always create joinable thread, so we must join it or memory leak,
|
||||
* Please read https://github.com/ossrs/srs/issues/78
|
||||
*/
|
||||
// A ST-coroutine is a lightweight thread, just like the goroutine.
|
||||
// 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
|
||||
// problem in multiple threads. For SRS, we only use single thread module,
|
||||
// like NGINX to get very high performance, with asynchronous and non-blocking
|
||||
// sockets.
|
||||
// @reamrk For multiple processes, please use go-oryx to fork many SRS processes.
|
||||
// Please read https://github.com/ossrs/go-oryx
|
||||
// @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
|
||||
// @remark We always create joinable thread, so we must join it or memory leak,
|
||||
// Please read https://github.com/ossrs/srs/issues/78
|
||||
class SrsSTCoroutine : public SrsCoroutine
|
||||
{
|
||||
private:
|
||||
|
@ -145,35 +135,25 @@ public:
|
|||
SrsSTCoroutine(const std::string& n, ISrsCoroutineHandler* h, int cid = 0);
|
||||
virtual ~SrsSTCoroutine();
|
||||
public:
|
||||
/**
|
||||
* Start the thread.
|
||||
* @remark Should never start it when stopped or terminated.
|
||||
*/
|
||||
// Start the thread.
|
||||
// @remark Should never start it when stopped or terminated.
|
||||
virtual srs_error_t start();
|
||||
/**
|
||||
* Interrupt the thread then wait to terminated.
|
||||
* @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
|
||||
* to terminate then use stop to wait for each to terminate.
|
||||
*/
|
||||
// Interrupt the thread then wait to terminated.
|
||||
// @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
|
||||
// to terminate then use stop to wait for each to terminate.
|
||||
virtual void stop();
|
||||
/**
|
||||
* 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,
|
||||
* finally the thread should terminated normally, user can use the stop to join it.
|
||||
*/
|
||||
// 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,
|
||||
// finally the thread should terminated normally, user can use the stop to join it.
|
||||
virtual void interrupt();
|
||||
/**
|
||||
* Check whether thread is terminated normally or error(stopped or termianted with error),
|
||||
* and the thread should be running if it return ERROR_SUCCESS.
|
||||
* @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_INTERRUPED when thread is interrupted.
|
||||
*/
|
||||
// Check whether thread is terminated normally or error(stopped or termianted with error),
|
||||
// and the thread should be running if it return ERROR_SUCCESS.
|
||||
// @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_INTERRUPED when thread is interrupted.
|
||||
virtual srs_error_t pull();
|
||||
/**
|
||||
* Get the context id of thread.
|
||||
*/
|
||||
// Get the context id of thread.
|
||||
virtual int cid();
|
||||
private:
|
||||
virtual srs_error_t cycle();
|
||||
|
|
|
@ -48,9 +48,7 @@ public:
|
|||
int nb_streams;
|
||||
int nb_clients;
|
||||
public:
|
||||
/**
|
||||
* vhost total kbps.
|
||||
*/
|
||||
// The vhost total kbps.
|
||||
SrsKbps* kbps;
|
||||
SrsWallClock* clk;
|
||||
public:
|
||||
|
@ -73,19 +71,17 @@ public:
|
|||
int nb_clients;
|
||||
uint64_t nb_frames;
|
||||
public:
|
||||
/**
|
||||
* stream total kbps.
|
||||
*/
|
||||
// The stream total kbps.
|
||||
SrsKbps* kbps;
|
||||
SrsWallClock* clk;
|
||||
public:
|
||||
bool has_video;
|
||||
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;
|
||||
// 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;
|
||||
// the width and height in codec info.
|
||||
// The width and height in codec info.
|
||||
int width;
|
||||
int height;
|
||||
public:
|
||||
|
@ -93,12 +89,10 @@ public:
|
|||
SrsAudioCodecId acodec;
|
||||
SrsAudioSampleRate asample_rate;
|
||||
SrsAudioChannels asound_type;
|
||||
/**
|
||||
* audio specified
|
||||
* audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
|
||||
* 1.5.1.1 Audio object type definition, page 23,
|
||||
* in ISO_IEC_14496-3-AAC-2001.pdf.
|
||||
*/
|
||||
// The audio specified
|
||||
// audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33,
|
||||
// 1.5.1.1 Audio object type definition, page 23,
|
||||
// in ISO_IEC_14496-3-AAC-2001.pdf.
|
||||
SrsAacObjectType aac_object;
|
||||
public:
|
||||
SrsStatisticStream();
|
||||
|
@ -106,13 +100,9 @@ public:
|
|||
public:
|
||||
virtual srs_error_t dumps(SrsJsonObject* obj);
|
||||
public:
|
||||
/**
|
||||
* publish the stream.
|
||||
*/
|
||||
// Publish the stream.
|
||||
virtual void publish(int cid);
|
||||
/**
|
||||
* close the stream.
|
||||
*/
|
||||
// Close the stream.
|
||||
virtual void close();
|
||||
};
|
||||
|
||||
|
@ -136,24 +126,24 @@ class SrsStatistic
|
|||
{
|
||||
private:
|
||||
static SrsStatistic *_instance;
|
||||
// the id to identify the sever.
|
||||
// The id to identify the sever.
|
||||
int64_t _server_id;
|
||||
private:
|
||||
// key: vhost id, value: vhost object.
|
||||
// The key: vhost id, value: vhost object.
|
||||
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.
|
||||
std::map<std::string, SrsStatisticVhost*> rvhosts;
|
||||
private:
|
||||
// key: stream id, value: stream Object.
|
||||
// The key: stream id, value: stream Object.
|
||||
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.
|
||||
std::map<std::string, SrsStatisticStream*> rstreams;
|
||||
private:
|
||||
// key: client id, value: stream object.
|
||||
// The key: client id, value: stream object.
|
||||
std::map<int, SrsStatisticClient*> clients;
|
||||
// server total kbps.
|
||||
// The server total kbps.
|
||||
SrsKbps* kbps;
|
||||
SrsWallClock* clk;
|
||||
private:
|
||||
|
@ -167,77 +157,51 @@ public:
|
|||
virtual SrsStatisticStream* find_stream(int sid);
|
||||
virtual SrsStatisticClient* find_client(int cid);
|
||||
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,
|
||||
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,
|
||||
SrsAudioChannels asound_type, SrsAacObjectType aac_object);
|
||||
/**
|
||||
* When got videos, update the frames.
|
||||
* We only stat the total number of video frames.
|
||||
*/
|
||||
// When got videos, update the frames.
|
||||
// We only stat the total number of video frames.
|
||||
virtual srs_error_t on_video_frames(SrsRequest* req, int nb_frames);
|
||||
/**
|
||||
* when publish stream.
|
||||
* @param req the request object of publish connection.
|
||||
* @param cid the cid of publish connection.
|
||||
*/
|
||||
// When publish stream.
|
||||
// @param req the request object of publish connection.
|
||||
// @param cid the cid of publish connection.
|
||||
virtual void on_stream_publish(SrsRequest* req, int cid);
|
||||
/**
|
||||
* when close stream.
|
||||
*/
|
||||
// When close stream.
|
||||
virtual void on_stream_close(SrsRequest* req);
|
||||
public:
|
||||
/**
|
||||
* when got a client to publish/play stream,
|
||||
* @param id, the client srs id.
|
||||
* @param req, the client request object.
|
||||
* @param conn, the physical absract connection object.
|
||||
* @param type, the type of connection.
|
||||
*/
|
||||
// When got a client to publish/play stream,
|
||||
// @param id, the client srs id.
|
||||
// @param req, the client request object.
|
||||
// @param conn, the physical absract connection object.
|
||||
// @param type, the type of connection.
|
||||
virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type);
|
||||
/**
|
||||
* client disconnect
|
||||
* @remark the on_disconnect always call, while the on_client is call when
|
||||
* only got the request object, so the client specified by id maybe not
|
||||
* exists in stat.
|
||||
*/
|
||||
// Client disconnect
|
||||
// @remark the on_disconnect always call, while the on_client is call when
|
||||
// only got the request object, so the client specified by id maybe not
|
||||
// exists in stat.
|
||||
virtual void on_disconnect(int id);
|
||||
/**
|
||||
* sample the kbps, add delta bytes of conn.
|
||||
* use kbps_sample() to get all result of kbps stat.
|
||||
*/
|
||||
// Sample the kbps, add delta bytes of conn.
|
||||
// Use kbps_sample() to get all result of kbps stat.
|
||||
// TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead.
|
||||
virtual void kbps_add_delta(SrsConnection* conn);
|
||||
/**
|
||||
* calc the result for all kbps.
|
||||
* @return the server kbps.
|
||||
*/
|
||||
// Calc the result for all kbps.
|
||||
// @return the server kbps.
|
||||
virtual SrsKbps* kbps_sample();
|
||||
public:
|
||||
/**
|
||||
* get the server id, used to identify the server.
|
||||
* for example, when restart, the server id must changed.
|
||||
*/
|
||||
// Get the server id, used to identify the server.
|
||||
// For example, when restart, the server id must changed.
|
||||
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);
|
||||
/**
|
||||
* dumps the streams to amf0 array.
|
||||
*/
|
||||
// Dumps the streams to amf0 array.
|
||||
virtual srs_error_t dumps_streams(SrsJsonArray* arr);
|
||||
/**
|
||||
* dumps the clients to amf0 array
|
||||
* @param start the start index, from 0.
|
||||
* @param count the max count of clients to dump.
|
||||
*/
|
||||
// Dumps the clients to amf0 array
|
||||
// @param start the start index, from 0.
|
||||
// @param count the max count of clients to dump.
|
||||
virtual srs_error_t dumps_clients(SrsJsonArray* arr, int start, int count);
|
||||
private:
|
||||
virtual SrsStatisticVhost* create_vhost(SrsRequest* req);
|
||||
|
|
|
@ -31,12 +31,10 @@
|
|||
#include <srs_app_st.hpp>
|
||||
#include <srs_service_conn.hpp>
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 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
|
||||
// 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.
|
||||
class SrsCoroutineManager : virtual public ISrsCoroutineHandler, virtual public IConnectionManager
|
||||
{
|
||||
private:
|
||||
|
@ -48,10 +46,10 @@ public:
|
|||
virtual ~SrsCoroutineManager();
|
||||
public:
|
||||
srs_error_t start();
|
||||
// ISrsCoroutineHandler
|
||||
// Interface ISrsCoroutineHandler
|
||||
public:
|
||||
virtual srs_error_t cycle();
|
||||
// IConnectionManager
|
||||
// Interface IConnectionManager
|
||||
public:
|
||||
virtual void remove(ISrsConnection* c);
|
||||
private:
|
||||
|
|
|
@ -362,7 +362,6 @@ bool get_proc_system_stat(SrsProcSystemStat& r)
|
|||
fclose(f);
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
r.ok = true;
|
||||
|
@ -401,7 +400,6 @@ bool get_proc_self_stat(SrsProcSelfStat& r)
|
|||
fclose(f);
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
r.ok = true;
|
||||
|
@ -520,7 +518,6 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r)
|
|||
fclose(f);
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
r.ok = true;
|
||||
|
@ -606,7 +603,6 @@ bool srs_get_disk_diskstats_stat(SrsDiskStat& r)
|
|||
fclose(f);
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
r.ok = true;
|
||||
|
@ -728,7 +724,6 @@ void srs_update_meminfo()
|
|||
fclose(f);
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
r.sample_time = srsu2ms(srs_get_system_time());
|
||||
|
@ -948,7 +943,6 @@ void srs_update_network_devices()
|
|||
}
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1023,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
|
|||
}
|
||||
#else
|
||||
// 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_tcp4_hashed = 0;
|
||||
nb_tcp_orphans = 0;
|
||||
|
@ -1073,7 +1066,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps)
|
|||
}
|
||||
#else
|
||||
// TODO: FIXME: impelments it.
|
||||
// Fuck all of you who use osx for a long time and never patch the osx features for srs.
|
||||
#endif
|
||||
|
||||
// @see: https://github.com/shemminger/iproute2/blob/master/misc/ss.c
|
||||
|
|
|
@ -41,51 +41,43 @@ class SrsKbps;
|
|||
class SrsBuffer;
|
||||
class SrsJsonObject;
|
||||
|
||||
/**
|
||||
* convert level in string to log level in int.
|
||||
* @return the log level defined in SrsLogLevel.
|
||||
*/
|
||||
// Convert level in string to log level in int.
|
||||
// @return the log level defined in SrsLogLevel.
|
||||
extern SrsLogLevel srs_get_log_level(std::string level);
|
||||
|
||||
/**
|
||||
* build the path according to vhost/app/stream, where replace variables:
|
||||
* [vhost], the vhost of stream.
|
||||
* [app], the app of stream.
|
||||
* [stream], the stream name of stream.
|
||||
* @return the replaced path.
|
||||
*/
|
||||
// Build the path according to vhost/app/stream, where replace variables:
|
||||
// [vhost], the vhost of stream.
|
||||
// [app], the app of stream.
|
||||
// [stream], the stream name of stream.
|
||||
// @return the replaced path.
|
||||
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:
|
||||
* [2006], replace this const to current year.
|
||||
* [01], replace this const to current month.
|
||||
* [02], replace this const to current date.
|
||||
* [15], replace this const to current hour.
|
||||
* [04], repleace this const to current minute.
|
||||
* [05], repleace this const to current second.
|
||||
* [999], repleace this const to current millisecond.
|
||||
* [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
* @return the replaced path.
|
||||
*/
|
||||
// Build the path according to timestamp, where replace variables:
|
||||
// [2006], replace this const to current year.
|
||||
// [01], replace this const to current month.
|
||||
// [02], replace this const to current date.
|
||||
// [15], replace this const to current hour.
|
||||
// [04], repleace this const to current minute.
|
||||
// [05], repleace this const to current second.
|
||||
// [999], repleace this const to current millisecond.
|
||||
// [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
// @return the replaced 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 SIGKILL again when exceed the timeout.
|
||||
* @param pid the pid to kill. ignore for -1. set to -1 when killed.
|
||||
* @return an int error code.
|
||||
*/
|
||||
// Kill the pid by SIGINT, then wait to quit,
|
||||
// Kill the pid by SIGKILL again when exceed the timeout.
|
||||
// @param pid the pid to kill. ignore for -1. set to -1 when killed.
|
||||
// @return an int error code.
|
||||
extern srs_error_t srs_kill_forced(int& pid);
|
||||
|
||||
// current process resouce usage.
|
||||
// Current process resouce usage.
|
||||
// @see: man getrusage
|
||||
class SrsRusage
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
// the time in ms when sample.
|
||||
// The time in ms when sample.
|
||||
int64_t sample_time;
|
||||
|
||||
public:
|
||||
|
@ -95,21 +87,21 @@ public:
|
|||
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();
|
||||
// the deamon st-thread will update it.
|
||||
// The deamon st-thread will update it.
|
||||
extern void srs_update_system_rusage();
|
||||
|
||||
// to stat the process info.
|
||||
// To stat the process info.
|
||||
// @see: man 5 proc, /proc/[pid]/stat
|
||||
class SrsProcSelfStat
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
// the time in ms when sample.
|
||||
// The time in ms when sample.
|
||||
int64_t sample_time;
|
||||
// the percent of usage. 0.153 is 15.3%.
|
||||
// The percent of usage. 0.153 is 15.3%.
|
||||
float percent;
|
||||
|
||||
// data of /proc/[pid]/stat
|
||||
|
@ -256,49 +248,47 @@ public:
|
|||
SrsProcSelfStat();
|
||||
};
|
||||
|
||||
// to stat the cpu time.
|
||||
// To stat the cpu time.
|
||||
// @see: man 5 proc, /proc/stat
|
||||
/**
|
||||
* 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:
|
||||
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
|
||||
* 5275153.01 4699624.99
|
||||
* cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0
|
||||
* 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"
|
||||
* that is, USER_HZ=1/100 seconds
|
||||
* cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ)
|
||||
* = 523331687 (USER_HZ)
|
||||
* = 523331687 * 1/100 (seconds)
|
||||
* = 5233316.87 seconds
|
||||
* the cpu total seconds almost the uptime, the delta is more precise.
|
||||
*
|
||||
* we run the command about 26minutes:
|
||||
* [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
|
||||
* 5276739.83 4701090.76
|
||||
* cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0
|
||||
* where the uptime is 5276739.83s
|
||||
* cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ)
|
||||
* = 523488898 (USER_HZ)
|
||||
* = 523488898 * 1/100 (seconds)
|
||||
* = 5234888.98 seconds
|
||||
* where:
|
||||
* uptime delta = 1586.82s
|
||||
* cpu total delta = 1572.11s
|
||||
* the deviation is more smaller.
|
||||
*/
|
||||
// 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:
|
||||
// [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
|
||||
// 5275153.01 4699624.99
|
||||
// cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0
|
||||
// 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"
|
||||
// that is, USER_HZ=1/100 seconds
|
||||
// cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ)
|
||||
// = 523331687 (USER_HZ)
|
||||
// = 523331687 * 1/100 (seconds)
|
||||
// = 5233316.87 seconds
|
||||
// The cpu total seconds almost the uptime, the delta is more precise.
|
||||
//
|
||||
// we run the command about 26minutes:
|
||||
// [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat
|
||||
// 5276739.83 4701090.76
|
||||
// cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0
|
||||
// Where the uptime is 5276739.83s
|
||||
// cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ)
|
||||
// = 523488898 (USER_HZ)
|
||||
// = 523488898 * 1/100 (seconds)
|
||||
// = 5234888.98 seconds
|
||||
// where:
|
||||
// uptime delta = 1586.82s
|
||||
// cpu total delta = 1572.11s
|
||||
// The deviation is more smaller.
|
||||
class SrsProcSystemStat
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
// the time in ms when sample.
|
||||
// The time in ms when sample.
|
||||
int64_t sample_time;
|
||||
// the percent of usage. 0.153 is 15.3%.
|
||||
// the percent is in [0, 1], where 1 is 100%.
|
||||
// The percent of usage. 0.153 is 15.3%.
|
||||
// The percent is in [0, 1], where 1 is 100%.
|
||||
// for multiple core cpu, max also is 100%.
|
||||
float percent;
|
||||
// the total cpu time units
|
||||
// The total cpu time units
|
||||
// @remark, zero for the previous total() is zero.
|
||||
// the usaged_cpu_delta = total_delta * percent
|
||||
// previous cpu total = this->total() - total_delta
|
||||
|
@ -310,7 +300,7 @@ public:
|
|||
// (1/100ths of a second on most architectures, use
|
||||
// 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;
|
||||
// user mode with low priority (nice),
|
||||
unsigned long long nice;
|
||||
|
@ -341,18 +331,18 @@ public:
|
|||
public:
|
||||
SrsProcSystemStat();
|
||||
|
||||
// get total cpu units.
|
||||
// Get total cpu units.
|
||||
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();
|
||||
// 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();
|
||||
// the deamon st-thread will update it.
|
||||
// The deamon st-thread will update it.
|
||||
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
|
||||
// for total disk io, @see: cat /proc/vmstat |grep pgpg
|
||||
// for device disk io, @see: cat /proc/diskstats
|
||||
|
@ -364,9 +354,9 @@ extern void srs_update_proc_stat();
|
|||
class SrsDiskStat
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
// the time in ms when sample.
|
||||
// The time in ms when sample.
|
||||
int64_t sample_time;
|
||||
|
||||
// input(read) KBytes per seconds
|
||||
|
@ -382,10 +372,10 @@ public:
|
|||
|
||||
public:
|
||||
// @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.
|
||||
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.
|
||||
unsigned long pgpgout;
|
||||
|
||||
|
@ -415,7 +405,7 @@ public:
|
|||
// Write I/O operations
|
||||
unsigned int wr_ios;
|
||||
// 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
|
||||
// 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.
|
||||
|
@ -446,7 +436,7 @@ public:
|
|||
// progress (field 9) times the number of milliseconds spent
|
||||
// doing I/O since the last update of this field. This can
|
||||
// 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
|
||||
unsigned int aveq;
|
||||
|
||||
|
@ -454,21 +444,21 @@ public:
|
|||
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();
|
||||
// the deamon st-thread will update it.
|
||||
// The deamon st-thread will update it.
|
||||
extern void srs_update_disk_stat();
|
||||
|
||||
// stat system memory info
|
||||
// Stat system memory info
|
||||
// @see: cat /proc/meminfo
|
||||
class SrsMemInfo
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
// the time in ms when sample.
|
||||
// The time in ms when sample.
|
||||
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_swap;
|
||||
|
||||
|
@ -495,9 +485,9 @@ public:
|
|||
SrsMemInfo();
|
||||
};
|
||||
|
||||
// get system meminfo, use cache to avoid performance problem.
|
||||
// Get system meminfo, use cache to avoid performance problem.
|
||||
extern SrsMemInfo* srs_get_meminfo();
|
||||
// the deamon st-thread will update it.
|
||||
// The deamon st-thread will update it.
|
||||
extern void srs_update_meminfo();
|
||||
|
||||
// system cpu hardware info.
|
||||
|
@ -506,7 +496,7 @@ extern void srs_update_meminfo();
|
|||
class SrsCpuInfo
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
|
||||
// data of /proc/cpuinfo
|
||||
|
@ -520,14 +510,14 @@ public:
|
|||
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();
|
||||
|
||||
// platform(os, srs) uptime/load summary
|
||||
// The platform(os, srs) uptime/load summary
|
||||
class SrsPlatformInfo
|
||||
{
|
||||
public:
|
||||
// whether the data is ok.
|
||||
// Whether the data is ok.
|
||||
bool ok;
|
||||
|
||||
// srs startup time, in ms.
|
||||
|
@ -551,22 +541,21 @@ public:
|
|||
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();
|
||||
// the deamon st-thread will update it.
|
||||
// The deamon st-thread will update it.
|
||||
extern void srs_update_platform_info();
|
||||
|
||||
// network device summary for each network device,
|
||||
// for example, eth0, eth1, ethN
|
||||
// The network device summary for each network device, for example, eth0, eth1, ethN
|
||||
class SrsNetworkDevices
|
||||
{
|
||||
public:
|
||||
// whether the network device is ok.
|
||||
// Whether the network device is ok.
|
||||
bool ok;
|
||||
|
||||
// 6-chars interfaces name
|
||||
char name[7];
|
||||
// the sample time in ms.
|
||||
// The sample time in ms.
|
||||
int64_t sample_time;
|
||||
|
||||
public:
|
||||
|
@ -594,20 +583,20 @@ public:
|
|||
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 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();
|
||||
|
||||
// system connections, and srs rtmp network summary
|
||||
// The system connections, and srs rtmp network summary
|
||||
class SrsNetworkRtmpServer
|
||||
{
|
||||
public:
|
||||
// whether the network device is ok.
|
||||
// Whether the network device is ok.
|
||||
bool ok;
|
||||
|
||||
// the sample time in ms.
|
||||
// The sample time in ms.
|
||||
int64_t sample_time;
|
||||
|
||||
public:
|
||||
|
@ -638,32 +627,32 @@ public:
|
|||
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();
|
||||
// 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);
|
||||
|
||||
// get local or peer ip.
|
||||
// where local ip is the server ip which client connected.
|
||||
// Get local or peer ip.
|
||||
// Where local ip is the server ip which client connected.
|
||||
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);
|
||||
// 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);
|
||||
|
||||
// whether string is digit number
|
||||
// Whether string is digit number
|
||||
// is_digit("1234567890") === true
|
||||
// is_digit("0123456789") === false
|
||||
// is_digit("1234567890a") === false
|
||||
// is_digit("a1234567890") === false
|
||||
extern bool srs_is_digit_number(const std::string& str);
|
||||
// whether string is boolean
|
||||
// Whether string is boolean
|
||||
// is_bool("true") == true
|
||||
// is_bool("false") == true
|
||||
// otherwise, false.
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,58 +24,43 @@
|
|||
#ifndef SRS_CORE_HPP
|
||||
#define SRS_CORE_HPP
|
||||
|
||||
// current release version
|
||||
// The version config.
|
||||
#define VERSION_MAJOR 3
|
||||
#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>
|
||||
|
||||
// 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_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_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_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_BRANCH SRS_XSTR(VERSION_STABLE)".0release"
|
||||
|
||||
// internal macros, covert macro values to str,
|
||||
// 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,
|
||||
// For 32bit os, 2G big file limit for unistd io,
|
||||
// ie. read/write/lseek to use 64bits size for huge file.
|
||||
#ifndef _FILE_OFFSET_BITS
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
#endif
|
||||
|
||||
// for int64_t print using PRId64 format.
|
||||
// For int64_t print using PRId64 format.
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#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
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
@ -86,22 +71,21 @@
|
|||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// Time defines.
|
||||
// The time unit for timeout, interval or duration.
|
||||
#include <srs_core_time.hpp>
|
||||
|
||||
// Some important performance options.
|
||||
#include <srs_core_performance.hpp>
|
||||
|
||||
// free the p and set to NULL.
|
||||
// p must be a T*.
|
||||
// To free the p and set to NULL.
|
||||
// @remark The p must be a pointer T*.
|
||||
#define srs_freep(p) \
|
||||
if (p) { \
|
||||
delete p; \
|
||||
p = NULL; \
|
||||
} \
|
||||
(void)0
|
||||
// please use the freepa(T[]) to free an array,
|
||||
// or the behavior is undefined.
|
||||
// Please use the freepa(T[]) to free an array, otherwise the behavior is undefined.
|
||||
#define srs_freepa(pa) \
|
||||
if (pa) { \
|
||||
delete[] pa; \
|
||||
|
@ -109,11 +93,8 @@
|
|||
} \
|
||||
(void)0
|
||||
|
||||
/**
|
||||
* important check for st(state-threads),
|
||||
* 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
|
||||
*/
|
||||
// Checking for st(state-threads), 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__)
|
||||
#error "only support i386/amd64/x86_64/arm cpu"
|
||||
#endif
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#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:
|
||||
* 1. free the ptr.
|
||||
* 2. set ptr to NULL.
|
||||
|
@ -56,9 +56,6 @@ private:
|
|||
T** ptr;
|
||||
bool is_array;
|
||||
public:
|
||||
/**
|
||||
* auto delete the ptr.
|
||||
*/
|
||||
impl_SrsAutoFree(T** p, bool array) {
|
||||
ptr = p;
|
||||
is_array = array;
|
||||
|
|
|
@ -28,15 +28,17 @@
|
|||
|
||||
#ifdef SRS_AUTO_MEM_WATCH
|
||||
|
||||
#warning "MemoryWatch is deprecated."
|
||||
|
||||
#include <string>
|
||||
|
||||
// watch the specified memory.
|
||||
// Watch the specified memory.
|
||||
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);
|
||||
|
||||
// report the memory watch.
|
||||
// Report the memory watch.
|
||||
extern void srs_memory_report();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,9 +35,7 @@
|
|||
class SrsBuffer;
|
||||
class ISrsStreamWriter;
|
||||
|
||||
/**
|
||||
* Transmux the RTMP packets to AAC stream.
|
||||
*/
|
||||
// Transmux the RTMP packets to AAC stream.
|
||||
class SrsAacTransmuxer
|
||||
{
|
||||
private:
|
||||
|
@ -51,17 +49,13 @@ public:
|
|||
SrsAacTransmuxer();
|
||||
virtual ~SrsAacTransmuxer();
|
||||
public:
|
||||
/**
|
||||
* initialize the underlayer file stream.
|
||||
* @remark user can initialize multiple times to encode multiple aac files.
|
||||
* @remark, user must free the fs, aac encoder never close/free it.
|
||||
*/
|
||||
// Initialize the underlayer file stream.
|
||||
// @remark User can initialize multiple times to encode multiple aac files.
|
||||
// @remark User must free the fs, aac encoder never close/free it.
|
||||
virtual srs_error_t initialize(ISrsStreamWriter* fs);
|
||||
public:
|
||||
/**
|
||||
* write audio/video packet.
|
||||
* @remark assert data is not NULL.
|
||||
*/
|
||||
// Write audio/video packet.
|
||||
// @remark The assert data should not be NULL.
|
||||
virtual srs_error_t write_audio(int64_t timestamp, char* data, int size);
|
||||
};
|
||||
|
||||
|
|
|
@ -36,82 +36,72 @@
|
|||
///////////////////////////////////////////////////////////
|
||||
// RTMP consts values
|
||||
///////////////////////////////////////////////////////////
|
||||
// default vhost of rtmp
|
||||
// Default vhost of rtmp
|
||||
#define SRS_CONSTS_RTMP_DEFAULT_VHOST "__defaultVhost__"
|
||||
#define SRS_CONSTS_RTMP_DEFAULT_APP "__defaultApp__"
|
||||
// default port of rtmp
|
||||
// Default port of rtmp
|
||||
#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
|
||||
// 6. Chunking, RTMP protocol default chunk size.
|
||||
#define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128
|
||||
|
||||
/**
|
||||
* 6. Chunking
|
||||
* The chunk size is configurable. It can be set using a control
|
||||
* message(Set Chunk Size) as described in section 7.1. The maximum
|
||||
* chunk size can be 65536 bytes and minimum 128 bytes. Larger values
|
||||
* reduce CPU usage, but also commit to larger writes that can delay
|
||||
* other content on lower bandwidth connections. Smaller chunks are not
|
||||
* good for high-bit rate streaming. Chunk size is maintained
|
||||
* independently for each direction.
|
||||
*/
|
||||
// 6. Chunking
|
||||
// The chunk size is configurable. It can be set using a control
|
||||
// message(Set Chunk Size) as described in section 7.1. The maximum
|
||||
// chunk size can be 65536 bytes and minimum 128 bytes. Larger values
|
||||
// reduce CPU usage, but also commit to larger writes that can delay
|
||||
// other content on lower bandwidth connections. Smaller chunks are not
|
||||
// good for high-bit rate streaming. Chunk size is maintained
|
||||
// independently for each direction.
|
||||
#define SRS_CONSTS_RTMP_MIN_CHUNK_SIZE 128
|
||||
#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.
|
||||
|
||||
// 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?
|
||||
#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,
|
||||
// generally, it's the pulse time for data seding.
|
||||
// @remark, recomment to 500ms.
|
||||
#define SRS_CONSTS_RTMP_PULSE (500 * SRS_UTIME_MILLISECONDS)
|
||||
|
||||
/**
|
||||
* max rtmp header size:
|
||||
* 1bytes basic header,
|
||||
* 11bytes message header,
|
||||
* 4bytes timestamp header,
|
||||
* that is, 1+11+4=16bytes.
|
||||
*/
|
||||
// The max rtmp header size:
|
||||
// 1bytes basic header,
|
||||
// 11bytes message header,
|
||||
// 4bytes timestamp header,
|
||||
// that is, 1+11+4=16bytes.
|
||||
#define SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE 16
|
||||
/**
|
||||
* max rtmp header size:
|
||||
* 1bytes basic header,
|
||||
* 4bytes timestamp header,
|
||||
* that is, 1+4=5bytes.
|
||||
*/
|
||||
// The max rtmp header size:
|
||||
// 1bytes basic header,
|
||||
// 4bytes timestamp header,
|
||||
// that is, 1+4=5bytes.
|
||||
// always use fmt0 as cache.
|
||||
#define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5
|
||||
|
||||
/**
|
||||
* for performance issue,
|
||||
* the iovs cache, @see https://github.com/ossrs/srs/issues/194
|
||||
* 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,
|
||||
* so the iovs max should be (SRS_PERF_MW_MSGS * 2)
|
||||
*
|
||||
* @remark, SRS will realloc when the iovs not enough.
|
||||
*/
|
||||
// For performance issue,
|
||||
// the iovs cache, @see https://github.com/ossrs/srs/issues/194
|
||||
// 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,
|
||||
// so the iovs max should be (SRS_PERF_MW_MSGS * 2)
|
||||
//
|
||||
// @remark, SRS will realloc when the iovs not enough.
|
||||
#define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2)
|
||||
/**
|
||||
* for performance issue,
|
||||
* the c0c3 cache, @see https://github.com/ossrs/srs/issues/194
|
||||
* c0c3 cache for multiple messages for each connections.
|
||||
* each c0 <= 16byes, suppose the chunk size is 64k,
|
||||
* each message send in a chunk which needs only a c0 header,
|
||||
* 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.
|
||||
* so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32)
|
||||
*/
|
||||
// For performance issue,
|
||||
// the c0c3 cache, @see https://github.com/ossrs/srs/issues/194
|
||||
// c0c3 cache for multiple messages for each connections.
|
||||
// each c0 <= 16byes, suppose the chunk size is 64k,
|
||||
// each message send in a chunk which needs only a c0 header,
|
||||
// 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.
|
||||
// so we use larger c0c3 cache, that is (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_LOCALHOST "127.0.0.1"
|
||||
|
||||
// signal defines.
|
||||
// reload the config file and apply new config.
|
||||
// The signal defines.
|
||||
// To reload the config file and apply new config.
|
||||
#define SRS_SIGNAL_RELOAD SIGHUP
|
||||
// reopen the log file.
|
||||
// Reopen the log file.
|
||||
#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
|
||||
|
||||
// application level signals.
|
||||
// persistence the config in memory to config file.
|
||||
// The application level signals.
|
||||
// Persistence the config in memory to config file.
|
||||
// @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.
|
||||
#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"
|
||||
// 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"
|
||||
// edge/origin forwarder.
|
||||
// The edge/origin forwarder.
|
||||
#define SRS_CONSTS_LOG_FOWARDER "FWR"
|
||||
// play stream on edge/origin.
|
||||
// Play stream on edge/origin.
|
||||
#define SRS_CONSTS_LOG_PLAY "PLA"
|
||||
// client publish to edge/origin
|
||||
// Client publish to edge/origin
|
||||
#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"
|
||||
// ingester for edge(play)/origin
|
||||
// Ingester for edge(play)/origin
|
||||
#define SRS_CONSTS_LOG_INGESTER "IGS"
|
||||
// hls log id.
|
||||
// The hls log id.
|
||||
#define SRS_CONSTS_LOG_HLS "HLS"
|
||||
// encoder log id.
|
||||
// The encoder log id.
|
||||
#define SRS_CONSTS_LOG_ENCODER "ENC"
|
||||
// http stream log id.
|
||||
// The http stream log id.
|
||||
#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"
|
||||
// stream caster log id.
|
||||
// The stream caster log id.
|
||||
#define SRS_CONSTS_LOG_STREAM_CASTER "SCS"
|
||||
// the nginx exec log id.
|
||||
// The nginx exec log id.
|
||||
#define SRS_CONSTS_LOG_EXEC "EXE"
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
@ -213,14 +203,14 @@
|
|||
///////////////////////////////////////////////////////////
|
||||
// HTTP consts values
|
||||
///////////////////////////////////////////////////////////
|
||||
// the default http port.
|
||||
// The default http port.
|
||||
#define SRS_CONSTS_HTTP_DEFAULT_PORT 80
|
||||
// linux path seprator
|
||||
// The linux path seprator
|
||||
#define SRS_CONSTS_HTTP_PATH_SEP '/'
|
||||
// query string seprator
|
||||
// Query string seprator
|
||||
#define SRS_CONSTS_HTTP_QUERY_SEP '?'
|
||||
|
||||
// the default recv timeout.
|
||||
// The default recv timeout.
|
||||
#define SRS_HTTP_RECV_TIMEOUT (60 * SRS_UTIME_SECONDS)
|
||||
|
||||
// 6.1.1 Status Code and Reason Phrase
|
||||
|
@ -405,7 +395,7 @@
|
|||
///////////////////////////////////////////////////////////
|
||||
#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)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
|
||||
#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
|
||||
#define ERROR_SUCCESS 0
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// system error.
|
||||
// The system error.
|
||||
///////////////////////////////////////////////////////
|
||||
#define ERROR_SOCKET_CREATE 1000
|
||||
#define ERROR_SOCKET_SETREUSE 1001
|
||||
|
@ -173,18 +173,18 @@
|
|||
#define ERROR_RTMP_STREAM_NAME_EMPTY 2051
|
||||
#define ERROR_HTTP_HIJACK 2052
|
||||
//
|
||||
// system control message,
|
||||
// not an error, but special control logic.
|
||||
// The system control message,
|
||||
// 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
|
||||
// sys ctl: rtmp close stream, support replay.
|
||||
// For sys ctl: rtmp close stream, support replay.
|
||||
#define ERROR_CONTROL_RTMP_CLOSE 2998
|
||||
// FMLE stop publish and republish.
|
||||
// When FMLE stop publish and republish.
|
||||
#define ERROR_CONTROL_REPUBLISH 2999
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// application level
|
||||
// The application level errors.
|
||||
///////////////////////////////////////////////////////
|
||||
#define ERROR_HLS_METADATA 3000
|
||||
#define ERROR_HLS_DECODE_ERROR 3001
|
||||
|
@ -329,23 +329,23 @@
|
|||
//#define ERROR_API_METHOD_NOT_ALLOWD
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// user-define error.
|
||||
// For user-define error.
|
||||
///////////////////////////////////////////////////////
|
||||
#define ERROR_USER_START 9000
|
||||
//#define ERROR_USER_DISCONNECT 9001
|
||||
#define ERROR_SOURCE_NOT_FOUND 9002
|
||||
#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.
|
||||
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_client_gracefully_close(int error_code);
|
||||
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
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
#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
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
@ -40,19 +40,13 @@ class SrsFileReader;
|
|||
|
||||
#define SRS_FLV_TAG_HEADER_SIZE 11
|
||||
#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
|
||||
with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID
|
||||
7 is used between edge server and origin server.
|
||||
*/
|
||||
// 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
|
||||
// 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_AbortMessage 0x02
|
||||
#define RTMP_MSG_Acknowledgement 0x03
|
||||
|
@ -60,167 +54,121 @@ class SrsFileReader;
|
|||
#define RTMP_MSG_WindowAcknowledgementSize 0x05
|
||||
#define RTMP_MSG_SetPeerBandwidth 0x06
|
||||
#define RTMP_MSG_EdgeAndOriginServerCommand 0x07
|
||||
/**
|
||||
3. Types of messages
|
||||
The server and the client send messages over the network to
|
||||
communicate with each other. The messages can be of any type which
|
||||
includes audio messages, video messages, command messages, shared
|
||||
object messages, data messages, and user control messages.
|
||||
3.1. Command message
|
||||
Command messages carry the AMF-encoded commands between the client
|
||||
and the server. These messages have been assigned message type value
|
||||
of 20 for AMF0 encoding and message type value of 17 for AMF3
|
||||
encoding. These messages are sent to perform some operations like
|
||||
connect, createStream, publish, play, pause on the peer. Command
|
||||
messages like onstatus, result etc. are used to inform the sender
|
||||
about the status of the requested commands. A command message
|
||||
consists of command name, transaction ID, and command object that
|
||||
contains related parameters. A client or a server can request Remote
|
||||
Procedure Calls (RPC) over streams that are communicated using the
|
||||
command messages to the peer.
|
||||
*/
|
||||
// 3. Types of messages
|
||||
// The server and the client send messages over the network to
|
||||
// communicate with each other. The messages can be of any type which
|
||||
// includes audio messages, video messages, command messages, shared
|
||||
// object messages, data messages, and user control messages.
|
||||
// 3.1. Command message
|
||||
// Command messages carry the AMF-encoded commands between the client
|
||||
// and the server. These messages have been assigned message type value
|
||||
// of 20 for AMF0 encoding and message type value of 17 for AMF3
|
||||
// encoding. These messages are sent to perform some operations like
|
||||
// connect, createStream, publish, play, pause on the peer. Command
|
||||
// messages like onstatus, result etc. are used to inform the sender
|
||||
// about the status of the requested commands. A command message
|
||||
// consists of command name, transaction ID, and command object that
|
||||
// contains related parameters. A client or a server can request Remote
|
||||
// Procedure Calls (RPC) over streams that are communicated using the
|
||||
// command messages to the peer.
|
||||
#define RTMP_MSG_AMF3CommandMessage 17 // 0x11
|
||||
#define RTMP_MSG_AMF0CommandMessage 20 // 0x14
|
||||
/**
|
||||
3.2. Data message
|
||||
The client or the server sends this message to send Metadata or any
|
||||
user data to the peer. Metadata includes details about the
|
||||
data(audio, video etc.) like creation time, duration, theme and so
|
||||
on. These messages have been assigned message type value of 18 for
|
||||
AMF0 and message type value of 15 for AMF3.
|
||||
*/
|
||||
// 3.2. Data message
|
||||
// The client or the server sends this message to send Metadata or any
|
||||
// user data to the peer. Metadata includes details about the
|
||||
// data(audio, video etc.) like creation time, duration, theme and so
|
||||
// on. These messages have been assigned message type value of 18 for
|
||||
// AMF0 and message type value of 15 for AMF3.
|
||||
#define RTMP_MSG_AMF0DataMessage 18 // 0x12
|
||||
#define RTMP_MSG_AMF3DataMessage 15 // 0x0F
|
||||
/**
|
||||
3.3. Shared object message
|
||||
A shared object is a Flash object (a collection of name value pairs)
|
||||
that are in synchronization across multiple clients, instances, and
|
||||
so on. The message types kMsgContainer=19 for AMF0 and
|
||||
kMsgContainerEx=16 for AMF3 are reserved for shared object events.
|
||||
Each message can contain multiple events.
|
||||
*/
|
||||
// 3.3. Shared object message
|
||||
// A shared object is a Flash object (a collection of name value pairs)
|
||||
// that are in synchronization across multiple clients, instances, and
|
||||
// so on. The message types kMsgContainer=19 for AMF0 and
|
||||
// kMsgContainerEx=16 for AMF3 are reserved for shared object events.
|
||||
// Each message can contain multiple events.
|
||||
#define RTMP_MSG_AMF3SharedObject 16 // 0x10
|
||||
#define RTMP_MSG_AMF0SharedObject 19 // 0x13
|
||||
/**
|
||||
3.4. Audio message
|
||||
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.
|
||||
*/
|
||||
// 3.4. Audio message
|
||||
// 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.
|
||||
#define RTMP_MSG_AudioMessage 8 // 0x08
|
||||
/* *
|
||||
3.5. Video message
|
||||
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.
|
||||
These messages are large and can delay the sending of other type of
|
||||
messages. To avoid such a situation, the video message is assigned
|
||||
the lowest priority.
|
||||
*/
|
||||
// 3.5. Video message
|
||||
// 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.
|
||||
// These messages are large and can delay the sending of other type of
|
||||
// messages. To avoid such a situation, the video message is assigned
|
||||
// The lowest priority.
|
||||
#define RTMP_MSG_VideoMessage 9 // 0x09
|
||||
/**
|
||||
3.6. Aggregate message
|
||||
An aggregate message is a single message that contains a list of submessages.
|
||||
The message type value of 22 is reserved for aggregate
|
||||
messages.
|
||||
*/
|
||||
// 3.6. Aggregate message
|
||||
// An aggregate message is a single message that contains a list of submessages.
|
||||
// The message type value of 22 is reserved for aggregate
|
||||
// messages.
|
||||
#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
|
||||
/**
|
||||
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection.
|
||||
* generally use 0x03.
|
||||
*/
|
||||
// The AMF0/AMF3 command message, invoke method and return the result, over NetConnection.
|
||||
// generally use 0x03.
|
||||
#define RTMP_CID_OverConnection 0x03
|
||||
/**
|
||||
* the AMF0/AMF3 command message, invoke method and return the result, over NetConnection,
|
||||
* the midst state(we guess).
|
||||
* rarely used, e.g. onStatus(NetStream.Play.Reset).
|
||||
*/
|
||||
// The AMF0/AMF3 command message, invoke method and return the result, over NetConnection,
|
||||
// The midst state(we guess).
|
||||
// rarely used, e.g. onStatus(NetStream.Play.Reset).
|
||||
#define RTMP_CID_OverConnection2 0x04
|
||||
/**
|
||||
* the stream message(amf0/amf3), over NetStream.
|
||||
* generally use 0x05.
|
||||
*/
|
||||
// The stream message(amf0/amf3), over NetStream.
|
||||
// generally use 0x05.
|
||||
#define RTMP_CID_OverStream 0x05
|
||||
/**
|
||||
* the stream message(amf0/amf3), over NetStream, the midst state(we guess).
|
||||
* rarely used, e.g. play("mp4:mystram.f4v")
|
||||
*/
|
||||
// The stream message(amf0/amf3), over NetStream, the midst state(we guess).
|
||||
// rarely used, e.g. play("mp4:mystram.f4v")
|
||||
#define RTMP_CID_OverStream2 0x08
|
||||
/**
|
||||
* the stream message(video), over NetStream
|
||||
* generally use 0x06.
|
||||
*/
|
||||
// The stream message(video), over NetStream
|
||||
// generally use 0x06.
|
||||
#define RTMP_CID_Video 0x06
|
||||
/**
|
||||
* the stream message(audio), over NetStream.
|
||||
* generally use 0x07.
|
||||
*/
|
||||
// The stream message(audio), over NetStream.
|
||||
// generally use 0x07.
|
||||
#define RTMP_CID_Audio 0x07
|
||||
|
||||
/**
|
||||
* 6.1. Chunk Format
|
||||
* Extended timestamp: 0 or 4 bytes
|
||||
* 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
|
||||
* anything else. So for values less than 0xffffff the normal
|
||||
* timestamp field SHOULD be used in which case the extended timestamp
|
||||
* 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
|
||||
* 0xffffff and the extended timestamp MUST be sent.
|
||||
*/
|
||||
// 6.1. Chunk Format
|
||||
// Extended timestamp: 0 or 4 bytes
|
||||
// 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
|
||||
// anything else. So for values less than 0xffffff the normal
|
||||
// timestamp field SHOULD be used in which case the extended timestamp
|
||||
// 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
|
||||
// 0xffffff and the extended timestamp MUST be sent.
|
||||
#define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF
|
||||
|
||||
/**
|
||||
* 4.1. Message Header
|
||||
*/
|
||||
// 4.1. Message Header
|
||||
class SrsMessageHeader
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 3bytes.
|
||||
* Three-byte field that contains a timestamp delta of the message.
|
||||
* @remark, only used for decoding message from chunk stream.
|
||||
*/
|
||||
// 3bytes.
|
||||
// Three-byte field that contains a timestamp delta of the message.
|
||||
// @remark, only used for decoding message from chunk stream.
|
||||
int32_t timestamp_delta;
|
||||
/**
|
||||
* 3bytes.
|
||||
* Three-byte field that represents the size of the payload in bytes.
|
||||
* It is set in big-endian format.
|
||||
*/
|
||||
// 3bytes.
|
||||
// Three-byte field that represents the size of the payload in bytes.
|
||||
// It is set in big-endian format.
|
||||
int32_t payload_length;
|
||||
/**
|
||||
* 1byte.
|
||||
* One byte field to represent the message type. A range of type IDs
|
||||
* (1-7) are reserved for protocol control messages.
|
||||
*/
|
||||
// 1byte.
|
||||
// One byte field to represent the message type. A range of type IDs
|
||||
// (1-7) are reserved for protocol control messages.
|
||||
int8_t message_type;
|
||||
/**
|
||||
* 4bytes.
|
||||
* Four-byte field that identifies the stream of the message. These
|
||||
* bytes are set in little-endian format.
|
||||
*/
|
||||
// 4bytes.
|
||||
// Four-byte field that identifies the stream of the message. These
|
||||
// bytes are set in little-endian format.
|
||||
int32_t stream_id;
|
||||
|
||||
/**
|
||||
* Four-byte field that contains a timestamp of the message.
|
||||
* The 4 bytes are packed in the big-endian order.
|
||||
* @remark, used as calc timestamp when decode and encode time.
|
||||
* @remark, we use 64bits for large time for jitter detect and hls.
|
||||
*/
|
||||
// Four-byte field that contains a timestamp of the message.
|
||||
// The 4 bytes are packed in the big-endian order.
|
||||
// @remark, used as calc timestamp when decode and encode time.
|
||||
// @remark, we use 64bits for large time for jitter detect and hls.
|
||||
int64_t timestamp;
|
||||
public:
|
||||
/**
|
||||
* get the perfered cid(chunk stream id) which sendout over.
|
||||
* set at decoding, and canbe used for directly send message,
|
||||
* for example, dispatch to all connections.
|
||||
*/
|
||||
// Get the perfered cid(chunk stream id) which sendout over.
|
||||
// set at decoding, and canbe used for directly send message,
|
||||
// For example, dispatch to all connections.
|
||||
int perfer_cid;
|
||||
public:
|
||||
SrsMessageHeader();
|
||||
|
@ -239,149 +187,114 @@ public:
|
|||
bool is_set_peer_bandwidth();
|
||||
bool is_aggregate();
|
||||
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);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* message is raw data RTMP message, bytes oriented,
|
||||
* protcol always recv RTMP message, and can send RTMP message or RTMP packet.
|
||||
* the common message is read from underlay protocol sdk.
|
||||
* while the shared ptr message used to copy and send.
|
||||
*/
|
||||
// The message is raw data RTMP message, bytes oriented,
|
||||
// protcol always recv RTMP message, and can send RTMP message or RTMP packet.
|
||||
// The common message is read from underlay protocol sdk.
|
||||
// while the shared ptr message used to copy and send.
|
||||
class SrsCommonMessage
|
||||
{
|
||||
// 4.1. Message Header
|
||||
// 4.1. Message Header
|
||||
public:
|
||||
SrsMessageHeader header;
|
||||
// 4.2. Message Payload
|
||||
// 4.2. Message Payload
|
||||
public:
|
||||
/**
|
||||
* current message parsed size,
|
||||
* size <= header.payload_length
|
||||
* for the payload maybe sent in multiple chunks.
|
||||
*/
|
||||
// The current message parsed size,
|
||||
// size <= header.payload_length
|
||||
// For the payload maybe sent in multiple chunks.
|
||||
int size;
|
||||
/**
|
||||
* the payload of message, the SrsCommonMessage never know about the detail of payload,
|
||||
* user must use SrsProtocol.decode_message to get concrete packet.
|
||||
* @remark, not all message payload can be decoded to packet. for example,
|
||||
* video/audio packet use raw bytes, no video/audio packet.
|
||||
*/
|
||||
// The payload of message, the SrsCommonMessage never know about the detail of payload,
|
||||
// user must use SrsProtocol.decode_message to get concrete packet.
|
||||
// @remark, not all message payload can be decoded to packet. for example,
|
||||
// video/audio packet use raw bytes, no video/audio packet.
|
||||
char* payload;
|
||||
public:
|
||||
SrsCommonMessage();
|
||||
virtual ~SrsCommonMessage();
|
||||
public:
|
||||
/**
|
||||
* alloc the payload to specified size of bytes.
|
||||
*/
|
||||
// Alloc the payload to specified size of bytes.
|
||||
virtual void create_payload(int size);
|
||||
public:
|
||||
/**
|
||||
* create common message,
|
||||
* from the header and body.
|
||||
* @remark user should never free the body.
|
||||
* @param pheader, the header to copy to the message. NULL to ignore.
|
||||
*/
|
||||
// Create common message,
|
||||
// from the header and body.
|
||||
// @remark user should never free the body.
|
||||
// @param pheader, the header to copy to the message. NULL to ignore.
|
||||
virtual srs_error_t create(SrsMessageHeader* pheader, char* body, int size);
|
||||
};
|
||||
|
||||
/**
|
||||
* the message header for shared ptr message.
|
||||
* only the message for all msgs are same.
|
||||
*/
|
||||
// The message header for shared ptr message.
|
||||
// only the message for all msgs are same.
|
||||
struct SrsSharedMessageHeader
|
||||
{
|
||||
/**
|
||||
* 3bytes.
|
||||
* Three-byte field that represents the size of the payload in bytes.
|
||||
* It is set in big-endian format.
|
||||
*/
|
||||
// 3bytes.
|
||||
// Three-byte field that represents the size of the payload in bytes.
|
||||
// It is set in big-endian format.
|
||||
int32_t payload_length;
|
||||
/**
|
||||
* 1byte.
|
||||
* One byte field to represent the message type. A range of type IDs
|
||||
* (1-7) are reserved for protocol control messages.
|
||||
*/
|
||||
// 1byte.
|
||||
// One byte field to represent the message type. A range of type IDs
|
||||
// (1-7) are reserved for protocol control messages.
|
||||
int8_t message_type;
|
||||
/**
|
||||
* get the perfered cid(chunk stream id) which sendout over.
|
||||
* set at decoding, and canbe used for directly send message,
|
||||
* for example, dispatch to all connections.
|
||||
*/
|
||||
// Get the perfered cid(chunk stream id) which sendout over.
|
||||
// set at decoding, and canbe used for directly send message,
|
||||
// For example, dispatch to all connections.
|
||||
int perfer_cid;
|
||||
|
||||
SrsSharedMessageHeader();
|
||||
virtual ~SrsSharedMessageHeader();
|
||||
};
|
||||
|
||||
/**
|
||||
* shared ptr message.
|
||||
* for audio/video/data message that need less memory copy.
|
||||
* and only for output.
|
||||
*
|
||||
* create first object by constructor and create(),
|
||||
* use copy if need reference count message.
|
||||
*
|
||||
*/
|
||||
// The shared ptr message.
|
||||
// For audio/video/data message that need less memory copy.
|
||||
// and only for output.
|
||||
//
|
||||
// Create first object by constructor and create(),
|
||||
// use copy if need reference count message.
|
||||
class SrsSharedPtrMessage
|
||||
{
|
||||
// 4.1. Message Header
|
||||
// 4.1. Message Header
|
||||
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
|
||||
//SrsSharedMessageHeader header;
|
||||
/**
|
||||
* Four-byte field that contains a timestamp of the message.
|
||||
* The 4 bytes are packed in the big-endian order.
|
||||
* @remark, used as calc timestamp when decode and encode time.
|
||||
* @remark, we use 64bits for large time for jitter detect and hls.
|
||||
*/
|
||||
// Four-byte field that contains a timestamp of the message.
|
||||
// The 4 bytes are packed in the big-endian order.
|
||||
// @remark, used as calc timestamp when decode and encode time.
|
||||
// @remark, we use 64bits for large time for jitter detect and hls.
|
||||
int64_t timestamp;
|
||||
/**
|
||||
* 4bytes.
|
||||
* Four-byte field that identifies the stream of the message. These
|
||||
* bytes are set in big-endian format.
|
||||
*/
|
||||
// 4bytes.
|
||||
// Four-byte field that identifies the stream of the message. These
|
||||
// bytes are set in big-endian format.
|
||||
int32_t stream_id;
|
||||
// 4.2. Message Payload
|
||||
public:
|
||||
/**
|
||||
* current message parsed size,
|
||||
* size <= header.payload_length
|
||||
* for the payload maybe sent in multiple chunks.
|
||||
*/
|
||||
// The current message parsed size,
|
||||
// size <= header.payload_length
|
||||
// For the payload maybe sent in multiple chunks.
|
||||
int size;
|
||||
/**
|
||||
* the payload of message, the SrsCommonMessage never know about the detail of payload,
|
||||
* user must use SrsProtocol.decode_message to get concrete packet.
|
||||
* @remark, not all message payload can be decoded to packet. for example,
|
||||
* video/audio packet use raw bytes, no video/audio packet.
|
||||
*/
|
||||
// The payload of message, the SrsCommonMessage never know about the detail of payload,
|
||||
// user must use SrsProtocol.decode_message to get concrete packet.
|
||||
// @remark, not all message payload can be decoded to packet. for example,
|
||||
// video/audio packet use raw bytes, no video/audio packet.
|
||||
char* payload;
|
||||
private:
|
||||
class SrsSharedPtrPayload
|
||||
{
|
||||
public:
|
||||
// shared message header.
|
||||
// The shared message header.
|
||||
// @see https://github.com/ossrs/srs/issues/251
|
||||
SrsSharedMessageHeader header;
|
||||
// actual shared payload.
|
||||
// The actual shared payload.
|
||||
char* payload;
|
||||
// size of payload.
|
||||
// The size of payload.
|
||||
int size;
|
||||
// the reference count
|
||||
// The reference count
|
||||
int shared_count;
|
||||
public:
|
||||
SrsSharedPtrPayload();
|
||||
|
@ -392,54 +305,40 @@ public:
|
|||
SrsSharedPtrMessage();
|
||||
virtual ~SrsSharedPtrMessage();
|
||||
public:
|
||||
/**
|
||||
* create shared ptr message,
|
||||
* copy header, manage the payload of msg,
|
||||
* set the payload to NULL to prevent double free.
|
||||
* @remark payload of msg set to NULL if success.
|
||||
*/
|
||||
// Create shared ptr message,
|
||||
// copy header, manage the payload of msg,
|
||||
// set the payload to NULL to prevent double free.
|
||||
// @remark payload of msg set to NULL if success.
|
||||
virtual srs_error_t create(SrsCommonMessage* msg);
|
||||
/**
|
||||
* create shared ptr message,
|
||||
* from the header and payload.
|
||||
* @remark user should never free the payload.
|
||||
* @param pheader, the header to copy to the message. NULL to ignore.
|
||||
*/
|
||||
// Create shared ptr message,
|
||||
// from the header and payload.
|
||||
// @remark user should never free the payload.
|
||||
// @param pheader, the header to copy to the message. NULL to ignore.
|
||||
virtual srs_error_t create(SrsMessageHeader* pheader, char* payload, int size);
|
||||
/**
|
||||
* get current reference count.
|
||||
* when this object created, count set to 0.
|
||||
* if copy() this object, count increase 1.
|
||||
* if this or copy deleted, free payload when count is 0, or count--.
|
||||
* @remark, assert object is created.
|
||||
*/
|
||||
// Get current reference count.
|
||||
// when this object created, count set to 0.
|
||||
// if copy() this object, count increase 1.
|
||||
// if this or copy deleted, free payload when count is 0, or count--.
|
||||
// @remark, assert object is created.
|
||||
virtual int count();
|
||||
/**
|
||||
* check perfer cid and stream id.
|
||||
* @return whether stream id already set.
|
||||
*/
|
||||
// check perfer cid and stream id.
|
||||
// @return whether stream id already set.
|
||||
virtual bool check(int stream_id);
|
||||
public:
|
||||
virtual bool is_av();
|
||||
virtual bool is_audio();
|
||||
virtual bool is_video();
|
||||
public:
|
||||
/**
|
||||
* generate the chunk header to cache.
|
||||
* @return the size of header.
|
||||
*/
|
||||
// generate the chunk header to cache.
|
||||
// @return the size of header.
|
||||
virtual int chunk_header(char* cache, int nb_cache, bool c0);
|
||||
public:
|
||||
/**
|
||||
* copy current shared ptr message, use ref-count.
|
||||
* @remark, assert object is created.
|
||||
*/
|
||||
// copy current shared ptr message, use ref-count.
|
||||
// @remark, assert object is created.
|
||||
virtual SrsSharedPtrMessage* copy();
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmux RTMP packets to FLV stream.
|
||||
*/
|
||||
// Transmux RTMP packets to FLV stream.
|
||||
class SrsFlvTransmuxer
|
||||
{
|
||||
private:
|
||||
|
@ -450,60 +349,48 @@ public:
|
|||
SrsFlvTransmuxer();
|
||||
virtual ~SrsFlvTransmuxer();
|
||||
public:
|
||||
/**
|
||||
* initialize the underlayer file stream.
|
||||
* @remark user can initialize multiple times to encode multiple flv files.
|
||||
* @remark, user must free the @param fw, flv encoder never close/free it.
|
||||
*/
|
||||
// Initialize the underlayer file stream.
|
||||
// @remark user can initialize multiple times to encode multiple flv files.
|
||||
// @remark, user must free the @param fw, flv encoder never close/free it.
|
||||
virtual srs_error_t initialize(ISrsWriter* fw);
|
||||
public:
|
||||
/**
|
||||
* write flv header.
|
||||
* write following:
|
||||
* 1. E.2 The FLV header
|
||||
* 2. PreviousTagSize0 UI32 Always 0
|
||||
* that is, 9+4=13bytes.
|
||||
*/
|
||||
// Write flv header.
|
||||
// Write following:
|
||||
// 1. E.2 The FLV header
|
||||
// 2. PreviousTagSize0 UI32 Always 0
|
||||
// that is, 9+4=13bytes.
|
||||
virtual srs_error_t write_header();
|
||||
virtual srs_error_t write_header(char flv_header[9]);
|
||||
/**
|
||||
* write flv metadata.
|
||||
* @param type, the type of data, or other message type.
|
||||
* @see SrsFrameType
|
||||
* @param data, the amf0 metadata which serialize from:
|
||||
* AMF0 string: onMetaData,
|
||||
* AMF0 object: the metadata object.
|
||||
* @remark assert data is not NULL.
|
||||
*/
|
||||
// Write flv metadata.
|
||||
// @param type, the type of data, or other message type.
|
||||
// @see SrsFrameType
|
||||
// @param data, the amf0 metadata which serialize from:
|
||||
// AMF0 string: onMetaData,
|
||||
// AMF0 object: the metadata object.
|
||||
// @remark assert data is not NULL.
|
||||
virtual srs_error_t write_metadata(char type, char* data, int size);
|
||||
/**
|
||||
* write audio/video packet.
|
||||
* @remark assert data is not NULL.
|
||||
*/
|
||||
// Write audio/video packet.
|
||||
// @remark assert data is not NULL.
|
||||
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);
|
||||
public:
|
||||
/**
|
||||
* get the tag size,
|
||||
* including the tag header, body, and 4bytes previous tag size.
|
||||
* @remark assert data_size is not negative.
|
||||
*/
|
||||
// Get the tag size,
|
||||
// including the tag header, body, and 4bytes previous tag size.
|
||||
// @remark assert data_size is not negative.
|
||||
static int size_tag(int data_size);
|
||||
#ifdef SRS_PERF_FAST_FLV_ENCODER
|
||||
private:
|
||||
// cache tag header.
|
||||
// The cache tag header.
|
||||
int nb_tag_headers;
|
||||
char* tag_headers;
|
||||
// cache pps(previous tag size)
|
||||
// The cache pps(previous tag size)
|
||||
int nb_ppts;
|
||||
char* ppts;
|
||||
// cache iovss.
|
||||
// The cache iovss.
|
||||
int nb_iovss_cache;
|
||||
iovec* iovss_cache;
|
||||
public:
|
||||
/**
|
||||
* write the tags in a time.
|
||||
*/
|
||||
// Write the tags in a time.
|
||||
virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count);
|
||||
#endif
|
||||
private:
|
||||
|
@ -514,9 +401,7 @@ private:
|
|||
virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size);
|
||||
};
|
||||
|
||||
/**
|
||||
* decode flv file.
|
||||
*/
|
||||
// Decode flv file.
|
||||
class SrsFlvDecoder
|
||||
{
|
||||
private:
|
||||
|
@ -525,40 +410,28 @@ public:
|
|||
SrsFlvDecoder();
|
||||
virtual ~SrsFlvDecoder();
|
||||
public:
|
||||
/**
|
||||
* initialize the underlayer file stream
|
||||
* @remark user can initialize multiple times to decode multiple flv files.
|
||||
* @remark user must free the @param fr, flv decoder never close/free it
|
||||
*/
|
||||
// Initialize the underlayer file stream
|
||||
// @remark user can initialize multiple times to decode multiple flv files.
|
||||
// @remark user must free the @param fr, flv decoder never close/free it
|
||||
virtual srs_error_t initialize(ISrsReader* fr);
|
||||
public:
|
||||
/**
|
||||
* read the flv header, donot including the 4bytes previous tag size.
|
||||
* @remark assert header not NULL.
|
||||
*/
|
||||
// Read the flv header, donot including the 4bytes previous tag size.
|
||||
// @remark assert header not NULL.
|
||||
virtual srs_error_t read_header(char header[9]);
|
||||
/**
|
||||
* read the tag header infos.
|
||||
* @remark assert ptype/pdata_size/ptime not NULL.
|
||||
*/
|
||||
// Read the tag header infos.
|
||||
// @remark assert ptype/pdata_size/ptime not NULL.
|
||||
virtual srs_error_t read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* ptime);
|
||||
/**
|
||||
* read the tag data.
|
||||
* @remark assert data not NULL.
|
||||
*/
|
||||
// Read the tag data.
|
||||
// @remark assert data not NULL.
|
||||
virtual srs_error_t read_tag_data(char* data, int32_t size);
|
||||
/**
|
||||
* read the 4bytes previous tag size.
|
||||
* @remark assert previous_tag_size not NULL.
|
||||
*/
|
||||
// Read the 4bytes previous tag size.
|
||||
// @remark assert previous_tag_size not NULL.
|
||||
virtual srs_error_t read_previous_tag_size(char previous_tag_size[4]);
|
||||
};
|
||||
|
||||
/**
|
||||
* decode flv fast by only decoding the header and tag.
|
||||
* used for vod flv stream to read the header and sequence header,
|
||||
* then seek to specified offset.
|
||||
*/
|
||||
// Decode flv fast by only decoding the header and tag.
|
||||
// used for vod flv stream to read the header and sequence header,
|
||||
// then seek to specified offset.
|
||||
class SrsFlvVodStreamDecoder
|
||||
{
|
||||
private:
|
||||
|
@ -567,31 +440,23 @@ public:
|
|||
SrsFlvVodStreamDecoder();
|
||||
virtual ~SrsFlvVodStreamDecoder();
|
||||
public:
|
||||
/**
|
||||
* initialize the underlayer file stream
|
||||
* @remark user can initialize multiple times to decode multiple flv files.
|
||||
* @remark user must free the @param fr, flv decoder never close/free it.
|
||||
*/
|
||||
// Initialize the underlayer file stream
|
||||
// @remark user can initialize multiple times to decode multiple flv files.
|
||||
// @remark user must free the @param fr, flv decoder never close/free it.
|
||||
virtual srs_error_t initialize(ISrsReader* fr);
|
||||
public:
|
||||
/**
|
||||
* read the flv header and its size.
|
||||
* @param header, fill it 13bytes(9bytes header, 4bytes previous tag size).
|
||||
* @remark assert header not NULL.
|
||||
*/
|
||||
// Read the flv header and its size.
|
||||
// @param header, fill it 13bytes(9bytes header, 4bytes previous tag size).
|
||||
// @remark assert header not NULL.
|
||||
virtual srs_error_t read_header_ext(char header[13]);
|
||||
/**
|
||||
* read the sequence header tags offset and its size.
|
||||
* @param pstart, the start offset of sequence header.
|
||||
* @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size).
|
||||
* @remark we think the first audio/video is sequence header.
|
||||
* @remark assert pstart/psize not NULL.
|
||||
*/
|
||||
// Read the sequence header tags offset and its size.
|
||||
// @param pstart, the start offset of sequence header.
|
||||
// @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size).
|
||||
// @remark we think the first audio/video is sequence header.
|
||||
// @remark assert pstart/psize not NULL.
|
||||
virtual srs_error_t read_sequence_header_summary(int64_t* pstart, int* psize);
|
||||
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);
|
||||
};
|
||||
|
||||
|
|
|
@ -33,15 +33,13 @@
|
|||
|
||||
#include <srs_kernel_consts.hpp>
|
||||
|
||||
/**
|
||||
* the log level, for example:
|
||||
* if specified Debug level, all level messages will be logged.
|
||||
* if specified Warn level, only Warn/Error/Fatal level messages will be logged.
|
||||
*/
|
||||
// The log level, for example:
|
||||
// if specified Debug level, all level messages will be logged.
|
||||
// if specified Warn level, only Warn/Error/Fatal level messages will be logged.
|
||||
enum SrsLogLevel
|
||||
{
|
||||
SrsLogLevelForbidden = 0x00,
|
||||
// only used for very verbose debug, generally,
|
||||
// Only used for very verbose debug, generally,
|
||||
// we compile without this level for high performance.
|
||||
SrsLogLevelVerbose = 0x01,
|
||||
SrsLogLevelInfo = 0x02,
|
||||
|
@ -51,85 +49,63 @@ enum SrsLogLevel
|
|||
SrsLogLevelDisabled = 0x20,
|
||||
};
|
||||
|
||||
/**
|
||||
* the log interface provides method to write log.
|
||||
* 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.
|
||||
*/
|
||||
// The log interface provides method to write log.
|
||||
// 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.
|
||||
class ISrsLog
|
||||
{
|
||||
public:
|
||||
ISrsLog();
|
||||
virtual ~ISrsLog();
|
||||
public:
|
||||
/**
|
||||
* initialize log utilities.
|
||||
*/
|
||||
// Initialize log utilities.
|
||||
virtual srs_error_t initialize();
|
||||
/**
|
||||
* reopen the log file for log rotate.
|
||||
*/
|
||||
// Reopen the log file for log rotate.
|
||||
virtual void reopen();
|
||||
public:
|
||||
/**
|
||||
* log for verbose, very verbose information.
|
||||
*/
|
||||
// The log for verbose, very verbose information.
|
||||
virtual void verbose(const char* tag, int context_id, const char* fmt, ...);
|
||||
/**
|
||||
* log for debug, detail information.
|
||||
*/
|
||||
// The log for debug, detail information.
|
||||
virtual void info(const char* tag, int context_id, const char* fmt, ...);
|
||||
/**
|
||||
* log for trace, important information.
|
||||
*/
|
||||
// The log for trace, important information.
|
||||
virtual void trace(const char* tag, int context_id, const char* fmt, ...);
|
||||
/**
|
||||
* log for warn, warn is something should take attention, but not a error.
|
||||
*/
|
||||
// The 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, ...);
|
||||
/**
|
||||
* log for error, something error occur, do something about the error, ie. close the connection,
|
||||
* but we will donot abort the program.
|
||||
*/
|
||||
// The log for error, something error occur, do something about the error, ie. close the connection,
|
||||
// but we will donot abort the program.
|
||||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
};
|
||||
|
||||
/**
|
||||
* the context id manager to identify context, for instance, the green-thread.
|
||||
* usage:
|
||||
* _srs_context->generate_id(); // when thread start.
|
||||
* _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.
|
||||
*/
|
||||
// the context for multiple clients.
|
||||
// The context id manager to identify context, for instance, the green-thread.
|
||||
// Usage:
|
||||
// _srs_context->generate_id(); // when thread start.
|
||||
// _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.
|
||||
// The context for multiple clients.
|
||||
class ISrsThreadContext
|
||||
{
|
||||
public:
|
||||
ISrsThreadContext();
|
||||
virtual ~ISrsThreadContext();
|
||||
public:
|
||||
/**
|
||||
* generate the id for current context.
|
||||
*/
|
||||
// Generate the id for current context.
|
||||
virtual int generate_id();
|
||||
/**
|
||||
* get the generated id of current context.
|
||||
*/
|
||||
// Get the generated id of current context.
|
||||
virtual int get_id();
|
||||
/**
|
||||
* set the id of current context.
|
||||
* @return the previous id value; 0 if no context.
|
||||
*/
|
||||
// Set the id of current context.
|
||||
// @return the previous id value; 0 if no context.
|
||||
virtual int set_id(int v);
|
||||
};
|
||||
|
||||
// @global user must provides a log object
|
||||
// @global User must provides a log object
|
||||
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;
|
||||
|
||||
// donot print method
|
||||
// Log style.
|
||||
// Use __FUNCTION__ to print c method
|
||||
// Use __PRETTY_FUNCTION__ to print c++ class:method
|
||||
#if 1
|
||||
#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__)
|
||||
|
@ -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_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
// use __FUNCTION__ to print c method
|
||||
#if 0
|
||||
#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__)
|
||||
|
@ -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_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
// use __PRETTY_FUNCTION__ to print c++ class:method
|
||||
#if 0
|
||||
#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__)
|
||||
|
@ -154,7 +128,7 @@ extern ISrsThreadContext* _srs_context;
|
|||
#define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// TODO: FIXME: add more verbose and info logs.
|
||||
// TODO: FIXME: Add more verbose and info logs.
|
||||
#ifndef SRS_AUTO_VERBOSE
|
||||
#undef srs_verbose
|
||||
#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
|
@ -33,160 +33,132 @@
|
|||
class SrsBuffer;
|
||||
class SrsBitBuffer;
|
||||
|
||||
// compare
|
||||
// Basic compare function.
|
||||
#define srs_min(a, b) (((a) < (b))? (a) : (b))
|
||||
#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_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_startup_time();
|
||||
// the deamon st-thread will update it.
|
||||
// A daemon st-thread updates it.
|
||||
extern srs_utime_t srs_update_system_time();
|
||||
|
||||
// the any address for listener,
|
||||
// it's "0.0.0.0" for ipv4, and "::" for ipv6.
|
||||
// The "ANY" address to listen, it's "0.0.0.0" for ipv4, and "::" for ipv6.
|
||||
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);
|
||||
|
||||
// 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.
|
||||
extern void srs_parse_hostport(const std::string& hostport, std::string& host, int& port);
|
||||
|
||||
// parse the endpoint to ip and port.
|
||||
// @remark hostport format in <[ip:]port>, where ip is default to "0.0.0.0".
|
||||
// Parse the endpoint to ip and port.
|
||||
// @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);
|
||||
|
||||
// parse the int64 value to string.
|
||||
// Parse the int64 value to string.
|
||||
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);
|
||||
// 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);
|
||||
|
||||
// whether system is little endian
|
||||
// Whether system 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);
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
// remove first substring from str
|
||||
// Remove first substring from str
|
||||
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);
|
||||
// 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 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, 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 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, 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 flag0, std::string flag1);
|
||||
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);
|
||||
// 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::vector<std::string> flags);
|
||||
|
||||
/**
|
||||
* compare the memory in bytes.
|
||||
* @return true if completely equal; otherwise, false.
|
||||
*/
|
||||
// Compare the memory in bytes.
|
||||
// @return true if completely equal; otherwise, false.
|
||||
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);
|
||||
|
||||
// whether path exists.
|
||||
// Whether path exists.
|
||||
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);
|
||||
// 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);
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
/**
|
||||
* whether stream starts with the avc NALU in "AnnexB"
|
||||
* from ISO_IEC_14496-10-AVC-2003.pdf, page 211.
|
||||
* 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.
|
||||
*/
|
||||
// Whether stream starts with the avc NALU in "AnnexB" from ISO_IEC_14496-10-AVC-2003.pdf, page 211.
|
||||
// The 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);
|
||||
|
||||
/**
|
||||
* whether stream starts with the aac ADTS
|
||||
* 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
|
||||
*/
|
||||
// Whether stream starts with the aac ADTS from ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS.
|
||||
// The start code must be '1111 1111 1111'B, that is 0xFFF
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Decode a base64-encoded string.
|
||||
*/
|
||||
// Decode a base64-encoded string.
|
||||
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)
|
||||
|
||||
/**
|
||||
* convert hex string to data.
|
||||
* for example, p=config='139056E5A0'
|
||||
* output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0}
|
||||
*/
|
||||
// Convert hex string to data, for example, p=config='139056E5A0'
|
||||
// The output data in hex {0x13, 0x90, 0x56, 0xe5, 0xa0} as such.
|
||||
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);
|
||||
|
||||
/**
|
||||
* generate the c0 chunk header for msg.
|
||||
* @param cache, the cache to write header.
|
||||
* @param nb_cache, the size of cache.
|
||||
* @return the size of header. 0 if cache not enough.
|
||||
*/
|
||||
// Generate the c0 chunk header for msg.
|
||||
// @param cache, the cache to write header.
|
||||
// @param nb_cache, the size of cache.
|
||||
// @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);
|
||||
|
||||
/**
|
||||
* generate the c3 chunk header for msg.
|
||||
* @param cache, the cache to write header.
|
||||
* @param nb_cache, the size of cache.
|
||||
* @return the size of header. 0 if cache not enough.
|
||||
*/
|
||||
// Generate the c3 chunk header for msg.
|
||||
// @param cache, the cache to write header.
|
||||
// @param nb_cache, the size of cache.
|
||||
// @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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -365,7 +365,7 @@ int SimpleSocketStream::connect(const char* server_ip, int 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_assert(io);
|
||||
|
@ -376,7 +376,7 @@ srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread)
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
// ISrsProtocolReader
|
||||
// Interface ISrsProtocolReader
|
||||
void SimpleSocketStream::set_recv_timeout(srs_utime_t tm)
|
||||
{
|
||||
srs_assert(io);
|
||||
|
@ -395,7 +395,7 @@ int64_t SimpleSocketStream::get_recv_bytes()
|
|||
return srs_hijack_io_get_recv_bytes(io);
|
||||
}
|
||||
|
||||
// ISrsProtocolWriter
|
||||
// Interface ISrsProtocolWriter
|
||||
void SimpleSocketStream::set_send_timeout(srs_utime_t tm)
|
||||
{
|
||||
srs_assert(io);
|
||||
|
@ -424,7 +424,7 @@ srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t*
|
|||
return srs_success;
|
||||
}
|
||||
|
||||
// ISrsProtocolReadWriter
|
||||
// Interface ISrsProtocolReadWriter
|
||||
bool SimpleSocketStream::is_never_timeout(srs_utime_t tm)
|
||||
{
|
||||
srs_assert(io);
|
||||
|
|
|
@ -49,21 +49,21 @@ public:
|
|||
virtual srs_hijack_io_t hijack_io();
|
||||
virtual int create_socket(srs_rtmp_t owner);
|
||||
virtual int connect(const char* server, int port);
|
||||
// ISrsReader
|
||||
// Interface ISrsReader
|
||||
public:
|
||||
virtual srs_error_t read(void* buf, size_t size, ssize_t* nread);
|
||||
// ISrsProtocolReader
|
||||
// Interface ISrsProtocolReader
|
||||
public:
|
||||
virtual void set_recv_timeout(srs_utime_t tm);
|
||||
virtual srs_utime_t get_recv_timeout();
|
||||
virtual int64_t get_recv_bytes();
|
||||
// ISrsProtocolWriter
|
||||
// Interface ISrsProtocolWriter
|
||||
public:
|
||||
virtual void set_send_timeout(srs_utime_t tm);
|
||||
virtual srs_utime_t get_send_timeout();
|
||||
virtual int64_t get_send_bytes();
|
||||
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite);
|
||||
// ISrsProtocolReadWriter
|
||||
// Interface ISrsProtocolReadWriter
|
||||
public:
|
||||
virtual bool is_never_timeout(srs_utime_t tm);
|
||||
virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread);
|
||||
|
|
|
@ -662,10 +662,10 @@ private:
|
|||
public:
|
||||
SrsIngestHlsOutput(SrsHttpUri* rtmp);
|
||||
virtual ~SrsIngestHlsOutput();
|
||||
// interface ISrsTsHandler
|
||||
// Interface ISrsTsHandler
|
||||
public:
|
||||
virtual srs_error_t on_ts_message(SrsTsMessage* msg);
|
||||
// interface IAacHandler
|
||||
// Interface IAacHandler
|
||||
public:
|
||||
virtual int on_aac_frame(char* frame, int frame_size, double duration);
|
||||
private:
|
||||
|
|
|
@ -118,9 +118,8 @@ srs_error_t do_main(int argc, char** argv)
|
|||
}
|
||||
|
||||
// config already applied to log.
|
||||
srs_trace(RTMP_SIG_SRS_SERVER ", stable is " RTMP_SIG_SRS_PRIMARY);
|
||||
srs_trace("license: " RTMP_SIG_SRS_LICENSE ", " RTMP_SIG_SRS_COPYRIGHT);
|
||||
srs_trace("authors: " RTMP_SIG_SRS_AUTHROS);
|
||||
srs_trace(RTMP_SIG_SRS_SERVER);
|
||||
srs_trace("license: " RTMP_SIG_SRS_LICENSE);
|
||||
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("configure detail: " SRS_AUTO_CONFIGURE);
|
||||
|
@ -373,17 +372,13 @@ string srs_getenv(const char* name)
|
|||
srs_error_t run(SrsServer* svr)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Initialize the whole system, set hooks to handle server level events.
|
||||
if ((err = svr->initialize(NULL)) != srs_success) {
|
||||
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 ((err = run_master(svr)) != srs_success) {
|
||||
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
|
@ -77,7 +77,7 @@ public:
|
|||
virtual bool empty();
|
||||
virtual std::string to_str();
|
||||
virtual void set_value(std::string v);
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -106,7 +106,7 @@ public:
|
|||
virtual void set_value(std::string v);
|
||||
virtual void set_value(const char* v, int nb_v);
|
||||
virtual uint32_t crc32(uint32_t previous);
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -164,7 +164,7 @@ public:
|
|||
{
|
||||
return elems.at(index);
|
||||
}
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes()
|
||||
{
|
||||
|
@ -251,7 +251,7 @@ public:
|
|||
{
|
||||
return elems.at(index);
|
||||
}
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes()
|
||||
{
|
||||
|
@ -400,7 +400,7 @@ public:
|
|||
virtual bool is_offset_commit_request();
|
||||
virtual bool is_offset_fetch_request();
|
||||
virtual bool is_consumer_metadata_request();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -466,7 +466,7 @@ public:
|
|||
* get the correlation id of response message.
|
||||
*/
|
||||
virtual int32_t correlation_id();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -533,7 +533,7 @@ private:
|
|||
* get the raw message, bytes after the message_size.
|
||||
*/
|
||||
virtual int raw_message_size();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -554,7 +554,7 @@ public:
|
|||
virtual ~SrsKafkaRawMessageSet();
|
||||
public:
|
||||
virtual void append(SrsKafkaRawMessage* msg);
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -585,7 +585,7 @@ public:
|
|||
* get the api key of request.
|
||||
*/
|
||||
virtual SrsKafkaApiKey api_key();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -608,7 +608,7 @@ public:
|
|||
* @param s an int value specifies the size of message in header.
|
||||
*/
|
||||
virtual void update_header(int s);
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -638,7 +638,7 @@ public:
|
|||
virtual ~SrsKafkaTopicMetadataRequest();
|
||||
public:
|
||||
virtual void add_topic(std::string topic);
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -658,7 +658,7 @@ public:
|
|||
public:
|
||||
SrsKafkaBroker();
|
||||
virtual ~SrsKafkaBroker();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -675,7 +675,7 @@ public:
|
|||
public:
|
||||
SrsKafkaPartitionMetadata();
|
||||
virtual ~SrsKafkaPartitionMetadata();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -690,7 +690,7 @@ public:
|
|||
public:
|
||||
SrsKafkaTopicMetadata();
|
||||
virtual ~SrsKafkaTopicMetadata();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -713,7 +713,7 @@ public:
|
|||
public:
|
||||
SrsKafkaTopicMetadataResponse();
|
||||
virtual ~SrsKafkaTopicMetadataResponse();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -740,7 +740,7 @@ public:
|
|||
* messages in set.
|
||||
*/
|
||||
SrsKafkaRawMessageSet messages;
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -757,7 +757,7 @@ public:
|
|||
* messages of partitions.
|
||||
*/
|
||||
SrsKafkaArray<SrsKafkaProducerPartitionMessages> partitions;
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
@ -801,7 +801,7 @@ public:
|
|||
public:
|
||||
SrsKafkaProducerRequest();
|
||||
virtual ~SrsKafkaProducerRequest();
|
||||
// interface ISrsCodec
|
||||
// Interface ISrsCodec
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// json decode
|
||||
// JSON decode
|
||||
// 1. SrsJsonAny: read any from str:char*
|
||||
// SrsJsonAny* any = NULL;
|
||||
// if ((any = SrsJsonAny::loads(str)) == NULL) {
|
||||
|
@ -45,7 +45,7 @@
|
|||
// 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:
|
||||
char marker;
|
||||
// donot directly create this object,
|
||||
// instead, for examle, use SrsJsonAny::str() to create a concreated one.
|
||||
// Don't directly create this object,
|
||||
// please use SrsJsonAny::str() to create a concreated one.
|
||||
protected:
|
||||
SrsJsonAny();
|
||||
public:
|
||||
|
@ -74,35 +74,23 @@ public:
|
|||
virtual bool is_array();
|
||||
virtual bool is_null();
|
||||
public:
|
||||
/**
|
||||
* get the string of any when is_string() indicates true.
|
||||
* user must ensure the type is a string, or assert failed.
|
||||
*/
|
||||
// Get the string of any when is_string() indicates true.
|
||||
// user must ensure the type is a string, or assert failed.
|
||||
virtual std::string to_str();
|
||||
/**
|
||||
* get the boolean of any when is_boolean() indicates true.
|
||||
* user must ensure the type is a boolean, or assert failed.
|
||||
*/
|
||||
// Get the boolean of any when is_boolean() indicates true.
|
||||
// user must ensure the type is a boolean, or assert failed.
|
||||
virtual bool to_boolean();
|
||||
/**
|
||||
* get the integer of any when is_integer() indicates true.
|
||||
* user must ensure the type is a integer, or assert failed.
|
||||
*/
|
||||
// Get the integer of any when is_integer() indicates true.
|
||||
// user must ensure the type is a integer, or assert failed.
|
||||
virtual int64_t to_integer();
|
||||
/**
|
||||
* get the number of any when is_number() indicates true.
|
||||
* user must ensure the type is a number, or assert failed.
|
||||
*/
|
||||
// Get the number of any when is_number() indicates true.
|
||||
// user must ensure the type is a number, or assert failed.
|
||||
virtual double to_number();
|
||||
/**
|
||||
* get the object of any when is_object() indicates true.
|
||||
* user must ensure the type is a object, or assert failed.
|
||||
*/
|
||||
// Get the object of any when is_object() indicates true.
|
||||
// user must ensure the type is a object, or assert failed.
|
||||
virtual SrsJsonObject* to_object();
|
||||
/**
|
||||
* get the ecma array of any when is_ecma_array() indicates true.
|
||||
* user must ensure the type is a ecma array, or assert failed.
|
||||
*/
|
||||
// Get the ecma array of any when is_ecma_array() indicates true.
|
||||
// user must ensure the type is a ecma array, or assert failed.
|
||||
virtual SrsJsonArray* to_array();
|
||||
public:
|
||||
virtual std::string dumps();
|
||||
|
@ -117,10 +105,8 @@ public:
|
|||
static SrsJsonObject* object();
|
||||
static SrsJsonArray* array();
|
||||
public:
|
||||
/**
|
||||
* read json tree from string.
|
||||
* @return json object. NULL if error.
|
||||
*/
|
||||
// Read json tree from string.
|
||||
// @return json object. NULL if error.
|
||||
static SrsJsonAny* loads(const std::string& str);
|
||||
};
|
||||
|
||||
|
@ -130,7 +116,7 @@ private:
|
|||
typedef std::pair<std::string, SrsJsonAny*> SrsJsonObjectPropertyType;
|
||||
std::vector<SrsJsonObjectPropertyType> properties;
|
||||
private:
|
||||
// use SrsJsonAny::object() to create it.
|
||||
// Use SrsJsonAny::object() to create it.
|
||||
friend class SrsJsonAny;
|
||||
SrsJsonObject();
|
||||
public:
|
||||
|
@ -161,7 +147,7 @@ private:
|
|||
std::vector<SrsJsonAny*> properties;
|
||||
|
||||
private:
|
||||
// use SrsJsonAny::array() to create it.
|
||||
// Use SrsJsonAny::array() to create it.
|
||||
friend class SrsJsonAny;
|
||||
SrsJsonArray();
|
||||
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
|
||||
|
|
|
@ -221,14 +221,14 @@ public:
|
|||
* use the add_delta() is better solutions.
|
||||
*/
|
||||
virtual void sample();
|
||||
// interface ISrsProtocolStatistic
|
||||
// Interface ISrsProtocolStatistic
|
||||
public:
|
||||
virtual int64_t get_send_bytes();
|
||||
virtual int64_t get_recv_bytes();
|
||||
// interface ISrsKbpsDelta
|
||||
// Interface ISrsKbpsDelta
|
||||
public:
|
||||
virtual void remark(int64_t* in, int64_t* out);
|
||||
// interface ISrsMemorySizer
|
||||
// Interface ISrsMemorySizer
|
||||
public:
|
||||
virtual int size_memory();
|
||||
};
|
||||
|
|
|
@ -32,61 +32,45 @@
|
|||
|
||||
class SrsBuffer;
|
||||
|
||||
/**
|
||||
* the raw h.264 stream, in annexb.
|
||||
*/
|
||||
// The raw h.264 stream, in annexb.
|
||||
class SrsRawH264Stream
|
||||
{
|
||||
public:
|
||||
SrsRawH264Stream();
|
||||
virtual ~SrsRawH264Stream();
|
||||
public:
|
||||
/**
|
||||
* demux the stream in annexb format.
|
||||
* @param stream the input stream bytes.
|
||||
* @param pframe the output h.264 frame in stream. user should never free it.
|
||||
* @param pnb_frame the output h.264 frame size.
|
||||
*/
|
||||
// Demux the stream in annexb format.
|
||||
// @param stream the input stream bytes.
|
||||
// @param pframe the output h.264 frame in stream. user should never free it.
|
||||
// @param pnb_frame the output h.264 frame size.
|
||||
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_pps(char* frame, int nb_frame);
|
||||
/**
|
||||
* demux the sps or pps to string.
|
||||
* @param sps/pps output the sps/pps.
|
||||
*/
|
||||
// Demux the sps or pps to string.
|
||||
// @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 pps_demux(char* frame, int nb_frame, std::string& pps);
|
||||
public:
|
||||
/**
|
||||
* h264 raw data to h264 packet, without flv payload header.
|
||||
* mux the sps/pps to flv sequence header packet.
|
||||
* @param sh output the sequence header.
|
||||
*/
|
||||
// The h264 raw data to h264 packet, without flv payload header.
|
||||
// Mux the sps/pps to flv sequence header packet.
|
||||
// @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);
|
||||
/**
|
||||
* h264 raw data to h264 packet, without flv payload header.
|
||||
* mux the ibp to flv ibp packet.
|
||||
* @param ibp output the packet.
|
||||
* @param frame_type output the frame type.
|
||||
*/
|
||||
// The h264 raw data to h264 packet, without flv payload header.
|
||||
// Mux the ibp to flv ibp packet.
|
||||
// @param ibp output the packet.
|
||||
// @param frame_type output the frame type.
|
||||
virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp);
|
||||
/**
|
||||
* mux the avc video packet to flv video packet.
|
||||
* @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
|
||||
* @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
|
||||
* @param video the h.264 raw data.
|
||||
* @param flv output the muxed flv packet.
|
||||
* @param nb_flv output the muxed flv size.
|
||||
*/
|
||||
// Mux the avc video packet to flv video packet.
|
||||
// @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame.
|
||||
// @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU.
|
||||
// @param video the h.264 raw data.
|
||||
// @param flv output the muxed flv packet.
|
||||
// @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);
|
||||
};
|
||||
|
||||
/**
|
||||
* the header of adts sample.
|
||||
*/
|
||||
// The header of adts sample.
|
||||
struct SrsRawAacStreamCodec
|
||||
{
|
||||
int8_t protection_absent;
|
||||
|
@ -103,37 +87,29 @@ struct SrsRawAacStreamCodec
|
|||
int8_t aac_packet_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* the raw aac stream, in adts.
|
||||
*/
|
||||
// The raw aac stream, in adts.
|
||||
class SrsRawAacStream
|
||||
{
|
||||
public:
|
||||
SrsRawAacStream();
|
||||
virtual ~SrsRawAacStream();
|
||||
public:
|
||||
/**
|
||||
* demux the stream in adts format.
|
||||
* @param stream the input stream bytes.
|
||||
* @param pframe the output aac frame in stream. user should never free it.
|
||||
* @param pnb_frame the output aac frame size.
|
||||
* @param codec the output codec info.
|
||||
*/
|
||||
// Demux the stream in adts format.
|
||||
// @param stream the input stream bytes.
|
||||
// @param pframe the output aac frame in stream. user should never free it.
|
||||
// @param pnb_frame the output aac frame size.
|
||||
// @param codec the output codec info.
|
||||
virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec);
|
||||
/**
|
||||
* aac raw data to aac packet, without flv payload header.
|
||||
* mux the aac specific config to flv sequence header packet.
|
||||
* @param sh output the sequence header.
|
||||
*/
|
||||
// Mux aac raw data to aac packet, without flv payload header.
|
||||
// Mux the aac specific config to flv sequence header packet.
|
||||
// @param sh output the sequence header.
|
||||
virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh);
|
||||
/**
|
||||
* mux the aac audio packet to flv audio packet.
|
||||
* @param frame the aac raw data.
|
||||
* @param nb_frame the count of aac frame.
|
||||
* @param codec the codec info of aac.
|
||||
* @param flv output the muxed flv packet.
|
||||
* @param nb_flv output the muxed flv size.
|
||||
*/
|
||||
// Mux the aac audio packet to flv audio packet.
|
||||
// @param frame the aac raw data.
|
||||
// @param nb_frame the count of aac frame.
|
||||
// @param codec the codec info of aac.
|
||||
// @param flv output the muxed flv packet.
|
||||
// @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);
|
||||
};
|
||||
|
||||
|
|
|
@ -42,6 +42,9 @@ using namespace _srs_internal;
|
|||
// for openssl_generate_key
|
||||
#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
|
||||
|
||||
static HMAC_CTX *HMAC_CTX_new(void)
|
||||
|
|
|
@ -31,21 +31,19 @@ class SrsComplexHandshake;
|
|||
class SrsHandshakeBytes;
|
||||
class SrsBuffer;
|
||||
|
||||
// for openssl.
|
||||
// For openssl.
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
namespace _srs_internal
|
||||
{
|
||||
// the digest key generate size.
|
||||
// The digest key generate size.
|
||||
#define SRS_OpensslHashSize 512
|
||||
extern uint8_t SrsGenuineFMSKey[];
|
||||
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_generate_key(char* public_key, int32_t size);
|
||||
|
||||
/**
|
||||
* the DH wrapper.
|
||||
*/
|
||||
// The DH wrapper.
|
||||
class SrsDH
|
||||
{
|
||||
private:
|
||||
|
@ -56,62 +54,48 @@ namespace _srs_internal
|
|||
private:
|
||||
virtual void close();
|
||||
public:
|
||||
/**
|
||||
* initialize dh, generate the public and private key.
|
||||
* @param ensure_128bytes_public_key whether ensure public key is 128bytes,
|
||||
* sometimes openssl generate 127bytes public key.
|
||||
* default to false to donot ensure.
|
||||
*/
|
||||
// Initialize dh, generate the public and private key.
|
||||
// @param ensure_128bytes_public_key whether ensure public key is 128bytes,
|
||||
// sometimes openssl generate 127bytes public key.
|
||||
// default to false to donot ensure.
|
||||
virtual srs_error_t initialize(bool ensure_128bytes_public_key = false);
|
||||
/**
|
||||
* 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.
|
||||
* user should never ignore this size.
|
||||
* @remark, when ensure_128bytes_public_key, the size always 128.
|
||||
*/
|
||||
// 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.
|
||||
// user should never ignore this size.
|
||||
// @remark, when ensure_128bytes_public_key, the size always 128.
|
||||
virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size);
|
||||
/**
|
||||
* generate and copy the shared key.
|
||||
* generate the shared key with peer public key.
|
||||
* @param ppkey peer public key.
|
||||
* @param ppkey_size the size of ppkey.
|
||||
* @param skey the computed shared key.
|
||||
* @param skey_size the max shared key size, output the actual shared key size.
|
||||
* user should never ignore this size.
|
||||
*/
|
||||
// Generate and copy the shared key.
|
||||
// Generate the shared key with peer public key.
|
||||
// @param ppkey peer public key.
|
||||
// @param ppkey_size the size of ppkey.
|
||||
// @param skey the computed shared key.
|
||||
// @param skey_size the max shared key size, output the actual shared key 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);
|
||||
private:
|
||||
virtual srs_error_t do_initialize();
|
||||
};
|
||||
/**
|
||||
* the schema type.
|
||||
*/
|
||||
// The schema type.
|
||||
enum srs_schema_type
|
||||
{
|
||||
srs_schema_invalid = 2,
|
||||
|
||||
/**
|
||||
* key-digest sequence
|
||||
*/
|
||||
// The key-digest sequence
|
||||
srs_schema0 = 0,
|
||||
|
||||
/**
|
||||
* digest-key sequence
|
||||
* @remark, FMS requires the schema1(digest-key), or connect failed.
|
||||
*/
|
||||
// The digest-key sequence
|
||||
// @remark, FMS requires the schema1(digest-key), or connect failed.
|
||||
//
|
||||
srs_schema1 = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* 764bytes key structure
|
||||
* random-data: (offset)bytes
|
||||
* key-data: 128bytes
|
||||
* random-data: (764-offset-128-4)bytes
|
||||
* offset: 4bytes
|
||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
*/
|
||||
// The 764bytes key structure
|
||||
// random-data: (offset)bytes
|
||||
// key-data: 128bytes
|
||||
// random-data: (764-offset-128-4)bytes
|
||||
// offset: 4bytes
|
||||
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
class key_block
|
||||
{
|
||||
public:
|
||||
|
@ -132,24 +116,22 @@ namespace _srs_internal
|
|||
key_block();
|
||||
virtual ~key_block();
|
||||
public:
|
||||
// parse key block from c1s1.
|
||||
// Parse key block from c1s1.
|
||||
// if created, user must free it by srs_key_block_free
|
||||
// @stream contains c1s1_key_bytes the key start bytes
|
||||
srs_error_t parse(SrsBuffer* stream);
|
||||
private:
|
||||
// calc the offset of key,
|
||||
// the key->offset cannot be used as the offset of key.
|
||||
// Calculate the offset of key,
|
||||
// The key->offset cannot be used as the offset of key.
|
||||
int calc_valid_offset();
|
||||
};
|
||||
|
||||
/**
|
||||
* 764bytes digest structure
|
||||
* offset: 4bytes
|
||||
* random-data: (offset)bytes
|
||||
* digest-data: 32bytes
|
||||
* random-data: (764-4-offset-32)bytes
|
||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
*/
|
||||
// The 764bytes digest structure
|
||||
// offset: 4bytes
|
||||
// random-data: (offset)bytes
|
||||
// digest-data: 32bytes
|
||||
// random-data: (764-4-offset-32)bytes
|
||||
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
class digest_block
|
||||
{
|
||||
public:
|
||||
|
@ -170,23 +152,21 @@ namespace _srs_internal
|
|||
digest_block();
|
||||
virtual ~digest_block();
|
||||
public:
|
||||
// parse digest block from c1s1.
|
||||
// Parse digest block from c1s1.
|
||||
// if created, user must free it by srs_digest_block_free
|
||||
// @stream contains c1s1_digest_bytes the digest start bytes
|
||||
srs_error_t parse(SrsBuffer* stream);
|
||||
private:
|
||||
// calc the offset of digest,
|
||||
// the key->offset cannot be used as the offset of digest.
|
||||
// Calculate the offset of digest,
|
||||
// The key->offset cannot be used as the offset of digest.
|
||||
int calc_valid_offset();
|
||||
};
|
||||
|
||||
class c1s1;
|
||||
|
||||
/**
|
||||
* the c1s1 strategy, use schema0 or schema1.
|
||||
* the template method class to defines common behaviors,
|
||||
* while the concrete class to implements in schema0 or schema1.
|
||||
*/
|
||||
// The c1s1 strategy, use schema0 or schema1.
|
||||
// The template method class to defines common behaviors,
|
||||
// while the concrete class to implements in schema0 or schema1.
|
||||
class c1s1_strategy
|
||||
{
|
||||
protected:
|
||||
|
@ -196,114 +176,82 @@ namespace _srs_internal
|
|||
c1s1_strategy();
|
||||
virtual ~c1s1_strategy();
|
||||
public:
|
||||
/**
|
||||
* get the scema.
|
||||
*/
|
||||
// Get the scema.
|
||||
virtual srs_schema_type schema() = 0;
|
||||
/**
|
||||
* get the digest.
|
||||
*/
|
||||
// Get the digest.
|
||||
virtual char* get_digest();
|
||||
/**
|
||||
* get the key.
|
||||
*/
|
||||
// Get the key.
|
||||
virtual char* get_key();
|
||||
/**
|
||||
* copy to bytes.
|
||||
* @param size must be 1536.
|
||||
*/
|
||||
// Copy to bytes.
|
||||
// @param size must be 1536.
|
||||
virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size);
|
||||
/**
|
||||
* server: parse the c1s1, discovery the key and digest by schema.
|
||||
* use the c1_validate_digest() to valid the digest of c1.
|
||||
*/
|
||||
// For server: parse the c1s1, discovery the key and digest by schema.
|
||||
// use the c1_validate_digest() to valid the digest of c1.
|
||||
virtual srs_error_t parse(char* _c1s1, int size) = 0;
|
||||
public:
|
||||
/**
|
||||
* client: create and sign c1 by schema.
|
||||
* sign the c1, generate the digest.
|
||||
* calc_c1_digest(c1, schema) {
|
||||
* get c1s1-joined from c1 by specified schema
|
||||
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||
* return digest-data;
|
||||
* }
|
||||
* random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||
* time = time() // c1[0-3]
|
||||
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||
* schema = choose schema0 or schema1
|
||||
* digest-data = calc_c1_digest(c1, schema)
|
||||
* copy digest-data to c1
|
||||
*/
|
||||
// For client: create and sign c1 by schema.
|
||||
// sign the c1, generate the digest.
|
||||
// calc_c1_digest(c1, schema) {
|
||||
// get c1s1-joined from c1 by specified schema
|
||||
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||
// return digest-data;
|
||||
// }
|
||||
// random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||
// time = time() // c1[0-3]
|
||||
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||
// schema = choose schema0 or schema1
|
||||
// digest-data = calc_c1_digest(c1, schema)
|
||||
// copy digest-data to c1
|
||||
virtual srs_error_t c1_create(c1s1* owner);
|
||||
/**
|
||||
* server: validate the parsed c1 schema
|
||||
*/
|
||||
// For server: validate the parsed c1 schema
|
||||
virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid);
|
||||
/**
|
||||
* server: create and sign the s1 from c1.
|
||||
* // decode c1 try schema0 then schema1
|
||||
* c1-digest-data = get-c1-digest-data(schema0)
|
||||
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||
* c1-key-data = get-c1-key-data(schema0)
|
||||
* schema = schema0
|
||||
* } else {
|
||||
* c1-digest-data = get-c1-digest-data(schema1)
|
||||
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||
* switch to simple handshake.
|
||||
* return
|
||||
* }
|
||||
* c1-key-data = get-c1-key-data(schema1)
|
||||
* schema = schema1
|
||||
* }
|
||||
*
|
||||
* // generate s1
|
||||
* random fill 1536bytes s1
|
||||
* time = time() // c1[0-3]
|
||||
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||
* get c1s1-joined by specified schema
|
||||
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||
* copy s1-digest-data and s1-key-data to s1.
|
||||
* @param c1, to get the peer_pub_key of client.
|
||||
*/
|
||||
// For server: create and sign the s1 from c1.
|
||||
// // decode c1 try schema0 then schema1
|
||||
// c1-digest-data = get-c1-digest-data(schema0)
|
||||
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||
// c1-key-data = get-c1-key-data(schema0)
|
||||
// schema = schema0
|
||||
// } else {
|
||||
// c1-digest-data = get-c1-digest-data(schema1)
|
||||
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||
// switch to simple handshake.
|
||||
// return
|
||||
// }
|
||||
// c1-key-data = get-c1-key-data(schema1)
|
||||
// schema = schema1
|
||||
// }
|
||||
//
|
||||
// // Generate s1
|
||||
// random fill 1536bytes s1
|
||||
// time = time() // c1[0-3]
|
||||
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||
// get c1s1-joined by specified schema
|
||||
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||
// copy s1-digest-data and s1-key-data to s1.
|
||||
// @param c1, to get the peer_pub_key of client.
|
||||
virtual srs_error_t s1_create(c1s1* owner, c1s1* c1);
|
||||
/**
|
||||
* server: validate the parsed s1 schema
|
||||
*/
|
||||
// For server: validate the parsed s1 schema
|
||||
virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid);
|
||||
public:
|
||||
/**
|
||||
* calc the digest for c1
|
||||
*/
|
||||
// Calculate the digest for c1
|
||||
virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest);
|
||||
/**
|
||||
* calc the digest for s1
|
||||
*/
|
||||
// Calculate the digest for s1
|
||||
virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest);
|
||||
/**
|
||||
* copy whole c1s1 to bytes.
|
||||
* @param size must always be 1536 with digest, and 1504 without digest.
|
||||
*/
|
||||
// Copy whole c1s1 to bytes.
|
||||
// @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;
|
||||
/**
|
||||
* copy time and version to stream.
|
||||
*/
|
||||
// Copy time and version to stream.
|
||||
virtual void copy_time_version(SrsBuffer* stream, c1s1* owner);
|
||||
/**
|
||||
* copy key to stream.
|
||||
*/
|
||||
// Copy key to stream.
|
||||
virtual void copy_key(SrsBuffer* stream);
|
||||
/**
|
||||
* copy digest to stream.
|
||||
*/
|
||||
// Copy digest to stream.
|
||||
virtual void copy_digest(SrsBuffer* stream, bool with_digest);
|
||||
};
|
||||
|
||||
/**
|
||||
* c1s1 schema0
|
||||
* key: 764bytes
|
||||
* digest: 764bytes
|
||||
*/
|
||||
// The c1s1 schema0
|
||||
// key: 764bytes
|
||||
// digest: 764bytes
|
||||
class c1s1_strategy_schema0 : public c1s1_strategy
|
||||
{
|
||||
public:
|
||||
|
@ -316,11 +264,9 @@ namespace _srs_internal
|
|||
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
||||
};
|
||||
|
||||
/**
|
||||
* c1s1 schema1
|
||||
* digest: 764bytes
|
||||
* key: 764bytes
|
||||
*/
|
||||
// The c1s1 schema1
|
||||
// digest: 764bytes
|
||||
// key: 764bytes
|
||||
class c1s1_strategy_schema1 : public c1s1_strategy
|
||||
{
|
||||
public:
|
||||
|
@ -333,19 +279,17 @@ namespace _srs_internal
|
|||
virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest);
|
||||
};
|
||||
|
||||
/**
|
||||
* c1s1 schema0
|
||||
* time: 4bytes
|
||||
* version: 4bytes
|
||||
* key: 764bytes
|
||||
* digest: 764bytes
|
||||
* c1s1 schema1
|
||||
* time: 4bytes
|
||||
* version: 4bytes
|
||||
* digest: 764bytes
|
||||
* key: 764bytes
|
||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
*/
|
||||
// The c1s1 schema0
|
||||
// time: 4bytes
|
||||
// version: 4bytes
|
||||
// key: 764bytes
|
||||
// digest: 764bytes
|
||||
// The c1s1 schema1
|
||||
// time: 4bytes
|
||||
// version: 4bytes
|
||||
// digest: 764bytes
|
||||
// key: 764bytes
|
||||
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
class c1s1
|
||||
{
|
||||
public:
|
||||
|
@ -359,92 +303,72 @@ namespace _srs_internal
|
|||
c1s1();
|
||||
virtual ~c1s1();
|
||||
public:
|
||||
/**
|
||||
* get the scema.
|
||||
*/
|
||||
// Get the scema.
|
||||
virtual srs_schema_type schema();
|
||||
/**
|
||||
* get the digest key.
|
||||
*/
|
||||
// Get the digest key.
|
||||
virtual char* get_digest();
|
||||
/**
|
||||
* get the key.
|
||||
*/
|
||||
// Get the key.
|
||||
virtual char* get_key();
|
||||
public:
|
||||
/**
|
||||
* copy to bytes.
|
||||
* @param size, must always be 1536.
|
||||
*/
|
||||
// Copy to bytes.
|
||||
// @param size, must always be 1536.
|
||||
virtual srs_error_t dump(char* _c1s1, int size);
|
||||
/**
|
||||
* server: parse the c1s1, discovery the key and digest by schema.
|
||||
* @param size, must always be 1536.
|
||||
* use the c1_validate_digest() to valid the digest of c1.
|
||||
* use the s1_validate_digest() to valid the digest of s1.
|
||||
*/
|
||||
// For server: parse the c1s1, discovery the key and digest by schema.
|
||||
// @param size, must always be 1536.
|
||||
// use the c1_validate_digest() to valid the digest of c1.
|
||||
// use the s1_validate_digest() to valid the digest of s1.
|
||||
virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema);
|
||||
public:
|
||||
/**
|
||||
* client: create and sign c1 by schema.
|
||||
* sign the c1, generate the digest.
|
||||
* calc_c1_digest(c1, schema) {
|
||||
* get c1s1-joined from c1 by specified schema
|
||||
* digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||
* return digest-data;
|
||||
* }
|
||||
* random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||
* time = time() // c1[0-3]
|
||||
* version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||
* schema = choose schema0 or schema1
|
||||
* digest-data = calc_c1_digest(c1, schema)
|
||||
* copy digest-data to c1
|
||||
*/
|
||||
// For client: create and sign c1 by schema.
|
||||
// sign the c1, generate the digest.
|
||||
// calc_c1_digest(c1, schema) {
|
||||
// get c1s1-joined from c1 by specified schema
|
||||
// digest-data = HMACsha256(c1s1-joined, FPKey, 30)
|
||||
// return digest-data;
|
||||
// }
|
||||
// random fill 1536bytes c1 // also fill the c1-128bytes-key
|
||||
// time = time() // c1[0-3]
|
||||
// version = [0x80, 0x00, 0x07, 0x02] // c1[4-7]
|
||||
// schema = choose schema0 or schema1
|
||||
// digest-data = calc_c1_digest(c1, schema)
|
||||
// copy digest-data to c1
|
||||
virtual srs_error_t c1_create(srs_schema_type _schema);
|
||||
/**
|
||||
* server: validate the parsed c1 schema
|
||||
*/
|
||||
// For server: validate the parsed c1 schema
|
||||
virtual srs_error_t c1_validate_digest(bool& is_valid);
|
||||
public:
|
||||
/**
|
||||
* server: create and sign the s1 from c1.
|
||||
* // decode c1 try schema0 then schema1
|
||||
* c1-digest-data = get-c1-digest-data(schema0)
|
||||
* if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||
* c1-key-data = get-c1-key-data(schema0)
|
||||
* schema = schema0
|
||||
* } else {
|
||||
* c1-digest-data = get-c1-digest-data(schema1)
|
||||
* if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||
* switch to simple handshake.
|
||||
* return
|
||||
* }
|
||||
* c1-key-data = get-c1-key-data(schema1)
|
||||
* schema = schema1
|
||||
* }
|
||||
*
|
||||
* // generate s1
|
||||
* random fill 1536bytes s1
|
||||
* time = time() // c1[0-3]
|
||||
* version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||
* s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||
* get c1s1-joined by specified schema
|
||||
* s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||
* copy s1-digest-data and s1-key-data to s1.
|
||||
*/
|
||||
// For server: create and sign the s1 from c1.
|
||||
// // decode c1 try schema0 then schema1
|
||||
// c1-digest-data = get-c1-digest-data(schema0)
|
||||
// if c1-digest-data equals to calc_c1_digest(c1, schema0) {
|
||||
// c1-key-data = get-c1-key-data(schema0)
|
||||
// schema = schema0
|
||||
// } else {
|
||||
// c1-digest-data = get-c1-digest-data(schema1)
|
||||
// if c1-digest-data not equals to calc_c1_digest(c1, schema1) {
|
||||
// switch to simple handshake.
|
||||
// return
|
||||
// }
|
||||
// c1-key-data = get-c1-key-data(schema1)
|
||||
// schema = schema1
|
||||
// }
|
||||
//
|
||||
// // Generate s1
|
||||
// random fill 1536bytes s1
|
||||
// time = time() // c1[0-3]
|
||||
// version = [0x04, 0x05, 0x00, 0x01] // s1[4-7]
|
||||
// s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data)
|
||||
// get c1s1-joined by specified schema
|
||||
// s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36)
|
||||
// copy s1-digest-data and s1-key-data to s1.
|
||||
virtual srs_error_t s1_create(c1s1* c1);
|
||||
/**
|
||||
* server: validate the parsed s1 schema
|
||||
*/
|
||||
// For server: validate the parsed s1 schema
|
||||
virtual srs_error_t s1_validate_digest(bool& is_valid);
|
||||
};
|
||||
|
||||
/**
|
||||
* the c2s2 complex handshake structure.
|
||||
* random-data: 1504bytes
|
||||
* digest-data: 32bytes
|
||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
*/
|
||||
// The c2s2 complex handshake structure.
|
||||
// random-data: 1504bytes
|
||||
// digest-data: 32bytes
|
||||
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
class c2s2
|
||||
{
|
||||
public:
|
||||
|
@ -454,85 +378,65 @@ namespace _srs_internal
|
|||
c2s2();
|
||||
virtual ~c2s2();
|
||||
public:
|
||||
/**
|
||||
* copy to bytes.
|
||||
* @param size, must always be 1536.
|
||||
*/
|
||||
// Copy to bytes.
|
||||
// @param size, must always be 1536.
|
||||
virtual srs_error_t dump(char* _c2s2, int size);
|
||||
/**
|
||||
* parse the c2s2
|
||||
* @param size, must always be 1536.
|
||||
*/
|
||||
// Parse the c2s2
|
||||
// @param size, must always be 1536.
|
||||
virtual srs_error_t parse(char* _c2s2, int size);
|
||||
public:
|
||||
/**
|
||||
* create c2.
|
||||
* random fill c2s2 1536 bytes
|
||||
*
|
||||
* // client generate C2, or server valid C2
|
||||
* temp-key = HMACsha256(s1-digest, FPKey, 62)
|
||||
* c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
|
||||
*/
|
||||
// Create c2.
|
||||
// random fill c2s2 1536 bytes
|
||||
//
|
||||
// // client generate C2, or server valid C2
|
||||
// temp-key = HMACsha256(s1-digest, FPKey, 62)
|
||||
// c2-digest-data = HMACsha256(c2-random-data, temp-key, 32)
|
||||
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);
|
||||
public:
|
||||
/**
|
||||
* create s2.
|
||||
* random fill c2s2 1536 bytes
|
||||
*
|
||||
* // server generate S2, or client valid S2
|
||||
* temp-key = HMACsha256(c1-digest, FMSKey, 68)
|
||||
* s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
|
||||
*/
|
||||
// Create s2.
|
||||
// random fill c2s2 1536 bytes
|
||||
//
|
||||
// For server generate S2, or client valid S2
|
||||
// temp-key = HMACsha256(c1-digest, FMSKey, 68)
|
||||
// s2-digest-data = HMACsha256(s2-random-data, temp-key, 32)
|
||||
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);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* simple handshake.
|
||||
* user can try complex handshake first,
|
||||
* rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
|
||||
*/
|
||||
// Simple handshake.
|
||||
// user can try complex handshake first,
|
||||
// rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS
|
||||
class SrsSimpleHandshake
|
||||
{
|
||||
public:
|
||||
SrsSimpleHandshake();
|
||||
virtual ~SrsSimpleHandshake();
|
||||
public:
|
||||
/**
|
||||
* simple handshake.
|
||||
*/
|
||||
// Simple handshake.
|
||||
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||
};
|
||||
|
||||
/**
|
||||
* rtmp complex handshake,
|
||||
* @see also crtmp(crtmpserver) or librtmp,
|
||||
* @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
*/
|
||||
// Complex handshake,
|
||||
// @see also crtmp(crtmpserver) or librtmp,
|
||||
// @see also: http://blog.csdn.net/win_lin/article/details/13006803
|
||||
class SrsComplexHandshake
|
||||
{
|
||||
public:
|
||||
SrsComplexHandshake();
|
||||
virtual ~SrsComplexHandshake();
|
||||
public:
|
||||
/**
|
||||
* complex hanshake.
|
||||
* @return user must:
|
||||
* continue connect app if success,
|
||||
* try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
|
||||
* otherwise, disconnect
|
||||
*/
|
||||
// Complex hanshake.
|
||||
// @return user must:
|
||||
// continue connect app if success,
|
||||
// try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS,
|
||||
// otherwise, disconnect
|
||||
virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||
virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io);
|
||||
};
|
||||
|
|
|
@ -28,43 +28,31 @@
|
|||
|
||||
class SrsSharedPtrMessage;
|
||||
|
||||
/**
|
||||
* the class to auto free the shared ptr message array.
|
||||
* when need to get some messages, for instance, from Consumer queue,
|
||||
* create a message array, whose msgs can used to accept the msgs,
|
||||
* then send each message and set to NULL.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
// The class to auto free the shared ptr message array.
|
||||
// When need to get some messages, for instance, from Consumer queue,
|
||||
// create a message array, whose msgs can used to accept the msgs,
|
||||
// then send each message and set to NULL.
|
||||
//
|
||||
// @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
|
||||
class SrsMessageArray
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* when user already send all msgs, please set to NULL,
|
||||
* for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
|
||||
* where send(msg) will always send and free it.
|
||||
*/
|
||||
// When user already send all msgs, please set to NULL,
|
||||
// for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg),
|
||||
// where send(msg) will always send and free it.
|
||||
SrsSharedPtrMessage** msgs;
|
||||
int max;
|
||||
public:
|
||||
/**
|
||||
* create msg array, initialize array to NULL ptrs.
|
||||
*/
|
||||
// Create msg array, initialize array to NULL ptrs.
|
||||
SrsMessageArray(int max_msgs);
|
||||
/**
|
||||
* free the msgs not sent out(not NULL).
|
||||
*/
|
||||
// Free the msgs not sent out(not NULL).
|
||||
virtual ~SrsMessageArray();
|
||||
public:
|
||||
/**
|
||||
* free specified count of messages.
|
||||
*/
|
||||
// Free specified count of messages.
|
||||
virtual void free(int count);
|
||||
private:
|
||||
/**
|
||||
* zero initialize the message array.
|
||||
*/
|
||||
// Zero initialize the message array.
|
||||
virtual void zero(int count);
|
||||
};
|
||||
|
||||
|
|
|
@ -2385,15 +2385,9 @@ 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_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
|
||||
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_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) {
|
||||
data->set("srs_server_ip", SrsAmf0Any::str(server_ip));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ class SrsSimpleStream;
|
|||
class SrsAudioFrame;
|
||||
class ISrsProtocolReadWriter;
|
||||
|
||||
// rtsp specification
|
||||
// From rtsp specification
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
#define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D
|
||||
// LF = <US-ASCII LF, linefeed (10)>
|
||||
|
@ -78,38 +78,28 @@ class ISrsProtocolReadWriter;
|
|||
// RTSP-Version
|
||||
#define SRS_RTSP_VERSION "RTSP/1.0"
|
||||
|
||||
/**
|
||||
* the rtsp sdp parse state.
|
||||
*/
|
||||
// The rtsp sdp parse state.
|
||||
enum SrsRtspSdpState
|
||||
{
|
||||
/**
|
||||
* other sdp properties.
|
||||
*/
|
||||
// Other sdp properties.
|
||||
SrsRtspSdpStateOthers,
|
||||
/**
|
||||
* parse sdp audio state.
|
||||
*/
|
||||
// Parse sdp audio state.
|
||||
SrsRtspSdpStateAudio,
|
||||
/**
|
||||
* parse sdp video state.
|
||||
*/
|
||||
// Parse sdp video state.
|
||||
SrsRtspSdpStateVideo,
|
||||
};
|
||||
|
||||
/**
|
||||
* 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
|
||||
* The method token indicates the method to be performed on the resource
|
||||
* identified by the Request-URI. The method is case-sensitive. New
|
||||
* methods may be defined in the future. Method names may not start with
|
||||
* a $ character (decimal 24) and must be a token. Methods are
|
||||
* summarized in Table 2.
|
||||
* Notes on Table 2: PAUSE is recommended, but not required in that a
|
||||
* fully functional server can be built that does not support this
|
||||
* method, for example, for live feeds. If a server does not support a
|
||||
* particular method, it MUST return "501 Not Implemented" and a client
|
||||
* SHOULD not try this method again for this server.
|
||||
*/
|
||||
// 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57
|
||||
// The method token indicates the method to be performed on the resource
|
||||
// identified by the Request-URI. The method is case-sensitive. New
|
||||
// methods may be defined in the future. Method names may not start with
|
||||
// a $ character (decimal 24) and must be a token. Methods are
|
||||
// summarized in Table 2.
|
||||
// Notes on Table 2: PAUSE is recommended, but not required in that a
|
||||
// fully functional server can be built that does not support this
|
||||
// method, for example, for live feeds. If a server does not support a
|
||||
// particular method, it MUST return "501 Not Implemented" and a client
|
||||
// SHOULD not try this method again for this server.
|
||||
enum SrsRtspMethod
|
||||
{
|
||||
SrsRtspMethodDescribe = 0x0001,
|
||||
|
@ -125,237 +115,187 @@ enum SrsRtspMethod
|
|||
SrsRtspMethodTeardown = 0x0400,
|
||||
};
|
||||
|
||||
/**
|
||||
* the state of rtsp token.
|
||||
*/
|
||||
// The state of rtsp token.
|
||||
enum SrsRtspTokenState
|
||||
{
|
||||
/**
|
||||
* parse token failed, default state.
|
||||
*/
|
||||
// Parse token failed, default state.
|
||||
SrsRtspTokenStateError = 100,
|
||||
/**
|
||||
* when SP follow the token.
|
||||
*/
|
||||
// When SP follow the token.
|
||||
SrsRtspTokenStateNormal = 101,
|
||||
/**
|
||||
* when CRLF follow the token.
|
||||
*/
|
||||
// When CRLF follow the token.
|
||||
SrsRtspTokenStateEOF = 102,
|
||||
};
|
||||
|
||||
/**
|
||||
* the rtp packet.
|
||||
* 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
|
||||
*/
|
||||
// The rtp packet.
|
||||
// 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12
|
||||
class SrsRtpPacket
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* version (V): 2 bits
|
||||
* 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
|
||||
* initially implemented in the \vat" audio tool.)
|
||||
*/
|
||||
// The version (V): 2 bits
|
||||
// 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
|
||||
// initially implemented in the \vat" audio tool.)
|
||||
int8_t version; //2bits
|
||||
/**
|
||||
* padding (P): 1 bit
|
||||
* 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
|
||||
* 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
|
||||
* lower-layer protocol data unit.
|
||||
*/
|
||||
// The padding (P): 1 bit
|
||||
// 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
|
||||
// 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
|
||||
// lower-layer protocol data unit.
|
||||
int8_t padding; //1bit
|
||||
/**
|
||||
* extension (X): 1 bit
|
||||
* 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.
|
||||
*/
|
||||
// The extension (X): 1 bit
|
||||
// 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.
|
||||
int8_t extension; //1bit
|
||||
/**
|
||||
* CSRC count (CC): 4 bits
|
||||
* The CSRC count contains the number of CSRC identifiers that follow the fixed header.
|
||||
*/
|
||||
// The CSRC count (CC): 4 bits
|
||||
// The CSRC count contains the number of CSRC identifiers that follow the fixed header.
|
||||
int8_t csrc_count; //4bits
|
||||
/**
|
||||
* marker (M): 1 bit
|
||||
* 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
|
||||
* 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).
|
||||
*/
|
||||
// The marker (M): 1 bit
|
||||
// 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
|
||||
// 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).
|
||||
int8_t marker; //1bit
|
||||
/**
|
||||
* payload type (PT): 7 bits
|
||||
* 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
|
||||
* 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
|
||||
* 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).
|
||||
* A receiver must ignore packets with payload types that it does not understand.
|
||||
*/
|
||||
// The payload type (PT): 7 bits
|
||||
// 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
|
||||
// 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
|
||||
// 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).
|
||||
// A receiver must ignore packets with payload types that it does not understand.
|
||||
int8_t payload_type; //7bits
|
||||
/**
|
||||
* sequence number: 16 bits
|
||||
* 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
|
||||
* 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
|
||||
* in Section 9.1, because the packets may flow through a translator that does. Techniques for
|
||||
* choosing unpredictable numbers are discussed in [17].
|
||||
*/
|
||||
// The sequence number: 16 bits
|
||||
// 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
|
||||
// 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
|
||||
// in Section 9.1, because the packets may flow through a translator that does. Techniques for
|
||||
// choosing unpredictable numbers are discussed in [17].
|
||||
uint16_t sequence_number; //16bits
|
||||
/**
|
||||
* timestamp: 32 bits
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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,
|
||||
* 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
|
||||
* 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
|
||||
* each such block, regardless of whether the block is transmitted in a packet or dropped as
|
||||
* silent.
|
||||
*
|
||||
* 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,
|
||||
* 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
|
||||
* of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
|
||||
* will still be monotonic.)
|
||||
*
|
||||
* RTP timestamps from different media streams may advance at different rates and usually
|
||||
* have independent, random offsets. Therefore, although these timestamps are sucient to
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* described in Section 6.4.
|
||||
*
|
||||
* 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
|
||||
* of encoding delays or other processing. The purpose is to allow synchronized presentation of
|
||||
* all media sampled at the same time.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* the receiver.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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 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
|
||||
* timestamp pairs in RTCP SR packets.
|
||||
*/
|
||||
// The timestamp: 32 bits
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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,
|
||||
// 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
|
||||
// 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
|
||||
// each such block, regardless of whether the block is transmitted in a packet or dropped as
|
||||
// silent.
|
||||
//
|
||||
// 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,
|
||||
// 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
|
||||
// of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted
|
||||
// will still be monotonic.)
|
||||
//
|
||||
// RTP timestamps from different media streams may advance at different rates and usually
|
||||
// have independent, random offsets. Therefore, although these timestamps are sucient to
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// described in Section 6.4.
|
||||
//
|
||||
// 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
|
||||
// of encoding delays or other processing. The purpose is to allow synchronized presentation of
|
||||
// all media sampled at the same time.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// The receiver.
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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 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
|
||||
// timestamp pairs in RTCP SR packets.
|
||||
uint32_t timestamp; //32bits
|
||||
/**
|
||||
* SSRC: 32 bits
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* avoid being interpreted as a looped source (see Section 8.2).
|
||||
*/
|
||||
// The SSRC: 32 bits
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
// avoid being interpreted as a looped source (see Section 8.2).
|
||||
uint32_t ssrc; //32bits
|
||||
|
||||
// the payload.
|
||||
// The payload.
|
||||
SrsSimpleStream* payload;
|
||||
// whether transport in chunked payload.
|
||||
// Whether transport in chunked payload.
|
||||
bool chunked;
|
||||
// whether message is completed.
|
||||
// Whether message is completed.
|
||||
// normal message always completed.
|
||||
// while chunked completed when the last chunk arriaved.
|
||||
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;
|
||||
public:
|
||||
SrsRtpPacket();
|
||||
virtual ~SrsRtpPacket();
|
||||
public:
|
||||
/**
|
||||
* copy the header from src.
|
||||
*/
|
||||
// copy the header from 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);
|
||||
/**
|
||||
* decode rtp packet from stream.
|
||||
*/
|
||||
// decode rtp packet from stream.
|
||||
virtual srs_error_t decode(SrsBuffer* stream);
|
||||
private:
|
||||
virtual srs_error_t decode_97(SrsBuffer* stream);
|
||||
virtual srs_error_t decode_96(SrsBuffer* stream);
|
||||
};
|
||||
|
||||
/**
|
||||
* the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
|
||||
* Appendix C: Use of SDP for RTSP Session Descriptions
|
||||
* The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
|
||||
* describe streams or presentations in RTSP.
|
||||
*/
|
||||
// The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159
|
||||
// Appendix C: Use of SDP for RTSP Session Descriptions
|
||||
// The Session Description Protocol (SDP, RFC 2327 [6]) may be used to
|
||||
// describe streams or presentations in RTSP.
|
||||
class SrsRtspSdp
|
||||
{
|
||||
private:
|
||||
SrsRtspSdpState state;
|
||||
public:
|
||||
/**
|
||||
* the version of sdp.
|
||||
*/
|
||||
// The version of sdp.
|
||||
std::string version;
|
||||
/**
|
||||
* the owner/creator of sdp.
|
||||
*/
|
||||
// The owner/creator of sdp.
|
||||
std::string owner_username;
|
||||
std::string owner_session_id;
|
||||
std::string owner_session_version;
|
||||
std::string owner_network_type;
|
||||
std::string owner_address_type;
|
||||
std::string owner_address;
|
||||
/**
|
||||
* the session name of sdp.
|
||||
*/
|
||||
// The session name of sdp.
|
||||
std::string session_name;
|
||||
/**
|
||||
* the connection info of sdp.
|
||||
*/
|
||||
// The connection info of sdp.
|
||||
std::string connection_network_type;
|
||||
std::string connection_address_type;
|
||||
std::string connection_address;
|
||||
/**
|
||||
* the tool attribute of sdp.
|
||||
*/
|
||||
// The tool attribute of sdp.
|
||||
std::string tool;
|
||||
/**
|
||||
* the video attribute of sdp.
|
||||
*/
|
||||
// The video attribute of sdp.
|
||||
std::string video_port;
|
||||
std::string video_protocol;
|
||||
std::string video_transport_format;
|
||||
|
@ -363,13 +303,11 @@ public:
|
|||
std::string video_codec;
|
||||
std::string video_sample_rate;
|
||||
std::string video_stream_id;
|
||||
// fmtp
|
||||
// The fmtp
|
||||
std::string video_packetization_mode;
|
||||
std::string video_sps; // sequence header: sps.
|
||||
std::string video_pps; // sequence header: pps.
|
||||
/**
|
||||
* the audio attribute of sdp.
|
||||
*/
|
||||
// The audio attribute of sdp.
|
||||
std::string audio_port;
|
||||
std::string audio_protocol;
|
||||
std::string audio_transport_format;
|
||||
|
@ -378,7 +316,7 @@ public:
|
|||
std::string audio_sample_rate;
|
||||
std::string audio_channel;
|
||||
std::string audio_stream_id;
|
||||
// fmtp
|
||||
// The fmtp
|
||||
std::string audio_profile_level_id;
|
||||
std::string audio_mode;
|
||||
std::string audio_size_length;
|
||||
|
@ -389,34 +327,24 @@ public:
|
|||
SrsRtspSdp();
|
||||
virtual ~SrsRtspSdp();
|
||||
public:
|
||||
/**
|
||||
* parse a line of token for sdp.
|
||||
*/
|
||||
// Parse a line of token for sdp.
|
||||
virtual srs_error_t parse(std::string token);
|
||||
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);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* decode the string by base64.
|
||||
*/
|
||||
// decode the string by base64.
|
||||
virtual std::string base64_decode(std::string value);
|
||||
};
|
||||
|
||||
/**
|
||||
* the rtsp transport.
|
||||
* 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
|
||||
* This request header indicates which transport protocol is to be used
|
||||
* and configures its parameters such as destination address,
|
||||
* compression, multicast time-to-live and destination port for a single
|
||||
* stream. It sets those values not already determined by a presentation
|
||||
* description.
|
||||
*/
|
||||
// The rtsp transport.
|
||||
// 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115
|
||||
// This request header indicates which transport protocol is to be used
|
||||
// and configures its parameters such as destination address,
|
||||
// compression, multicast time-to-live and destination port for a single
|
||||
// stream. It sets those values not already determined by a presentation
|
||||
// description.
|
||||
class SrsRtspTransport
|
||||
{
|
||||
public:
|
||||
|
@ -431,7 +359,7 @@ public:
|
|||
// Clients that are capable of handling both unicast and
|
||||
// multicast transmission MUST indicate such capability by
|
||||
// including two full transport-specs with separate parameters
|
||||
// for each.
|
||||
// For each.
|
||||
std::string cast_type;
|
||||
// The mode parameter indicates the methods to be supported for
|
||||
// this session. Valid values are PLAY and RECORD. If not
|
||||
|
@ -449,79 +377,59 @@ public:
|
|||
SrsRtspTransport();
|
||||
virtual ~SrsRtspTransport();
|
||||
public:
|
||||
/**
|
||||
* parse a line of token for transport.
|
||||
*/
|
||||
// Parse a line of token for transport.
|
||||
virtual srs_error_t parse(std::string attr);
|
||||
};
|
||||
|
||||
/**
|
||||
* the rtsp request message.
|
||||
* 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
|
||||
* 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
|
||||
* the resource, the identifier of the resource, and the protocol
|
||||
* version in use.
|
||||
* Request = Request-Line ; Section 6.1
|
||||
* *( general-header ; Section 5
|
||||
* | request-header ; Section 6.2
|
||||
* | entity-header ) ; Section 8.1
|
||||
* CRLF
|
||||
* [ message-body ] ; Section 4.3
|
||||
*/
|
||||
// The rtsp request message.
|
||||
// 6 Request, @see rfc2326-1998-rtsp.pdf, page 39
|
||||
// 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
|
||||
// The resource, the identifier of the resource, and the protocol
|
||||
// version in use.
|
||||
// Request = Request-Line ; Section 6.1
|
||||
// // ( general-header ; Section 5
|
||||
// | request-header ; Section 6.2
|
||||
// | entity-header ) ; Section 8.1
|
||||
// CRLF
|
||||
// [ message-body ] ; Section 4.3
|
||||
class SrsRtspRequest
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 6.1 Request Line
|
||||
* Request-Line = Method SP Request-URI SP RTSP-Version CRLF
|
||||
*/
|
||||
// 6.1 Request Line
|
||||
// Request-Line = Method SP Request-URI SP RTSP-Version CRLF
|
||||
std::string method;
|
||||
std::string uri;
|
||||
std::string version;
|
||||
/**
|
||||
* 12.17 CSeq
|
||||
* The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||
* pair. This field MUST be present in all requests and
|
||||
* responses. For every RTSP request containing the given sequence
|
||||
* number, there will be a corresponding response having the same
|
||||
* number. Any retransmitted request must contain the same sequence
|
||||
* number as the original (i.e. the sequence number is not incremented
|
||||
* for retransmissions of the same request).
|
||||
*/
|
||||
// 12.17 CSeq
|
||||
// The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||
// pair. This field MUST be present in all requests and
|
||||
// responses. For every RTSP request containing the given sequence
|
||||
// number, there will be a corresponding response having the same
|
||||
// number. Any retransmitted request must contain the same sequence
|
||||
// number as the original (i.e. the sequence number is not incremented
|
||||
// For retransmissions of the same request).
|
||||
long seq;
|
||||
/**
|
||||
* 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
* See [H14.18]. Note that the content types suitable for RTSP are
|
||||
* likely to be restricted in practice to presentation descriptions and
|
||||
* parameter-value types.
|
||||
*/
|
||||
// 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
// See [H14.18]. Note that the content types suitable for RTSP are
|
||||
// likely to be restricted in practice to presentation descriptions and
|
||||
// parameter-value types.
|
||||
std::string content_type;
|
||||
/**
|
||||
* 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
* This field contains the length of the content of the method (i.e.
|
||||
* after the double CRLF following the last header). Unlike HTTP, it
|
||||
* 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
|
||||
* assumed. It is interpreted according to [H14.14].
|
||||
*/
|
||||
// 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
// This field contains the length of the content of the method (i.e.
|
||||
// after the double CRLF following the last header). Unlike HTTP, it
|
||||
// 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
|
||||
// assumed. It is interpreted according to [H14.14].
|
||||
long content_length;
|
||||
/**
|
||||
* the session id.
|
||||
*/
|
||||
// The session id.
|
||||
std::string session;
|
||||
|
||||
/**
|
||||
* the sdp in announce, NULL for no sdp.
|
||||
*/
|
||||
// The sdp in announce, NULL for no sdp.
|
||||
SrsRtspSdp* sdp;
|
||||
/**
|
||||
* the transport in setup, NULL for no transport.
|
||||
*/
|
||||
// The transport in setup, NULL for no transport.
|
||||
SrsRtspTransport* transport;
|
||||
/**
|
||||
* for setup message, parse the stream id from uri.
|
||||
*/
|
||||
// For setup message, parse the stream id from uri.
|
||||
int stream_id;
|
||||
public:
|
||||
SrsRtspRequest();
|
||||
|
@ -533,79 +441,63 @@ public:
|
|||
virtual bool is_record();
|
||||
};
|
||||
|
||||
/**
|
||||
* the rtsp response message.
|
||||
* 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
|
||||
* [H6] applies except that HTTP-Version is replaced by RTSP-Version.
|
||||
* Also, RTSP defines additional status codes and does not define some
|
||||
* HTTP codes. The valid response codes and the methods they can be used
|
||||
* with are defined in Table 1.
|
||||
* After receiving and interpreting a request message, the recipient
|
||||
* responds with an RTSP response message.
|
||||
* Response = Status-Line ; Section 7.1
|
||||
* *( general-header ; Section 5
|
||||
* | response-header ; Section 7.1.2
|
||||
* | entity-header ) ; Section 8.1
|
||||
* CRLF
|
||||
* [ message-body ] ; Section 4.3
|
||||
*/
|
||||
// The rtsp response message.
|
||||
// 7 Response, @see rfc2326-1998-rtsp.pdf, page 43
|
||||
// [H6] applies except that HTTP-Version is replaced by RTSP-Version.
|
||||
// Also, RTSP defines additional status codes and does not define some
|
||||
// HTTP codes. The valid response codes and the methods they can be used
|
||||
// with are defined in Table 1.
|
||||
// After receiving and interpreting a request message, the recipient
|
||||
// responds with an RTSP response message.
|
||||
// Response = Status-Line ; Section 7.1
|
||||
// // ( general-header ; Section 5
|
||||
// | response-header ; Section 7.1.2
|
||||
// | entity-header ) ; Section 8.1
|
||||
// CRLF
|
||||
// [ message-body ] ; Section 4.3
|
||||
class SrsRtspResponse
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* 7.1 Status-Line
|
||||
* The first line of a Response message is the Status-Line, consisting
|
||||
* of the protocol version followed by a numeric status code, and the
|
||||
* textual phrase associated with the status code, with each element
|
||||
* separated by SP characters. No CR or LF is allowed except in the
|
||||
* final CRLF sequence.
|
||||
* Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
|
||||
*/
|
||||
// 7.1 Status-Line
|
||||
// The first line of a Response message is the Status-Line, consisting
|
||||
// of the protocol version followed by a numeric status code, and the
|
||||
// textual phrase associated with the status code, with each element
|
||||
// separated by SP characters. No CR or LF is allowed except in the
|
||||
// final CRLF sequence.
|
||||
// Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF
|
||||
// @see about the version of rtsp, see SRS_RTSP_VERSION
|
||||
// @see about the status of rtsp, see SRS_CONSTS_RTSP_OK
|
||||
int status;
|
||||
/**
|
||||
* 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
* The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||
* pair. This field MUST be present in all requests and
|
||||
* responses. For every RTSP request containing the given sequence
|
||||
* number, there will be a corresponding response having the same
|
||||
* number. Any retransmitted request must contain the same sequence
|
||||
* number as the original (i.e. the sequence number is not incremented
|
||||
* for retransmissions of the same request).
|
||||
*/
|
||||
// 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99
|
||||
// The CSeq field specifies the sequence number for an RTSP requestresponse
|
||||
// pair. This field MUST be present in all requests and
|
||||
// responses. For every RTSP request containing the given sequence
|
||||
// number, there will be a corresponding response having the same
|
||||
// number. Any retransmitted request must contain the same sequence
|
||||
// number as the original (i.e. the sequence number is not incremented
|
||||
// For retransmissions of the same request).
|
||||
long seq;
|
||||
/**
|
||||
* the session id.
|
||||
*/
|
||||
// The session id.
|
||||
std::string session;
|
||||
public:
|
||||
SrsRtspResponse(int cseq);
|
||||
virtual ~SrsRtspResponse();
|
||||
public:
|
||||
/**
|
||||
* encode message to string.
|
||||
*/
|
||||
// Encode message to string.
|
||||
virtual srs_error_t encode(std::stringstream& ss);
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
|
||||
* 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
|
||||
* try a nonstandard request. It does not influence server state.
|
||||
*/
|
||||
// 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59
|
||||
// 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
|
||||
// try a nonstandard request. It does not influence server state.
|
||||
class SrsRtspOptionsResponse : public SrsRtspResponse
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* join of SrsRtspMethod
|
||||
*/
|
||||
// Join of SrsRtspMethod
|
||||
SrsRtspMethod methods;
|
||||
public:
|
||||
SrsRtspOptionsResponse(int cseq);
|
||||
|
@ -614,28 +506,26 @@ protected:
|
|||
virtual srs_error_t encode_header(std::stringstream& ss);
|
||||
};
|
||||
|
||||
/**
|
||||
* 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
|
||||
* 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
|
||||
* stream that is already playing to change transport parameters, which
|
||||
* 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
|
||||
* intervening firewalls, a client must indicate the transport
|
||||
* parameters even if it has no influence over these parameters, for
|
||||
* example, where the server advertises a fixed multicast address.
|
||||
*/
|
||||
// 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65
|
||||
// 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
|
||||
// stream that is already playing to change transport parameters, which
|
||||
// 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
|
||||
// intervening firewalls, a client must indicate the transport
|
||||
// parameters even if it has no influence over these parameters, for
|
||||
// example, where the server advertises a fixed multicast address.
|
||||
class SrsRtspSetupResponse : public SrsRtspResponse
|
||||
{
|
||||
public:
|
||||
// the client specified port.
|
||||
// The client specified port.
|
||||
int client_port_min;
|
||||
int client_port_max;
|
||||
// client will use the port in:
|
||||
// The client will use the port in:
|
||||
// [local_port_min, local_port_max)
|
||||
int local_port_min;
|
||||
int local_port_max;
|
||||
// session.
|
||||
// The session.
|
||||
std::string session;
|
||||
public:
|
||||
SrsRtspSetupResponse(int cseq);
|
||||
|
@ -644,65 +534,45 @@ protected:
|
|||
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
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* cached bytes buffer.
|
||||
*/
|
||||
// The cached bytes buffer.
|
||||
SrsSimpleStream* buf;
|
||||
/**
|
||||
* underlayer socket object, send/recv bytes.
|
||||
*/
|
||||
// The underlayer socket object, send/recv bytes.
|
||||
ISrsProtocolReadWriter* skt;
|
||||
public:
|
||||
SrsRtspStack(ISrsProtocolReadWriter* s);
|
||||
virtual ~SrsRtspStack();
|
||||
public:
|
||||
/**
|
||||
* recv rtsp message from underlayer io.
|
||||
* @param preq the output rtsp request message, which user must free it.
|
||||
* @return an int error code.
|
||||
* ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
|
||||
*/
|
||||
// Recv rtsp message from underlayer io.
|
||||
// @param preq the output rtsp request message, which user must free it.
|
||||
// @return an int error code.
|
||||
// ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF.
|
||||
virtual srs_error_t recv_message(SrsRtspRequest** preq);
|
||||
/**
|
||||
* send rtsp message over underlayer io.
|
||||
* @param res the rtsp response message, which user should never free it.
|
||||
* @return an int error code.
|
||||
*/
|
||||
// Send rtsp message over underlayer io.
|
||||
// @param res the rtsp response message, which user should never free it.
|
||||
// @return an int error code.
|
||||
virtual srs_error_t send_message(SrsRtspResponse* res);
|
||||
private:
|
||||
/**
|
||||
* recv the rtsp message.
|
||||
*/
|
||||
// Recv the rtsp message.
|
||||
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);
|
||||
/**
|
||||
* 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);
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
// 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.
|
||||
virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL);
|
||||
/**
|
||||
* read a token from io, split by SP, endswith CRLF:
|
||||
* token1 SP token2 SP ... tokenN CRLF
|
||||
* @param token, output the read token.
|
||||
* @param state, output the token parse state.
|
||||
* @param normal_ch, the char to indicates the normal token.
|
||||
* 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
|
||||
* @param pconsumed, output the token parsed length. NULL to ignore.
|
||||
*/
|
||||
// Read a token from io, split by SP, endswith CRLF:
|
||||
// token1 SP token2 SP ... tokenN CRLF
|
||||
// @param token, output the read token.
|
||||
// @param state, output the token parse state.
|
||||
// @param normal_ch, the char to indicates the normal token.
|
||||
// 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
|
||||
// @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);
|
||||
};
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
/**
|
||||
* The connection interface for all HTTP/RTMP/RTSP object.
|
||||
*/
|
||||
// The connection interface for all HTTP/RTMP/RTSP object.
|
||||
class ISrsConnection
|
||||
{
|
||||
public:
|
||||
|
@ -36,18 +34,14 @@ public:
|
|||
virtual ~ISrsConnection();
|
||||
};
|
||||
|
||||
/**
|
||||
* the manager for connection.
|
||||
*/
|
||||
// The manager for connection.
|
||||
class IConnectionManager
|
||||
{
|
||||
public:
|
||||
IConnectionManager();
|
||||
virtual ~IConnectionManager();
|
||||
public:
|
||||
/**
|
||||
* Remove then free the specified connection.
|
||||
*/
|
||||
// Remove then free the specified connection.
|
||||
virtual void remove(ISrsConnection* c) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -40,18 +40,16 @@ class SrsKbps;
|
|||
class SrsWallClock;
|
||||
class SrsTcpClient;
|
||||
|
||||
// the default timeout for http client.
|
||||
// The default timeout for http client.
|
||||
#define SRS_HTTP_CLIENT_TIMEOUT (30 * SRS_UTIME_SECONDS)
|
||||
|
||||
/**
|
||||
* The client to GET/POST/PUT/DELETE over HTTP.
|
||||
* @remark We will reuse the TCP transport until initialize or channel error,
|
||||
* such as send/recv failed.
|
||||
* Usage:
|
||||
* SrsHttpClient hc;
|
||||
* hc.initialize("127.0.0.1", 80, 9000);
|
||||
* hc.post("/api/v1/version", "Hello world!", NULL);
|
||||
*/
|
||||
// The client to GET/POST/PUT/DELETE over HTTP.
|
||||
// @remark We will reuse the TCP transport until initialize or channel error,
|
||||
// such as send/recv failed.
|
||||
// Usage:
|
||||
// SrsHttpClient hc;
|
||||
// hc.initialize("127.0.0.1", 80, 9000);
|
||||
// hc.post("/api/v1/version", "Hello world!", NULL);
|
||||
class SrsHttpClient
|
||||
{
|
||||
private:
|
||||
|
@ -72,33 +70,25 @@ public:
|
|||
SrsHttpClient();
|
||||
virtual ~SrsHttpClient();
|
||||
public:
|
||||
/**
|
||||
* Initliaze the client, disconnect the transport, renew the HTTP parser.
|
||||
* @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.
|
||||
*/
|
||||
// Initliaze the client, disconnect the transport, renew the HTTP parser.
|
||||
// @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.
|
||||
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.
|
||||
* @return the HTTP client itself.
|
||||
*/
|
||||
// Set HTTP request header in header[k]=v.
|
||||
// @return the HTTP client itself.
|
||||
virtual SrsHttpClient* set_header(std::string k, std::string v);
|
||||
public:
|
||||
/**
|
||||
* to post data to the uri.
|
||||
* @param the path to request on.
|
||||
* @param req the data post to uri. empty string to ignore.
|
||||
* @param ppmsg output the http message to read the response.
|
||||
* @remark user must free the ppmsg if not NULL.
|
||||
*/
|
||||
// Post data to the uri.
|
||||
// @param the path to request on.
|
||||
// @param req the data post to uri. empty string to ignore.
|
||||
// @param ppmsg output the http message to read the response.
|
||||
// @remark user must free the ppmsg if not NULL.
|
||||
virtual srs_error_t post(std::string path, std::string req, ISrsHttpMessage** ppmsg);
|
||||
/**
|
||||
* to get data from the uri.
|
||||
* @param the path to request on.
|
||||
* @param req the data post to uri. empty string to ignore.
|
||||
* @param ppmsg output the http message to read the response.
|
||||
* @remark user must free the ppmsg if not NULL.
|
||||
*/
|
||||
// Get data from the uri.
|
||||
// @param the path to request on.
|
||||
// @param req the data post to uri. empty string to ignore.
|
||||
// @param ppmsg output the http message to read the response.
|
||||
// @remark user must free the ppmsg if not NULL.
|
||||
virtual srs_error_t get(std::string path, std::string req, ISrsHttpMessage** ppmsg);
|
||||
private:
|
||||
virtual void set_recv_timeout(srs_utime_t tm);
|
||||
|
|
|
@ -82,7 +82,7 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p
|
|||
header = http_parser();
|
||||
url = "";
|
||||
headers.clear();
|
||||
header_parsed = 0;
|
||||
pbody = NULL;
|
||||
|
||||
// do parse
|
||||
if ((err = parse_message_imp(reader)) != srs_success) {
|
||||
|
@ -109,38 +109,32 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader)
|
|||
srs_error_t err = srs_success;
|
||||
|
||||
while (true) {
|
||||
ssize_t nparsed = 0;
|
||||
|
||||
// when got entire http header, parse it.
|
||||
// @see https://github.com/ossrs/srs/issues/400
|
||||
char* start = buffer->bytes();
|
||||
char* end = start + buffer->size();
|
||||
for (char* p = start; p <= end - 4; p++) {
|
||||
// SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A
|
||||
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());
|
||||
srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed);
|
||||
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;
|
||||
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());
|
||||
}
|
||||
|
||||
// The consumed size, does not include the body.
|
||||
ssize_t consumed = nparsed;
|
||||
if (pbody && buffer->bytes() < pbody) {
|
||||
consumed = pbody - buffer->bytes();
|
||||
}
|
||||
srs_info("size=%d, nparsed=%d, consumed=%d", buffer->size(), (int)nparsed, consumed);
|
||||
|
||||
// Only consume the header bytes.
|
||||
buffer->read_slice(consumed);
|
||||
|
||||
// Done when header completed, never wait for body completed, because it maybe chunked.
|
||||
if (state >= SrsHttpParseStateHeaderComplete) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// when nothing parsed, read more to parse.
|
||||
if (nparsed == 0) {
|
||||
// when requires more, only grow 1bytes, but the buffer will cache more.
|
||||
if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) {
|
||||
return srs_error_wrap(err, "grow buffer");
|
||||
}
|
||||
// when requires more, only grow 1bytes, but the buffer will cache more.
|
||||
if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) {
|
||||
return srs_error_wrap(err, "grow buffer");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,8 +166,7 @@ int SrsHttpParser::on_headers_complete(http_parser* parser)
|
|||
obj->header = *parser;
|
||||
// save the parser when header parse completed.
|
||||
obj->state = SrsHttpParseStateHeaderComplete;
|
||||
obj->header_parsed = (int)parser->nread;
|
||||
|
||||
|
||||
srs_info("***HEADERS COMPLETE***");
|
||||
|
||||
// see http_parser.c:1570, return 1 to skip body.
|
||||
|
@ -248,6 +241,12 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length)
|
|||
{
|
||||
SrsHttpParser* obj = (SrsHttpParser*)parser->data;
|
||||
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);
|
||||
|
||||
|
|
|
@ -37,18 +37,16 @@ class ISrsReader;
|
|||
class SrsHttpResponseReader;
|
||||
class SrsStSocket;
|
||||
|
||||
/**
|
||||
* wrapper for http-parser,
|
||||
* provides HTTP message originted service.
|
||||
*/
|
||||
// A wrapper for http-parser,
|
||||
// provides HTTP message originted service.
|
||||
class SrsHttpParser
|
||||
{
|
||||
private:
|
||||
http_parser_settings settings;
|
||||
http_parser parser;
|
||||
// the global parse buffer.
|
||||
// The global parse buffer.
|
||||
SrsFastStream* buffer;
|
||||
// whether allow jsonp parse.
|
||||
// Whether allow jsonp parse.
|
||||
bool jsonp;
|
||||
private:
|
||||
// http parse data, reset before parse message.
|
||||
|
@ -59,29 +57,23 @@ private:
|
|||
http_parser header;
|
||||
std::string url;
|
||||
std::vector<SrsHttpHeaderField> headers;
|
||||
int header_parsed;
|
||||
const char* pbody;
|
||||
public:
|
||||
SrsHttpParser();
|
||||
virtual ~SrsHttpParser();
|
||||
public:
|
||||
/**
|
||||
* initialize the http parser with specified type,
|
||||
* one parser can only parse request or response messages.
|
||||
* @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);
|
||||
/**
|
||||
* always parse a http message,
|
||||
* that is, the *ppmsg always NOT-NULL when return success.
|
||||
* 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.
|
||||
*/
|
||||
// initialize the http parser with specified type,
|
||||
// one parser can only parse request or response messages.
|
||||
// @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,
|
||||
// that is, the *ppmsg always NOT-NULL when return success.
|
||||
// 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);
|
||||
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);
|
||||
private:
|
||||
static int on_message_begin(http_parser* parser);
|
||||
|
@ -105,62 +97,41 @@ typedef std::pair<std::string, std::string> SrsHttpHeaderField;
|
|||
class SrsHttpMessage : public ISrsHttpMessage
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* parsed url.
|
||||
*/
|
||||
// The parsed url.
|
||||
std::string _url;
|
||||
/**
|
||||
* the extension of file, for example, .flv
|
||||
*/
|
||||
// The extension of file, for example, .flv
|
||||
std::string _ext;
|
||||
/**
|
||||
* parsed http header.
|
||||
*/
|
||||
// parsed http header.
|
||||
http_parser _header;
|
||||
/**
|
||||
* body object, reader object.
|
||||
* @remark, user can get body in string by get_body().
|
||||
*/
|
||||
// The body object, reader object.
|
||||
// @remark, user can get body in string by get_body().
|
||||
SrsHttpResponseReader* _body;
|
||||
/**
|
||||
* whether the body is chunked.
|
||||
*/
|
||||
// Whether the body is chunked.
|
||||
bool chunked;
|
||||
/**
|
||||
* whether the body is infinite chunked.
|
||||
*/
|
||||
// Whether the body is 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;
|
||||
/**
|
||||
* uri parser
|
||||
*/
|
||||
// The uri parser
|
||||
SrsHttpUri* _uri;
|
||||
/**
|
||||
* use a buffer to read and send ts file.
|
||||
*/
|
||||
// Use a buffer to read and send ts file.
|
||||
// TODO: FIXME: remove it.
|
||||
char* _http_ts_send_buffer;
|
||||
// http headers
|
||||
// The http headers
|
||||
std::vector<SrsHttpHeaderField> _headers;
|
||||
// the query map
|
||||
// The query map
|
||||
std::map<std::string, std::string> _query;
|
||||
// the transport connection, can be NULL.
|
||||
// The transport connection, can be NULL.
|
||||
SrsConnection* owner_conn;
|
||||
// whether request is jsonp.
|
||||
// Whether request is 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;
|
||||
public:
|
||||
SrsHttpMessage(ISrsReader* io);
|
||||
virtual ~SrsHttpMessage();
|
||||
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);
|
||||
public:
|
||||
// Get the owner connection, maybe NULL.
|
||||
|
@ -169,91 +140,62 @@ public:
|
|||
public:
|
||||
virtual uint8_t method();
|
||||
virtual uint16_t status_code();
|
||||
/**
|
||||
* method helpers.
|
||||
*/
|
||||
// The method helpers.
|
||||
virtual std::string method_str();
|
||||
virtual bool is_http_get();
|
||||
virtual bool is_http_put();
|
||||
virtual bool is_http_post();
|
||||
virtual bool is_http_delete();
|
||||
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();
|
||||
/**
|
||||
* whether body is infinite chunked encoding.
|
||||
* @remark set by enter_infinite_chunked.
|
||||
*/
|
||||
// Whether body is infinite chunked encoding.
|
||||
// @remark set by enter_infinite_chunked.
|
||||
virtual bool is_infinite_chunked();
|
||||
/**
|
||||
* whether should keep the connection alive.
|
||||
*/
|
||||
// Whether should keep the connection alive.
|
||||
virtual bool is_keep_alive();
|
||||
/**
|
||||
* the uri contains the host and path.
|
||||
*/
|
||||
// The uri contains the host and path.
|
||||
virtual std::string uri();
|
||||
/**
|
||||
* the url maybe the path.
|
||||
*/
|
||||
// The url maybe the path.
|
||||
virtual std::string url();
|
||||
virtual std::string host();
|
||||
virtual std::string path();
|
||||
virtual std::string query();
|
||||
virtual std::string ext();
|
||||
/**
|
||||
* get the RESTful matched id.
|
||||
*/
|
||||
// Get the RESTful matched id.
|
||||
virtual int parse_rest_id(std::string pattern);
|
||||
public:
|
||||
virtual srs_error_t enter_infinite_chunked();
|
||||
public:
|
||||
/**
|
||||
* read body to string.
|
||||
* @remark for small http body.
|
||||
*/
|
||||
// Read body to string.
|
||||
// @remark for small http body.
|
||||
virtual srs_error_t body_read_all(std::string& body);
|
||||
/**
|
||||
* get the body reader, to read one by one.
|
||||
* @remark when body is very large, or chunked, use this.
|
||||
*/
|
||||
// Get the body reader, to read one by one.
|
||||
// @remark when body is very large, or chunked, use this.
|
||||
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();
|
||||
/**
|
||||
* get the param in query string,
|
||||
* for instance, query is "start=100&end=200",
|
||||
* then query_get("start") is "100", and query_get("end") is "200"
|
||||
*/
|
||||
// Get the param in query string, 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);
|
||||
/**
|
||||
* get the headers.
|
||||
*/
|
||||
// Get the headers.
|
||||
virtual int request_header_count();
|
||||
virtual std::string request_header_key_at(int index);
|
||||
virtual std::string request_header_value_at(int index);
|
||||
virtual std::string get_request_header(std::string name);
|
||||
public:
|
||||
/**
|
||||
* convert the http message to a request.
|
||||
* @remark user must free the return request.
|
||||
*/
|
||||
// Convert the http message to a request.
|
||||
// @remark user must free the return request.
|
||||
virtual SrsRequest* to_request(std::string vhost);
|
||||
public:
|
||||
virtual bool is_jsonp();
|
||||
};
|
||||
|
||||
// the http chunked header size,
|
||||
// The http chunked header size,
|
||||
// for writev, there always one chunk to send it.
|
||||
#define SRS_HTTP_HEADER_CACHE_SIZE 64
|
||||
|
||||
/**
|
||||
* response writer use st socket
|
||||
*/
|
||||
// Response writer use st socket
|
||||
class SrsHttpResponseWriter : public ISrsHttpResponseWriter
|
||||
{
|
||||
private:
|
||||
|
@ -264,17 +206,17 @@ private:
|
|||
iovec* iovss_cache;
|
||||
int nb_iovss_cache;
|
||||
private:
|
||||
// reply header has been (logically) written
|
||||
// Reply header has been (logically) written
|
||||
bool header_wrote;
|
||||
// status code passed to WriteHeader
|
||||
// The status code passed to WriteHeader
|
||||
int status;
|
||||
private:
|
||||
// explicitly-declared Content-Length; or -1
|
||||
// The explicitly-declared Content-Length; or -1
|
||||
int64_t content_length;
|
||||
// number of bytes written in body
|
||||
// The number of bytes written in body
|
||||
int64_t written;
|
||||
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
|
||||
// (*response).wroteHeader, which tells only whether it was
|
||||
// logically written.
|
||||
|
@ -291,9 +233,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -301,21 +241,19 @@ private:
|
|||
SrsHttpMessage* owner;
|
||||
SrsFastStream* buffer;
|
||||
bool is_eof;
|
||||
// the left bytes in chunk.
|
||||
// The left bytes in chunk.
|
||||
int nb_left_chunk;
|
||||
// the number of bytes of current chunk.
|
||||
// The number of bytes of current chunk.
|
||||
int nb_chunk;
|
||||
// already read total bytes.
|
||||
// Already read total bytes.
|
||||
int64_t nb_total_read;
|
||||
public:
|
||||
SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader);
|
||||
virtual ~SrsHttpResponseReader();
|
||||
public:
|
||||
/**
|
||||
* initialize the response reader with buffer.
|
||||
*/
|
||||
// Initialize the response reader with buffer.
|
||||
virtual srs_error_t initialize(SrsFastStream* buffer);
|
||||
// interface ISrsHttpResponseReader
|
||||
// Interface ISrsHttpResponseReader
|
||||
public:
|
||||
virtual bool eof();
|
||||
virtual srs_error_t read(char* data, int nb_data, int* nb_read);
|
||||
|
|
|
@ -31,10 +31,8 @@
|
|||
#include <srs_service_st.hpp>
|
||||
#include <srs_kernel_log.hpp>
|
||||
|
||||
/**
|
||||
* st thread context, get_id will get the st-thread id,
|
||||
* which identify the client.
|
||||
*/
|
||||
// The st thread context, get_id will get the st-thread id,
|
||||
// which identify the client.
|
||||
class SrsThreadContext : public ISrsThreadContext
|
||||
{
|
||||
private:
|
||||
|
@ -50,9 +48,7 @@ public:
|
|||
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
|
||||
{
|
||||
private:
|
||||
|
@ -63,7 +59,7 @@ private:
|
|||
public:
|
||||
SrsConsoleLog(SrsLogLevel l, bool u);
|
||||
virtual ~SrsConsoleLog();
|
||||
// interface ISrsLog
|
||||
// Interface ISrsLog
|
||||
public:
|
||||
virtual srs_error_t initialize();
|
||||
virtual void reopen();
|
||||
|
@ -74,13 +70,11 @@ public:
|
|||
virtual void error(const char* tag, int context_id, const char* fmt, ...);
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate the log header.
|
||||
* @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 psize Output the actual header size.
|
||||
* @remark It's a internal API.
|
||||
*/
|
||||
// Generate the log header.
|
||||
// @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 psize Output the actual header size.
|
||||
// @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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
|
||||
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_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.
|
||||
data->set("srs_pid", SrsAmf0Any::number(getpid()));
|
||||
data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id()));
|
||||
|
|
|
@ -37,15 +37,13 @@ class SrsPacket;
|
|||
class SrsKbps;
|
||||
class SrsWallClock;
|
||||
|
||||
/**
|
||||
* The simple RTMP client, provides friendly APIs.
|
||||
* @remark Should never use client when closed.
|
||||
* Usage:
|
||||
* SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000);
|
||||
* client.connect();
|
||||
* client.play();
|
||||
* client.close();
|
||||
*/
|
||||
// The simple RTMP client, provides friendly APIs.
|
||||
// @remark Should never use client when closed.
|
||||
// Usage:
|
||||
// SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000);
|
||||
// client.connect();
|
||||
// client.play();
|
||||
// client.close();
|
||||
class SrsBasicRtmpClient
|
||||
{
|
||||
private:
|
||||
|
|
|
@ -36,10 +36,10 @@ typedef void* srs_thread_t;
|
|||
typedef void* srs_cond_t;
|
||||
typedef void* srs_mutex_t;
|
||||
|
||||
// initialize st, requires epoll.
|
||||
// Initialize st, requires epoll.
|
||||
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.
|
||||
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);
|
||||
|
||||
/**
|
||||
* The mutex locker.
|
||||
*/
|
||||
// The mutex locker.
|
||||
#define SrsLocker(instance) \
|
||||
impl__SrsLocker _srs_auto_free_##instance(&instance)
|
||||
|
||||
|
@ -102,10 +100,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* the socket provides TCP socket over st,
|
||||
* that is, the sync socket mechanism.
|
||||
*/
|
||||
// the socket provides TCP socket over st,
|
||||
// that is, the sync socket mechanism.
|
||||
class SrsStSocket : public ISrsProtocolReadWriter
|
||||
{
|
||||
private:
|
||||
|
@ -133,28 +129,22 @@ public:
|
|||
virtual int64_t get_recv_bytes();
|
||||
virtual int64_t get_send_bytes();
|
||||
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_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 writev(const iovec *iov, int iov_size, ssize_t* nwrite);
|
||||
};
|
||||
|
||||
/**
|
||||
* The client to connect to server over TCP.
|
||||
* User must never reuse the client when close it.
|
||||
* Usage:
|
||||
* SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS);
|
||||
* client.connect();
|
||||
* client.write("Hello world!", 12, NULL);
|
||||
* client.read(buf, 4096, NULL);
|
||||
* @remark User can directly free the object, which will close the fd.
|
||||
*/
|
||||
// The client to connect to server over TCP.
|
||||
// User must never reuse the client when close it.
|
||||
// Usage:
|
||||
// SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS);
|
||||
// client.connect();
|
||||
// client.write("Hello world!", 12, NULL);
|
||||
// client.read(buf, 4096, NULL);
|
||||
// @remark User can directly free the object, which will close the fd.
|
||||
class SrsTcpClient : public ISrsProtocolReadWriter
|
||||
{
|
||||
private:
|
||||
|
@ -166,27 +156,21 @@ private:
|
|||
// The timeout in srs_utime_t.
|
||||
srs_utime_t timeout;
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* @param h the ip or hostname of server.
|
||||
* @param p the port to connect to.
|
||||
* @param tm the timeout in srs_utime_t.
|
||||
*/
|
||||
// Constructor.
|
||||
// @param h the ip or hostname of server.
|
||||
// @param p the port to connect to.
|
||||
// @param tm the timeout in srs_utime_t.
|
||||
SrsTcpClient(std::string h, int p, srs_utime_t tm);
|
||||
virtual ~SrsTcpClient();
|
||||
public:
|
||||
/**
|
||||
* Connect to server over TCP.
|
||||
* @remark We will close the exists connection before do connect.
|
||||
*/
|
||||
// Connect to server over TCP.
|
||||
// @remark We will close the exists connection before do connect.
|
||||
virtual srs_error_t connect();
|
||||
private:
|
||||
/**
|
||||
* Close the connection to server.
|
||||
* @remark User should never use the client when close it.
|
||||
*/
|
||||
// Close the connection to server.
|
||||
// @remark User should never use the client when close it.
|
||||
virtual void close();
|
||||
// interface ISrsProtocolReadWriter
|
||||
// Interface ISrsProtocolReadWriter
|
||||
public:
|
||||
virtual bool is_never_timeout(srs_utime_t tm);
|
||||
virtual void set_recv_timeout(srs_utime_t tm);
|
||||
|
|
|
@ -32,17 +32,17 @@
|
|||
|
||||
#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_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();
|
||||
|
||||
// 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();
|
||||
|
||||
// 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(const sockaddr* addr);
|
||||
|
||||
|
|
|
@ -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.
|
||||
#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:
|
||||
// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual
|
||||
// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2
|
||||
|
|
|
@ -5597,35 +5597,480 @@ VOID TEST(ProtocolRTMPTest, RTMPHandshakeBytes)
|
|||
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)
|
||||
{
|
||||
if (true) {
|
||||
MockBufferIO bio;
|
||||
SrsHttpParser hp;
|
||||
|
||||
|
||||
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));
|
||||
|
||||
if (true) {
|
||||
ISrsHttpMessage* req = NULL;
|
||||
SrsAutoFree(ISrsHttpMessage, req);
|
||||
ASSERT_TRUE(0 == hp.parse_message(&bio, &req));
|
||||
|
||||
// We should read body, or next parsing message will fail.
|
||||
// @see https://github.com/ossrs/srs/issues/1181
|
||||
EXPECT_FALSE(req->body_reader()->eof());
|
||||
}
|
||||
|
||||
if (true) {
|
||||
bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello");
|
||||
|
||||
// Should fail because there is body which not read.
|
||||
// @see https://github.com/ossrs/srs/issues/1181
|
||||
|
||||
ISrsHttpMessage* req = NULL;
|
||||
SrsAutoFree(ISrsHttpMessage, req);
|
||||
ASSERT_FALSE(0 == hp.parse_message(&bio, &req));
|
||||
}
|
||||
|
||||
ISrsHttpMessage* req = NULL;
|
||||
ASSERT_TRUE(0 == hp.parse_message(&bio, &req));
|
||||
|
||||
// We should read body, or next parsing message will fail.
|
||||
// @see https://github.com/ossrs/srs/issues/1181
|
||||
EXPECT_FALSE(req->body_reader()->eof());
|
||||
srs_freep(req);
|
||||
|
||||
// Got new packet, notice that previous body still exists in bio.
|
||||
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.
|
||||
// @see https://github.com/ossrs/srs/issues/1181
|
||||
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) {
|
||||
|
|
Loading…
Reference in a new issue