listen and serve stream caster mpegts over udp.

pull/133/head
winlin 10 years ago
parent f9d1e1111a
commit 52891b491a

@ -323,6 +323,12 @@ else
echo "#undef SRS_AUTO_HTTP_SERVER" >> $SRS_AUTO_HEADERS_H
fi
if [ $SRS_STREAM_CASTER = YES ]; then
echo "#define SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
else
echo "#undef SRS_AUTO_STREAM_CASTER" >> $SRS_AUTO_HEADERS_H
fi
if [ $SRS_HTTP_API = YES ]; then
echo "#define SRS_AUTO_HTTP_API" >> $SRS_AUTO_HEADERS_H
else

@ -25,6 +25,7 @@ SRS_INGEST=RESERVED
SRS_STAT=RESERVED
SRS_HTTP_CALLBACK=RESERVED
SRS_HTTP_SERVER=RESERVED
SRS_STREAM_CASTER=RESERVED
SRS_HTTP_API=RESERVED
SRS_LIBRTMP=RESERVED
SRS_RESEARCH=RESERVED
@ -114,6 +115,7 @@ Options:
build nginx at: ./objs/nginx/sbin/nginx
--with-http-callback enable http hooks, build cherrypy as demo api server.
--with-http-server enable http server to delivery http stream.
--with-stream-caster enable stream caster to serve other stream over other protocol.
--with-http-api enable http api, to manage SRS by http api.
--with-ffmpeg enable transcoding tool ffmpeg.
build ffmpeg at: ./objs/ffmpeg/bin/ffmpeg
@ -138,6 +140,7 @@ Options:
--without-nginx disable delivery HTTP stream with nginx.
--without-http-callback disable http, http hooks callback.
--without-http-server disable http server, use external server to delivery http stream.
--without-stream-caster disable stream caster, only listen and serve RTMP/HTTP.
--without-http-api disable http api, only use console to manage SRS process.
--without-ffmpeg disable the ffmpeg transcode tool feature.
--without-transcode disable the transcoding feature.
@ -213,6 +216,7 @@ function parse_user_option() {
--with-stat) SRS_STAT=YES ;;
--with-http-callback) SRS_HTTP_CALLBACK=YES ;;
--with-http-server) SRS_HTTP_SERVER=YES ;;
--with-stream-caster) SRS_STREAM_CASTER=YES ;;
--with-http-api) SRS_HTTP_API=YES ;;
--with-librtmp) SRS_LIBRTMP=YES ;;
--with-research) SRS_RESEARCH=YES ;;
@ -235,6 +239,7 @@ function parse_user_option() {
--without-stat) SRS_STAT=NO ;;
--without-http-callback) SRS_HTTP_CALLBACK=NO ;;
--without-http-server) SRS_HTTP_SERVER=NO ;;
--without-stream-caster) SRS_STREAM_CASTER=NO ;;
--without-http-api) SRS_HTTP_API=NO ;;
--without-librtmp) SRS_LIBRTMP=NO ;;
--without-research) SRS_RESEARCH=NO ;;
@ -362,6 +367,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=NO
SRS_HTTP_CALLBACK=NO
SRS_HTTP_SERVER=NO
SRS_STREAM_CASTER=NO
SRS_HTTP_API=NO
SRS_LIBRTMP=NO
SRS_RESEARCH=NO
@ -387,6 +393,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=YES
@ -412,6 +419,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=NO
SRS_HTTP_CALLBACK=NO
SRS_HTTP_SERVER=NO
SRS_STREAM_CASTER=NO
SRS_HTTP_API=NO
SRS_LIBRTMP=NO
SRS_RESEARCH=NO
@ -437,6 +445,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=NO
SRS_HTTP_CALLBACK=NO
SRS_HTTP_SERVER=NO
SRS_STREAM_CASTER=NO
SRS_HTTP_API=NO
SRS_LIBRTMP=NO
SRS_RESEARCH=NO
@ -462,6 +471,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=NO
SRS_HTTP_CALLBACK=NO
SRS_HTTP_SERVER=NO
SRS_STREAM_CASTER=NO
SRS_HTTP_API=NO
SRS_LIBRTMP=NO
SRS_RESEARCH=NO
@ -487,6 +497,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -513,6 +524,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -538,6 +550,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -563,6 +576,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=YES
@ -588,6 +602,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=NO
SRS_RESEARCH=NO
@ -613,6 +628,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -638,6 +654,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -663,6 +680,7 @@ function apply_user_presets() {
SRS_HTTP_PARSER=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
SRS_RESEARCH=NO
@ -723,6 +741,7 @@ function apply_user_detail_options() {
SRS_HTTP_PARSER=NO
SRS_HTTP_CALLBACK=NO
SRS_HTTP_SERVER=NO
SRS_STREAM_CASTER=NO
SRS_HTTP_API=NO
SRS_LIBRTMP=YES
SRS_RESEARCH=YES
@ -752,6 +771,7 @@ function regenerate_options() {
if [ $SRS_STAT = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-stat"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-stat"; fi
if [ $SRS_HTTP_CALLBACK = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-callback"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-callback"; fi
if [ $SRS_HTTP_SERVER = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-server"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-server"; fi
if [ $SRS_STREAM_CASTER = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-stream-caster"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-stream-caster"; fi
if [ $SRS_HTTP_API = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-api"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-api"; fi
if [ $SRS_LIBRTMP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-librtmp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-librtmp"; fi
if [ $SRS_RESEARCH = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-research"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-research"; fi
@ -828,6 +848,7 @@ function check_option_conflicts() {
if [ $SRS_FFMPEG_TOOL = RESERVED ]; then echo "you must specifies the ffmpeg, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_HTTP_CALLBACK = RESERVED ]; then echo "you must specifies the http-callback, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_HTTP_SERVER = RESERVED ]; then echo "you must specifies the http-server, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_STREAM_CASTER = RESERVED ]; then echo "you must specifies the stream-caster, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_HTTP_API = RESERVED ]; then echo "you must specifies the http-api, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_LIBRTMP = RESERVED ]; then echo "you must specifies the librtmp, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_RESEARCH = RESERVED ]; then echo "you must specifies the research, see: ./configure --help"; __check_ok=NO; fi

@ -142,6 +142,16 @@ stream_caster {
# whether stream caster is enabled.
# default: off
enabled on;
# the caster type of stream, the casters:
# mpegts_over_udp, MPEG-TS over UDP caster.
caster mpegts_over_udp;
# the output rtmp url.
# for example, rtmp://127.0.0.1/live/livestream.
output rtmp://127.0.0.1/live/livestream;
# the listen port for stream caster.
# for caster:
# mpegts_over_udp, listen at udp port.
listen 1935;
}
#############################################################################################

@ -140,6 +140,11 @@ bool SrsConfDirective::is_vhost()
return name == "vhost";
}
bool SrsConfDirective::is_stream_caster()
{
return name == "stream_caster";
}
int SrsConfDirective::parse(SrsConfigBuffer* buffer)
{
return parse_conf(buffer, parse_file);
@ -519,6 +524,8 @@ int SrsConfig::reload_conf(SrsConfig* conf)
return ret;
}
// TODO: FIXME: support reload stream_caster.
// merge config: vhost
if ((ret = reload_vhost(old_root)) != ERROR_SUCCESS) {
return ret;
@ -1295,6 +1302,7 @@ int SrsConfig::check_config()
srs_trace("srs checking config...");
vector<SrsConfDirective*> vhosts = get_vhosts();
vector<SrsConfDirective*> stream_casters = get_stream_casters();
////////////////////////////////////////////////////////////////////////
// check empty
@ -1315,7 +1323,7 @@ int SrsConfig::check_config()
&& n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file"
&& n != "max_connections" && n != "daemon" && n != "heartbeat"
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print"
&& n != "http_stream" && n != "http_server")
&& n != "http_stream" && n != "http_server" && n != "stream_caster")
{
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported directive %s, ret=%d", n.c_str(), ret);
@ -1381,6 +1389,20 @@ int SrsConfig::check_config()
}
}
}
for (int n = 0; n < (int)stream_casters.size(); n++) {
SrsConfDirective* stream_caster = stream_casters[n];
for (int i = 0; stream_caster && i < (int)stream_caster->directives.size(); i++) {
SrsConfDirective* conf = stream_caster->at(i);
string n = conf->name;
if (n != "enabled" && n != "caster" && n != "output"
&& n != "listen"
) {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported stream_caster directive %s, ret=%d", n.c_str(), ret);
return ret;
}
}
}
for (int n = 0; n < (int)vhosts.size(); n++) {
SrsConfDirective* vhost = vhosts[n];
for (int i = 0; vhost && i < (int)vhost->directives.size(); i++) {
@ -1969,6 +1991,77 @@ int SrsConfig::get_pithy_print_edge()
return ::atoi(pithy->arg0().c_str());
}
vector<SrsConfDirective*> SrsConfig::get_stream_casters()
{
srs_assert(root);
std::vector<SrsConfDirective*> stream_casters;
for (int i = 0; i < (int)root->directives.size(); i++) {
SrsConfDirective* conf = root->at(i);
if (!conf->is_stream_caster()) {
continue;
}
stream_casters.push_back(conf);
}
return stream_casters;
}
bool SrsConfig::get_stream_caster_enabled(SrsConfDirective* sc)
{
srs_assert(sc);
SrsConfDirective* conf = sc->get("enabled");
if (!conf) {
return SRS_CONF_DEFAULT_STREAM_CASTER_ENABLED;
}
if (conf->arg0() != "on") {
return false;
}
return true;
}
string SrsConfig::get_stream_caster_engine(SrsConfDirective* sc)
{
srs_assert(sc);
SrsConfDirective* conf = sc->get("caster");
if (!conf) {
return "";
}
return conf->arg0();
}
string SrsConfig::get_stream_caster_output(SrsConfDirective* sc)
{
srs_assert(sc);
SrsConfDirective* conf = sc->get("output");
if (!conf) {
return "";
}
return conf->arg0();
}
int SrsConfig::get_stream_caster_listen(SrsConfDirective* sc)
{
srs_assert(sc);
SrsConfDirective* conf = sc->get("listen");
if (!conf) {
return 0;
}
return ::atoi(conf->arg0().c_str());
}
SrsConfDirective* SrsConfig::get_vhost(string vhost)
{
srs_assert(root);

@ -80,6 +80,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define SRS_CONF_DEFAULT_SECURITY_ENABLED false
#define SRS_CONF_DEFAULT_STREAM_CASTER_ENABLED false
#define SRS_CONF_DEFAULT_STREAM_CASTER_MPEGTS_OVER_UDP "mpegts_over_udp"
#define SRS_CONF_DEFAULT_STATS_NETWORK_DEVICE_INDEX 0
#define SRS_CONF_DEFAULT_STAGE_PLAY_USER_INTERVAL_MS 10000
@ -188,6 +191,10 @@ public:
* whether current directive is vhost.
*/
virtual bool is_vhost();
/**
* whether current directive is stream_caster.
*/
virtual bool is_stream_caster();
// parse utilities
public:
/**
@ -446,6 +453,28 @@ public:
* the edge will get stream from upnode.
*/
virtual int get_pithy_print_edge();
// stream_caster section
public:
/**
* get all stream_caster in config file.
*/
virtual std::vector<SrsConfDirective*> get_stream_casters();
/**
* get whether the specified stream_caster is enabled.
*/
virtual bool get_stream_caster_enabled(SrsConfDirective* sc);
/**
* get the engine of stream_caster, the caster config.
*/
virtual std::string get_stream_caster_engine(SrsConfDirective* sc);
/**
* get the output rtmp url of stream_caster, the output config.
*/
virtual std::string get_stream_caster_output(SrsConfDirective* sc);
/**
* get the listen port of stream caster.
*/
virtual int get_stream_caster_listen(SrsConfDirective* sc);
// vhost specified section
public:
/**

@ -93,6 +93,22 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES
#define SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES 9
std::string __srs_listener_type2string(SrsListenerType type)
{
switch (type) {
case SrsListenerRtmpStream:
return "RTMP";
case SrsListenerHttpApi:
return "HTTP-API";
case SrsListenerHttpStream:
return "HTTP-Server";
case SrsListenerMpegTsOverUdp:
return "MPEG-TS over UDP";
default:
return "UNKONWN";
}
}
SrsListener::SrsListener(SrsServer* server, SrsListenerType type)
{
fd = -1;
@ -174,18 +190,15 @@ int SrsListener::listen(int port)
}
srs_verbose("create st listen thread success, port=%d", port);
srs_trace("listen thread cid=%d, current_cid=%d, "
srs_info("listen thread cid=%d, current_cid=%d, "
"listen at port=%d, type=%d, fd=%d started success, port=%d",
pthread->cid(), _srs_context->get_id(), _port, _type, fd, port);
srs_trace("%s listen at tcp://%d, fd=%d", __srs_listener_type2string(_type).c_str(), _port, fd);
return ret;
}
void SrsListener::on_thread_start()
{
srs_trace("listen cycle start, port=%d, type=%d, fd=%d", _port, _type, fd);
}
int SrsListener::cycle()
{
int ret = ERROR_SUCCESS;
@ -207,6 +220,86 @@ int SrsListener::cycle()
return ret;
}
SrsUdpListener::SrsUdpListener(SrsServer* server, SrsListenerType type) : SrsListener(server, type)
{
}
SrsUdpListener::~SrsUdpListener()
{
}
int SrsUdpListener::listen(int port)
{
int ret = ERROR_SUCCESS;
// the caller already ensure the type is ok,
// we just assert here for unknown stream caster.
srs_assert(_type == SrsListenerMpegTsOverUdp);
_port = port;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
ret = ERROR_SOCKET_CREATE;
srs_error("create linux socket error. port=%d, ret=%d", port, ret);
return ret;
}
srs_verbose("create linux socket success. port=%d, fd=%d", port, fd);
int reuse_socket = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse_socket, sizeof(int)) == -1) {
ret = ERROR_SOCKET_SETREUSE;
srs_error("setsockopt reuse-addr error. port=%d, ret=%d", port, ret);
return ret;
}
srs_verbose("setsockopt reuse-addr success. port=%d, fd=%d", port, fd);
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(_port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(fd, (const sockaddr*)&addr, sizeof(sockaddr_in)) == -1) {
ret = ERROR_SOCKET_BIND;
srs_error("bind socket error. port=%d, ret=%d", port, ret);
return ret;
}
srs_verbose("bind socket success. port=%d, fd=%d", port, fd);
if ((stfd = st_netfd_open_socket(fd)) == NULL){
ret = ERROR_ST_OPEN_SOCKET;
srs_error("st_netfd_open_socket open socket failed. port=%d, ret=%d", port, ret);
return ret;
}
srs_verbose("st open socket success. port=%d, fd=%d", port, fd);
if ((ret = pthread->start()) != ERROR_SUCCESS) {
srs_error("st_thread_create listen thread error. port=%d, ret=%d", port, ret);
return ret;
}
srs_verbose("create st listen thread success, port=%d", port);
srs_info("listen thread cid=%d, current_cid=%d, "
"listen at port=%d, type=%d, fd=%d started success, port=%d",
pthread->cid(), _srs_context->get_id(), _port, _type, fd, port);
srs_trace("%s listen at udp://%d, fd=%d", __srs_listener_type2string(_type).c_str(), _port, fd);
return ret;
}
int SrsUdpListener::cycle()
{
int ret = ERROR_SUCCESS;
// the caller already ensure the type is ok,
// we just assert here for unknown stream caster.
srs_assert(_type == SrsListenerMpegTsOverUdp);
// TODO: FIXME: recv udp packet.
st_sleep(1);
return ret;
}
SrsSignalManager* SrsSignalManager::instance = NULL;
SrsSignalManager::SrsSignalManager(SrsServer* server)
@ -608,6 +701,10 @@ int SrsServer::listen()
return ret;
}
if ((ret = listen_stream_caster()) != ERROR_SUCCESS) {
return ret;
}
return ret;
}
@ -869,6 +966,53 @@ int SrsServer::listen_http_stream()
return ret;
}
int SrsServer::listen_stream_caster()
{
int ret = ERROR_SUCCESS;
#ifdef SRS_AUTO_STREAM_CASTER
close_listeners(SrsListenerMpegTsOverUdp);
std::vector<SrsConfDirective*>::iterator it;
std::vector<SrsConfDirective*> stream_casters = _srs_config->get_stream_casters();
for (it = stream_casters.begin(); it != stream_casters.end(); ++it) {
SrsConfDirective* stream_caster = *it;
if (!_srs_config->get_stream_caster_enabled(stream_caster)) {
continue;
}
SrsUdpListener* listener = NULL;
std::string caster = _srs_config->get_stream_caster_engine(stream_caster);
if (caster == SRS_CONF_DEFAULT_STREAM_CASTER_MPEGTS_OVER_UDP) {
listener = new SrsUdpListener(this, SrsListenerMpegTsOverUdp);
} else {
ret = ERROR_STREAM_CASTER_ENGINE;
srs_error("unsupported stream caster %s. ret=%d", caster.c_str(), ret);
return ret;
}
srs_assert(listener != NULL);
listeners.push_back(listener);
int port = _srs_config->get_stream_caster_listen(stream_caster);
if (port <= 0) {
ret = ERROR_STREAM_CASTER_PORT;
srs_error("invalid stream caster port %d. ret=%d", port, ret);
return ret;
}
if ((ret = listener->listen(port)) != ERROR_SUCCESS) {
srs_error("StreamCaster listen at port %d failed. ret=%d", port, ret);
return ret;
}
}
#endif
return ret;
}
void SrsServer::close_listeners(SrsListenerType type)
{
std::vector<SrsListener*>::iterator it;

@ -50,18 +50,23 @@ class SrsKbps;
enum SrsListenerType
{
// RTMP client,
SrsListenerRtmpStream = 0,
SrsListenerRtmpStream = 0,
// HTTP api,
SrsListenerHttpApi = 1,
SrsListenerHttpApi = 1,
// HTTP stream, HDS/HLS/DASH
SrsListenerHttpStream = 2
SrsListenerHttpStream = 2,
// UDP stream, MPEG-TS over udp.
SrsListenerMpegTsOverUdp = 3,
};
/**
* the common tcp listener, for RTMP/HTTP server.
*/
class SrsListener : public ISrsThreadHandler
{
public:
SrsListenerType _type;
private:
protected:
int fd;
st_netfd_t stfd;
int _port;
@ -75,7 +80,21 @@ public:
virtual int listen(int port);
// interface ISrsThreadHandler.
public:
virtual void on_thread_start();
virtual int cycle();
};
/**
* the udp listener, for udp server.
*/
class SrsUdpListener : public SrsListener
{
public:
SrsUdpListener(SrsServer* server, SrsListenerType type);
virtual ~SrsUdpListener();
public:
virtual int listen(int port);
// interface ISrsThreadHandler.
public:
virtual int cycle();
};
@ -211,6 +230,7 @@ private:
virtual int listen_rtmp();
virtual int listen_http_api();
virtual int listen_http_stream();
virtual int listen_stream_caster();
/**
* close the listeners for specified type,
* remove the listen object from manager.

@ -204,7 +204,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_AAC_DATA_INVALID 3048
///////////////////////////////////////////////////////
// HTTP protocol error.
// HTTP/StreamCaster protocol error.
///////////////////////////////////////////////////////
#define ERROR_HTTP_PATTERN_EMPTY 4000
#define ERROR_HTTP_PATTERN_DUPLICATED 4001
@ -216,6 +216,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_AAC_DECODE_ERROR 4007
#define ERROR_KERNEL_MP3_STREAM_CLOSED 4008
#define ERROR_MP3_DECODE_ERROR 4009
#define ERROR_STREAM_CASTER_ENGINE 4010
#define ERROR_STREAM_CASTER_PORT 4011
/**
* whether the error code is an system control error.

Loading…
Cancel
Save