diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 000000000..49c96d4cf --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,4 @@ +Authors ordered by first contribution. + +* winlin +* wenjie diff --git a/LICENSE b/LICENSE index f37c3072c..85fff8a0e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/README.md b/README.md index b0bb23c7d..e877a82f1 100755 --- a/README.md +++ b/README.md @@ -1,68 +1,74 @@ -simple-rtmp-server +Simple-RTMP-Server ================== -srs(simple rtmp origin live server) over state-threads.
-srs is a simple, high-performance, running in single process, origin live server.
-srs supports vhost, rtmp, HLS, transcoding, forward, http hooks.
-blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin)
-see also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server)
-see also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server)
+SRS(SIMPLE RTMP Server) over state-threads created in 2013.
+SRS is a simple, high-performance, running in single process, origin live server.
+SRS supports vhost, rtmp, HLS, transcoding, forward, http hooks.
+Blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin)
+See also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server)
+See also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server)
TencentQQ: [http://url.cn/WAHICw](http://url.cn/WAHICw) (Group: 212189142) -### Contributors -winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin)
-wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html)
-about the contributors:
-1. contribute important features to srs.
-2. the name of all contributors will send in the response of NetConnection.connect and metadata. +### AUTHORS +The PRIMARY AUTHORS are (and/or have been)(Authors ordered by first contribution):
+* winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin)
+* wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html)
+ +About the primary AUTHORS:
+* Contribute important features to SRS.
+* Names of all PRIMARY AUTHORS response in NetConnection.connect and metadata.
+ +And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --
+people who have submitted patches, reported bugs, added translations, helped
+answer newbie questions, and generally made SRS that much better: [AUTHORS.txt](https://github.com/winlinvip/simple-rtmp-server/blob/master/AUTHORS.txt) ### Usage(simple) -step -1: get srs
+Step -1: get SRS
 git clone https://github.com/winlinvip/simple-rtmp-server &&
 cd simple-rtmp-server/trunk
 
-step 0: build srs system.
+Step 0: build SRS system.
 bash scripts/build.sh
 
-step 1: start srs all demo features.
+Step 1: start SRS all demo features.
 bash scripts/run.sh
 
-step 2: srs live show: [http://your-server-ip](http://your-server-ip)
-step 3: stop srs demo
+Step 2: SRS live show: [http://your-server-ip](http://your-server-ip)
+Step 3: stop SRS demo
 bash scripts/stop.sh
 
### Usage(detail) -step 0: get srs
+Step 0: get SRS
 git clone https://github.com/winlinvip/simple-rtmp-server &&
 cd simple-rtmp-server/trunk
 
-step 1: build srs
+Step 1: build SRS
 ./configure --with-ssl --with-hls --with-ffmpeg --with-http && make
 
-step 2: start srs
+Step 2: start SRS
 ./objs/srs -c conf/srs.conf
 
-step 3(optinal): start srs listen at 19350 to forward to
+Step 3(optinal): start SRS listen at 19350 to forward to
 ./objs/srs -c conf/srs.19350.conf
 
-step 4(optinal): start nginx for HLS
+Step 4(optinal): start nginx for HLS
 sudo ./objs/nginx/sbin/nginx
 
-step 5(optinal): start http hooks for srs callback
+Step 5(optinal): start http hooks for SRS callback
 python ./research/api-server/server.py 8085
 
-step 6: publish demo live stream
+Step 6: publish demo live stream
 FMS URL: rtmp://127.0.0.1/live?vhost=demo.srs.com
 Stream:  livestream
@@ -74,7 +80,7 @@ FFMPEG to publish the default demo stream:
         sleep 1; \
     done
 
-step 7: publish players live stream
+Step 7: publish players live stream
 FMS URL: rtmp://127.0.0.1/live?vhost=players
 Stream:  livestream
@@ -86,7 +92,7 @@ FFMPEG to publish the players demo stream:
         sleep 1; \
     done
 
-step 8: add server ip to client hosts as demo.
+Step 8: add server ip to client hosts as demo.
 # edit the folowing file:
 # linux: /etc/hosts
@@ -94,14 +100,14 @@ FFMPEG to publish the players demo stream:
 # where server ip is 192.168.2.111
 192.168.2.111 demo.srs.com
 
-step 9: play live stream.
+Step 9: play live stream.
 players: http://demo.srs.com/players
 rtmp url: rtmp://demo.srs.com/live/livestream
 m3u8 url: http://demo.srs.com/live/livestream.m3u8
 for android: http://demo.srs.com/live/livestream.html
 
-step 10(optinal): play live stream auto transcoded
+Step 10(optinal): play live stream auto transcoded
 rtmp url: rtmp://demo.srs.com/live/livestream_ld
 m3u8 url: http://demo.srs.com/live/livestream_ld.m3u8
@@ -110,7 +116,7 @@ rtmp url: rtmp://demo.srs.com/live/livestream_sd
 m3u8 url: http://demo.srs.com/live/livestream_sd.m3u8
 for android: http://demo.srs.com/live/livestream_sd.html
 
-step 11(optinal): play live stream auto forwarded, the hls dir change to /forward
+Step 11(optinal): play live stream auto forwarded, the hls dir change to /forward
 rtmp url: rtmp://demo.srs.com:19350/live/livestream
 m3u8 url: http://demo.srs.com/forward/live/livestream.m3u8
@@ -122,7 +128,7 @@ rtmp url: rtmp://demo.srs.com:19350/live/livestream_sd
 m3u8 url: http://demo.srs.com/forward/live/livestream_sd.m3u8
 for android: http://demo.srs.com/forward/live/livestream_sd.html
 
-step 12(optinal): modify the config and reload it (all features support reload)
+Step 12(optinal): modify the config and reload it (all features support reload)
 killall -1 srs
 
@@ -135,7 +141,7 @@ killall -s SIGHUP srs System Architecture:
 +------------------------------------------------------+
-|             SRS(Simple Rtmp Server)                  |
+|             SRS(Simple RTMP Server)                  |
 +---------------+---------------+-----------+----------+
 |   API/hook    |   Transcoder  |    HLS    |   RTMP   |
 |  http-parser  |  FFMPEG/x264  |  NGINX/ts | protocol |
@@ -151,7 +157,7 @@ Stream Architecture:
         + Publish +              +  Deliver | 
         +---|-----+              +----|-----+ 
 +-----------+-------------------------+----------------+
-| Encoder   | SRS(Simple Rtmp Server) |     Client     |
+| Encoder   | SRS(Simple RTMP Server) |     Client     |
 +-----------+-------------------------+----------------+
 | (FMLE,    |   +-> RTMP protocol ----+-> Flash Player |
 | FFMPEG, --+-> +-> HLS/NGINX --------+-> m3u8 player  |
@@ -186,7 +192,7 @@ Bandwidth Test Workflow:
          |   final(2)----------------->    |
          |           <END>                 |
          
-@see: class SrsBandwidth comments.
+@See: class SrsBandwidth comments.
 
### System Requirements @@ -195,37 +201,38 @@ Supported operating systems and hardware: * All handware. ### Summary -1. simple: also stable enough.
-2. high-performance: single-thread, async socket, event/st-thread driven.
-3. no edge server, origin server only.
-4. no vod streaming, live streaming only.
-5. no multiple processes, single process only.
-6. support vhost, support \_\_defaultVhost\_\_.
-7. support adobe rtmp live streaming.
-8. support apple hls(m3u8) live streaming.
-9. support reload config to enable changes.
-10. support cache last gop for flash player to fast startup.
-11. support listen at multiple ports.
-12. support long time(>4.6hours) publish/play.
-13. high performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB
-14. support forward publish stream to build active-standby cluster.
-15. support broadcast by forward the stream to other servers(origin/edge).
-16. support live stream transcoding by ffmpeg.
-17. support live stream forward(acopy/vcopy) by ffmpeg.
-18. support ffmpeg filters(logo/overlay/crop), x264 params.
-19. support audio transcode only, speex/mp3 to aac
-20. support http callback api hooks(for authentication and injection).
-21. support bandwidth test api and flash client.
-22. player, publisher(encoder), and demo pages(jquery+bootstrap).
-23. demo video meeting or chat(srs+cherrypy+jquery+bootstrap).
-24. [plan] support network based cli and json result.
-25. [plan] support adobe flash refer/token/swf verification.
-26. [plan] support adobe amf3 codec.
-27. [plan] support dvr(record live to vod file)
-28. [plan] support FMS edge protocol
-29. [plan] support encryption: RTMPE/RTMPS, HLS DRM
-30. [plan] support RTMPT, http to tranverse firewalls
-31. [plan] support file source, transcoding file to live stream
+1. Simple: also stable enough.
+2. [High-performance](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance): single-thread, async socket, event/st-thread driven.
+3. NO edge server, origin server only.
+4. NO vod streaming, live streaming only.
+5. NO multiple processes, single process only.
+6. Support vhost, support \_\_defaultVhost\_\_.
+7. Support adobe rtmp live streaming.
+8. Support apple hls(m3u8) live streaming.
+9. Support reload config to enable changes.
+10. Support cache last gop for flash player to fast startup.
+11. Support listen at multiple ports.
+12. Support long time(>4.6hours) publish/play.
+13. High performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB
+14. Support forward publish stream to build active-standby [cluster](https://github.com/winlinvip/simple-rtmp-server/wiki/Cluster).
+15. Support broadcast by forward the stream to other servers(origin/edge).
+16. Support live stream transcoding by ffmpeg.
+17. Support live stream forward(acopy/vcopy) by ffmpeg.
+18. Support ffmpeg filters(logo/overlay/crop), x264 params.
+19. Support audio transcode only, speex/mp3 to aac
+20. Support http callback api hooks(for authentication and injection).
+21. Support bandwidth test api and flash client.
+22. Player, publisher(encoder), and demo pages(jquery+bootstrap).
+23. Demo video meeting or chat(SRS+cherrypy+jquery+bootstrap).
+24. [dev] Full documents in wiki, in chineses.
+25. [plan] Support network based cli and json result.
+26. [plan] Support adobe flash refer/token/swf verification.
+27. [plan] Support adobe amf3 codec.
+28. [plan] Support dvr(record live to vod file)
+29. [plan] Support FMS edge protocol
+30. [plan] Support encryption: RTMPE/RTMPS, HLS DRM
+31. [plan] Support RTMPT, http to tranverse firewalls
+32. [plan] Support file source, transcoding file to live stream
### Performance 1. 300 connections, 150Mbps, 500kbps, CPU 18.8%, 5956KB. @@ -234,53 +241,54 @@ Supported operating systems and hardware: 4. 1200 connections, 600Mbps, 500kbps, CPU 72.4%, 15MB. 5. 1500 connections, 750Mbps, 500kbps, CPU 81.9%, 28MB. 6. 1800 connections, 900Mbps, 500kbps, CPU 90.2%, 41MB. +
+[winlin@dev6 srs]$ dstat
 ----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
 usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
  58   9  32   0   0   1|   0  4168k| 277M  277M|   0     0 |  29k   25k
  61   8  30   0   0   1|   0  1168k| 336M  336M|   0     0 |  29k   24k
  63   8  27   0   0   1|   0  2240k| 124M  124M|   0     0 |  32k   33k
  62   8  28   0   0   1|   0  1632k| 110M  110M|   0     0 |  31k   33k
- 67   9  23   0   0   2|   0  1604k| 130M  130M|   0     0 |  33k   32k
- 63   9  27   0   0   2|   0  1496k| 145M  145M|   0     0 |  32k   32k
- 61   9  29   0   0   1|   0  1112k| 132M  132M|   0     0 |  32k   33k
- 63   9  27   0   0   2|   0  1220k| 145M  145M|   0     0 |  32k   33k
  53   7  40   0   0   1|   0  1360k| 115M  115M|   0     0 |  24k   26k
  51   7  41   0   0   1|   0  1184k| 146M  146M|   0     0 |  24k   27k
  39   6  54   0   0   1|   0  1284k| 105M  105M|   0     0 |  22k   28k
  41   6  52   0   0   1|   0  1264k| 116M  116M|   0     0 |  25k   28k
  48   6  45   0   0   1|   0  1272k| 143M  143M|   0     0 |  27k   27k
 
+See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance) ### Releases -* 2013-12-25, [release v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9), support bandwidth test, add player/encoder/chat demos. 20926 lines.
-* 2013-12-08, [release v0.8](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.8), support http hooks callback, update [st_load](https://github.com/winlinvip/st-load). 19186 lines.
-* 2013-12-03, [release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.
-* 2013-11-29, [release v0.6](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.6), support forward stream to origin/edge. 16094 lines.
-* 2013-11-26, [release v0.5](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.5), support HLS(m3u8), fragment and window. 14449 lines.
-* 2013-11-10, [release v0.4](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.4), support reload config, pause, longtime publish/play. 12500 lines.
-* 2013-11-04, [release v0.3](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.3), support vhost, refer, gop cache, listen multiple ports. 11773 lines.
-* 2013-10-25, [release v0.2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.2), support rtmp flash publish, h264, time jitter correct. 10125 lines.
-* 2013-10-23, [release v0.1](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.1), support rtmp FMLE/FFMPEG publish, vp6. 8287 lines.
-* 2013-10-17, created.
+* 2013-12-25, [Release v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9), support bandwidth test, add player/encoder/chat demos. 20926 lines.
+* 2013-12-08, [Release v0.8](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.8), support http hooks callback, update [st_load](https://github.com/winlinvip/st-load). 19186 lines.
+* 2013-12-03, [Release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.
+* 2013-11-29, [Release v0.6](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.6), support forward stream to origin/edge. 16094 lines.
+* 2013-11-26, [Release v0.5](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.5), support HLS(m3u8), fragment and window. 14449 lines.
+* 2013-11-10, [Release v0.4](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.4), support reload config, pause, longtime publish/play. 12500 lines.
+* 2013-11-04, [Release v0.3](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.3), support vhost, refer, gop cache, listen multiple ports. 11773 lines.
+* 2013-10-25, [Release v0.2](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.2), support rtmp flash publish, h264, time jitter correct. 10125 lines.
+* 2013-10-23, [Release v0.1](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.1), support rtmp FMLE/FFMPEG publish, vp6. 8287 lines.
+* 2013-10-17, Created.
### Compare -* srs v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.
-* srs v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
-* srs v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com).
-* srs v0.6: 16094 lines. important feature forward for CDN.
-* srs v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
-* srs v0.4: 12500 lines. important feature reload for CDN.
-* srs v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html).
-* srs v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
-* srs v0.1: 8287 lines. base on state-threads.
+* SRS v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.
+* SRS v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
+* SRS v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com).
+* SRS v0.6: 16094 lines. important feature forward for CDN.
+* SRS v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
+* SRS v0.4: 12500 lines. important feature reload for CDN.
+* SRS v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html).
+* SRS v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module).
+* SRS v0.1: 8287 lines. base on state-threads.
* nginx-rtmp v1.0.4: 26786 lines
* nginx v1.5.0: 139524 lines
### History +* v1.0, 2014-01-01, change listen(512), chunk-size(60000), to improve performance. +* v1.0, 2013-12-27, merge from wenjie, the bandwidth test feature. * v0.9, 2013-12-25, [v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9) released. 20926 lines. * v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone. -* v0.9, 2013-12-22, demo video meeting or chat(srs+cherrypy+jquery+bootstrap). +* v0.9, 2013-12-22, demo video meeting or chat(SRS+cherrypy+jquery+bootstrap). * v0.9, 2013-12-22, merge from wenjie, support banwidth test. * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level * v0.9, 2013-12-21, add [players](http://demo.srs.com/players) for play and publish. @@ -297,7 +305,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw * v0.8, 2013-12-08, support multiple http hooks for a event. * v0.8, 2013-12-07, support http callback hooks, on_connect. * v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4. -* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use srs rtmp sdk. +* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use SRS rtmp sdk. * v0.8, 2013-12-06, support max_connections, drop if exceed. * v0.8, 2013-12-05, support log_dir, write ffmpeg log to file. * v0.8, 2013-12-05, fix the forward/hls/encoder bug. diff --git a/trunk/conf/srs.conf b/trunk/conf/srs.conf index 18996067c..2634b9a3b 100755 --- a/trunk/conf/srs.conf +++ b/trunk/conf/srs.conf @@ -1,5 +1,14 @@ # the listen ports, split by space. listen 1935; +<<<<<<< HEAD +======= +# the default chunk size is 128, max is 65536, +# some client does not support chunk size change, +# however, most clients supports it and it can improve +# performance about 10%. +# default: 60000 +chunk_size 60000; +>>>>>>> upstream/master # the logs dir. # if enabled ffmpeg, each stracoding stream will create a log file. # default: ./objs/logs @@ -28,7 +37,7 @@ vhost __defaultVhost__ { # for which cannot identify the required vhost. # for default demo. vhost demo.srs.com { - chunk_size 4096; + chunk_size 60000; enabled on; gop_cache on; queue_length 30; @@ -226,7 +235,7 @@ vhost bandcheck.srs.com { enabled on; # the key for server to valid, # if invalid key, server disconnect and abort the bandwidth check. - key 35c9b402c12a7246868752e2878f7e0e; + key "35c9b402c12a7246868752e2878f7e0e"; # the interval in seconds for bandwidth check, # server donot allow new test request. # default: 30 diff --git a/trunk/configure b/trunk/configure index ba8b1b4fa..5be8cc473 100755 --- a/trunk/configure +++ b/trunk/configure @@ -47,22 +47,27 @@ echo "" >> $SRS_AUTO_HEADERS_H echo "generate Makefile" cat << END > ${SRS_MAKEFILE} -.PHONY: default help clean server _prepare_dir -default: server +.PHONY: default help clean server bandwidth _prepare_dir +default: server bandwidth help: - @echo "Usage: make ||" + @echo "Usage: make |||" @echo " help display this help menu" @echo " clean cleanup project" @echo " server build the srs(simple rtmp server) over st(state-threads)" + @echo " bandwidth build the bandwidth test client tool." clean: - (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs Makefile *.hpp src st_*_load) + (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs bandwidth Makefile *.hpp src st_*_load) server: _prepare_dir @echo "build the srs(simple rtmp server) over st(state-threads)" \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} srs +bandwidth: _prepare_dir + @echo "build the bandwidth test client tool" + \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} bandwidth + # the ./configure will generate it. _prepare_dir: @mkdir -p ${SRS_OBJS} @@ -87,7 +92,7 @@ GCC = g++ LINK = \$(GCC) AR = ar -.PHONY: default srs +.PHONY: default srs bandwidth default: @@ -124,12 +129,12 @@ CORE_OBJS="${MODULE_OBJS[@]}" MODULE_ID="MAIN" MODULE_DEPENDS=("CORE") ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS}) -MODULE_FILES=("srs_main_server") +MODULE_FILES=("srs_main_server" "srs_main_bandcheck") MODULE_DIR="src/main" . auto/modules.sh MAIN_OBJS="${MODULE_OBJS[@].o}" # all main entrances -MAIN_ENTRANCES=("srs_main_server") +MAIN_ENTRANCES=("srs_main_server" "srs_main_bandcheck") # srs(simple rtmp server) over st(state-threads) ModuleLibFiles=(${LibSTfile}) @@ -143,6 +148,7 @@ else LINK_OPTIONS="-ldl" fi BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" SO_PATH="" . auto/apps.sh +BUILD_KEY="bandwidth" APP_MAIN="srs_main_bandcheck" APP_NAME="bandwidth" SO_PATH="" . auto/apps.sh echo 'configure ok! ' diff --git a/trunk/research/api-server/server.py b/trunk/research/api-server/server.py index 01b7bf929..5f73022bd 100755 --- a/trunk/research/api-server/server.py +++ b/trunk/research/api-server/server.py @@ -2,7 +2,7 @@ ''' The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -463,7 +463,7 @@ if __name__ != "__main__": # check the user options if len(sys.argv) <= 1: - print "SRS api callback server, Copyright (c) 2013 winlin" + print "SRS api callback server, Copyright (c) 2013-2014 winlin" print "Usage: python %s "%(sys.argv[0]) print " port: the port to listen at." print "For example:" diff --git a/trunk/research/ffempty/ffempty.cc b/trunk/research/ffempty/ffempty.cc index 8def35f25..8df9c7d1b 100644 --- a/trunk/research/ffempty/ffempty.cc +++ b/trunk/research/ffempty/ffempty.cc @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/research/hls/ts_info.cc b/trunk/research/hls/ts_info.cc index dfe682428..7cc1abe2f 100644 --- a/trunk/research/hls/ts_info.cc +++ b/trunk/research/hls/ts_info.cc @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -417,38 +417,38 @@ public: */ enum TSPESStreamId { - PES_program_stream_map = 0b10111100, // 0xbc - PES_private_stream_1 = 0b10111101, // 0xbd - PES_padding_stream = 0b10111110, // 0xbe - PES_private_stream_2 = 0b10111111, // 0xbf + PES_program_stream_map = 0xbc, // 0b10111100 + PES_private_stream_1 = 0xbd, // 0b10111101 + PES_padding_stream = 0xbe, // 0b10111110 + PES_private_stream_2 = 0xbf, // 0b10111111 // 110x xxxx // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC // 14496-3 audio stream number x xxxx // (stream_id>>5)&0x07 == PES_audio_prefix - PES_audio_prefix = 0b110, + PES_audio_prefix = 0x06, // 0b110 // 1110 xxxx // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC // 14496-2 video stream number xxxx // (stream_id>>4)&0x0f == PES_audio_prefix - PES_video_prefix = 0b1110, + PES_video_prefix = 0x0e, // 0b1110 - PES_ECM_stream = 0b11110000, // 0xf0 - PES_EMM_stream = 0b11110001, // 0xf1 - PES_DSMCC_stream = 0b11110010, // 0xf2 - PES_13522_stream = 0b11110011, // 0xf3 - PES_H_222_1_type_A = 0b11110100, // 0xf4 - PES_H_222_1_type_B = 0b11110101, // 0xf5 - PES_H_222_1_type_C = 0b11110110, // 0xf6 - PES_H_222_1_type_D = 0b11110111, // 0xf7 - PES_H_222_1_type_E = 0b11111000, // 0xf8 - PES_ancillary_stream = 0b11111001, // 0xf9 - PES_SL_packetized_stream = 0b11111010, // 0xfa - PES_FlexMux_stream = 0b11111011, // 0xfb + PES_ECM_stream = 0xf0, // 0b11110000 + PES_EMM_stream = 0xf1, // 0b11110001 + PES_DSMCC_stream = 0xf2, // 0b11110010 + PES_13522_stream = 0xf3, // 0b11110011 + PES_H_222_1_type_A = 0xf4, // 0b11110100 + PES_H_222_1_type_B = 0xf5, // 0b11110101 + PES_H_222_1_type_C = 0xf6, // 0b11110110 + PES_H_222_1_type_D = 0xf7, // 0b11110111 + PES_H_222_1_type_E = 0xf8, // 0b11111000 + PES_ancillary_stream = 0xf9, // 0b11111001 + PES_SL_packetized_stream = 0xfa, // 0b11111010 + PES_FlexMux_stream = 0xfb, // 0b11111011 // reserved data stream // 1111 1100 … 1111 1110 - PES_program_stream_directory= 0b11111111, // 0xff + PES_program_stream_directory= 0xff, // 0b11111111 }; diff --git a/trunk/research/players/js/srs.bandwidth.js b/trunk/research/players/js/srs.bandwidth.js index 79c51e2f8..4f7ccafd7 100755 --- a/trunk/research/players/js/srs.bandwidth.js +++ b/trunk/research/players/js/srs.bandwidth.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD // for bw to init url // url: scheme://host:port/path?query#fragment function srs_init_bwt(rtmp_url, hls_url) { @@ -24,4 +25,141 @@ function srs_bwt_check_url(url) { function srs_bwt_build_default_url() { var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"; return url_default; +======= +/** +* the SrsBandwidth object. +* @param container the html container id. +* @param width a float value specifies the width of bandwidth. +* @param height a float value specifies the height of bandwidth. +* @param private_object [optional] an object that used as private object, +* for example, the logic chat object which owner this bandwidth. +*/ +function SrsBandwidth(container, width, height, private_object) { + if (!SrsBandwidth.__id) { + SrsBandwidth.__id = 100; + } + if (!SrsBandwidth.__bandwidths) { + SrsBandwidth.__bandwidths = []; + } + + SrsBandwidth.__bandwidths.push(this); + + this.private_object = private_object; + this.container = container; + this.width = width; + this.height = height; + this.id = SrsBandwidth.__id++; + this.stream_url = null; + this.callbackObj = null; + + // the callback set data. + this.percent = 0; + this.status = ""; +} +/** +* user can set some callback, then start the bandwidth. +* @param url the bandwidth test url. +* callbacks: +* on_bandwidth_ready():void, when srs bandwidth ready, user can play. +* on_update_progress(percent:Number):void, when srs bandwidth update the progress. +* percent:Number 100 means 100%. +* on_update_status(status:String):void, when srs bandwidth update the status. +* status:String the human readable status text. +*/ +SrsBandwidth.prototype.start = function(url) { + if (url) { + this.stream_url = url; + } + + // embed the flash. + var flashvars = {}; + flashvars.id = this.id; + flashvars.on_bandwidth_ready = "__srs_on_bandwidth_ready"; + flashvars.on_update_progress = "__srs_on_update_progress"; + flashvars.on_update_status = "__srs_on_update_status"; + + var params = {}; + params.wmode = "opaque"; + params.allowFullScreen = "true"; + params.allowScriptAccess = "always"; + + var attributes = {}; + + var self = this; + + swfobject.embedSWF( + "srs_bwt/release/srs_bwt.swf?_version="+srs_get_version_code(), + this.container, + this.width, this.height, + "11.1.0", "js/AdobeFlashbandwidthInstall.swf", + flashvars, params, attributes, + function(callbackObj){ + self.callbackObj = callbackObj; + } + ); + + return this; +} +/** +* play the stream. +* @param stream_url the url of stream, rtmp or http. +* @param volume the volume, 0 is mute, 1 is 100%, 2 is 200%. +*/ +SrsBandwidth.prototype.check_bandwidth = function(url) { + this.stop(); + SrsBandwidth.__bandwidths.push(this); + + if (url) { + this.stream_url = url; + } + + this.callbackObj.ref.__check_bandwidth(this.stream_url); +} +SrsBandwidth.prototype.stop = function(url) { + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) { + var bandwidth = SrsBandwidth.__bandwidths[i]; + + if (bandwidth.id != this.id) { + continue; + } + + SrsBandwidth.__bandwidths.splice(i, 1); + break; + } + + this.callbackObj.ref.__stop(); +} +SrsBandwidth.prototype.on_bandwidth_ready = function() { +} +SrsBandwidth.prototype.on_update_progress = function(percent) { +} +SrsBandwidth.prototype.on_update_status = function(status) { +} +function __srs_find_bandwidth(id) { + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) { + var bandwidth = SrsBandwidth.__bandwidths[i]; + + if (bandwidth.id != id) { + continue; + } + + return bandwidth; + } + + throw new Error("bandwidth not found. id=" + id); +} +function __srs_on_bandwidth_ready(id) { + var bandwidth = __srs_find_bandwidth(id); + bandwidth.on_bandwidth_ready(); +} +function __srs_on_update_progress(id, percent) { + var bandwidth = __srs_find_bandwidth(id); + bandwidth.percent = percent; + bandwidth.on_update_progress(percent); +} +function __srs_on_update_status(id, status) { + var bandwidth = __srs_find_bandwidth(id); + bandwidth.status = status; + bandwidth.on_update_status(status); +>>>>>>> upstream/master } \ No newline at end of file diff --git a/trunk/research/players/js/srs.page.js b/trunk/research/players/js/srs.page.js index 68ce4bd6c..62e28a52c 100755 --- a/trunk/research/players/js/srs.page.js +++ b/trunk/research/players/js/srs.page.js @@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } // to query the swf anti cache. -function srs_get_version_code() { return "1.17"; } +function srs_get_version_code() { return "1.19"; } // get the default vhost for players. function srs_get_player_vhost() { return "players"; } // the api server port, for chat room. @@ -80,6 +80,18 @@ function build_default_publish_rtmp_url() { return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; } } +// for the bandwidth tool to init page +function build_default_bandwidth_rtmp_url() { + var query = parse_query_string(); + + var server = (query.server == undefined)? window.location.hostname:query.server; + var port = (query.port == undefined)? 1935:query.port; + var vhost = "bandcheck.srs.com"; + var app = (query.app == undefined)? "app":query.app; + var key = (query.key == undefined)? "35c9b402c12a7246868752e2878f7e0e":query.key; + + return "rtmp://" + server + ":" + port + "/" + app + "?key=" + key + "&vhost=" + vhost; +} /** @param server the ip of server. default to window.location.hostname @@ -139,6 +151,15 @@ function srs_init_publish(rtmp_url) { $(rtmp_url).val(build_default_publish_rtmp_url()); } } +// for bw to init url +// url: scheme://host:port/path?query#fragment +function srs_init_bwt(rtmp_url, hls_url) { + update_nav(); + + if (rtmp_url) { + $(rtmp_url).val(build_default_bandwidth_rtmp_url()); + } +} // check whether can republish function srs_can_republish() { diff --git a/trunk/research/players/js/srs.player.js b/trunk/research/players/js/srs.player.js index 3d9da3bb5..dad0ba927 100755 --- a/trunk/research/players/js/srs.player.js +++ b/trunk/research/players/js/srs.player.js @@ -63,7 +63,7 @@ SrsPlayer.prototype.start = function(url) { "srs_player/release/srs_player.swf?_version="+srs_get_version_code(), this.container, this.width, this.height, - "11.1", "js/AdobeFlashPlayerInstall.swf", + "11.1.0", "js/AdobeFlashPlayerInstall.swf", flashvars, params, attributes, function(callbackObj){ self.callbackObj = callbackObj; diff --git a/trunk/research/players/js/srs.publisher.js b/trunk/research/players/js/srs.publisher.js index 50363e7d5..25f29bfed 100755 --- a/trunk/research/players/js/srs.publisher.js +++ b/trunk/research/players/js/srs.publisher.js @@ -73,7 +73,7 @@ SrsPublisher.prototype.start = function() { "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), this.container, this.width, this.height, - "11.1", "js/AdobeFlashPlayerInstall.swf", + "11.1.0", "js/AdobeFlashPlayerInstall.swf", flashvars, params, attributes, function(callbackObj){ self.callbackObj = callbackObj; diff --git a/trunk/research/players/js/srs.utility.js b/trunk/research/players/js/srs.utility.js index e3886cc77..60562e209 100755 --- a/trunk/research/players/js/srs.utility.js +++ b/trunk/research/players/js/srs.utility.js @@ -13,6 +13,21 @@ function padding(number, length, prefix) { /** * parse the query string to object. +* parse the url location object as: host(hostname:http_port), pathname(dir/filename) +* for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream +* parsed to object: +{ + host : "192.168.1.168:1980", + hostname : "192.168.1.168", + http_port : 1980, + pathname : "/ui/players.html", + dir : "/ui", + filename : "/players.html", + + vhost : "player.vhost.com", + app : "test", + stream : "livestream" +} */ function parse_query_string(){ var obj = {}; diff --git a/trunk/research/players/srs_bwt.html b/trunk/research/players/srs_bwt.html index 3f68ea6b5..681a1db45 100755 --- a/trunk/research/players/srs_bwt.html +++ b/trunk/research/players/srs_bwt.html @@ -12,13 +12,18 @@ +<<<<<<< HEAD +======= + +>>>>>>> upstream/master + @@ -141,6 +196,7 @@
+<<<<<<< HEAD
URL: @@ -164,15 +220,49 @@
status +======= +
+ + Usage: 点击“开始测速”即可测带宽,最大可测试带宽由服务器限制 +
+
+ URL: + + +
+ +<<<<<<< HEAD +======= +>>>>>>> upstream/master
+
+
+
diff --git a/trunk/research/players/srs_bwt/.actionScriptProperties b/trunk/research/players/srs_bwt/.actionScriptProperties index cd87f23d7..f073e8327 100755 --- a/trunk/research/players/srs_bwt/.actionScriptProperties +++ b/trunk/research/players/srs_bwt/.actionScriptProperties @@ -1,6 +1,10 @@ +<<<<<<< HEAD +======= + +>>>>>>> upstream/master @@ -17,6 +21,7 @@ +<<<<<<< HEAD @@ -24,6 +29,15 @@ +======= + + + + + + + +>>>>>>> upstream/master diff --git a/trunk/research/players/srs_bwt/src/srs_bwt.as b/trunk/research/players/srs_bwt/src/srs_bwt.as index ef69cc8c8..8a8870cf5 100755 --- a/trunk/research/players/srs_bwt/src/srs_bwt.as +++ b/trunk/research/players/srs_bwt/src/srs_bwt.as @@ -20,10 +20,22 @@ package public class srs_bwt extends Sprite { +<<<<<<< HEAD private var connection:NetConnection; private var updatePlayProgressTimer:Timer; private var elapTimer:SrsElapsedTimer; +======= + private var connection:NetConnection = null; + + private var updatePlayProgressTimer:Timer = null; + private var elapTimer:SrsElapsedTimer = null; + + // user set id. + private var js_id:String = null; + // play param url. + private var user_url:String = null; +>>>>>>> upstream/master // server ip get from server private var server_ip:String; @@ -32,8 +44,13 @@ package private var stop_pub:Boolean = false; // js interface +<<<<<<< HEAD private var js_update_progress:String; private var js_progress_reset:String; +======= + private var js_on_player_ready:String; + private var js_update_progress:String; +>>>>>>> upstream/master private var js_update_status:String; private var value_progressbar:Number = 0; @@ -44,10 +61,26 @@ package public function srs_bwt() { +<<<<<<< HEAD +======= + if (!this.stage) { + this.addEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage); + } else { + this.system_on_add_to_stage(null); + } + } + + /** + * system event callback, when this control added to stage. + * the main function. + */ + private function system_on_add_to_stage(evt:Event):void { +>>>>>>> upstream/master this.stage.scaleMode = StageScaleMode.NO_SCALE; this.stage.align = StageAlign.TOP_LEFT; var flashvars:Object = this.root.loaderInfo.parameters; +<<<<<<< HEAD this.js_update_progress = flashvars.update_progress; this.js_progress_reset = flashvars.progress_reset; this.js_update_status = flashvars.update_status; @@ -58,11 +91,56 @@ package myMenu.customItems.push(new ContextMenuItem("Srs 带宽测试工具 0.1", true)); this.contextMenu = myMenu; +======= + + if (!flashvars.hasOwnProperty("id")) { + throw new Error("must specifies the id"); + } + + this.js_id = flashvars.id; + this.js_on_player_ready = flashvars.on_bandwidth_ready; + this.js_update_progress = flashvars.on_update_progress; + this.js_update_status = flashvars.on_update_status; + + // init context menu + var myMenu:ContextMenu = new ContextMenu(); + myMenu.hideBuiltInItems(); + myMenu.customItems.push(new ContextMenuItem("SRS 带宽测试工具", true)); + this.contextMenu = myMenu; + + flash.utils.setTimeout(this.system_on_js_ready, 0); + } + + /** + * system callack event, when js ready, register callback for js. + * the actual main function. + */ + private function system_on_js_ready():void { + if (!flash.external.ExternalInterface.available) { + trace("js not ready, try later."); + flash.utils.setTimeout(this.system_on_js_ready, 100); + return; + } + + flash.external.ExternalInterface.addCallback("__check_bandwidth", this.js_call_check_bandwidth); + flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop); + + flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id); + } + + private function js_call_check_bandwidth(url:String):void { + js_call_stop(); + +>>>>>>> upstream/master // init connection connection = new NetConnection; connection.client = this; connection.addEventListener(NetStatusEvent.NET_STATUS, onStatus); +<<<<<<< HEAD connection.connect(flashvars.url); +======= + connection.connect(url); +>>>>>>> upstream/master //connection.connect("rtmp://192.168.8.234:1935/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"); // for play to update progress bar @@ -73,10 +151,43 @@ package updatePlayProgressTimer.addEventListener(TimerEvent.TIMER, onTimerTimeout); updatePlayProgressTimer.start(); } +<<<<<<< HEAD // get NetConnection NetStatusEvent public function onStatus(evt:NetStatusEvent) : void{ trace(evt.info.code); +======= + private function js_call_stop():void { + if (connection) { + connection.close(); + connection = null; + } + if (updatePlayProgressTimer) { + updatePlayProgressTimer.stop(); + updatePlayProgressTimer = null; + } + if (elapTimer) { + elapTimer.restart(); + } + } + + // get NetConnection NetStatusEvent + public function onStatus(evt:NetStatusEvent) : void{ + trace(evt.info.code); + + if (evt.info.hasOwnProperty("data") && evt.info.data) { + // for context menu + var customItems:Array = [new ContextMenuItem("SrsPlayer")]; + if (evt.info.data.hasOwnProperty("srs_server")) { + customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); + } + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); + } + contextMenu.customItems = customItems; + } + +>>>>>>> upstream/master switch(evt.info.code){ case "NetConnection.Connect.Failed": updateState("连接服务器失败!"); @@ -92,8 +203,18 @@ package //updateState("连接已断开!"); break; } +<<<<<<< HEAD } +======= + } + + public function onTimerTimeout(evt:TimerEvent):void + { + value_progressbar = elapTimer.elapsed(); + updateProgess(value_progressbar, max_progressbar); + } +>>>>>>> upstream/master /** * NetConnection callback this function, when recv server call "onSrsBandCheckStartPlayBytes" @@ -104,13 +225,18 @@ package var interval_ms:Number = evt.interval_ms; connection.call("onSrsBandCheckStartingPlayBytes", null); +<<<<<<< HEAD updateState("测试下行带宽(" + server_ip + ")"); +======= + updateState("开始测试下行带宽,服务器IP:" + server_ip); +>>>>>>> upstream/master // we suppose play duration_ms = pub duration_ms max_progressbar = duration_ms * 2; } public function onSrsBandCheckPlaying(evt:Object):void{ +<<<<<<< HEAD } @@ -118,6 +244,8 @@ package { value_progressbar = elapTimer.elapsed(); updateProgess(value_progressbar, max_progressbar); +======= +>>>>>>> upstream/master } public function onSrsBandCheckStopPlayBytes(evt:Object):void{ @@ -133,6 +261,10 @@ package kbps = (int(kbps * 10))/10.0; flash.utils.setTimeout(stopPlayTest, 0); +<<<<<<< HEAD +======= + updateState("下行带宽测试完毕,服务器: " + server_ip + "," + kbps + "kbps,开始测试上行带宽。"); +>>>>>>> upstream/master } private function stopPlayTest():void{ @@ -144,7 +276,10 @@ package var interval_ms:Number = evt.interval_ms; connection.call("onSrsBandCheckStartingPublishBytes", null); +<<<<<<< HEAD updateState("测试上行带宽(" + server_ip + ")"); +======= +>>>>>>> upstream/master flash.utils.setTimeout(publisher, 0); } @@ -208,6 +343,7 @@ package connection.call("finalClientPacket", null); } +<<<<<<< HEAD public function onBWDone():void{ // do nothing } @@ -215,13 +351,27 @@ package // update progressBar's value private function updateProgess(value:Number, maxValue:Number):void{ flash.external.ExternalInterface.call(this.js_update_progress, value * 100 / maxValue + "%"); +======= + // update progressBar's value + private function updateProgess(value:Number, maxValue:Number):void{ + flash.external.ExternalInterface.call(this.js_update_progress, this.js_id, value * 100 / maxValue); +>>>>>>> upstream/master trace(value + "-" + maxValue + "-" + value * 100 / maxValue + "%"); } // update checking status private function updateState(text:String):void{ +<<<<<<< HEAD flash.external.ExternalInterface.call(this.js_update_status, text); trace(text); } +======= + flash.external.ExternalInterface.call(this.js_update_status, this.js_id, text); + trace(text); + } + + public function onBWDone():void{ + } +>>>>>>> upstream/master } } \ No newline at end of file diff --git a/trunk/research/players/srs_player/release/srs_player.swf b/trunk/research/players/srs_player/release/srs_player.swf index bb8c11647..7361e298b 100755 Binary files a/trunk/research/players/srs_player/release/srs_player.swf and b/trunk/research/players/srs_player/release/srs_player.swf differ diff --git a/trunk/research/players/srs_player/src/srs_player.as b/trunk/research/players/srs_player/src/srs_player.as index 0b5282a6f..9640f387e 100755 --- a/trunk/research/players/srs_player/src/srs_player.as +++ b/trunk/research/players/srs_player/src/srs_player.as @@ -305,8 +305,8 @@ package if (evt.info.data.hasOwnProperty("srs_server")) { customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); } - if (evt.info.data.hasOwnProperty("srs_contributor")) { - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); } contextMenu.customItems = customItems; } @@ -334,7 +334,7 @@ package if (url.indexOf("http") == 0) { media_stream.play(url); } else { - var streamName:String = url.substr(url.lastIndexOf("/")); + var streamName:String = url.substr(url.lastIndexOf("/") + 1); media_stream.play(streamName); } diff --git a/trunk/research/players/srs_publisher/release/srs_publisher.swf b/trunk/research/players/srs_publisher/release/srs_publisher.swf index 3f173e84a..b63ee1ff7 100755 Binary files a/trunk/research/players/srs_publisher/release/srs_publisher.swf and b/trunk/research/players/srs_publisher/release/srs_publisher.swf differ diff --git a/trunk/research/players/srs_publisher/src/srs_publisher.as b/trunk/research/players/srs_publisher/src/srs_publisher.as index d9141b4ce..d91641493 100755 --- a/trunk/research/players/srs_publisher/src/srs_publisher.as +++ b/trunk/research/players/srs_publisher/src/srs_publisher.as @@ -192,8 +192,8 @@ package if (evt.info.data.hasOwnProperty("srs_server")) { customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); } - if (evt.info.data.hasOwnProperty("srs_contributor")) { - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); + if (evt.info.data.hasOwnProperty("srs_primary_authors")) { + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors)); } contextMenu.customItems = customItems; } diff --git a/trunk/src/core/srs_core.cpp b/trunk/src/core/srs_core.cpp index 8ef6cceca..05a80f45a 100755 --- a/trunk/src/core/srs_core.cpp +++ b/trunk/src/core/srs_core.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index ce3bfadc5..b42d35e70 100755 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -76,10 +76,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" -#define RTMP_SIG_SRS_EMAIL "winterserver@126.com" +#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin" -#define RTMP_SIG_SRS_CONTRIBUTOR "winlin,wenjiegit" +#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin" +#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjiegit" // compare #define srs_min(a, b) (((a) < (b))? (a) : (b)) diff --git a/trunk/src/core/srs_core_amf0.cpp b/trunk/src/core/srs_core_amf0.cpp index b6b8a2dc5..940bf6f1e 100755 --- a/trunk/src/core/srs_core_amf0.cpp +++ b/trunk/src/core/srs_core_amf0.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_amf0.hpp b/trunk/src/core/srs_core_amf0.hpp index 68ff63784..219011351 100755 --- a/trunk/src/core/srs_core_amf0.hpp +++ b/trunk/src/core/srs_core_amf0.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_autofree.cpp b/trunk/src/core/srs_core_autofree.cpp index ba391709a..cbd317870 100755 --- a/trunk/src/core/srs_core_autofree.cpp +++ b/trunk/src/core/srs_core_autofree.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_autofree.hpp b/trunk/src/core/srs_core_autofree.hpp index 73035b783..513a4dcf5 100755 --- a/trunk/src/core/srs_core_autofree.hpp +++ b/trunk/src/core/srs_core_autofree.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_bandwidth.cpp b/trunk/src/core/srs_core_bandwidth.cpp index 4e3a5dd6e..fd833bd11 100755 --- a/trunk/src/core/srs_core_bandwidth.cpp +++ b/trunk/src/core/srs_core_bandwidth.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 wenjiegit +Copyright (c) 2013-2014 wenjiegit 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 diff --git a/trunk/src/core/srs_core_bandwidth.hpp b/trunk/src/core/srs_core_bandwidth.hpp index ef66a86f2..0f375bdc5 100755 --- a/trunk/src/core/srs_core_bandwidth.hpp +++ b/trunk/src/core/srs_core_bandwidth.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 wenjiegit +Copyright (c) 2013-2014 wenjiegit 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 diff --git a/trunk/src/core/srs_core_buffer.cpp b/trunk/src/core/srs_core_buffer.cpp index 11d760a2c..31572b6c5 100755 --- a/trunk/src/core/srs_core_buffer.cpp +++ b/trunk/src/core/srs_core_buffer.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_buffer.hpp b/trunk/src/core/srs_core_buffer.hpp index a36f5f65b..8d66cdcbd 100755 --- a/trunk/src/core/srs_core_buffer.hpp +++ b/trunk/src/core/srs_core_buffer.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_client.cpp b/trunk/src/core/srs_core_client.cpp index e1901c248..3d5dc6c4d 100755 --- a/trunk/src/core/srs_core_client.cpp +++ b/trunk/src/core/srs_core_client.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -42,11 +42,6 @@ using namespace std; #include #include -#define SRS_PULSE_TIMEOUT_MS 100 -#define SRS_SEND_TIMEOUT_US 5000000L -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US -#define SRS_STREAM_BUSY_SLEEP_MS 2000 - SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) : SrsConnection(srs_server, client_stfd) { @@ -198,7 +193,7 @@ int SrsClient::service_cycle() srs_warn("stream %s is already publishing. ret=%d", req->get_stream_url().c_str(), ret); // to delay request - st_usleep(SRS_STREAM_BUSY_SLEEP_MS * 1000); + st_usleep(SRS_STREAM_BUSY_SLEEP_US); return ret; } @@ -324,12 +319,12 @@ int SrsClient::playing(SrsSource* source) SrsAutoFree(SrsConsumer, consumer, false); srs_verbose("consumer created success."); - rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); + rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US); SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER); while (true) { - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); // switch to other st-threads. st_usleep(0); diff --git a/trunk/src/core/srs_core_client.hpp b/trunk/src/core/srs_core_client.hpp index f8aaee87c..3d93f4123 100755 --- a/trunk/src/core/srs_core_client.hpp +++ b/trunk/src/core/srs_core_client.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_codec.cpp b/trunk/src/core/srs_core_codec.cpp index af1b91519..323d7621e 100755 --- a/trunk/src/core/srs_core_codec.cpp +++ b/trunk/src/core/srs_core_codec.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_codec.hpp b/trunk/src/core/srs_core_codec.hpp index 18cc32a5a..5e700dafe 100755 --- a/trunk/src/core/srs_core_codec.hpp +++ b/trunk/src/core/srs_core_codec.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_config.cpp b/trunk/src/core/srs_core_config.cpp index ed83a46d6..812bb7062 100755 --- a/trunk/src/core/srs_core_config.cpp +++ b/trunk/src/core/srs_core_config.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -735,9 +735,9 @@ int SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { - printf(RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION - " Copyright (c) 2013 winlin\n" - "Contributors: "RTMP_SIG_SRS_CONTRIBUTOR"\n" + printf( + RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION" "RTMP_SIG_SRS_COPYRIGHT"\n" + "Primary Authors: "RTMP_SIG_SRS_PRIMARY_AUTHROS"\n" "Build: "SRS_BUILD_DATE" Configuration: "SRS_CONFIGURE"\n" "Usage: %s [-h?vV] [-c ]\n" "\n" @@ -1664,4 +1664,3 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) return true; } - diff --git a/trunk/src/core/srs_core_config.hpp b/trunk/src/core/srs_core_config.hpp index 3c7dd3b65..4bbe122eb 100755 --- a/trunk/src/core/srs_core_config.hpp +++ b/trunk/src/core/srs_core_config.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -57,7 +57,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // the interval in seconds for bandwidth check #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000 -#define SRS_CONF_DEFAULT_CHUNK_SIZE 4096 +// the default chunk size for system. +#define SRS_CONF_DEFAULT_CHUNK_SIZE 60000 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 diff --git a/trunk/src/core/srs_core_conn.cpp b/trunk/src/core/srs_core_conn.cpp index e148db79a..02c758891 100755 --- a/trunk/src/core/srs_core_conn.cpp +++ b/trunk/src/core/srs_core_conn.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_conn.hpp b/trunk/src/core/srs_core_conn.hpp index 4689eb7d7..8ac78f8d3 100755 --- a/trunk/src/core/srs_core_conn.hpp +++ b/trunk/src/core/srs_core_conn.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_encoder.cpp b/trunk/src/core/srs_core_encoder.cpp index f2b041ac6..95cf523ac 100755 --- a/trunk/src/core/srs_core_encoder.cpp +++ b/trunk/src/core/srs_core_encoder.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -37,11 +37,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #ifdef SRS_FFMPEG -#define SRS_ENCODER_SLEEP_MS 2000 - #define SRS_ENCODER_COPY "copy" #define SRS_ENCODER_VCODEC "libx264" #define SRS_ENCODER_ACODEC "libaacplus" @@ -483,7 +482,7 @@ void SrsFFMPEG::stop() SrsEncoder::SrsEncoder() { - pthread = new SrsThread(this, SRS_ENCODER_SLEEP_MS); + pthread = new SrsThread(this, SRS_ENCODER_SLEEP_US); pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER); } @@ -549,7 +548,7 @@ int SrsEncoder::cycle() // pithy print encoder(); - pithy_print->elapse(SRS_ENCODER_SLEEP_MS); + pithy_print->elapse(SRS_ENCODER_SLEEP_US / 1000); return ret; } diff --git a/trunk/src/core/srs_core_encoder.hpp b/trunk/src/core/srs_core_encoder.hpp index 4ecfd59c9..eb34572d1 100755 --- a/trunk/src/core/srs_core_encoder.hpp +++ b/trunk/src/core/srs_core_encoder.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_error.cpp b/trunk/src/core/srs_core_error.cpp index b9ea1d673..3163d0036 100755 --- a/trunk/src/core/srs_core_error.cpp +++ b/trunk/src/core/srs_core_error.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_error.hpp b/trunk/src/core/srs_core_error.hpp index 15af170a3..587491579 100755 --- a/trunk/src/core/srs_core_error.hpp +++ b/trunk/src/core/srs_core_error.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_forward.cpp b/trunk/src/core/srs_core_forward.cpp index 73e398343..98c545399 100755 --- a/trunk/src/core/srs_core_forward.cpp +++ b/trunk/src/core/srs_core_forward.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -38,11 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#define SRS_PULSE_TIMEOUT_MS 100 -#define SRS_FORWARDER_SLEEP_MS 2000 -#define SRS_SEND_TIMEOUT_US 3000000L -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US - SrsForwarder::SrsForwarder(SrsSource* _source) { source = _source; @@ -51,7 +46,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) stfd = NULL; stream_id = 0; - pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_MS); + pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_US); queue = new SrsMessageQueue(); jitter = new SrsRtmpJitter(); } @@ -286,11 +281,11 @@ int SrsForwarder::forward() { int ret = ERROR_SUCCESS; - client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); + client->set_recv_timeout(SRS_PULSE_TIMEOUT_US); SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); - while (true) { + while (pthread->can_loop()) { // switch to other st-threads. st_usleep(0); @@ -322,7 +317,7 @@ int SrsForwarder::forward() SrsAutoFree(SrsSharedPtrMessage*, msgs, true); // pithy print - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000); if (pithy_print.can_print()) { srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); diff --git a/trunk/src/core/srs_core_forward.hpp b/trunk/src/core/srs_core_forward.hpp index a2e832cb5..34bfbfb95 100755 --- a/trunk/src/core/srs_core_forward.hpp +++ b/trunk/src/core/srs_core_forward.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_handshake.cpp b/trunk/src/core/srs_core_handshake.cpp index 44c3e4a01..32239ee03 100755 --- a/trunk/src/core/srs_core_handshake.cpp +++ b/trunk/src/core/srs_core_handshake.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_handshake.hpp b/trunk/src/core/srs_core_handshake.hpp index e34135a7c..06686fc1e 100755 --- a/trunk/src/core/srs_core_handshake.hpp +++ b/trunk/src/core/srs_core_handshake.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_hls.cpp b/trunk/src/core/srs_core_hls.cpp index b7182cad5..8d0b14d81 100755 --- a/trunk/src/core/srs_core_hls.cpp +++ b/trunk/src/core/srs_core_hls.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_hls.hpp b/trunk/src/core/srs_core_hls.hpp index 9474909f3..746d6e3c0 100755 --- a/trunk/src/core/srs_core_hls.hpp +++ b/trunk/src/core/srs_core_hls.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_http.cpp b/trunk/src/core/srs_core_http.cpp index 867f3635f..9f350e493 100755 --- a/trunk/src/core/srs_core_http.cpp +++ b/trunk/src/core/srs_core_http.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_http.hpp b/trunk/src/core/srs_core_http.hpp index 0989717bb..67a05088d 100755 --- a/trunk/src/core/srs_core_http.hpp +++ b/trunk/src/core/srs_core_http.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_log.cpp b/trunk/src/core/srs_core_log.cpp index 27aa5ae0a..64f0c9294 100755 --- a/trunk/src/core/srs_core_log.cpp +++ b/trunk/src/core/srs_core_log.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_log.hpp b/trunk/src/core/srs_core_log.hpp index e97c51bdc..ffeca8ec2 100755 --- a/trunk/src/core/srs_core_log.hpp +++ b/trunk/src/core/srs_core_log.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_pithy_print.cpp b/trunk/src/core/srs_core_pithy_print.cpp index abb568596..e375c4006 100755 --- a/trunk/src/core/srs_core_pithy_print.cpp +++ b/trunk/src/core/srs_core_pithy_print.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_pithy_print.hpp b/trunk/src/core/srs_core_pithy_print.hpp index 9a86c0e8d..c402f5a3c 100755 --- a/trunk/src/core/srs_core_pithy_print.hpp +++ b/trunk/src/core/srs_core_pithy_print.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_protocol.hpp b/trunk/src/core/srs_core_protocol.hpp index 490d7cb94..ca6602c67 100755 --- a/trunk/src/core/srs_core_protocol.hpp +++ b/trunk/src/core/srs_core_protocol.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -36,6 +36,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +// the following is the timeout for rtmp protocol, +// to avoid death connection. + +// when got a messae header, there must be some data, +// increase recv timeout to got an entire message. +#define SRS_MIN_RECV_TIMEOUT_US 60*1000*1000L + +// the timeout to wait for client control message, +// if timeout, we generally ignore and send the data to client, +// generally, it's the pulse time for data seding. +#define SRS_PULSE_TIMEOUT_US 200*1000L + +// the timeout to wait client data, +// if timeout, close the connection. +#define SRS_SEND_TIMEOUT_US 30*1000*1000L + +// the timeout to send data to client, +// if timeout, close the connection. +#define SRS_RECV_TIMEOUT_US 30*1000*1000L + +// when stream is busy, for example, streaming is already +// publishing, when a new client to request to publish, +// sleep a while and close the connection. +#define SRS_STREAM_BUSY_SLEEP_US 3*1000*1000L + +// when error, forwarder sleep for a while and retry. +#define SRS_FORWARDER_SLEEP_US 3*1000*1000L + +// when error, encoder sleep for a while and retry. +#define SRS_ENCODER_SLEEP_US 3*1000*1000L + class SrsSocket; class SrsBuffer; class SrsPacket; diff --git a/trunk/src/core/srs_core_refer.cpp b/trunk/src/core/srs_core_refer.cpp index fbe70b559..c7ff7ac1a 100755 --- a/trunk/src/core/srs_core_refer.cpp +++ b/trunk/src/core/srs_core_refer.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_refer.hpp b/trunk/src/core/srs_core_refer.hpp index 17067e297..9b4e27b9c 100755 --- a/trunk/src/core/srs_core_refer.hpp +++ b/trunk/src/core/srs_core_refer.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_reload.cpp b/trunk/src/core/srs_core_reload.cpp index f6feee15e..d4cd85f58 100755 --- a/trunk/src/core/srs_core_reload.cpp +++ b/trunk/src/core/srs_core_reload.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_reload.hpp b/trunk/src/core/srs_core_reload.hpp index 3d8f3e8b9..78f6effa6 100755 --- a/trunk/src/core/srs_core_reload.hpp +++ b/trunk/src/core/srs_core_reload.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_rtmp.cpp b/trunk/src/core/srs_core_rtmp.cpp index 471e19262..deeddd54f 100755 --- a/trunk/src/core/srs_core_rtmp.cpp +++ b/trunk/src/core/srs_core_rtmp.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -391,12 +391,44 @@ int SrsRtmpClient::play(string stream, int stream_id) } } + // SetChunkSize + if (true) { + SrsCommonMessage* msg = new SrsCommonMessage(); + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); + + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE; + msg->set_packet(pkt, 0); + + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { + srs_error("send set chunk size failed. " + "stream=%s, chunk_size=%d, ret=%d", + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret); + return ret; + } + } + return ret; } int SrsRtmpClient::publish(string stream, int stream_id) { int ret = ERROR_SUCCESS; + + // SetChunkSize + if (true) { + SrsCommonMessage* msg = new SrsCommonMessage(); + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket(); + + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE; + msg->set_packet(pkt, 0); + + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) { + srs_error("send set chunk size failed. " + "stream=%s, chunk_size=%d, ret=%d", + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret); + return ret; + } + } // publish(stream) if (true) { @@ -617,7 +649,7 @@ int SrsRtmp::response_connect_app(SrsRequest *req, const char* server_ip) data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB)); data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL)); data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT)); - data->set("srs_contributor", new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); + data->set("srs_primary_authors", new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS)); if (server_ip) { data->set("srs_server_ip", new SrsAmf0String(server_ip)); @@ -1194,4 +1226,3 @@ int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& return ret; } - diff --git a/trunk/src/core/srs_core_rtmp.hpp b/trunk/src/core/srs_core_rtmp.hpp index 6cf60cb57..6c967c1c3 100755 --- a/trunk/src/core/srs_core_rtmp.hpp +++ b/trunk/src/core/srs_core_rtmp.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -110,7 +110,7 @@ enum SrsClientType */ class SrsRtmpClient { -private: +protected: SrsProtocol* protocol; st_netfd_t stfd; public: diff --git a/trunk/src/core/srs_core_server.cpp b/trunk/src/core/srs_core_server.cpp index 4833673f4..a10e6da80 100755 --- a/trunk/src/core/srs_core_server.cpp +++ b/trunk/src/core/srs_core_server.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#define SERVER_LISTEN_BACKLOG 10 +#define SERVER_LISTEN_BACKLOG 512 #define SRS_TIME_RESOLUTION_MS 500 SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type) diff --git a/trunk/src/core/srs_core_server.hpp b/trunk/src/core/srs_core_server.hpp index 79664657d..13599b465 100755 --- a/trunk/src/core/srs_core_server.hpp +++ b/trunk/src/core/srs_core_server.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_socket.cpp b/trunk/src/core/srs_core_socket.cpp index 365b3ed77..7628c3c70 100755 --- a/trunk/src/core/srs_core_socket.cpp +++ b/trunk/src/core/srs_core_socket.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_socket.hpp b/trunk/src/core/srs_core_socket.hpp index f355dbfb1..8b25c39dd 100755 --- a/trunk/src/core/srs_core_socket.hpp +++ b/trunk/src/core/srs_core_socket.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_source.cpp b/trunk/src/core/srs_core_source.cpp index 5cca79543..a86c0cc97 100755 --- a/trunk/src/core/srs_core_source.cpp +++ b/trunk/src/core/srs_core_source.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -642,7 +642,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata metadata->metadata->set("server", new SrsAmf0String( RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); metadata->metadata->set("contributor", - new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); + new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS)); SrsAmf0Any* prop = NULL; if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { diff --git a/trunk/src/core/srs_core_source.hpp b/trunk/src/core/srs_core_source.hpp index 405c51e53..3f8d62796 100755 --- a/trunk/src/core/srs_core_source.hpp +++ b/trunk/src/core/srs_core_source.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_stream.cpp b/trunk/src/core/srs_core_stream.cpp index 6530ee40d..a22581c07 100755 --- a/trunk/src/core/srs_core_stream.cpp +++ b/trunk/src/core/srs_core_stream.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_stream.hpp b/trunk/src/core/srs_core_stream.hpp index 7bbc4d5a1..df7cc27f9 100755 --- a/trunk/src/core/srs_core_stream.hpp +++ b/trunk/src/core/srs_core_stream.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/core/srs_core_thread.cpp b/trunk/src/core/srs_core_thread.cpp index fbbe4b300..b6742f29c 100755 --- a/trunk/src/core/srs_core_thread.cpp +++ b/trunk/src/core/srs_core_thread.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -54,10 +54,10 @@ void ISrsThreadHandler::on_leave_loop() { } -SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms) +SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us) { handler = thread_handler; - cycle_interval_milliseconds = interval_ms; + cycle_interval_us = interval_us; tid = NULL; loop = false; @@ -102,6 +102,11 @@ void SrsThread::stop() } } +bool SrsThread::can_loop() +{ + return loop; +} + void SrsThread::thread_cycle() { int ret = ERROR_SUCCESS; @@ -138,7 +143,7 @@ failed: break; } - st_usleep(cycle_interval_milliseconds * 1000); + st_usleep(cycle_interval_us); } handler->on_leave_loop(); diff --git a/trunk/src/core/srs_core_thread.hpp b/trunk/src/core/srs_core_thread.hpp index fb3ef8136..3210dcb56 100755 --- a/trunk/src/core/srs_core_thread.hpp +++ b/trunk/src/core/srs_core_thread.hpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * when stop, the thread will interrupt the st_thread, * which will cause the socket to return error and * terminate the cycle thread. +* +* when thread interrupt, the socket maybe not got EINT, +* espectially on st_usleep(), so the cycle must check the loop, +* when handler->cycle() has loop itself, for example: +* handler->cycle() is: +* while (true): +* st_usleep(0); +* if (read_from_socket(skt) < 0) break; +* if thread stop when read_from_socket, it's ok, the loop will break, +* but when thread stop interrupt the s_usleep(0), then the loop is +* death loop. +* in a word, the handler->cycle() must: +* handler->cycle() is: +* while (pthread->can_loop()): +* st_usleep(0); +* if (read_from_socket(skt) < 0) break; +* check the loop, then it works. */ class ISrsThreadHandler { @@ -68,14 +85,14 @@ private: bool loop; private: ISrsThreadHandler* handler; - int64_t cycle_interval_milliseconds; + int64_t cycle_interval_us; public: /** * initialize the thread. * @param thread_handler, the cycle handler for the thread. - * @param interval_ms, the sleep interval when cycle finished. + * @param interval_us, the sleep interval when cycle finished. */ - SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms); + SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us); virtual ~SrsThread(); public: /** @@ -90,6 +107,12 @@ public: * @remark user can stop multiple times, ignore if already stopped. */ virtual void stop(); + /** + * whether the thread should loop, + * used for handler->cycle() which has a loop method, + * to check this method, break if false. + */ + virtual bool can_loop(); private: virtual void thread_cycle(); static void* thread_fun(void* arg); diff --git a/trunk/src/main/srs_main_bandcheck.cpp b/trunk/src/main/srs_main_bandcheck.cpp index 7d82f2a21..107722d1c 100755 --- a/trunk/src/main/srs_main_bandcheck.cpp +++ b/trunk/src/main/srs_main_bandcheck.cpp @@ -1,826 +1,832 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013 wenjiegit - -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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -// server play control -#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes" -#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes" -#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes" -#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes" - -// server publish control -#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes" -#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes" -#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes" -#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes" - -// EOF control. -#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished" -#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket" - -// client only -#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying" -#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" - -/** -* @brief class of Linux version band check client -* check play and publish speed. -*/ -class SrsBandCheckClient : public SrsRtmpClient -{ -public: - SrsBandCheckClient(st_netfd_t _stfd); - ~SrsBandCheckClient(); - -public: - /** - * @brief test play - * - */ - int check_play(); - /** - * @brief test publish - * - */ - int check_publish(); - -private: - /** - * @brief just return success. - */ - int create_stream(int& stream_id); - /** - * @brief just return success. - */ - int play(std::string stream, int stream_id); - /** - * @brief just return success. - */ - int publish(std::string stream, int stream_id); - -private: - int expect_start_play(); - int send_starting_play(); - int expect_stop_play(); - int send_stopped_play(); - int expect_start_pub(); - int send_starting_pub(); - int send_pub_data(); - int expect_stop_pub(); - /** - * @brief expect result. - * because the core module has no method to decode this packet - * so we must get the internal data and decode it here. - */ - int expect_finished(); - int send_stopped_pub(); - /** - * @brief notify server the check procedure is over. - */ - int send_final(); -}; - -/** -* @brief class of band check -* used to check band width with a client @param bandCheck_Client -*/ -class SrsBandCheck -{ -public: - SrsBandCheck(); - ~SrsBandCheck(); - -public: - /** - * @brief band check method - * - * connect to server------>rtmp handshake------>rtmp connect------>play------>publish - * @retval ERROR_SUCCESS when success. - */ - int check(const std::string& app, const std::string& tcUrl); - - /** - * @brief set the address and port of test server - * - * @param server server address, domain or ip - * @param server listened port ,default is 1935 - */ - void set_server(const std::string& server, int port = 1935); - -private: - int connect_server(); - -private: - SrsBandCheckClient* bandCheck_Client; - std::string server_address; - int server_port; -}; - -/** -* @brief init st lib -*/ -static int init_st(); -static void print_help(); -static void print_version(); - -/** -* @brief get user option -* @internal ip Mandatory arguments -* @internal key Mandatory arguments -* @internal port default 1935 -* @internal vhost default bandcheck.srs.com -*/ -static int get_opt(int argc ,char* argv[]); - -/** -* global var. -*/ -static struct option long_options[] = -{ - {"ip", required_argument, 0, 'i'}, - {"port", optional_argument, 0, 'p'}, - {"key", required_argument, 0, 'k'}, - {"vhost", optional_argument, 0, 'v'}, - {"help", no_argument, 0, 'h'}, - {"version", no_argument, 0, 'V'}, -}; - -static const char* short_options = "i:p::k:v::hV"; - -static std::string g_ip; -static int g_port = 1935; -static std::string g_key; -static std::string g_vhost = "bandcheck.srs.com"; - -#define BUILD_VERSION "srs band check 0.1" - -int main(int argc ,char* argv[]) -{ - int ret = ERROR_SUCCESS; - - if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) { - return -1; - } - - // check param - if (g_ip.empty()) { - printf("ip address should not be empty."); - return -1; - } - - if (g_key.empty()) { - printf("test key should not be empty."); - return -1; - } - - if ((ret = init_st()) != ERROR_SUCCESS) { - srs_error("band check init failed. ret=%d", ret); - return ret; - } - - std::string app = "app?key=" + g_key + "&vhost=" + g_vhost; - - char tcUrl_buffer[1024] = {0}; - sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str()); - std::string tcUrl = tcUrl_buffer; - - SrsBandCheck band_check; - band_check.set_server(g_ip, g_port); - if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) { - srs_error("band check failed. address=%s ret=%d", "xx.com", ret); - return -1; - } - - return 0; -} - -SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd) - : SrsRtmpClient(_stfd) -{ -} - -SrsBandCheckClient::~SrsBandCheckClient() -{ -} - -int SrsBandCheckClient::check_play() -{ - int ret = ERROR_SUCCESS; - - if ((ret = expect_start_play()) != ERROR_SUCCESS) { - srs_error("expect_start_play failed. ret=%d", ret); - return ret; - } - - if ((ret = send_starting_play()) != ERROR_SUCCESS) { - srs_error("send starting play failed. ret=%d", ret); - return ret; - } - - if ((ret = expect_stop_play()) != ERROR_SUCCESS) { - srs_error("expect stop play failed. ret=%d", ret); - return ret; - } - - if ((ret = send_stopped_play()) != ERROR_SUCCESS) { - srs_error("send stopped play failed. ret=%d", ret); - return ret; - } - - return ret; -} - -int SrsBandCheckClient::check_publish() -{ - int ret = ERROR_SUCCESS; - - if ((ret = expect_start_pub()) != ERROR_SUCCESS) { - srs_error("expect start pub failed. ret=%d", ret); - return ret; - } - - if ((ret = send_starting_pub())!= ERROR_SUCCESS) { - srs_error("send starting pub failed. ret=%d", ret); - return ret; - } - - if ((ret = send_pub_data()) != ERROR_SUCCESS) { - srs_error("publish data failed. ret=%d", ret); - return ret; - } - - if ((ret = send_stopped_pub()) != ERROR_SUCCESS) { - srs_error("send stopped pub failed. ret=%d", ret); - return ret; - } - - if ((ret = expect_finished()) != ERROR_SUCCESS) { - srs_error("expect finished msg failed. ret=%d", ret); - return ret; - } - - if ((ret = send_final()) != ERROR_SUCCESS) { - srs_error("send final msg failed. ret=%d", ret); - return ret; - } - - return ret; -} - -int SrsBandCheckClient::create_stream(int &stream_id) -{ - return ERROR_SUCCESS; -} - -int SrsBandCheckClient::play(std::string stream, int stream_id) -{ - return ERROR_SUCCESS; -} - -int SrsBandCheckClient::publish(std::string stream, int stream_id) -{ - return ERROR_SUCCESS; -} - -int SrsBandCheckClient::expect_start_play() -{ - int ret = ERROR_SUCCESS; - - // expect connect _result - SrsCommonMessage* msg = NULL; - SrsBandwidthPacket* pkt = NULL; - if ((ret = srs_rtmp_expect_message(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { - srs_error("expect bandcheck start play message failed. ret=%d", ret); - return ret; - } - SrsAutoFree(SrsCommonMessage, msg, false); - srs_info("get bandcheck start play message"); - - if (pkt->command_name != SRS_BW_CHECK_START_PLAY) { - srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str()); - return -1; - } - - return ret; -} - -int SrsBandCheckClient::send_starting_play() -{ - int ret = ERROR_SUCCESS; - - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_STARTING_PLAY; - msg->set_packet(pkt, 0); - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send starting play msg failed. ret=%d", ret); - return ret; - } - - return ret; -} - -int SrsBandCheckClient::expect_stop_play() -{ - int ret = ERROR_SUCCESS; - - while (true) { - SrsCommonMessage* msg = NULL; - SrsBandwidthPacket* pkt = NULL; - if ((ret = srs_rtmp_expect_message(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { - srs_error("expect stop play message failed. ret=%d", ret); - return ret; - } - SrsAutoFree(SrsCommonMessage, msg, false); - srs_info("get bandcheck stop play message"); - - if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) { - break; - } - } - - return ret; -} - -int SrsBandCheckClient::send_stopped_play() -{ - int ret = ERROR_SUCCESS; - - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY; - msg->set_packet(pkt, 0); - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send stopped play msg failed. ret=%d", ret); - return ret; - } - - return ret; -} - -int SrsBandCheckClient::expect_start_pub() -{ - int ret = ERROR_SUCCESS; - - while (true) { - SrsCommonMessage* msg = NULL; - SrsBandwidthPacket* pkt = NULL; - if ((ret = srs_rtmp_expect_message(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { - srs_error("expect start pub message failed. ret=%d", ret); - return ret; - } - SrsAutoFree(SrsCommonMessage, msg, false); - srs_info("get bandcheck start pub message"); - - if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) { - break; - } - } - - return ret; -} - -int SrsBandCheckClient::send_starting_pub() -{ - int ret = ERROR_SUCCESS; - - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH; - msg->set_packet(pkt, 0); - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send starting play msg failed. ret=%d", ret); - return ret; - } - srs_info("send starting play msg success."); - - return ret; -} - -int SrsBandCheckClient::send_pub_data() -{ - int ret = ERROR_SUCCESS; - - int data_count = 100; - while (true) { - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_PUBLISHING; - msg->set_packet(pkt, 0); - - for (int i = 0; i < data_count; ++i) { - std::stringstream seq; - seq << i; - std::string play_data = "SrS band check data from client's publishing......"; - pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str())); - } - data_count += 100; - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send publish message failed.ret=%d", ret); - return ret; - } - - if ((ret = expect_stop_pub()) == ERROR_SUCCESS) { - break; - } - } - - return ret; -} - -int SrsBandCheckClient::expect_stop_pub() -{ - int ret = ERROR_SUCCESS; - - while (true) { - if ((ret = st_netfd_poll(get_st_fd(), POLLIN, 1000)) == ERROR_SUCCESS) { - SrsCommonMessage* msg = 0; - if ((ret = recv_message(&msg)) != ERROR_SUCCESS) - { - srs_error("recv message failed while expect stop pub. ret=%d", ret); - return ret; - } - - if ((ret = msg->decode_packet(get_protocol())) != ERROR_SUCCESS) { - srs_error("decode packet error while expect stop pub. ret=%d", ret); - return ret; - } - - SrsBandwidthPacket* pkt = dynamic_cast(msg->get_packet()); - if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) { - - return ret; - } - } else { - break; - } - } - - return ret; -} - -int SrsBandCheckClient::expect_finished() -{ - int ret = ERROR_SUCCESS; - - while (true) { - SrsCommonMessage* msg = NULL; - SrsBandwidthPacket* pkt = NULL; - if ((ret = srs_rtmp_expect_message(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) { - srs_error("expect finished message failed. ret=%d", ret); - return ret; - } - SrsAutoFree(SrsCommonMessage, msg, false); - srs_info("get bandcheck finished message"); - - if (pkt->command_name == SRS_BW_CHECK_FINISHED) { - SrsStream *stream = new SrsStream; - SrsAutoFree(SrsStream, stream, false); - - if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) { - srs_error("initialize stream error. ret=%d", ret); - return ret; - } - - std::string command_name; - if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { - srs_error("amfo read string error. ret=%d", ret); - return ret; - } - - double action_id; - if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) { - srs_error("amfo read number error. ret=%d", ret); - return ret; - } - - if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { - srs_error("amfo read number error. ret=%d", ret); - return ret; - } - - SrsAmf0Object* object; - if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) { - srs_error("amfo read object error. ret=%d", ret); - return ret; - } - - int64_t start_time = 0; - int64_t end_time = 0; - - SrsAmf0Any* start_time_any = object->get_property("start_time"); - if (start_time_any && start_time_any->is_number()) { - SrsAmf0Number* start_time_number = dynamic_cast (start_time_any); - if (start_time_number) { - start_time = start_time_number->value; - } - } - - SrsAmf0Any* end_time_any = object->get_property("end_time"); - if (end_time_any && end_time_any->is_number()) { - SrsAmf0Number* end_time_number = dynamic_cast (end_time_any); - if (end_time_number) { - end_time = end_time_number->value; - } - } - - int play_kbps = 0; - int pub_kbps = 0; - SrsAmf0Any* play_kbp_any = object->get_property("play_kbps"); - if (play_kbp_any && play_kbp_any->is_number()) { - SrsAmf0Number* play_kbps_number = dynamic_cast (play_kbp_any); - if (play_kbps_number) { - play_kbps = play_kbps_number->value; - } - } - - SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps"); - if (pub_kbp_any && pub_kbp_any->is_number()) { - SrsAmf0Number* pub_kbps_number = dynamic_cast (pub_kbp_any); - if (pub_kbps_number) { - pub_kbps = pub_kbps_number->value; - } - } - - float time_elapsed; - if (end_time - start_time > 0) { - time_elapsed = (end_time - start_time) / 1000.00; - } - - srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n" - , play_kbps, pub_kbps, time_elapsed); - - break; - } - } - - return ret; -} - -int SrsBandCheckClient::send_stopped_pub() -{ - int ret = ERROR_SUCCESS; - - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH; - msg->set_packet(pkt, 0); - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send stopped pub msg failed. ret=%d", ret); - return ret; - } - srs_info("send stopped pub msg success."); - - return ret; -} - -int SrsBandCheckClient::send_final() -{ - int ret = ERROR_SUCCESS; - - SrsCommonMessage* msg = new SrsCommonMessage; - SrsBandwidthPacket* pkt = new SrsBandwidthPacket; - pkt->command_name = SRS_BW_CHECK_FLASH_FINAL; - msg->set_packet(pkt, 0); - - if ((ret = send_message(msg)) != ERROR_SUCCESS) { - srs_error("send final msg failed. ret=%d", ret); - return ret; - } - srs_info("send final msg success."); - - return ret; -} - -SrsBandCheck::SrsBandCheck() - : bandCheck_Client(0) -{ -} - -SrsBandCheck::~SrsBandCheck() -{ - if (bandCheck_Client) { - srs_freep(bandCheck_Client); - } -} - -int SrsBandCheck::check(const std::string &app, const std::string &tcUrl) -{ - int ret = ERROR_SUCCESS; - - if ((ret = connect_server()) != ERROR_SUCCESS) { - srs_error("connect to server failed. ret = %d", ret); - return ret; - } - - if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) { - srs_error("handshake failed. ret = %d", ret); - return ret; - } - - if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) { - srs_error("handshake failed. ret = %d", ret); - return ret; - } - - if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) { - srs_error("band check play failed."); - return ret; - } - - if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) { - srs_error("band check publish failed."); - return ret; - } - - return ret; -} - -void SrsBandCheck::set_server(const std::string &server, int port) -{ - server_address = server; - server_port = port; -} - -int SrsBandCheck::connect_server() -{ - int ret = ERROR_SUCCESS; - - int sock = socket(AF_INET, SOCK_STREAM, 0); - if(sock == -1){ - ret = ERROR_SOCKET_CREATE; - srs_error("create socket error. ret=%d", ret); - return ret; - } - - st_netfd_t stfd = st_netfd_open_socket(sock); - if(stfd == NULL){ - ret = ERROR_ST_OPEN_SOCKET; - srs_error("st_netfd_open_socket failed. ret=%d", ret); - return ret; - } - - bandCheck_Client = new SrsBandCheckClient(stfd); - - // connect to server. - std::string ip = srs_dns_resolve(server_address); - if (ip.empty()) { - ret = ERROR_SYSTEM_IP_INVALID; - srs_error("dns resolve server error, ip empty. ret=%d", ret); - return ret; - } - - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(server_port); - addr.sin_addr.s_addr = inet_addr(ip.c_str()); - - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ - ret = ERROR_ST_CONNECT; - srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret); - return ret; - } - srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port); - - return ret; -} - -int init_st() -{ - int ret = ERROR_SUCCESS; - - if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { - ret = ERROR_ST_SET_EPOLL; - srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); - return ret; - } - - if(st_init() != 0){ - ret = ERROR_ST_INITIALIZE; - srs_error("st_init failed. ret=%d", ret); - return ret; - } - - return ret; -} - -void print_help() -{ - const char *help = "Usage: srs-bandcheck [OPTION]...\n" - "test band width from client to rtmp server.\n" - - "Mandatory arguments to long options are mandatory for short options too.\n" - " -i, --ip the ip or domain that to test\n" - " -p, --port the port that server listen \n" - " -k, --key the key used to test \n" - " -v, --vhost the vhost used to test \n" - " -V, --version output version information and exit \n" - " -h, --help display this help and exit \n" - "\n\n\n" - "Exit status:\n" - "0 if OK,\n" - "other if error occured, and the detail should be printed.\n" - "\n\n" - "srs home page: \n" - "srs home page: \n"; - - printf("%s", help); -} - -void print_version() -{ - const char *version = "" - "srs_bandcheck "BUILD_VERSION"\n" - "Copyright (C) 2013 wenjiegit.\n" - "License MIT\n" - "This is free software: you are free to change and redistribute it.\n" - "There is NO WARRANTY, to the extent permitted by law.\n" - "\n" - "Written by wenjie.\n"; - - printf("%s", version); -} - -int get_opt(int argc, char *argv[]) -{ - int ret = ERROR_SUCCESS; - - int c; - while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) { - switch (c) { - case 'i': - if (optarg) { - g_ip = optarg; - } - break; - case 'p': - if (optarg) { - g_port = atoi(optarg); - } - break; - case 'k': - if (optarg) { - g_key = optarg; - } - break; - case 'v': - if (optarg) { - g_vhost = optarg; - } - break; - case 'V': - print_version(); - exit(0); - break; - case 'h': - print_help(); - exit(0); - break; - default: - printf("see --help or -h\n"); - ret = -1; - } - } - - return ret; -} +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 wenjiegit + +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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +// server play control +#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes" +#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes" +#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes" +#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes" + +// server publish control +#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes" +#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes" +#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes" +#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes" + +// EOF control. +#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished" +#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket" + +// client only +#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying" +#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" + +/** +* @brief class of Linux version band check client +* check play and publish speed. +*/ +class SrsBandCheckClient : public SrsRtmpClient +{ +public: + SrsBandCheckClient(st_netfd_t _stfd); + ~SrsBandCheckClient(); + +public: + /** + * @brief test play + * + */ + int check_play(); + /** + * @brief test publish + * + */ + int check_publish(); + +private: + /** + * @brief just return success. + */ + int create_stream(int& stream_id); + /** + * @brief just return success. + */ + int play(std::string stream, int stream_id); + /** + * @brief just return success. + */ + int publish(std::string stream, int stream_id); + +private: + int expect_start_play(); + int send_starting_play(); + int expect_stop_play(); + int send_stopped_play(); + int expect_start_pub(); + int send_starting_pub(); + int send_pub_data(); + int expect_stop_pub(); + /** + * @brief expect result. + * because the core module has no method to decode this packet + * so we must get the internal data and decode it here. + */ + int expect_finished(); + int send_stopped_pub(); + /** + * @brief notify server the check procedure is over. + */ + int send_final(); +}; + +/** +* @brief class of band check +* used to check band width with a client @param bandCheck_Client +*/ +class SrsBandCheck +{ +public: + SrsBandCheck(); + ~SrsBandCheck(); + +public: + /** + * @brief band check method + * + * connect to server------>rtmp handshake------>rtmp connect------>play------>publish + * @retval ERROR_SUCCESS when success. + */ + int check(const std::string& app, const std::string& tcUrl); + + /** + * @brief set the address and port of test server + * + * @param server server address, domain or ip + * @param server listened port ,default is 1935 + */ + void set_server(const std::string& server, int port = 1935); + +private: + int connect_server(); + +private: + SrsBandCheckClient* bandCheck_Client; + std::string server_address; + int server_port; +}; + +/** +* @brief init st lib +*/ +static int init_st(); +static void print_help(char** argv); +static void print_version(); + +/** +* @brief get user option +* @internal ip Mandatory arguments +* @internal key Mandatory arguments +* @internal port default 1935 +* @internal vhost default bandcheck.srs.com +*/ +static int get_opt(int argc ,char* argv[]); + +/** +* global var. +*/ +static struct option long_options[] = +{ + {"ip", required_argument, 0, 'i'}, + {"port", optional_argument, 0, 'p'}, + {"key", required_argument, 0, 'k'}, + {"vhost", optional_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'V'}, +}; + +static const char* short_options = "i:p::k:v::hV"; + +static std::string g_ip; +static int g_port = 1935; +static std::string g_key; +static std::string g_vhost = "bandcheck.srs.com"; + +#define BUILD_VERSION "srs band check 0.1" + +int main(int argc ,char* argv[]) +{ + int ret = ERROR_SUCCESS; + + if (argc <= 1) { + print_help(argv); + exit(1); + } + + if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) { + return -1; + } + + // check param + if (g_ip.empty()) { + printf("ip address should not be empty.\n"); + return -1; + } + + if (g_key.empty()) { + printf("test key should not be empty.\n"); + return -1; + } + + if ((ret = init_st()) != ERROR_SUCCESS) { + srs_error("band check init failed. ret=%d", ret); + return ret; + } + + std::string app = "app?key=" + g_key + "&vhost=" + g_vhost; + + char tcUrl_buffer[1024] = {0}; + sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str()); + std::string tcUrl = tcUrl_buffer; + + SrsBandCheck band_check; + band_check.set_server(g_ip, g_port); + if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) { + srs_error("band check failed. address=%s ret=%d", "xx.com", ret); + return -1; + } + + return 0; +} + +SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd) + : SrsRtmpClient(_stfd) +{ +} + +SrsBandCheckClient::~SrsBandCheckClient() +{ +} + +int SrsBandCheckClient::check_play() +{ + int ret = ERROR_SUCCESS; + + if ((ret = expect_start_play()) != ERROR_SUCCESS) { + srs_error("expect_start_play failed. ret=%d", ret); + return ret; + } + + if ((ret = send_starting_play()) != ERROR_SUCCESS) { + srs_error("send starting play failed. ret=%d", ret); + return ret; + } + + if ((ret = expect_stop_play()) != ERROR_SUCCESS) { + srs_error("expect stop play failed. ret=%d", ret); + return ret; + } + + if ((ret = send_stopped_play()) != ERROR_SUCCESS) { + srs_error("send stopped play failed. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsBandCheckClient::check_publish() +{ + int ret = ERROR_SUCCESS; + + if ((ret = expect_start_pub()) != ERROR_SUCCESS) { + srs_error("expect start pub failed. ret=%d", ret); + return ret; + } + + if ((ret = send_starting_pub())!= ERROR_SUCCESS) { + srs_error("send starting pub failed. ret=%d", ret); + return ret; + } + + if ((ret = send_pub_data()) != ERROR_SUCCESS) { + srs_error("publish data failed. ret=%d", ret); + return ret; + } + + if ((ret = send_stopped_pub()) != ERROR_SUCCESS) { + srs_error("send stopped pub failed. ret=%d", ret); + return ret; + } + + if ((ret = expect_finished()) != ERROR_SUCCESS) { + srs_error("expect finished msg failed. ret=%d", ret); + return ret; + } + + if ((ret = send_final()) != ERROR_SUCCESS) { + srs_error("send final msg failed. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsBandCheckClient::create_stream(int &stream_id) +{ + return ERROR_SUCCESS; +} + +int SrsBandCheckClient::play(std::string stream, int stream_id) +{ + return ERROR_SUCCESS; +} + +int SrsBandCheckClient::publish(std::string stream, int stream_id) +{ + return ERROR_SUCCESS; +} + +int SrsBandCheckClient::expect_start_play() +{ + int ret = ERROR_SUCCESS; + + // expect connect _result + SrsCommonMessage* msg = NULL; + SrsBandwidthPacket* pkt = NULL; + if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + srs_error("expect bandcheck start play message failed. ret=%d", ret); + return ret; + } + SrsAutoFree(SrsCommonMessage, msg, false); + srs_info("get bandcheck start play message"); + + if (pkt->command_name != SRS_BW_CHECK_START_PLAY) { + srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str()); + return -1; + } + + return ret; +} + +int SrsBandCheckClient::send_starting_play() +{ + int ret = ERROR_SUCCESS; + + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_STARTING_PLAY; + msg->set_packet(pkt, 0); + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send starting play msg failed. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsBandCheckClient::expect_stop_play() +{ + int ret = ERROR_SUCCESS; + + while (true) { + SrsCommonMessage* msg = NULL; + SrsBandwidthPacket* pkt = NULL; + if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + srs_error("expect stop play message failed. ret=%d", ret); + return ret; + } + SrsAutoFree(SrsCommonMessage, msg, false); + srs_info("get bandcheck stop play message"); + + if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) { + break; + } + } + + return ret; +} + +int SrsBandCheckClient::send_stopped_play() +{ + int ret = ERROR_SUCCESS; + + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY; + msg->set_packet(pkt, 0); + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send stopped play msg failed. ret=%d", ret); + return ret; + } + + return ret; +} + +int SrsBandCheckClient::expect_start_pub() +{ + int ret = ERROR_SUCCESS; + + while (true) { + SrsCommonMessage* msg = NULL; + SrsBandwidthPacket* pkt = NULL; + if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + srs_error("expect start pub message failed. ret=%d", ret); + return ret; + } + SrsAutoFree(SrsCommonMessage, msg, false); + srs_info("get bandcheck start pub message"); + + if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) { + break; + } + } + + return ret; +} + +int SrsBandCheckClient::send_starting_pub() +{ + int ret = ERROR_SUCCESS; + + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH; + msg->set_packet(pkt, 0); + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send starting play msg failed. ret=%d", ret); + return ret; + } + srs_info("send starting play msg success."); + + return ret; +} + +int SrsBandCheckClient::send_pub_data() +{ + int ret = ERROR_SUCCESS; + + int data_count = 100; + while (true) { + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_PUBLISHING; + msg->set_packet(pkt, 0); + + for (int i = 0; i < data_count; ++i) { + std::stringstream seq; + seq << i; + std::string play_data = "SrS band check data from client's publishing......"; + pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str())); + } + data_count += 100; + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send publish message failed.ret=%d", ret); + return ret; + } + + if ((ret = expect_stop_pub()) == ERROR_SUCCESS) { + break; + } + } + + return ret; +} + +int SrsBandCheckClient::expect_stop_pub() +{ + int ret = ERROR_SUCCESS; + + while (true) { + if ((ret = st_netfd_poll(stfd, POLLIN, 1000)) == ERROR_SUCCESS) { + SrsCommonMessage* msg = 0; + if ((ret = recv_message(&msg)) != ERROR_SUCCESS) + { + srs_error("recv message failed while expect stop pub. ret=%d", ret); + return ret; + } + + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) { + srs_error("decode packet error while expect stop pub. ret=%d", ret); + return ret; + } + + SrsBandwidthPacket* pkt = dynamic_cast(msg->get_packet()); + if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) { + + return ret; + } + } else { + break; + } + } + + return ret; +} + +int SrsBandCheckClient::expect_finished() +{ + int ret = ERROR_SUCCESS; + + while (true) { + SrsCommonMessage* msg = NULL; + SrsBandwidthPacket* pkt = NULL; + if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + srs_error("expect finished message failed. ret=%d", ret); + return ret; + } + SrsAutoFree(SrsCommonMessage, msg, false); + srs_info("get bandcheck finished message"); + + if (pkt->command_name == SRS_BW_CHECK_FINISHED) { + SrsStream *stream = new SrsStream; + SrsAutoFree(SrsStream, stream, false); + + if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) { + srs_error("initialize stream error. ret=%d", ret); + return ret; + } + + std::string command_name; + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { + srs_error("amfo read string error. ret=%d", ret); + return ret; + } + + double action_id; + if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) { + srs_error("amfo read number error. ret=%d", ret); + return ret; + } + + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { + srs_error("amfo read number error. ret=%d", ret); + return ret; + } + + SrsAmf0Object* object; + if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) { + srs_error("amfo read object error. ret=%d", ret); + return ret; + } + + int64_t start_time = 0; + int64_t end_time = 0; + + SrsAmf0Any* start_time_any = object->get_property("start_time"); + if (start_time_any && start_time_any->is_number()) { + SrsAmf0Number* start_time_number = dynamic_cast (start_time_any); + if (start_time_number) { + start_time = start_time_number->value; + } + } + + SrsAmf0Any* end_time_any = object->get_property("end_time"); + if (end_time_any && end_time_any->is_number()) { + SrsAmf0Number* end_time_number = dynamic_cast (end_time_any); + if (end_time_number) { + end_time = end_time_number->value; + } + } + + int play_kbps = 0; + int pub_kbps = 0; + SrsAmf0Any* play_kbp_any = object->get_property("play_kbps"); + if (play_kbp_any && play_kbp_any->is_number()) { + SrsAmf0Number* play_kbps_number = dynamic_cast (play_kbp_any); + if (play_kbps_number) { + play_kbps = play_kbps_number->value; + } + } + + SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps"); + if (pub_kbp_any && pub_kbp_any->is_number()) { + SrsAmf0Number* pub_kbps_number = dynamic_cast (pub_kbp_any); + if (pub_kbps_number) { + pub_kbps = pub_kbps_number->value; + } + } + + float time_elapsed; + if (end_time - start_time > 0) { + time_elapsed = (end_time - start_time) / 1000.00; + } + + srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n" + , play_kbps, pub_kbps, time_elapsed); + + break; + } + } + + return ret; +} + +int SrsBandCheckClient::send_stopped_pub() +{ + int ret = ERROR_SUCCESS; + + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH; + msg->set_packet(pkt, 0); + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send stopped pub msg failed. ret=%d", ret); + return ret; + } + srs_info("send stopped pub msg success."); + + return ret; +} + +int SrsBandCheckClient::send_final() +{ + int ret = ERROR_SUCCESS; + + SrsCommonMessage* msg = new SrsCommonMessage; + SrsBandwidthPacket* pkt = new SrsBandwidthPacket; + pkt->command_name = SRS_BW_CHECK_FLASH_FINAL; + msg->set_packet(pkt, 0); + + if ((ret = send_message(msg)) != ERROR_SUCCESS) { + srs_error("send final msg failed. ret=%d", ret); + return ret; + } + srs_info("send final msg success."); + + return ret; +} + +SrsBandCheck::SrsBandCheck() + : bandCheck_Client(0) +{ +} + +SrsBandCheck::~SrsBandCheck() +{ + if (bandCheck_Client) { + srs_freep(bandCheck_Client); + } +} + +int SrsBandCheck::check(const std::string &app, const std::string &tcUrl) +{ + int ret = ERROR_SUCCESS; + + if ((ret = connect_server()) != ERROR_SUCCESS) { + srs_error("connect to server failed. ret = %d", ret); + return ret; + } + + if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) { + srs_error("handshake failed. ret = %d", ret); + return ret; + } + + if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) { + srs_error("handshake failed. ret = %d", ret); + return ret; + } + + if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) { + srs_error("band check play failed."); + return ret; + } + + if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) { + srs_error("band check publish failed."); + return ret; + } + + return ret; +} + +void SrsBandCheck::set_server(const std::string &server, int port) +{ + server_address = server; + server_port = port; +} + +int SrsBandCheck::connect_server() +{ + int ret = ERROR_SUCCESS; + + int sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock == -1){ + ret = ERROR_SOCKET_CREATE; + srs_error("create socket error. ret=%d", ret); + return ret; + } + + st_netfd_t stfd = st_netfd_open_socket(sock); + if(stfd == NULL){ + ret = ERROR_ST_OPEN_SOCKET; + srs_error("st_netfd_open_socket failed. ret=%d", ret); + return ret; + } + + bandCheck_Client = new SrsBandCheckClient(stfd); + + // connect to server. + std::string ip = srs_dns_resolve(server_address); + if (ip.empty()) { + ret = ERROR_SYSTEM_IP_INVALID; + srs_error("dns resolve server error, ip empty. ret=%d", ret); + return ret; + } + + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(server_port); + addr.sin_addr.s_addr = inet_addr(ip.c_str()); + + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){ + ret = ERROR_ST_CONNECT; + srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret); + return ret; + } + srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port); + + return ret; +} + +int init_st() +{ + int ret = ERROR_SUCCESS; + + if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) { + ret = ERROR_ST_SET_EPOLL; + srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret); + return ret; + } + + if(st_init() != 0){ + ret = ERROR_ST_INITIALIZE; + srs_error("st_init failed. ret=%d", ret); + return ret; + } + + return ret; +} + +void print_help(char** argv) +{ + printf( + "Usage: %s [OPTION]...\n" + "test band width from client to rtmp server.\n" + "Mandatory arguments to long options are mandatory for short options too.\n" + " -i, --ip the ip or domain that to test\n" + " -p, --port the port that server listen \n" + " -k, --key the key used to test \n" + " -v, --vhost the vhost used to test \n" + " -V, --version output version information and exit \n" + " -h, --help display this help and exit \n" + "\n" + "For example:\n" + " %s -i 192.168.1.248 -p 1935 -v bandcheck.srs.com -k 35c9b402c12a7246868752e2878f7e0e" + "\n\n" + "Exit status:\n" + "0 if OK,\n" + "other if error occured, and the detail should be printed.\n" + "\n\n" + "srs home page: \n", + argv[0], argv[0]); +} + +void print_version() +{ + const char *version = "" + "srs_bandcheck "BUILD_VERSION"\n" + "Copyright (c) 2013-2014 wenjiegit.\n" + "License MIT\n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n" + "\n" + "Written by wenjie.\n"; + + printf("%s", version); +} + +int get_opt(int argc, char *argv[]) +{ + int ret = ERROR_SUCCESS; + + int c; + while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) { + switch (c) { + case 'i': + if (optarg) { + g_ip = optarg; + } + break; + case 'p': + if (optarg) { + g_port = atoi(optarg); + } + break; + case 'k': + if (optarg) { + g_key = optarg; + } + break; + case 'v': + if (optarg) { + g_vhost = optarg; + } + break; + case 'V': + print_version(); + exit(0); + break; + case 'h': + print_help(argv); + exit(0); + break; + default: + printf("see --help or -h\n"); + ret = -1; + } + } + + return ret; +} diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 94d6fc31e..e87527e36 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2013 winlin +Copyright (c) 2013-2014 winlin 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 diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index 06e6aca70..fca1a86ca 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -1,6 +1,7 @@ file main readonly separator, ..\main\srs_main_server.cpp, + ..\main\srs_main_bandcheck.cpp, auto readonly separator, ..\..\objs\srs_auto_headers.hpp, core readonly separator, @@ -57,7 +58,7 @@ file ..\core\srs_core_source.hpp, ..\core\srs_core_source.cpp, research readonly separator, - ..\..\research\ts_info.cc; + ..\..\research\hls\ts_info.cc; mainconfig "" = "MAIN";