1
0
Fork 0
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:
winlin 2019-05-05 07:59:15 +08:00
commit 7c002308e9
87 changed files with 7840 additions and 9677 deletions

View file

@ -147,9 +147,9 @@ Please select according to languages:
- [x] Enhanced complex error code with description and stack, read [#913][bug #913].
- [x] Enhanced 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

View file

@ -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

View file

@ -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

View file

@ -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();
};

View file

@ -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();
};

View file

@ -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:

View file

@ -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

View file

@ -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;
};

View file

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

View file

@ -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:

View file

@ -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);
};

View file

@ -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();
};

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

@ -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:

View file

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

View file

@ -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:

View file

@ -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:

View file

@ -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();
};

View file

@ -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());

View file

@ -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();
};

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -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:

View file

@ -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);

View file

@ -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();
};

View file

@ -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();
};

View file

@ -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();

View file

@ -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:

View file

@ -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:

View file

@ -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();
};

View file

@ -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();
};

View file

@ -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();
};

View file

@ -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);

View file

@ -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:

View file

@ -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();

View file

@ -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);
};

View file

@ -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);
};

View file

@ -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);

View file

@ -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));

View file

@ -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();

View file

@ -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();

View file

@ -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);

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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);
};

View file

@ -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

View file

@ -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:

View file

@ -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);
};

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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:

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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();
};

View file

@ -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);
};

View file

@ -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)

View file

@ -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);
};

View file

@ -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);
};

View file

@ -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

View file

@ -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);
};

View file

@ -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;
};

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -118,14 +118,8 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug)
data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY));
data->set("srs_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()));

View file

@ -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:

View file

@ -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);

View file

@ -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);

View file

@ -40,6 +40,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// we add an empty macro for upp to show the smart tips.
#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

View file

@ -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) {