From f1e7e9d933b6f34c5de32b4ae6ea9f1039302920 Mon Sep 17 00:00:00 2001 From: winlin Date: Fri, 8 Jan 2016 13:58:19 +0800 Subject: [PATCH] support gmd. change work_dir. hourglass. add utilies. --- trunk/auto/auto_headers.sh | 5 + trunk/auto/depends.sh | 0 trunk/auto/options.sh | 61 ++++++++--- trunk/auto/setup_variables.sh | 0 trunk/auto/summary.sh | 4 + trunk/auto/utest.sh | 0 trunk/conf/full.conf | 3 + trunk/configure | 9 +- trunk/etc/init.d/srs | 2 +- trunk/etc/init.d/srs-demo | 2 +- trunk/etc/init.d/srs-demo-19350 | 2 +- .../srs_xcode.xcodeproj/project.pbxproj | 23 ++++ .../gperftools/memory.error.notcmalloc.cpp | 16 +++ .../gperftools/memory.error.tcmalloc.cpp | 16 +++ trunk/research/librtmp/srs_detect_rtmp.c | 44 ++++++-- trunk/research/librtmp/srs_rtmp_dump.c | 1 - trunk/src/app/srs_app_config.cpp | 30 ++++-- trunk/src/app/srs_app_config.hpp | 10 ++ trunk/src/app/srs_app_hourglass.cpp | 86 +++++++++++++++ trunk/src/app/srs_app_hourglass.hpp | 101 ++++++++++++++++++ trunk/src/app/srs_app_process.cpp | 90 +++++++++++----- trunk/src/app/srs_app_process.hpp | 6 ++ trunk/src/app/srs_app_server.cpp | 1 + trunk/src/app/srs_app_utility.cpp | 65 +++++++++++ trunk/src/app/srs_app_utility.hpp | 1 + trunk/src/core/srs_core.hpp | 6 +- trunk/src/core/srs_core_performance.hpp | 6 ++ trunk/src/kernel/srs_kernel_error.hpp | 1 + trunk/src/libs/srs_librtmp.cpp | 42 +++++++- trunk/src/libs/srs_librtmp.hpp | 24 +++++ trunk/src/main/srs_main_server.cpp | 30 +++++- trunk/src/protocol/srs_protocol_utility.cpp | 60 +++++++++-- trunk/src/protocol/srs_protocol_utility.hpp | 28 +++++ 33 files changed, 702 insertions(+), 73 deletions(-) mode change 100644 => 100755 trunk/auto/depends.sh mode change 100644 => 100755 trunk/auto/setup_variables.sh mode change 100644 => 100755 trunk/auto/utest.sh create mode 100644 trunk/research/gperftools/memory.error.notcmalloc.cpp create mode 100644 trunk/research/gperftools/memory.error.tcmalloc.cpp create mode 100644 trunk/src/app/srs_app_hourglass.cpp create mode 100644 trunk/src/app/srs_app_hourglass.hpp diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index 4fa2ecd9a..25db5e6c8 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -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 diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh old mode 100644 new mode 100755 diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index 3111c7b03..fe13f19ca 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -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 diff --git a/trunk/auto/setup_variables.sh b/trunk/auto/setup_variables.sh old mode 100644 new mode 100755 diff --git a/trunk/auto/summary.sh b/trunk/auto/summary.sh index 0d34fbb72..ba375eca9 100755 --- a/trunk/auto/summary.sh +++ b/trunk/auto/summary.sh @@ -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}" diff --git a/trunk/auto/utest.sh b/trunk/auto/utest.sh old mode 100644 new mode 100755 diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index f0f3ca74c..2b0790186 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -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, diff --git a/trunk/configure b/trunk/configure index 6052f4b2e..df5ca6720 100755 --- a/trunk/configure +++ b/trunk/configure @@ -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 diff --git a/trunk/etc/init.d/srs b/trunk/etc/init.d/srs index 1363cb826..12e5d6cb3 100755 --- a/trunk/etc/init.d/srs +++ b/trunk/etc/init.d/srs @@ -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 diff --git a/trunk/etc/init.d/srs-demo b/trunk/etc/init.d/srs-demo index 8ab0af17c..f714dbc1a 100755 --- a/trunk/etc/init.d/srs-demo +++ b/trunk/etc/init.d/srs-demo @@ -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 diff --git a/trunk/etc/init.d/srs-demo-19350 b/trunk/etc/init.d/srs-demo-19350 index b473526be..4e55540c8 100755 --- a/trunk/etc/init.d/srs-demo-19350 +++ b/trunk/etc/init.d/srs-demo-19350 @@ -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 diff --git a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj index 03f95d1aa..c8ef8ae6f 100644 --- a/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj +++ b/trunk/ide/srs_xcode/srs_xcode.xcodeproj/project.pbxproj @@ -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 = ""; }; 3C1EE6D51AB1367D00576EE9 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../../../LICENSE; sourceTree = ""; }; 3C1EE6D61AB1367D00576EE9 /* README.md */ = {isa = PBXFileReference; explicitFileType = net.daringfireball.markdown; fileEncoding = 4; name = README.md; path = ../../../README.md; sourceTree = ""; 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 = ""; }; + 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 = ""; }; 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 = ""; }; 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 = ""; }; 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 = ""; }; @@ -374,6 +379,8 @@ 3C8280291BAFF896004A1794 /* transform.edge.conf */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = transform.edge.conf; path = ../../../conf/transform.edge.conf; sourceTree = ""; }; 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 = ""; }; 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 = ""; }; + 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 = ""; }; + 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 = ""; }; 3CB25C281BB2596300C97A63 /* setup_variables.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = setup_variables.sh; path = ../../../auto/setup_variables.sh; sourceTree = ""; }; 3CB25C291BB269FD00C97A63 /* jmp_sp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jmp_sp.cpp; path = ../../../research/arm/jmp_sp.cpp; sourceTree = ""; }; 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 = ""; }; @@ -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 = ""; }; + 3C96ADC41B00A71000885304 /* modules */ = { + isa = PBXGroup; + children = ( + 3C24ECCA1C3A42D800460622 /* readme.txt */, + ); + name = modules; + sourceTree = ""; + }; 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 */, diff --git a/trunk/research/gperftools/memory.error.notcmalloc.cpp b/trunk/research/gperftools/memory.error.notcmalloc.cpp new file mode 100644 index 000000000..32638bb05 --- /dev/null +++ b/trunk/research/gperftools/memory.error.notcmalloc.cpp @@ -0,0 +1,16 @@ +/** +g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc +*/ +#include +#include +#include + +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; +} diff --git a/trunk/research/gperftools/memory.error.tcmalloc.cpp b/trunk/research/gperftools/memory.error.tcmalloc.cpp new file mode 100644 index 000000000..32638bb05 --- /dev/null +++ b/trunk/research/gperftools/memory.error.tcmalloc.cpp @@ -0,0 +1,16 @@ +/** +g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc +*/ +#include +#include +#include + +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; +} diff --git a/trunk/research/librtmp/srs_detect_rtmp.c b/trunk/research/librtmp/srs_detect_rtmp.c index e5414eb22..3174f0eba 100644 --- a/trunk/research/librtmp/srs_detect_rtmp.c +++ b/trunk/research/librtmp/srs_detect_rtmp.c @@ -26,6 +26,7 @@ gcc srs_detect_rtmp.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_detect #include #include +#include #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 \n" + "Usage: %s [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; } diff --git a/trunk/research/librtmp/srs_rtmp_dump.c b/trunk/research/librtmp/srs_rtmp_dump.c index 74f776c50..f477f8616 100644 --- a/trunk/research/librtmp/srs_rtmp_dump.c +++ b/trunk/research/librtmp/srs_rtmp_dump.c @@ -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) { diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index ecd09a0ca..fcca70e5a 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -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 SrsConfig::get_stream_casters() { srs_assert(root); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index cfb353016..fa12a889d 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -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: /** diff --git a/trunk/src/app/srs_app_hourglass.cpp b/trunk/src/app/srs_app_hourglass.cpp new file mode 100644 index 000000000..63887a2ff --- /dev/null +++ b/trunk/src/app/srs_app_hourglass.cpp @@ -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 + +using namespace std; + +#include +#include +#include + +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::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; +} diff --git a/trunk/src/app/srs_app_hourglass.hpp b/trunk/src/app/srs_app_hourglass.hpp new file mode 100644 index 000000000..7bb675c0b --- /dev/null +++ b/trunk/src/app/srs_app_hourglass.hpp @@ -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 +*/ + +#include + +#include + +/** + * 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 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 diff --git a/trunk/src/app/srs_app_process.cpp b/trunk/src/app/srs_app_process.cpp index 2954e4eaf..d155a5334 100644 --- a/trunk/src/app/srs_app_process.cpp +++ b/trunk/src/app/srs_app_process.cpp @@ -41,6 +41,9 @@ using namespace std; #include #include #include +#include +#include +#include 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 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 " 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; diff --git a/trunk/src/app/srs_app_process.hpp b/trunk/src/app/srs_app_process.hpp index 5e22020f5..ca71ea11b 100644 --- a/trunk/src/app/srs_app_process.hpp +++ b/trunk/src/app/srs_app_process.hpp @@ -61,10 +61,15 @@ private: std::vector 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 argv); public: diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 37e5cbdb4..2dde7fa48 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -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); diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 0811f578f..94b15f69c 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -1270,6 +1270,66 @@ vector& 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& 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()) { diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index 106761702..433d01447 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -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 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 7efa48f0f..0332f585b 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -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" diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp index 6e8907f94..3f751dbc1 100644 --- a/trunk/src/core/srs_core_performance.hpp +++ b/trunk/src/core/srs_core_performance.hpp @@ -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 diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 1fcce968e..be34492d8 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -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. diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index c94783315..928dd2c69 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -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; diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index e5e5c7185..39d339032 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -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 diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 619396c1d..0c84f68b6 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -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) { diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index ba4e77fed..96e38fa06 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -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 +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& 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; +} + diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp index c44d84221..8849d85c5 100644 --- a/trunk/src/protocol/srs_protocol_utility.hpp +++ b/trunk/src/protocol/srs_protocol_utility.hpp @@ -36,11 +36,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include #include 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& 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(