1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-14 12:21:55 +00:00

support gmd. change work_dir. hourglass. add utilies.

This commit is contained in:
winlin 2016-01-08 13:58:19 +08:00
parent c9b977d337
commit f1e7e9d933
33 changed files with 702 additions and 73 deletions

View file

@ -195,6 +195,11 @@ if [ $SRS_GPERF_MC = YES ]; then
else
srs_undefine_macro "SRS_AUTO_GPERF_MC" $SRS_AUTO_HEADERS_H
fi
if [ $SRS_GPERF_MD = YES ]; then
srs_define_macro "SRS_AUTO_GPERF_MD" $SRS_AUTO_HEADERS_H
else
srs_undefine_macro "SRS_AUTO_GPERF_MD" $SRS_AUTO_HEADERS_H
fi
if [ $SRS_GPERF_MP = YES ]; then
srs_define_macro "SRS_AUTO_GPERF_MP" $SRS_AUTO_HEADERS_H
else

0
trunk/auto/depends.sh Normal file → Executable file
View file

View file

@ -36,6 +36,8 @@ SRS_UTEST=RESERVED
SRS_GPERF=RESERVED
# gperf memory check
SRS_GPERF_MC=RESERVED
# gperf memory defence
SRS_GPERF_MD=RESERVED
# gperf memory profile
SRS_GPERF_MP=RESERVED
# gperf cpu profile
@ -130,8 +132,9 @@ Options:
--with-librtmp enable srs-librtmp, library for client.
--with-research build the research tools.
--with-utest build the utest for SRS.
--with-gperf build SRS with gperf tools(no gmc/gmp/gcp, with tcmalloc only).
--with-gperf build SRS with gperf tools(no gmd/gmc/gmp/gcp, with tcmalloc only).
--with-gmc build memory check for SRS with gperf tools.
--with-gmd build memory defense(corrupt memory) for SRS with gperf tools.
--with-gmp build memory profile for SRS with gperf tools.
--with-gcp build cpu profile for SRS with gperf tools.
--with-gprof build SRS with gprof(GNU profile tool).
@ -155,8 +158,9 @@ Options:
--without-librtmp disable srs-librtmp, library for client.
--without-research do not build the research tools.
--without-utest do not build the utest for SRS.
--without-gperf do not build SRS with gperf tools(without tcmalloc and gmc/gmp/gcp).
--without-gperf do not build SRS with gperf tools(without tcmalloc and gmd/gmc/gmp/gcp).
--without-gmc do not build memory check for SRS with gperf tools.
--without-gmd do not build memory defense for SRS with gperf tools.
--without-gmp do not build memory profile for SRS with gperf tools.
--without-gcp do not build cpu profile for SRS with gperf tools.
--without-gprof do not build srs with gprof(GNU profile tool).
@ -241,6 +245,7 @@ function parse_user_option() {
--with-utest) SRS_UTEST=YES ;;
--with-gperf) SRS_GPERF=YES ;;
--with-gmc) SRS_GPERF_MC=YES ;;
--with-gmd) SRS_GPERF_MD=YES ;;
--with-gmp) SRS_GPERF_MP=YES ;;
--with-gcp) SRS_GPERF_CP=YES ;;
--with-gprof) SRS_GPROF=YES ;;
@ -266,6 +271,7 @@ function parse_user_option() {
--without-utest) SRS_UTEST=NO ;;
--without-gperf) SRS_GPERF=NO ;;
--without-gmc) SRS_GPERF_MC=NO ;;
--without-gmd) SRS_GPERF_MD=NO ;;
--without-gmp) SRS_GPERF_MP=NO ;;
--without-gcp) SRS_GPERF_CP=NO ;;
--without-gprof) SRS_GPROF=NO ;;
@ -401,6 +407,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -429,6 +436,7 @@ function apply_user_presets() {
SRS_UTEST=YES
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -457,6 +465,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -485,6 +494,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -513,6 +523,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -533,7 +544,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -541,6 +552,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -562,7 +574,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -570,6 +582,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -590,7 +603,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -598,6 +611,7 @@ function apply_user_presets() {
SRS_UTEST=YES
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -618,7 +632,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -626,6 +640,7 @@ function apply_user_presets() {
SRS_UTEST=YES
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -646,7 +661,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -654,6 +669,7 @@ function apply_user_presets() {
SRS_UTEST=YES
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -674,7 +690,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=NO
@ -682,6 +698,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -702,7 +719,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -710,6 +727,7 @@ function apply_user_presets() {
SRS_UTEST=YES
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -730,7 +748,7 @@ function apply_user_presets() {
SRS_HTTP_CORE=YES
SRS_HTTP_CALLBACK=YES
SRS_HTTP_SERVER=YES
SRS_STREAM_CASTER=NO
SRS_STREAM_CASTER=YES
SRS_KAFKA=YES
SRS_HTTP_API=YES
SRS_LIBRTMP=YES
@ -738,6 +756,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -766,6 +785,7 @@ function apply_user_presets() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -829,6 +849,7 @@ function apply_user_detail_options() {
SRS_UTEST=NO
SRS_GPERF=NO
SRS_GPERF_MC=NO
SRS_GPERF_MD=NO
SRS_GPERF_MP=NO
SRS_GPERF_CP=NO
SRS_GPROF=NO
@ -861,6 +882,7 @@ SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
if [ $SRS_UTEST = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-utest"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-utest"; fi
if [ $SRS_GPERF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gperf"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gperf"; fi
if [ $SRS_GPERF_MC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmc"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmc"; fi
if [ $SRS_GPERF_MD = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmd"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmd"; fi
if [ $SRS_GPERF_MP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmp"; fi
if [ $SRS_GPERF_CP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gcp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gcp"; fi
if [ $SRS_GPROF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gprof"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gprof"; fi
@ -882,6 +904,7 @@ function check_option_conflicts() {
# check conflict
if [ $SRS_GPERF = NO ]; then
if [ $SRS_GPERF_MC = YES ]; then echo "gperf-mc depends on gperf, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MD = YES ]; then echo "gperf-md depends on gperf, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MP = YES ]; then echo "gperf-mp depends on gperf, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_CP = YES ]; then echo "gperf-cp depends on gperf, see: ./configure --help"; __check_ok=NO; fi
fi
@ -897,6 +920,7 @@ function check_option_conflicts() {
# generate the group option: SRS_GPERF
__gperf_slow=NO
if [ $SRS_GPERF_MC = YES ]; then SRS_GPERF=YES; __gperf_slow=YES; fi
if [ $SRS_GPERF_MD = YES ]; then SRS_GPERF=YES; __gperf_slow=YES; fi
if [ $SRS_GPERF_MP = YES ]; then SRS_GPERF=YES; __gperf_slow=YES; fi
if [ $SRS_GPERF_CP = YES ]; then SRS_GPERF=YES; __gperf_slow=YES; fi
if [ $__gperf_slow = YES ]; then if [ $SRS_GPROF = YES ]; then
@ -910,14 +934,24 @@ function check_option_conflicts() {
if [ $SRS_RESEARCH = YES ]; then echo "research for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF = YES ]; then echo "gperf for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MC = YES ]; then echo "gmc for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MD = YES ]; then echo "gmd for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MP = YES ]; then echo "gmp for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_CP = YES ]; then echo "gcp for arm is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPROF = YES ]; then echo "gprof for arm is not available, see: ./configure --help"; __check_ok=NO; fi
fi
# if x86/x64 or directly build, never use static
if [[ $SRS_X86_X64 = YES && $SRS_STATIC = YES ]]; then
echo "x86/x64 should never use static, see: ./configure --help"; __check_ok=NO;
# osx not support gperf.
if [ $SRS_OSX = YES ]; then
if [ $SRS_GPERF = YES ]; then echo "gperf for osx is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MC = YES ]; then echo "gmc for osx is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MD = YES ]; then echo "gmd for osx is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MP = YES ]; then echo "gmp for osx is not available, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_CP = YES ]; then echo "gcp for osx is not available, see: ./configure --help"; __check_ok=NO; fi
fi
# if osx, never use static
if [[ $SRS_OSX = YES && $SRS_STATIC = YES ]]; then
echo "osx should never use static, see: ./configure --help"; __check_ok=NO;
fi
# TODO: FIXME: check more os.
@ -939,6 +973,7 @@ function check_option_conflicts() {
if [ $SRS_UTEST = RESERVED ]; then echo "you must specifies the utest, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF = RESERVED ]; then echo "you must specifies the gperf, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MC = RESERVED ]; then echo "you must specifies the gperf-mc, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MD = RESERVED ]; then echo "you must specifies the gperf-md, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_MP = RESERVED ]; then echo "you must specifies the gperf-mp, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPERF_CP = RESERVED ]; then echo "you must specifies the gperf-cp, see: ./configure --help"; __check_ok=NO; fi
if [ $SRS_GPROF = RESERVED ]; then echo "you must specifies the gprof, see: ./configure --help"; __check_ok=NO; fi

0
trunk/auto/setup_variables.sh Normal file → Executable file
View file

View file

@ -19,6 +19,7 @@ SrsResearchSummaryColor="\${GREEN}{disabled} "; if [ $SRS_RESEARCH = YES ]; then
SrsUtestSummaryColor="\${YELLOW}{disabled} "; if [ $SRS_UTEST = YES ]; then SrsUtestSummaryColor="\${GREEN}"; fi
SrsGperfSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPERF = YES ]; then SrsGperfSummaryColor="\${GREEN}"; fi
SrsGperfMCSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPERF_MC = YES ]; then SrsGperfMCSummaryColor="\${YELLOW}"; fi
SrsGperfMDSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPERF_MD = YES ]; then SrsGperfMDSummaryColor="\${YELLOW}"; fi
SrsGperfMPSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPERF_MP = YES ]; then SrsGperfMPSummaryColor="\${YELLOW}"; fi
SrsGperfCPSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPERF_CP = YES ]; then SrsGperfCPSummaryColor="\${YELLOW}"; fi
SrsGprofSummaryColor="\${GREEN}{disabled} "; if [ $SRS_GPROF = YES ]; then SrsGprofSummaryColor="\${YELLOW}"; fi
@ -37,6 +38,9 @@ BLACK="\\${BLACK}"
echo -e "\${GREEN}build summary:\${BLACK}"
echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
echo -e " |${SrsGperfSummaryColor}gperf @see: https://github.com/ossrs/srs/wiki/v1_CN_GPERF\${BLACK}"
echo -e " | ${SrsGperfMDSummaryColor}gmd @see: http://blog.csdn.net/win_lin/article/details/50461709\${BLACK}"
echo -e " | ${SrsGperfMDSummaryColor}gmd: gperf memory defense, or memory corrupt detect\${BLACK}"
echo -e " | ${SrsGperfMDSummaryColor}env TCMALLOC_PAGE_FENCE=1 ./objs/srs -c conf/console.conf\${BLACK}"
echo -e " | ${SrsGperfMCSummaryColor}gmc @see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html\${BLACK}"
echo -e " | ${SrsGperfMCSummaryColor}gmc: gperf memory check, or memory leak detect\${BLACK}"
echo -e " | ${SrsGperfMCSummaryColor}env PPROF_PATH=./objs/pprof HEAPCHECK=normal ./objs/srs -c conf/console.conf 2>gmc.log # start gmc\${BLACK}"

0
trunk/auto/utest.sh Normal file → Executable file
View file

View file

@ -7,6 +7,9 @@
# for example, 192.168.1.100:1935 10.10.10.100:1935
# where the ip is optional, default to 0.0.0.0, that is 1935 equals to 0.0.0.0:1935
listen 1935;
# change to this dir as the cwd.
# ignore if empty or not configed.
work_dir /usr/local/srs;
# the pid file
# to ensure only one process can use a pid file
# and provides the current running process id, for script,

9
trunk/configure vendored
View file

@ -126,6 +126,7 @@ if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = NO ]; then LibSSLRoot="${SRS
# gperftools-2.1, for mem check and mem/cpu profile
LibGperfRoot=""; LibGperfFile=""
if [ $SRS_GPERF = YES ]; then LibGperfRoot="${SRS_OBJS_DIR}/gperf/include"; LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_and_profiler.a"; fi
if [ $SRS_GPERF_MD = YES ]; then LibGperfFile="${SRS_OBJS_DIR}/gperf/lib/libtcmalloc_debug.a"; fi
# the link options, always use static link
SrsLinkOptions="-ldl";
if [ $SRS_SSL = YES ]; then if [ $SRS_USE_SYS_SSL = YES ]; then SrsLinkOptions="${SrsLinkOptions} -lssl"; fi fi
@ -181,7 +182,8 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
"srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
"srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_kafka")
"srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_kafka"
"srs_app_hourglass")
DEFINES=""
# add each modules for app
for SRS_MODULE in ${SRS_MODULES[*]}; do
@ -608,6 +610,11 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
else
echo -e "${GREEN}note: gmc(gperf memory check) for srs are not builded${BLACK}"
fi
if [ $SRS_GPERF_MD = YES ]; then
echo -e "${YELLOW}gmd(gperf memory defense) for srs are builded -- Performance may suffer${BLACK}"
else
echo -e "${GREEN}note: gmd(gperf memory defense) for srs are not builded${BLACK}"
fi
if [ $SRS_GPERF_MP = YES ]; then
echo -e "${YELLOW}gmp(gperf memory profile) for srs are builded -- Performance may suffer${BLACK}"
else

View file

@ -78,7 +78,7 @@ start() {
if [[ -z $log_file ]]; then
(ulimit -c unlimited && cd ${ROOT}; ${APP} -c ${CONFIG} >/dev/null 2>&1)
else
(ulimit -c unlimited && cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file 2>&1)
(ulimit -c unlimited && cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file.sys 2>&1)
fi
# check again after start server

View file

@ -78,7 +78,7 @@ start() {
if [[ -z $log_file ]]; then
(cd ${ROOT}; ${APP} -c ${CONFIG} >/dev/null 2>&1)
else
(cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file 2>&1)
(cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file.sys 2>&1)
fi
# check again after start server

View file

@ -78,7 +78,7 @@ start() {
if [[ -z $log_file ]]; then
(cd ${ROOT}; ${APP} -c ${CONFIG} >/dev/null 2>&1)
else
(cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file 2>&1)
(cd ${ROOT}; ${APP} -c ${CONFIG} >> $log_file.sys 2>&1)
fi
# check again after start server

View file

@ -75,6 +75,8 @@
3C1232ED1AAEA70F00CE8F6C /* libhttp_parser.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C1232EC1AAEA70F00CE8F6C /* libhttp_parser.a */; };
3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6AC1AB1055800576EE9 /* srs_app_hds.cpp */; };
3C1EE6D71AB1367D00576EE9 /* README.md in Sources */ = {isa = PBXBuildFile; fileRef = 3C1EE6D61AB1367D00576EE9 /* README.md */; };
3C24ECCD1C3B824800460622 /* memory.error.notcmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C24ECCB1C3B824800460622 /* memory.error.notcmalloc.cpp */; };
3C24ECCE1C3B824800460622 /* memory.error.tcmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */; };
3C26E3C61BB146FF00D0F9DB /* srs_app_kafka.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C26E3C41BB146FF00D0F9DB /* srs_app_kafka.cpp */; };
3C28EDDF1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */; };
3C36DB5B1ABD1CB90066CCAF /* srs_lib_bandwidth.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C36DB551ABD1CB90066CCAF /* srs_lib_bandwidth.cpp */; };
@ -103,6 +105,7 @@
3C689FA01AB6AAC800C9CEEE /* stk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9C1AB6AAC800C9CEEE /* stk.c */; };
3C689FA11AB6AAC800C9CEEE /* sync.c in Sources */ = {isa = PBXBuildFile; fileRef = 3C689F9D1AB6AAC800C9CEEE /* sync.c */; };
3C82802C1BAFF8CC004A1794 /* srs_kafka_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C82802A1BAFF8CC004A1794 /* srs_kafka_stack.cpp */; };
3C8CE01E1C3F482100548CC6 /* srs_app_hourglass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */; };
3CB25C2A1BB269FD00C97A63 /* jmp_sp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */; };
3CC52DD81ACE4023006FEB01 /* srs_utest_amf0.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DCA1ACE4023006FEB01 /* srs_utest_amf0.cpp */; };
3CC52DD91ACE4023006FEB01 /* srs_utest_config.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3CC52DCC1ACE4023006FEB01 /* srs_utest_config.cpp */; };
@ -326,6 +329,8 @@
3C1EE6D41AB1367D00576EE9 /* DONATIONS.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = DONATIONS.txt; path = ../../../DONATIONS.txt; sourceTree = "<group>"; };
3C1EE6D51AB1367D00576EE9 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../../LICENSE; sourceTree = "<group>"; };
3C1EE6D61AB1367D00576EE9 /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; name = README.md; path = ../../../README.md; sourceTree = "<group>"; wrapsLines = 0; };
3C24ECCB1C3B824800460622 /* memory.error.notcmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.error.notcmalloc.cpp; path = ../../../research/gperftools/memory.error.notcmalloc.cpp; sourceTree = "<group>"; };
3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = memory.error.tcmalloc.cpp; path = ../../../research/gperftools/memory.error.tcmalloc.cpp; sourceTree = "<group>"; };
3C26E3C41BB146FF00D0F9DB /* srs_app_kafka.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_kafka.cpp; path = ../../../src/app/srs_app_kafka.cpp; sourceTree = "<group>"; };
3C26E3C51BB146FF00D0F9DB /* srs_app_kafka.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_kafka.hpp; path = ../../../src/app/srs_app_kafka.hpp; sourceTree = "<group>"; };
3C28EDDD1AF5C43F00A3AEAC /* srs_app_caster_flv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_caster_flv.cpp; path = ../../../src/app/srs_app_caster_flv.cpp; sourceTree = "<group>"; };
@ -374,6 +379,8 @@
3C8280291BAFF896004A1794 /* transform.edge.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = transform.edge.conf; path = ../../../conf/transform.edge.conf; sourceTree = "<group>"; };
3C82802A1BAFF8CC004A1794 /* srs_kafka_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_kafka_stack.cpp; path = ../../../src/protocol/srs_kafka_stack.cpp; sourceTree = "<group>"; };
3C82802B1BAFF8CC004A1794 /* srs_kafka_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_kafka_stack.hpp; path = ../../../src/protocol/srs_kafka_stack.hpp; sourceTree = "<group>"; };
3C8CE01C1C3F482100548CC6 /* srs_app_hourglass.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_hourglass.hpp; path = ../../../src/app/srs_app_hourglass.hpp; sourceTree = "<group>"; };
3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_hourglass.cpp; path = ../../../src/app/srs_app_hourglass.cpp; sourceTree = "<group>"; };
3CB25C281BB2596300C97A63 /* setup_variables.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = setup_variables.sh; path = ../../../auto/setup_variables.sh; sourceTree = "<group>"; };
3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jmp_sp.cpp; path = ../../../research/arm/jmp_sp.cpp; sourceTree = "<group>"; };
3CC52DCA1ACE4023006FEB01 /* srs_utest_amf0.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_utest_amf0.cpp; path = ../../src/utest/srs_utest_amf0.cpp; sourceTree = "<group>"; };
@ -444,6 +451,7 @@
3C1232041AAE80CB00CE8F6C /* main */,
3C1231F91AAE670E00CE8F6C /* objs */,
3C1232BA1AAE826F00CE8F6C /* auto */,
3C96ADC41B00A71000885304 /* modules */,
3C1232B91AAE825100CE8F6C /* scripts */,
3C1EE6AF1AB107EE00576EE9 /* conf */,
3C36DB541ABD1CA70066CCAF /* libs */,
@ -581,6 +589,8 @@
3C12325F1AAE81D900CE8F6C /* srs_app_heartbeat.hpp */,
3C1232601AAE81D900CE8F6C /* srs_app_hls.cpp */,
3C1232611AAE81D900CE8F6C /* srs_app_hls.hpp */,
3C8CE01D1C3F482100548CC6 /* srs_app_hourglass.cpp */,
3C8CE01C1C3F482100548CC6 /* srs_app_hourglass.hpp */,
3C1232621AAE81D900CE8F6C /* srs_app_http_api.cpp */,
3C1232631AAE81D900CE8F6C /* srs_app_http_api.hpp */,
3C1232641AAE81D900CE8F6C /* srs_app_http_client.cpp */,
@ -782,6 +792,8 @@
isa = PBXGroup;
children = (
3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */,
3C24ECCB1C3B824800460622 /* memory.error.notcmalloc.cpp */,
3C24ECCC1C3B824800460622 /* memory.error.tcmalloc.cpp */,
3C663F021AB0155100286D8B /* srs_aac_raw_publish.c */,
3C663F031AB0155100286D8B /* srs_audio_raw_publish.c */,
3C663F041AB0155100286D8B /* srs_bandwidth_check.c */,
@ -816,6 +828,14 @@
name = "st-1.9";
sourceTree = "<group>";
};
3C96ADC41B00A71000885304 /* modules */ = {
isa = PBXGroup;
children = (
3C24ECCA1C3A42D800460622 /* readme.txt */,
);
name = modules;
sourceTree = "<group>";
};
3CC52DC91ACE4006006FEB01 /* utest */ = {
isa = PBXGroup;
children = (
@ -904,6 +924,7 @@
3C663F171AB0155100286D8B /* srs_ingest_rtmp.c in Sources */,
3C26E3C61BB146FF00D0F9DB /* srs_app_kafka.cpp in Sources */,
3C663F131AB0155100286D8B /* srs_flv_injecter.c in Sources */,
3C24ECCD1C3B824800460622 /* memory.error.notcmalloc.cpp in Sources */,
3C1232971AAE81D900CE8F6C /* srs_app_dvr.cpp in Sources */,
3CD247C31BB3F14100DC1922 /* srs_kernel_balance.cpp in Sources */,
3C1232271AAE814D00CE8F6C /* srs_kernel_log.cpp in Sources */,
@ -928,6 +949,7 @@
3CC52DDA1ACE4023006FEB01 /* srs_utest_core.cpp in Sources */,
3C36DB5C1ABD1CB90066CCAF /* srs_lib_simple_socket.cpp in Sources */,
3C1232201AAE814D00CE8F6C /* srs_kernel_aac.cpp in Sources */,
3C8CE01E1C3F482100548CC6 /* srs_app_hourglass.cpp in Sources */,
3C1232941AAE81D900CE8F6C /* srs_app_bandwidth.cpp in Sources */,
3C1232221AAE814D00CE8F6C /* srs_kernel_codec.cpp in Sources */,
3C1232B71AAE81D900CE8F6C /* srs_app_utility.cpp in Sources */,
@ -958,6 +980,7 @@
3C689F9F1AB6AAC800C9CEEE /* sched.c in Sources */,
3C1232061AAE812C00CE8F6C /* srs_main_server.cpp in Sources */,
3C1232281AAE814D00CE8F6C /* srs_kernel_mp3.cpp in Sources */,
3C24ECCE1C3B824800460622 /* memory.error.tcmalloc.cpp in Sources */,
3C1232B21AAE81D900CE8F6C /* srs_app_source.cpp in Sources */,
3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */,
3CC52DD81ACE4023006FEB01 /* srs_utest_amf0.cpp in Sources */,

View file

@ -0,0 +1,16 @@
/**
g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc
*/
#include <unistd.h>
#include <string.h>
#include <stdio.h>
void foo(char* p){
memcpy(p, "01234567890abcdef", 16);
}
int main(int argc, char** argv){
char* p = new char[10];
foo(p);
printf("p=%s\n", p);
return 0;
}

View file

@ -0,0 +1,16 @@
/**
g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc
*/
#include <unistd.h>
#include <string.h>
#include <stdio.h>
void foo(char* p){
memcpy(p, "01234567890abcdef", 16);
}
int main(int argc, char** argv){
char* p = new char[10];
foo(p);
printf("p=%s\n", p);
return 0;
}

View file

@ -26,6 +26,7 @@ gcc srs_detect_rtmp.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_detect
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../objs/include/srs_librtmp.h"
@ -41,8 +42,6 @@ int main(int argc, char** argv)
int64_t time_play_stream = 0;
int64_t time_first_packet = 0;
int64_t time_cleanup = 0;
// delay = actual - expect time when quit.
int delay = 0;
// bytes
int64_t bytes_nsend = 0;
int time_duration = 0;
@ -59,6 +58,7 @@ int main(int argc, char** argv)
const char* rtmp_url = NULL;
int duration = 0;
int timeout = 0;
enum srs_url_schema sus;
printf("detect rtmp stream\n");
printf("srs(ossrs) client librtmp library.\n");
@ -66,12 +66,17 @@ int main(int argc, char** argv)
if (argc <= 3) {
printf("detect stream on RTMP server, print result to stderr.\n"
"Usage: %s <rtmp_url> <duration> <timeout>\n"
"Usage: %s <rtmp_url> <duration> <timeout> [url_schema]\n"
" rtmp_url RTMP stream url to play\n"
" duration how long to play, in seconds, stream time.\n"
" timeout how long to timeout, in seconds, system time.\n"
" url_schema the schema of url, default to vis, can be:\n"
" normal: rtmp://vhost:port/app/stream\n"
" via : rtmp://ip:port/vhost/app/stream\n"
" vis : rtmp://ip:port/app/stream?vhost=xxx\n"
" vis2 : rtmp://ip:port/app/stream?domain=xxx\n"
"For example:\n"
" %s rtmp://127.0.0.1:1935/live/livestream 3 10\n",
" %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n",
argv[0], argv[0]);
exit(-1);
}
@ -79,15 +84,36 @@ int main(int argc, char** argv)
rtmp_url = argv[1];
duration = atoi(argv[2]);
timeout = atoi(argv[3]);
if (1) {
char *p = "vis";
if (argc > 4) {
p = argv[4];
}
if (strcmp(p, "normal") == 0) {
sus = srs_url_schema_normal;
} else if (strcmp(p, "via") == 0) {
sus = srs_url_schema_via;
} else if (strcmp(p, "vis") == 0) {
sus = srs_url_schema_vis;
} else if (strcmp(p, "vis2") == 0){
sus = srs_url_schema_vis2;
} else {
srs_human_trace("url_schema must be normal/via/vis/vis2");
exit(-2);
}
srs_human_trace("url schema: %s", p);
}
srs_human_trace("rtmp url: %s", rtmp_url);
srs_human_trace("duration: %ds, timeout:%ds", duration, timeout);
if (duration <= 0 || timeout <= 0) {
srs_human_trace("duration and timeout must be positive.");
exit(-2);
exit(-3);
}
rtmp = srs_rtmp_create(rtmp_url);
if ((ret = srs_rtmp_dns_resolve(rtmp)) != 0) {
@ -109,8 +135,8 @@ int main(int argc, char** argv)
goto rtmp_destroy;
}
srs_human_trace("do simple handshake success");
if ((ret = srs_rtmp_connect_app(rtmp)) != 0) {
if ((ret = srs_rtmp_connect_app3(rtmp, sus)) != 0) {
srs_human_trace("connect vhost/app failed. ret=%d", ret);
goto rtmp_destroy;
}

View file

@ -234,7 +234,6 @@ int main(int argc, char** argv)
goto rtmp_destroy;
}
if (srs_rtmp_connect_app2(rtmp,
srs_server_ip, srs_server, srs_primary, srs_authors, srs_version,
&srs_id, &srs_pid) != 0) {

View file

@ -1905,11 +1905,6 @@ int SrsConfig::parse_options(int argc, char** argv)
}
}
// cwd
char cwd[256];
getcwd(cwd, sizeof(cwd));
_cwd = cwd;
// config
show_help = true;
for (int i = 1; i < argc; i++) {
@ -1987,6 +1982,18 @@ int SrsConfig::parse_options(int argc, char** argv)
return ret;
}
int SrsConfig::initialize_cwd()
{
int ret = ERROR_SUCCESS;
// cwd
char cwd[256];
getcwd(cwd, sizeof(cwd));
_cwd = cwd;
return ret;
}
int SrsConfig::persistence()
{
int ret = ERROR_SUCCESS;
@ -3529,7 +3536,7 @@ int SrsConfig::check_config()
&& n != "max_connections" && n != "daemon" && n != "heartbeat"
&& n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms"
&& n != "http_server" && n != "stream_caster" && n != "kafka"
&& n != "utc_time"
&& n != "utc_time" && n != "work_dir"
) {
ret = ERROR_SYSTEM_CONFIG_INVALID;
srs_error("unsupported directive %s, ret=%d", n.c_str(), ret);
@ -4179,6 +4186,17 @@ bool SrsConfig::get_utc_time()
return SRS_CONF_PERFER_FALSE(conf->arg0());
}
string SrsConfig::get_work_dir() {
static string DEFAULT = "";
SrsConfDirective* conf = root->get("work_dir");
if( !conf || conf->arg0().empty()) {
return DEFAULT;
}
return conf->arg0();
}
vector<SrsConfDirective*> SrsConfig::get_stream_casters()
{
srs_assert(root);

View file

@ -416,6 +416,11 @@ public:
* parse the cli, the main(argc,argv) function.
*/
virtual int parse_options(int argc, char** argv);
/**
* initialize the cwd for server,
* because we may change the workdir.
*/
virtual int initialize_cwd();
/**
* persistence current config to file.
*/
@ -607,6 +612,11 @@ public:
* whether use utc-time to format the time.
*/
virtual bool get_utc_time();
/**
* get the configed work dir.
* ignore if empty string.
*/
virtual std::string get_work_dir();
// stream_caster section
public:
/**

View file

@ -0,0 +1,86 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2016 SRS(ossrs)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <srs_app_hourglass.hpp>
using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_app_st.hpp>
#include <srs_kernel_log.hpp>
ISrsHourGlass::ISrsHourGlass()
{
}
ISrsHourGlass::~ISrsHourGlass()
{
}
SrsHourGlass::SrsHourGlass(ISrsHourGlass* h, int resolution_ms)
{
handler = h;
resolution = resolution_ms;
total_elapse = 0;
}
SrsHourGlass::~SrsHourGlass()
{
}
int SrsHourGlass::tick(int type, int interval)
{
int ret = ERROR_SUCCESS;
if (resolution > 0 && (interval % resolution) != 0) {
ret = ERROR_SYSTEM_HOURGLASS_RESOLUTION;
srs_error("hourglass interval=%d invalid, resolution=%d. ret=%d", interval, resolution, ret);
return ret;
}
ticks[type] = interval;
return ret;
}
int SrsHourGlass::cycle()
{
int ret = ERROR_SUCCESS;
map<int, int>::iterator it;
for (it = ticks.begin(); it != ticks.end(); ++it) {
int type = it->first;
int interval = it->second;
if (interval == 0 || (total_elapse % interval) == 0) {
if ((ret = handler->notify(type, interval, total_elapse)) != ERROR_SUCCESS) {
return ret;
}
}
}
total_elapse += resolution;
st_usleep(resolution * 1000);
return ret;
}

View file

@ -0,0 +1,101 @@
/*
The MIT License (MIT)
Copyright (c) 2013-2016 SRS(ossrs)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SRS_APP_HOURGLASS_HPP
#define SRS_APP_HOURGLASS_HPP
/*
#include <srs_app_hourglass.hpp>
*/
#include <srs_core.hpp>
#include <map>
/**
* the handler for the tick.
*/
class ISrsHourGlass
{
public:
ISrsHourGlass();
virtual ~ISrsHourGlass();
public:
/**
* notify the handler, the type and tick.
*/
virtual int notify(int type, int interval, int64_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, 1000);
* hg->tick(1, 3000);
* hg->tick(2, 5000);
* hg->tick(3, 7000);
* // create a thread to cycle, which will call handerl when ticked.
* while (true) {
* hg->cycle();
* }
*/
class SrsHourGlass
{
private:
ISrsHourGlass* handler;
int resolution;
// key: the type of tick.
// value: the interval of tick.
std::map<int, int> ticks;
// the total elapsed time,
// for each cycle, we increase it with a resolution.
int64_t total_elapse;
public:
SrsHourGlass(ISrsHourGlass* h, int resolution_ms);
virtual ~SrsHourGlass();
public:
// add a pair of tick(type, interval).
// @param type the type of tick.
// @param interval the interval in ms of tick.
virtual int tick(int type, int interval);
public:
// cycle the hourglass, which will sleep resolution every time.
// and call handler when ticked.
virtual int cycle();
};
#endif

View file

@ -41,6 +41,9 @@ using namespace std;
#include <srs_kernel_log.hpp>
#include <srs_app_config.hpp>
#include <srs_app_utility.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_app_utility.hpp>
SrsProcess::SrsProcess()
{
@ -53,6 +56,11 @@ SrsProcess::~SrsProcess()
{
}
int SrsProcess::get_pid()
{
return pid;
}
bool SrsProcess::started()
{
return is_started;
@ -64,39 +72,66 @@ int SrsProcess::initialize(string binary, vector<string> argv)
bin = binary;
cli = "";
actual_cli = "";
params.clear();
for (int i = 0; i < (int)argv.size(); i++) {
std::string ffp = argv[i];
cli += ffp;
if (i < (int)argv.size() - 1) {
cli += " ";
}
}
for (int i = 0; i < (int)argv.size(); i++) {
std::string ffp = argv[i];
std::string nffp = (i < (int)argv.size() -1)? argv[i + 1] : "";
std::string nffp = (i < (int)argv.size() - 1)? argv[i + 1] : "";
std::string nnffp = (i < (int)argv.size() - 2)? argv[i + 2] : "";
// remove the stdout and stderr.
if (ffp == "1" && nffp == ">") {
if (i + 2 < (int)argv.size()) {
stdout_file = argv[i + 2];
i += 2;
}
continue;
} else if (ffp == "2" && nffp == ">") {
if (i + 2 < (int)argv.size()) {
stderr_file = argv[i + 2];
i += 2;
}
// 1>file
if (srs_string_starts_with(ffp, "1>")) {
stdout_file = ffp.substr(2);
continue;
}
// 2>file
if (srs_string_starts_with(ffp, "2>")) {
stderr_file = ffp.substr(2);
continue;
}
// 1 >X
if (ffp == "1" && srs_string_starts_with(nffp, ">")) {
if (nffp == ">") {
// 1 > file
if (!nnffp.empty()) {
stderr_file = nnffp;
i++;
}
} else {
// 1 >file
stdout_file = srs_string_trim_start(nffp, ">");
}
// skip the >
i++;
continue;
}
// 2 >X
if (ffp == "2" && srs_string_starts_with(nffp, ">")) {
if (nffp == ">") {
// 2 > file
if (!nnffp.empty()) {
stderr_file = nnffp;
i++;
}
} else {
// 2 >file
stderr_file = srs_string_trim_start(nffp, ">");
}
// skip the >
i++;
continue;
}
// startup params.
params.push_back(ffp);
}
actual_cli = srs_join_vector_string(params, " ");
cli = srs_join_vector_string(argv, " ");
return ret;
}
@ -109,7 +144,7 @@ int SrsProcess::start()
}
// generate the argv of process.
srs_trace("fork process: %s", cli.c_str());
srs_info("fork process: %s", cli.c_str());
// for log
int cid = _srs_context->get_id();
@ -118,11 +153,12 @@ int SrsProcess::start()
// TODO: fork or vfork?
if ((pid = fork()) < 0) {
ret = ERROR_ENCODER_FORK;
srs_error("vfork process failed. ret=%d", ret);
srs_error("vfork process failed, cli=%s. ret=%d", cli.c_str(), ret);
return ret;
}
// for osx(lldb) to debug the child process.
// user can use "lldb -p <pid>" to resume the parent or child process.
//kill(0, SIGSTOP);
// child process: ffmpeg encoder engine.
@ -176,6 +212,7 @@ int SrsProcess::start()
fprintf(stderr, "process parent cid=%d\n", cid);
fprintf(stderr, "process binary=%s\n", bin.c_str());
fprintf(stderr, "process cli: %s\n", cli.c_str());
fprintf(stderr, "process actual cli: %s\n", actual_cli.c_str());
}
// close other fds
@ -204,7 +241,8 @@ int SrsProcess::start()
// parent.
if (pid > 0) {
is_started = true;
srs_trace("vfored process, pid=%d, bin=%s", pid, bin.c_str());
srs_trace("fored process, pid=%d, bin=%s, stdout=%s, stderr=%s, argv=%s",
pid, bin.c_str(), stdout_file.c_str(), stdout_file.c_str(), actual_cli.c_str());
return ret;
}
@ -238,7 +276,7 @@ int SrsProcess::cycle()
return ret;
}
srs_trace("process pid=%d terminate, restart it.", pid);
srs_trace("process pid=%d terminate, please restart it.", pid);
is_started = false;
return ret;

View file

@ -61,10 +61,15 @@ private:
std::vector<std::string> params;
// the cli to fork process.
std::string cli;
std::string actual_cli;
public:
SrsProcess();
virtual ~SrsProcess();
public:
/**
* get pid of process.
*/
virtual int get_pid();
/**
* whether process is already started.
*/
@ -73,6 +78,7 @@ public:
* 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 int initialize(std::string binary, std::vector<std::string> argv);
public:

View file

@ -959,6 +959,7 @@ int SrsServer::do_cycle()
#endif
// the deamon thread, update the time cache
// TODO: FIXME: use SrsHourGlass.
while (true) {
if (handler && (ret = handler->on_cycle()) != ERROR_SUCCESS) {
srs_error("cycle handle failed. ret=%d", ret);

View file

@ -1270,6 +1270,66 @@ vector<string>& srs_get_local_ipv4_ips()
return _srs_system_ipv4_ips;
}
std::string _public_internet_address;
string srs_get_public_internet_address()
{
if (!_public_internet_address.empty()) {
return _public_internet_address;
}
std::vector<std::string>& ips = srs_get_local_ipv4_ips();
// find the best match public address.
for (int i = 0; i < (int)ips.size(); i++) {
std::string ip = ips[i];
in_addr_t addr = inet_addr(ip.c_str());
u_int32_t addr_h = ntohl(addr);
// lo, 127.0.0.0-127.0.0.1
if (addr_h >= 0x7f000000 && addr_h <= 0x7f000001) {
srs_trace("ignore private address: %s", ip.c_str());
continue;
}
// Class A 10.0.0.0-10.255.255.255
if (addr_h >= 0x0a000000 && addr_h <= 0x0affffff) {
srs_trace("ignore private address: %s", ip.c_str());
continue;
}
// Class B 172.16.0.0-172.31.255.255
if (addr_h >= 0xac100000 && addr_h <= 0xac1fffff) {
srs_trace("ignore private address: %s", ip.c_str());
continue;
}
// Class C 192.168.0.0-192.168.255.255
if (addr_h >= 0xc0a80000 && addr_h <= 0xc0a8ffff) {
srs_trace("ignore private address: %s", ip.c_str());
continue;
}
srs_warn("use public address as ip: %s", ip.c_str());
_public_internet_address = ip;
return ip;
}
// no public address, use private address.
for (int i = 0; i < (int)ips.size(); i++) {
std::string ip = ips[i];
in_addr_t addr = inet_addr(ip.c_str());
u_int32_t addr_h = ntohl(addr);
// lo, 127.0.0.0-127.0.0.1
if (addr_h >= 0x7f000000 && addr_h <= 0x7f000001) {
srs_trace("ignore private address: %s", ip.c_str());
continue;
}
srs_warn("use private address as ip: %s", ip.c_str());
_public_internet_address = ip;
return ip;
}
return "";
}
string srs_get_local_ip(int fd)
{
std::string ip;
@ -1347,6 +1407,11 @@ bool srs_string_is_http(string url)
return srs_string_starts_with(url, "http://", "https://");
}
bool srs_string_is_rtmp(string url)
{
return srs_string_starts_with(url, "rtmp://");
}
bool srs_is_digit_number(const string& str)
{
if (str.empty()) {

View file

@ -664,6 +664,7 @@ extern std::string srs_get_peer_ip(int fd);
// 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);
// whether string is digit number
// is_digit("1234567890") === true

View file

@ -45,12 +45,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
// debug info.
#define RTMP_SIG_SRS_ROLE "cluster"
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)"
#define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Stream Media Server)"
#define RTMP_SIG_SRS_URL_SHORT "github.com/ossrs/srs"
#define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
#define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2016 SRS(ossrs)"
#define RTMP_SIG_SRS_PRIMARY "SRS/"VERSION_STABLE_BRANCH
#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2016 "RTMP_SIG_SRS_KEY"("RTMP_SIG_SRS_AUTHROS")"
#define RTMP_SIG_SRS_PRIMARY RTMP_SIG_SRS_KEY"/"VERSION_STABLE_BRANCH
#define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt"
#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY"("RTMP_SIG_SRS_VERSION")"
#define RTMP_SIG_SRS_RELEASE RTMP_SIG_SRS_URL"/tree/"VERSION_STABLE_BRANCH".0release"

View file

@ -188,5 +188,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#undef SRS_PERF_FAST_FLV_ENCODER
#define SRS_PERF_FAST_FLV_ENCODER
/**
* whether ensure glibc memory check.
*/
#undef SRS_PERF_GLIBC_MEMORY_CHECK
#define SRS_PERF_GLIBC_MEMORY_CHECK
#endif

View file

@ -103,6 +103,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED 1062
#define ERROR_SYSTEM_CONFIG_RAW_PARAMS 1063
#define ERROR_SYSTEM_FILE_NOT_EXISTS 1064
#define ERROR_SYSTEM_HOURGLASS_RESOLUTION 1065
///////////////////////////////////////////////////////
// RTMP protocol error.

View file

@ -467,6 +467,8 @@ int srs_librtmp_context_parse_uri(Context* context)
std::string schema;
srs_parse_rtmp_url(context->url, context->tcUrl, context->stream);
// when connect, we only need to parse the tcUrl
srs_discovery_tc_url(context->tcUrl,
schema, context->host, context->vhost, context->app, context->port,
context->param);
@ -688,11 +690,11 @@ int srs_rtmp_connect_app(srs_rtmp_t rtmp)
srs_assert(rtmp != NULL);
Context* context = (Context*)rtmp;
string tcUrl = srs_generate_tc_url(
context->ip, context->vhost, context->app, context->port,
context->param
);
context->ip, context->vhost, context->app, context->port,
context->param
);
if ((ret = context->rtmp->connect_app(
context->app, tcUrl, context->req, true)) != ERROR_SUCCESS)
@ -742,6 +744,38 @@ int srs_rtmp_connect_app2(srs_rtmp_t rtmp,
return ret;
}
int srs_rtmp_connect_app3(srs_rtmp_t rtmp, enum srs_url_schema sus)
{
int ret = ERROR_SUCCESS;
srs_assert(rtmp != NULL);
Context* context = (Context*)rtmp;
string tcUrl;
switch(sus) {
case srs_url_schema_normal:
tcUrl=srs_generate_normal_tc_url(context->ip, context->vhost, context->app, context->port);
break;
case srs_url_schema_via:
tcUrl=srs_generate_via_tc_url(context->ip, context->vhost, context->app, context->port);
break;
case srs_url_schema_vis:
case srs_url_schema_vis2:
tcUrl=srs_generate_vis_tc_url(context->ip, context->vhost, context->app, context->port);
break;
default:
break;
}
if ((ret = context->rtmp->connect_app(
context->app, tcUrl, context->req, true)) != ERROR_SUCCESS)
{
return ret;
}
return ret;
}
int srs_rtmp_play_stream(srs_rtmp_t rtmp)
{
int ret = ERROR_SUCCESS;

View file

@ -68,6 +68,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern "C"{
#endif
/**
* the schema of url, now bravo support 4 kinds of url:
* srs_url_schema_normal: rtmp://vhost:port/app/stream
* srs_url_schema_via : rtmp://ip:port/vhost/app/stream
* srs_url_schema_vis : rtmp://ip:port/app/stream?vhost=xxx
* srs_url_schema_vis2 : rtmp://ip:port/app/stream?domain=xxx
*/
enum srs_url_schema{
srs_url_schema_normal = 0,
srs_url_schema_via,
srs_url_schema_vis,
srs_url_schema_vis2
};
// typedefs
typedef int srs_bool;
@ -187,6 +201,16 @@ extern int srs_rtmp_connect_app2(srs_rtmp_t rtmp,
char srs_version[32], int* srs_id, int* srs_pid
);
/**
* connect to rtmp vhost/app
* category: publish/play
* previous: handshake
* next: publish or play
*
* @return 0, success; otherswise, failed.
*/
extern int srs_rtmp_connect_app3(srs_rtmp_t rtmp, enum srs_url_schema sus);
/**
* play a live/vod stream.
* category: play

View file

@ -261,7 +261,17 @@ int main(int argc, char** argv)
if ((ret = _srs_config->parse_options(argc, argv)) != ERROR_SUCCESS) {
return ret;
}
// change the work dir and set cwd.
string cwd = _srs_config->get_work_dir();
if (!cwd.empty() && (ret = chdir(cwd.c_str())) != ERROR_SUCCESS) {
srs_error("change cwd to %s failed. ret=%d", cwd.c_str(), ret);
return ret;
}
if ((ret = _srs_config->initialize_cwd()) != ERROR_SUCCESS) {
return ret;
}
// config parsed, initialize log.
if ((ret = _srs_log->initialize()) != ERROR_SUCCESS) {
return ret;
@ -277,6 +287,24 @@ int main(int argc, char** argv)
#ifdef SRS_AUTO_EMBEDED_TOOL_CHAIN
srs_trace("crossbuild tool chain: "SRS_AUTO_EMBEDED_TOOL_CHAIN);
#endif
srs_trace("cwd=%s, work_dir=%s", _srs_config->cwd().c_str(), cwd.c_str());
#ifdef SRS_PERF_GLIBC_MEMORY_CHECK
// ensure glibc write error to stderr.
setenv("LIBC_FATAL_STDERR_", "1", 1);
// ensure glibc to do alloc check.
setenv("MALLOC_CHECK_", "1", 1);
srs_trace("env MALLOC_CHECK_=1 LIBC_FATAL_STDERR_=1");
#endif
#ifdef SRS_AUTO_GPERF_MD
char* TCMALLOC_PAGE_FENCE = getenv("TCMALLOC_PAGE_FENCE");
if (!TCMALLOC_PAGE_FENCE || strcmp(TCMALLOC_PAGE_FENCE, "1")) {
srs_trace("gmd enabled without env TCMALLOC_PAGE_FENCE=1");
} else {
srs_trace("env TCMALLOC_PAGE_FENCE=1");
}
#endif
// we check the config when the log initialized.
if ((ret = _srs_config->check_config()) != ERROR_SUCCESS) {

View file

@ -149,11 +149,28 @@ string srs_generate_tc_url(string ip, string vhost, string app, int port, string
tcUrl += "/";
tcUrl += app;
tcUrl += param;
if (!param.empty()) {
tcUrl += "?" + param;
}
return tcUrl;
}
string srs_generate_normal_tc_url(string ip, string vhost, string app, int port)
{
return "rtmp://" + vhost + ":" + srs_int2str(port) + "/" + app;
}
string srs_generate_via_tc_url(string ip, string vhost, string app, int port)
{
return "rtmp://" + ip + ":" + srs_int2str(port) + "/" + vhost + "/" + app;
}
string srs_generate_vis_tc_url(string ip, string vhost, string app, int port)
{
return "rtmp://" + ip + ":" + srs_int2str(port) + "/" + app;
}
/**
* compare the memory in bytes.
*/
@ -179,18 +196,19 @@ bool srs_bytes_equals(void* pa, void* pb, int size)
return true;
}
int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg)
template<typename T>
int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, T** ppmsg)
{
int ret = ERROR_SUCCESS;
*ppmsg = NULL;
SrsSharedPtrMessage* msg = NULL;
T* msg = NULL;
if (type == SrsCodecFlvTagAudio) {
SrsMessageHeader header;
header.initialize_audio(size, timestamp, stream_id);
msg = new SrsSharedPtrMessage();
msg = new T();
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
srs_freep(msg);
return ret;
@ -199,7 +217,7 @@ int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size,
SrsMessageHeader header;
header.initialize_video(size, timestamp, stream_id);
msg = new SrsSharedPtrMessage();
msg = new T();
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
srs_freep(msg);
return ret;
@ -208,7 +226,7 @@ int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size,
SrsMessageHeader header;
header.initialize_amf0_script(size, stream_id);
msg = new SrsSharedPtrMessage();
msg = new T();
if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) {
srs_freep(msg);
return ret;
@ -237,6 +255,19 @@ int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, in
return ret;
}
int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsCommonMessage** ppmsg)
{
int ret = ERROR_SUCCESS;
// only when failed, we must free the data.
if ((ret = srs_do_rtmp_create_msg(type, timestamp, data, size, stream_id, ppmsg)) != ERROR_SUCCESS) {
srs_freepa(data);
return ret;
}
return ret;
}
string srs_generate_stream_url(string vhost, string app, string stream)
{
std::string url = "";
@ -334,3 +365,20 @@ string srs_join_vector_string(vector<string>& vs, string separator)
return str;
}
bool srs_is_ipv4(string domain)
{
for (int i = 0; i < (int)domain.length(); i++) {
char ch = domain.at(i);
if (ch == '.') {
continue;
}
if (ch >= '0' && ch <= '9') {
continue;
}
return false;
}
return true;
}

View file

@ -36,11 +36,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string>
#include <vector>
#include <map>
#include <srs_kernel_consts.hpp>
class SrsMessageHeader;
class SrsSharedPtrMessage;
class SrsCommonMessage;
class ISrsProtocolReaderWriter;
/**
@ -62,6 +64,10 @@ extern void srs_discovery_tc_url(
std::string& app, int& port, std::string& param
);
// parse query string to map(k,v).
// must format as key=value&...&keyN=valueN
extern void srs_parse_query_string(std::string q, std::map<std::string, std::string>& query);
/**
* generate ramdom data for handshake.
*/
@ -79,6 +85,24 @@ extern std::string srs_generate_tc_url(
std::string param
);
/**
* srs_detect_tools generate the normal tcUrl
*/
extern std::string srs_generate_normal_tc_url(
std::string ip, std::string vhost, std::string app, int port);
/**
* srs_detect_tools generate the normal tcUrl
*/
extern std::string srs_generate_via_tc_url(
std::string ip, std::string vhost, std::string app, int port);
/**
* srs_detect_tools generate the vis/vis2 tcUrl
*/
extern std::string srs_generate_vis_tc_url(
std::string ip, std::string vhost, std::string app, int port);
/**
* compare the memory in bytes.
* @return true if completely equal; otherwise, false.
@ -94,6 +118,10 @@ extern int srs_rtmp_create_msg(
char type, u_int32_t timestamp, char* data, int size, int stream_id,
SrsSharedPtrMessage** ppmsg
);
extern int srs_rtmp_create_msg(
char type, u_int32_t timestamp, char* data, int size, int stream_id,
SrsCommonMessage** ppmsg
);
// get the stream identify, vhost/app/stream.
extern std::string srs_generate_stream_url(