wenjiegit

fixbug[play packet decode bug: srs only read bool type play reset value, actuall…

…y this value can be bool or number]
正在显示 74 个修改的文件 包含 1591 行增加1050 行删除
  1 +Authors ordered by first contribution.
  2 +
  3 +* winlin <winlin@vip.126.com>
  4 +* wenjie
1 The MIT License (MIT) 1 The MIT License (MIT)
2 2
3 -Copyright (c) 2013 winlin 3 +Copyright (c) 2013-2014 winlin
4 4
5 Permission is hereby granted, free of charge, to any person obtaining a copy of 5 Permission is hereby granted, free of charge, to any person obtaining a copy of
6 this software and associated documentation files (the "Software"), to deal in 6 this software and associated documentation files (the "Software"), to deal in
1 -simple-rtmp-server 1 +Simple-RTMP-Server
2 ================== 2 ==================
3 3
4 -srs(simple rtmp origin live server) over state-threads.<br/>  
5 -srs is a simple, high-performance, running in single process, origin live server.<br/>  
6 -srs supports vhost, rtmp, HLS, transcoding, forward, http hooks. <br/>  
7 -blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/>  
8 -see also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server) <br/>  
9 -see also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server) <br/> 4 +SRS(SIMPLE RTMP Server) over state-threads created in 2013.<br/>
  5 +SRS is a simple, high-performance, running in single process, origin live server.<br/>
  6 +SRS supports vhost, rtmp, HLS, transcoding, forward, http hooks. <br/>
  7 +Blog: [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/>
  8 +See also: [https://github.com/winlinvip/simple-rtmp-server](https://github.com/winlinvip/simple-rtmp-server) <br/>
  9 +See also: [http://winlinvip.github.io/simple-rtmp-server](http://winlinvip.github.io/simple-rtmp-server) <br/>
10 TencentQQ: [http://url.cn/WAHICw](http://url.cn/WAHICw) (Group: 212189142) 10 TencentQQ: [http://url.cn/WAHICw](http://url.cn/WAHICw) (Group: 212189142)
11 11
12 -### Contributors  
13 -winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/>  
14 -wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html) <br/>  
15 -about the contributors: <br/>  
16 -1. contribute important features to srs. <br/>  
17 -2. the name of all contributors will send in the response of NetConnection.connect and metadata. 12 +### AUTHORS
  13 +The PRIMARY AUTHORS are (and/or have been)(Authors ordered by first contribution): <br/>
  14 +* winlin([winterserver](#)): [http://blog.csdn.net/win_lin](http://blog.csdn.net/win_lin) <br/>
  15 +* wenjie([wenjiegit](https://github.com/wenjiegit/simple-rtmp-server)): [http://blog.chinaunix.net/uid/25006789.html](http://blog.chinaunix.net/uid/25006789.html) <br/>
  16 +
  17 +About the primary AUTHORS: <br/>
  18 +* Contribute important features to SRS. <br/>
  19 +* Names of all PRIMARY AUTHORS response in NetConnection.connect and metadata. <br/>
  20 +
  21 +And here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS --<br/>
  22 +people who have submitted patches, reported bugs, added translations, helped<br/>
  23 +answer newbie questions, and generally made SRS that much better: [AUTHORS.txt](https://github.com/winlinvip/simple-rtmp-server/blob/master/AUTHORS.txt)
18 24
19 ### Usage(simple) 25 ### Usage(simple)
20 -<strong>step -1:</strong> get srs<br/> 26 +<strong>Step -1:</strong> get SRS<br/>
21 <pre> 27 <pre>
22 git clone https://github.com/winlinvip/simple-rtmp-server && 28 git clone https://github.com/winlinvip/simple-rtmp-server &&
23 cd simple-rtmp-server/trunk 29 cd simple-rtmp-server/trunk
24 </pre> 30 </pre>
25 -<strong>step 0:</strong> build srs system.<br/> 31 +<strong>Step 0:</strong> build SRS system.<br/>
26 <pre> 32 <pre>
27 bash scripts/build.sh 33 bash scripts/build.sh
28 </pre> 34 </pre>
29 -<strong>step 1:</strong> start srs all demo features.<br/> 35 +<strong>Step 1:</strong> start SRS all demo features.<br/>
30 <pre> 36 <pre>
31 bash scripts/run.sh 37 bash scripts/run.sh
32 </pre> 38 </pre>
33 -<strong>step 2:</strong> srs live show: [http://your-server-ip](http://your-server-ip) <br/>  
34 -<strong>step 3:</strong> stop srs demo<br/> 39 +<strong>Step 2:</strong> SRS live show: [http://your-server-ip](http://your-server-ip) <br/>
  40 +<strong>Step 3:</strong> stop SRS demo<br/>
35 <pre> 41 <pre>
36 bash scripts/stop.sh 42 bash scripts/stop.sh
37 </pre> 43 </pre>
38 44
39 ### Usage(detail) 45 ### Usage(detail)
40 -<strong>step 0:</strong> get srs <br/> 46 +<strong>Step 0:</strong> get SRS <br/>
41 <pre> 47 <pre>
42 git clone https://github.com/winlinvip/simple-rtmp-server && 48 git clone https://github.com/winlinvip/simple-rtmp-server &&
43 cd simple-rtmp-server/trunk 49 cd simple-rtmp-server/trunk
44 </pre> 50 </pre>
45 -<strong>step 1:</strong> build srs <br/> 51 +<strong>Step 1:</strong> build SRS <br/>
46 <pre> 52 <pre>
47 ./configure --with-ssl --with-hls --with-ffmpeg --with-http && make 53 ./configure --with-ssl --with-hls --with-ffmpeg --with-http && make
48 </pre> 54 </pre>
49 -<strong>step 2:</strong> start srs <br/> 55 +<strong>Step 2:</strong> start SRS <br/>
50 <pre> 56 <pre>
51 ./objs/srs -c conf/srs.conf 57 ./objs/srs -c conf/srs.conf
52 </pre> 58 </pre>
53 -<strong>step 3(optinal):</strong> start srs listen at 19350 to forward to<br/> 59 +<strong>Step 3(optinal):</strong> start SRS listen at 19350 to forward to<br/>
54 <pre> 60 <pre>
55 ./objs/srs -c conf/srs.19350.conf 61 ./objs/srs -c conf/srs.19350.conf
56 </pre> 62 </pre>
57 -<strong>step 4(optinal):</strong> start nginx for HLS <br/> 63 +<strong>Step 4(optinal):</strong> start nginx for HLS <br/>
58 <pre> 64 <pre>
59 sudo ./objs/nginx/sbin/nginx 65 sudo ./objs/nginx/sbin/nginx
60 </pre> 66 </pre>
61 -<strong>step 5(optinal):</strong> start http hooks for srs callback <br/> 67 +<strong>Step 5(optinal):</strong> start http hooks for SRS callback <br/>
62 <pre> 68 <pre>
63 python ./research/api-server/server.py 8085 69 python ./research/api-server/server.py 8085
64 </pre> 70 </pre>
65 -<strong>step 6:</strong> publish demo live stream <br/> 71 +<strong>Step 6:</strong> publish demo live stream <br/>
66 <pre> 72 <pre>
67 FMS URL: rtmp://127.0.0.1/live?vhost=demo.srs.com 73 FMS URL: rtmp://127.0.0.1/live?vhost=demo.srs.com
68 Stream: livestream 74 Stream: livestream
@@ -74,7 +80,7 @@ FFMPEG to publish the default demo stream: @@ -74,7 +80,7 @@ FFMPEG to publish the default demo stream:
74 sleep 1; \ 80 sleep 1; \
75 done 81 done
76 </pre> 82 </pre>
77 -<strong>step 7:</strong> publish players live stream <br/> 83 +<strong>Step 7:</strong> publish players live stream <br/>
78 <pre> 84 <pre>
79 FMS URL: rtmp://127.0.0.1/live?vhost=players 85 FMS URL: rtmp://127.0.0.1/live?vhost=players
80 Stream: livestream 86 Stream: livestream
@@ -86,7 +92,7 @@ FFMPEG to publish the players demo stream: @@ -86,7 +92,7 @@ FFMPEG to publish the players demo stream:
86 sleep 1; \ 92 sleep 1; \
87 done 93 done
88 </pre> 94 </pre>
89 -<strong>step 8:</strong> add server ip to client hosts as demo. <br/> 95 +<strong>Step 8:</strong> add server ip to client hosts as demo. <br/>
90 <pre> 96 <pre>
91 # edit the folowing file: 97 # edit the folowing file:
92 # linux: /etc/hosts 98 # linux: /etc/hosts
@@ -94,14 +100,14 @@ FFMPEG to publish the players demo stream: @@ -94,14 +100,14 @@ FFMPEG to publish the players demo stream:
94 # where server ip is 192.168.2.111 100 # where server ip is 192.168.2.111
95 192.168.2.111 demo.srs.com 101 192.168.2.111 demo.srs.com
96 </pre> 102 </pre>
97 -<strong>step 9:</strong> play live stream. <br/> 103 +<strong>Step 9:</strong> play live stream. <br/>
98 <pre> 104 <pre>
99 players: http://demo.srs.com/players 105 players: http://demo.srs.com/players
100 rtmp url: rtmp://demo.srs.com/live/livestream 106 rtmp url: rtmp://demo.srs.com/live/livestream
101 m3u8 url: http://demo.srs.com/live/livestream.m3u8 107 m3u8 url: http://demo.srs.com/live/livestream.m3u8
102 for android: http://demo.srs.com/live/livestream.html 108 for android: http://demo.srs.com/live/livestream.html
103 </pre> 109 </pre>
104 -<strong>step 10(optinal):</strong> play live stream auto transcoded<br/> 110 +<strong>Step 10(optinal):</strong> play live stream auto transcoded<br/>
105 <pre> 111 <pre>
106 rtmp url: rtmp://demo.srs.com/live/livestream_ld 112 rtmp url: rtmp://demo.srs.com/live/livestream_ld
107 m3u8 url: http://demo.srs.com/live/livestream_ld.m3u8 113 m3u8 url: http://demo.srs.com/live/livestream_ld.m3u8
@@ -110,7 +116,7 @@ rtmp url: rtmp://demo.srs.com/live/livestream_sd @@ -110,7 +116,7 @@ rtmp url: rtmp://demo.srs.com/live/livestream_sd
110 m3u8 url: http://demo.srs.com/live/livestream_sd.m3u8 116 m3u8 url: http://demo.srs.com/live/livestream_sd.m3u8
111 for android: http://demo.srs.com/live/livestream_sd.html 117 for android: http://demo.srs.com/live/livestream_sd.html
112 </pre> 118 </pre>
113 -<strong>step 11(optinal):</strong> play live stream auto forwarded, the hls dir change to /forward<br/> 119 +<strong>Step 11(optinal):</strong> play live stream auto forwarded, the hls dir change to /forward<br/>
114 <pre> 120 <pre>
115 rtmp url: rtmp://demo.srs.com:19350/live/livestream 121 rtmp url: rtmp://demo.srs.com:19350/live/livestream
116 m3u8 url: http://demo.srs.com/forward/live/livestream.m3u8 122 m3u8 url: http://demo.srs.com/forward/live/livestream.m3u8
@@ -122,7 +128,7 @@ rtmp url: rtmp://demo.srs.com:19350/live/livestream_sd @@ -122,7 +128,7 @@ rtmp url: rtmp://demo.srs.com:19350/live/livestream_sd
122 m3u8 url: http://demo.srs.com/forward/live/livestream_sd.m3u8 128 m3u8 url: http://demo.srs.com/forward/live/livestream_sd.m3u8
123 for android: http://demo.srs.com/forward/live/livestream_sd.html 129 for android: http://demo.srs.com/forward/live/livestream_sd.html
124 </pre> 130 </pre>
125 -<strong>step 12(optinal):</strong> modify the config and reload it (all features support reload)<br/> 131 +<strong>Step 12(optinal):</strong> modify the config and reload it (all features support reload)<br/>
126 <pre> 132 <pre>
127 killall -1 srs 133 killall -1 srs
128 </pre> 134 </pre>
@@ -135,7 +141,7 @@ killall -s SIGHUP srs @@ -135,7 +141,7 @@ killall -s SIGHUP srs
135 System Architecture: 141 System Architecture:
136 <pre> 142 <pre>
137 +------------------------------------------------------+ 143 +------------------------------------------------------+
138 -| SRS(Simple Rtmp Server) | 144 +| SRS(Simple RTMP Server) |
139 +---------------+---------------+-----------+----------+ 145 +---------------+---------------+-----------+----------+
140 | API/hook | Transcoder | HLS | RTMP | 146 | API/hook | Transcoder | HLS | RTMP |
141 | http-parser | FFMPEG/x264 | NGINX/ts | protocol | 147 | http-parser | FFMPEG/x264 | NGINX/ts | protocol |
@@ -151,7 +157,7 @@ Stream Architecture: @@ -151,7 +157,7 @@ Stream Architecture:
151 + Publish + + Deliver | 157 + Publish + + Deliver |
152 +---|-----+ +----|-----+ 158 +---|-----+ +----|-----+
153 +-----------+-------------------------+----------------+ 159 +-----------+-------------------------+----------------+
154 -| Encoder | SRS(Simple Rtmp Server) | Client | 160 +| Encoder | SRS(Simple RTMP Server) | Client |
155 +-----------+-------------------------+----------------+ 161 +-----------+-------------------------+----------------+
156 | (FMLE, | +-> RTMP protocol ----+-> Flash Player | 162 | (FMLE, | +-> RTMP protocol ----+-> Flash Player |
157 | FFMPEG, --+-> +-> HLS/NGINX --------+-> m3u8 player | 163 | FFMPEG, --+-> +-> HLS/NGINX --------+-> m3u8 player |
@@ -186,7 +192,7 @@ Bandwidth Test Workflow: @@ -186,7 +192,7 @@ Bandwidth Test Workflow:
186 | final(2)-----------------> | 192 | final(2)-----------------> |
187 | &lt;END> | 193 | &lt;END> |
188 194
189 -@see: class SrsBandwidth comments. 195 +@See: class SrsBandwidth comments.
190 </pre> 196 </pre>
191 197
192 ### System Requirements 198 ### System Requirements
@@ -195,37 +201,38 @@ Supported operating systems and hardware: @@ -195,37 +201,38 @@ Supported operating systems and hardware:
195 * All handware. 201 * All handware.
196 202
197 ### Summary 203 ### Summary
198 -1. simple: also stable enough.<br/>  
199 -2. high-performance: single-thread, async socket, event/st-thread driven.<br/>  
200 -3. no edge server, origin server only.<br/>  
201 -4. no vod streaming, live streaming only.<br/>  
202 -5. no multiple processes, single process only.<br/>  
203 -6. support vhost, support \_\_defaultVhost\_\_.<br/>  
204 -7. support adobe rtmp live streaming.<br/>  
205 -8. support apple hls(m3u8) live streaming.<br/>  
206 -9. support reload config to enable changes.<br/>  
207 -10. support cache last gop for flash player to fast startup.<br/>  
208 -11. support listen at multiple ports.<br/>  
209 -12. support long time(>4.6hours) publish/play.<br/>  
210 -13. high performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB<br/>  
211 -14. support forward publish stream to build active-standby cluster.<br/>  
212 -15. support broadcast by forward the stream to other servers(origin/edge).<br/>  
213 -16. support live stream transcoding by ffmpeg.<br/>  
214 -17. support live stream forward(acopy/vcopy) by ffmpeg.<br/>  
215 -18. support ffmpeg filters(logo/overlay/crop), x264 params.<br/>  
216 -19. support audio transcode only, speex/mp3 to aac<br/>  
217 -20. support http callback api hooks(for authentication and injection).<br/>  
218 -21. support bandwidth test api and flash client.<br/>  
219 -22. player, publisher(encoder), and demo pages(jquery+bootstrap). <br/>  
220 -23. demo video meeting or chat(srs+cherrypy+jquery+bootstrap). <br/>  
221 -24. [plan] support network based cli and json result.<br/>  
222 -25. [plan] support adobe flash refer/token/swf verification.<br/>  
223 -26. [plan] support adobe amf3 codec.<br/>  
224 -27. [plan] support dvr(record live to vod file)<br/>  
225 -28. [plan] support FMS edge protocol<br/>  
226 -29. [plan] support encryption: RTMPE/RTMPS, HLS DRM<br/>  
227 -30. [plan] support RTMPT, http to tranverse firewalls<br/>  
228 -31. [plan] support file source, transcoding file to live stream<br/> 204 +1. Simple: also stable enough.<br/>
  205 +2. [High-performance](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance): single-thread, async socket, event/st-thread driven.<br/>
  206 +3. NO edge server, origin server only.<br/>
  207 +4. NO vod streaming, live streaming only.<br/>
  208 +5. NO multiple processes, single process only.<br/>
  209 +6. Support vhost, support \_\_defaultVhost\_\_.<br/>
  210 +7. Support adobe rtmp live streaming.<br/>
  211 +8. Support apple hls(m3u8) live streaming.<br/>
  212 +9. Support reload config to enable changes.<br/>
  213 +10. Support cache last gop for flash player to fast startup.<br/>
  214 +11. Support listen at multiple ports.<br/>
  215 +12. Support long time(>4.6hours) publish/play.<br/>
  216 +13. High performace, 1800 connections(500kbps), 900Mbps, CPU 90.2%, 41MB<br/>
  217 +14. Support forward publish stream to build active-standby [cluster](https://github.com/winlinvip/simple-rtmp-server/wiki/Cluster).<br/>
  218 +15. Support broadcast by forward the stream to other servers(origin/edge).<br/>
  219 +16. Support live stream transcoding by ffmpeg.<br/>
  220 +17. Support live stream forward(acopy/vcopy) by ffmpeg.<br/>
  221 +18. Support ffmpeg filters(logo/overlay/crop), x264 params.<br/>
  222 +19. Support audio transcode only, speex/mp3 to aac<br/>
  223 +20. Support http callback api hooks(for authentication and injection).<br/>
  224 +21. Support bandwidth test api and flash client.<br/>
  225 +22. Player, publisher(encoder), and demo pages(jquery+bootstrap). <br/>
  226 +23. Demo video meeting or chat(SRS+cherrypy+jquery+bootstrap). <br/>
  227 +24. [dev] Full documents in wiki, in chineses. <br/>
  228 +25. [plan] Support network based cli and json result.<br/>
  229 +26. [plan] Support adobe flash refer/token/swf verification.<br/>
  230 +27. [plan] Support adobe amf3 codec.<br/>
  231 +28. [plan] Support dvr(record live to vod file)<br/>
  232 +29. [plan] Support FMS edge protocol<br/>
  233 +30. [plan] Support encryption: RTMPE/RTMPS, HLS DRM<br/>
  234 +31. [plan] Support RTMPT, http to tranverse firewalls<br/>
  235 +32. [plan] Support file source, transcoding file to live stream<br/>
229 236
230 ### Performance 237 ### Performance
231 1. 300 connections, 150Mbps, 500kbps, CPU 18.8%, 5956KB. 238 1. 300 connections, 150Mbps, 500kbps, CPU 18.8%, 5956KB.
@@ -234,53 +241,54 @@ Supported operating systems and hardware: @@ -234,53 +241,54 @@ Supported operating systems and hardware:
234 4. 1200 connections, 600Mbps, 500kbps, CPU 72.4%, 15MB. 241 4. 1200 connections, 600Mbps, 500kbps, CPU 72.4%, 15MB.
235 5. 1500 connections, 750Mbps, 500kbps, CPU 81.9%, 28MB. 242 5. 1500 connections, 750Mbps, 500kbps, CPU 81.9%, 28MB.
236 6. 1800 connections, 900Mbps, 500kbps, CPU 90.2%, 41MB. 243 6. 1800 connections, 900Mbps, 500kbps, CPU 90.2%, 41MB.
  244 +
237 <pre> 245 <pre>
  246 +[winlin@dev6 srs]$ dstat
238 ----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system-- 247 ----total-cpu-usage---- -dsk/total- ---net/lo-- ---paging-- ---system--
239 usr sys idl wai hiq siq| read writ| recv send| in out | int csw 248 usr sys idl wai hiq siq| read writ| recv send| in out | int csw
240 58 9 32 0 0 1| 0 4168k| 277M 277M| 0 0 | 29k 25k 249 58 9 32 0 0 1| 0 4168k| 277M 277M| 0 0 | 29k 25k
241 61 8 30 0 0 1| 0 1168k| 336M 336M| 0 0 | 29k 24k 250 61 8 30 0 0 1| 0 1168k| 336M 336M| 0 0 | 29k 24k
242 63 8 27 0 0 1| 0 2240k| 124M 124M| 0 0 | 32k 33k 251 63 8 27 0 0 1| 0 2240k| 124M 124M| 0 0 | 32k 33k
243 62 8 28 0 0 1| 0 1632k| 110M 110M| 0 0 | 31k 33k 252 62 8 28 0 0 1| 0 1632k| 110M 110M| 0 0 | 31k 33k
244 - 67 9 23 0 0 2| 0 1604k| 130M 130M| 0 0 | 33k 32k  
245 - 63 9 27 0 0 2| 0 1496k| 145M 145M| 0 0 | 32k 32k  
246 - 61 9 29 0 0 1| 0 1112k| 132M 132M| 0 0 | 32k 33k  
247 - 63 9 27 0 0 2| 0 1220k| 145M 145M| 0 0 | 32k 33k  
248 53 7 40 0 0 1| 0 1360k| 115M 115M| 0 0 | 24k 26k 253 53 7 40 0 0 1| 0 1360k| 115M 115M| 0 0 | 24k 26k
249 51 7 41 0 0 1| 0 1184k| 146M 146M| 0 0 | 24k 27k 254 51 7 41 0 0 1| 0 1184k| 146M 146M| 0 0 | 24k 27k
250 39 6 54 0 0 1| 0 1284k| 105M 105M| 0 0 | 22k 28k 255 39 6 54 0 0 1| 0 1284k| 105M 105M| 0 0 | 22k 28k
251 41 6 52 0 0 1| 0 1264k| 116M 116M| 0 0 | 25k 28k 256 41 6 52 0 0 1| 0 1264k| 116M 116M| 0 0 | 25k 28k
252 48 6 45 0 0 1| 0 1272k| 143M 143M| 0 0 | 27k 27k 257 48 6 45 0 0 1| 0 1272k| 143M 143M| 0 0 | 27k 27k
253 </pre> 258 </pre>
  259 +See also: [Performance Test Guide](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance)
254 260
255 ### Releases 261 ### Releases
256 -* 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.<br/>  
257 -* 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.<br/>  
258 -* 2013-12-03, [release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.<br/>  
259 -* 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.<br/>  
260 -* 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.<br/>  
261 -* 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.<br/>  
262 -* 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.<br/>  
263 -* 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.<br/>  
264 -* 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.<br/>  
265 -* 2013-10-17, created.<br/> 262 +* 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.<br/>
  263 +* 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.<br/>
  264 +* 2013-12-03, [Release v0.7](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.7), support live stream transcoding. 17605 lines.<br/>
  265 +* 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.<br/>
  266 +* 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.<br/>
  267 +* 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.<br/>
  268 +* 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.<br/>
  269 +* 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.<br/>
  270 +* 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.<br/>
  271 +* 2013-10-17, Created.<br/>
266 272
267 ### Compare 273 ### Compare
268 -* srs v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.<br/>  
269 -* srs v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>  
270 -* srs v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com). <br/>  
271 -* srs v0.6: 16094 lines. important feature forward for CDN. <br/>  
272 -* srs v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>  
273 -* srs v0.4: 12500 lines. important feature reload for CDN. <br/>  
274 -* srs v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html). <br/>  
275 -* srs v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>  
276 -* srs v0.1: 8287 lines. base on state-threads. <br/> 274 +* SRS v0.9: 20926 lines. player/encoder/chat demos. bandwidth test for encoder/CDN.<br/>
  275 +* SRS v0.8: 19186 lines. implements http hooks refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>
  276 +* SRS v0.7: 17605 lines. implements transcoding(FFMPEG) feature refer to [wowza](http://www.wowza.com). <br/>
  277 +* SRS v0.6: 16094 lines. important feature forward for CDN. <br/>
  278 +* SRS v0.5: 14449 lines. implements HLS feature refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>
  279 +* SRS v0.4: 12500 lines. important feature reload for CDN. <br/>
  280 +* SRS v0.3: 11773 lines. implements vhost feature refer to [FMS](http://www.adobe.com/products/adobe-media-server-family.html). <br/>
  281 +* SRS v0.2: 10125 lines. implements rtmp protocol stack refer to [nginx-rtmp](https://github.com/arut/nginx-rtmp-module). <br/>
  282 +* SRS v0.1: 8287 lines. base on state-threads. <br/>
277 * nginx-rtmp v1.0.4: 26786 lines <br/> 283 * nginx-rtmp v1.0.4: 26786 lines <br/>
278 * nginx v1.5.0: 139524 lines <br/> 284 * nginx v1.5.0: 139524 lines <br/>
279 285
280 ### History 286 ### History
  287 +* v1.0, 2014-01-01, change listen(512), chunk-size(60000), to improve performance.
  288 +* v1.0, 2013-12-27, merge from wenjie, the bandwidth test feature.
281 * v0.9, 2013-12-25, [v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9) released. 20926 lines. 289 * v0.9, 2013-12-25, [v0.9](https://github.com/winlinvip/simple-rtmp-server/releases/tag/0.9) released. 20926 lines.
282 * v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone. 290 * v0.9, 2013-12-25, fix the bitrate bug(in Bps), use enhanced microphone.
283 -* v0.9, 2013-12-22, demo video meeting or chat(srs+cherrypy+jquery+bootstrap). 291 +* v0.9, 2013-12-22, demo video meeting or chat(SRS+cherrypy+jquery+bootstrap).
284 * v0.9, 2013-12-22, merge from wenjie, support banwidth test. 292 * v0.9, 2013-12-22, merge from wenjie, support banwidth test.
285 * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level 293 * v0.9, 2013-12-22, merge from wenjie: support set chunk size at vhost level
286 * v0.9, 2013-12-21, add [players](http://demo.srs.com/players) for play and publish. 294 * 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 @@ -297,7 +305,7 @@ usr sys idl wai hiq siq| read writ| recv send| in out | int csw
297 * v0.8, 2013-12-08, support multiple http hooks for a event. 305 * v0.8, 2013-12-08, support multiple http hooks for a event.
298 * v0.8, 2013-12-07, support http callback hooks, on_connect. 306 * v0.8, 2013-12-07, support http callback hooks, on_connect.
299 * v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4. 307 * v0.8, 2013-12-07, support network based cli and json result, add CherryPy 3.2.4.
300 -* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use srs rtmp sdk. 308 +* v0.8, 2013-12-07, update http/hls/rtmp load test tool [st_load](https://github.com/winlinvip/st-load), use SRS rtmp sdk.
301 * v0.8, 2013-12-06, support max_connections, drop if exceed. 309 * v0.8, 2013-12-06, support max_connections, drop if exceed.
302 * v0.8, 2013-12-05, support log_dir, write ffmpeg log to file. 310 * v0.8, 2013-12-05, support log_dir, write ffmpeg log to file.
303 * v0.8, 2013-12-05, fix the forward/hls/encoder bug. 311 * v0.8, 2013-12-05, fix the forward/hls/encoder bug.
1 # the listen ports, split by space. 1 # the listen ports, split by space.
2 listen 1935; 2 listen 1935;
  3 +<<<<<<< HEAD
  4 +=======
  5 +# the default chunk size is 128, max is 65536,
  6 +# some client does not support chunk size change,
  7 +# however, most clients supports it and it can improve
  8 +# performance about 10%.
  9 +# default: 60000
  10 +chunk_size 60000;
  11 +>>>>>>> upstream/master
3 # the logs dir. 12 # the logs dir.
4 # if enabled ffmpeg, each stracoding stream will create a log file. 13 # if enabled ffmpeg, each stracoding stream will create a log file.
5 # default: ./objs/logs 14 # default: ./objs/logs
@@ -28,7 +37,7 @@ vhost __defaultVhost__ { @@ -28,7 +37,7 @@ vhost __defaultVhost__ {
28 # for which cannot identify the required vhost. 37 # for which cannot identify the required vhost.
29 # for default demo. 38 # for default demo.
30 vhost demo.srs.com { 39 vhost demo.srs.com {
31 - chunk_size 4096; 40 + chunk_size 60000;
32 enabled on; 41 enabled on;
33 gop_cache on; 42 gop_cache on;
34 queue_length 30; 43 queue_length 30;
@@ -226,7 +235,7 @@ vhost bandcheck.srs.com { @@ -226,7 +235,7 @@ vhost bandcheck.srs.com {
226 enabled on; 235 enabled on;
227 # the key for server to valid, 236 # the key for server to valid,
228 # if invalid key, server disconnect and abort the bandwidth check. 237 # if invalid key, server disconnect and abort the bandwidth check.
229 - key 35c9b402c12a7246868752e2878f7e0e; 238 + key "35c9b402c12a7246868752e2878f7e0e";
230 # the interval in seconds for bandwidth check, 239 # the interval in seconds for bandwidth check,
231 # server donot allow new test request. 240 # server donot allow new test request.
232 # default: 30 241 # default: 30
@@ -47,22 +47,27 @@ echo "" >> $SRS_AUTO_HEADERS_H @@ -47,22 +47,27 @@ echo "" >> $SRS_AUTO_HEADERS_H
47 echo "generate Makefile" 47 echo "generate Makefile"
48 48
49 cat << END > ${SRS_MAKEFILE} 49 cat << END > ${SRS_MAKEFILE}
50 -.PHONY: default help clean server _prepare_dir  
51 -default: server 50 +.PHONY: default help clean server bandwidth _prepare_dir
  51 +default: server bandwidth
52 52
53 help: 53 help:
54 - @echo "Usage: make <help>|<clean>|<server>" 54 + @echo "Usage: make <help>|<clean>|<server>|<bandwidth>"
55 @echo " help display this help menu" 55 @echo " help display this help menu"
56 @echo " clean cleanup project" 56 @echo " clean cleanup project"
57 @echo " server build the srs(simple rtmp server) over st(state-threads)" 57 @echo " server build the srs(simple rtmp server) over st(state-threads)"
  58 + @echo " bandwidth build the bandwidth test client tool."
58 59
59 clean: 60 clean:
60 - (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs Makefile *.hpp src st_*_load) 61 + (rm -f Makefile; cd ${SRS_OBJS}; rm -rf srs bandwidth Makefile *.hpp src st_*_load)
61 62
62 server: _prepare_dir 63 server: _prepare_dir
63 @echo "build the srs(simple rtmp server) over st(state-threads)" 64 @echo "build the srs(simple rtmp server) over st(state-threads)"
64 \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} srs 65 \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} srs
65 66
  67 +bandwidth: _prepare_dir
  68 + @echo "build the bandwidth test client tool"
  69 + \$(MAKE) -f ${SRS_OBJS}/${SRS_MAKEFILE} bandwidth
  70 +
66 # the ./configure will generate it. 71 # the ./configure will generate it.
67 _prepare_dir: 72 _prepare_dir:
68 @mkdir -p ${SRS_OBJS} 73 @mkdir -p ${SRS_OBJS}
@@ -87,7 +92,7 @@ GCC = g++ @@ -87,7 +92,7 @@ GCC = g++
87 LINK = \$(GCC) 92 LINK = \$(GCC)
88 AR = ar 93 AR = ar
89 94
90 -.PHONY: default srs 95 +.PHONY: default srs bandwidth
91 96
92 default: 97 default:
93 98
@@ -124,12 +129,12 @@ CORE_OBJS="${MODULE_OBJS[@]}" @@ -124,12 +129,12 @@ CORE_OBJS="${MODULE_OBJS[@]}"
124 MODULE_ID="MAIN" 129 MODULE_ID="MAIN"
125 MODULE_DEPENDS=("CORE") 130 MODULE_DEPENDS=("CORE")
126 ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS}) 131 ModuleLibIncs=(${LibSTRoot} ${SRS_OBJS})
127 -MODULE_FILES=("srs_main_server") 132 +MODULE_FILES=("srs_main_server" "srs_main_bandcheck")
128 MODULE_DIR="src/main" . auto/modules.sh 133 MODULE_DIR="src/main" . auto/modules.sh
129 MAIN_OBJS="${MODULE_OBJS[@].o}" 134 MAIN_OBJS="${MODULE_OBJS[@].o}"
130 135
131 # all main entrances 136 # all main entrances
132 -MAIN_ENTRANCES=("srs_main_server") 137 +MAIN_ENTRANCES=("srs_main_server" "srs_main_bandcheck")
133 138
134 # srs(simple rtmp server) over st(state-threads) 139 # srs(simple rtmp server) over st(state-threads)
135 ModuleLibFiles=(${LibSTfile}) 140 ModuleLibFiles=(${LibSTfile})
@@ -143,6 +148,7 @@ else @@ -143,6 +148,7 @@ else
143 LINK_OPTIONS="-ldl" 148 LINK_OPTIONS="-ldl"
144 fi 149 fi
145 BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" SO_PATH="" . auto/apps.sh 150 BUILD_KEY="srs" APP_MAIN="srs_main_server" APP_NAME="srs" SO_PATH="" . auto/apps.sh
  151 +BUILD_KEY="bandwidth" APP_MAIN="srs_main_bandcheck" APP_NAME="bandwidth" SO_PATH="" . auto/apps.sh
146 152
147 echo 'configure ok! ' 153 echo 'configure ok! '
148 154
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 ''' 2 '''
3 The MIT License (MIT) 3 The MIT License (MIT)
4 4
5 -Copyright (c) 2013 winlin 5 +Copyright (c) 2013-2014 winlin
6 6
7 Permission is hereby granted, free of charge, to any person obtaining a copy of 7 Permission is hereby granted, free of charge, to any person obtaining a copy of
8 this software and associated documentation files (the "Software"), to deal in 8 this software and associated documentation files (the "Software"), to deal in
@@ -463,7 +463,7 @@ if __name__ != "__main__": @@ -463,7 +463,7 @@ if __name__ != "__main__":
463 463
464 # check the user options 464 # check the user options
465 if len(sys.argv) <= 1: 465 if len(sys.argv) <= 1:
466 - print "SRS api callback server, Copyright (c) 2013 winlin" 466 + print "SRS api callback server, Copyright (c) 2013-2014 winlin"
467 print "Usage: python %s <port>"%(sys.argv[0]) 467 print "Usage: python %s <port>"%(sys.argv[0])
468 print " port: the port to listen at." 468 print " port: the port to listen at."
469 print "For example:" 469 print "For example:"
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -417,38 +417,38 @@ public: @@ -417,38 +417,38 @@ public:
417 */ 417 */
418 enum TSPESStreamId 418 enum TSPESStreamId
419 { 419 {
420 - PES_program_stream_map = 0b10111100, // 0xbc  
421 - PES_private_stream_1 = 0b10111101, // 0xbd  
422 - PES_padding_stream = 0b10111110, // 0xbe  
423 - PES_private_stream_2 = 0b10111111, // 0xbf 420 + PES_program_stream_map = 0xbc, // 0b10111100
  421 + PES_private_stream_1 = 0xbd, // 0b10111101
  422 + PES_padding_stream = 0xbe, // 0b10111110
  423 + PES_private_stream_2 = 0xbf, // 0b10111111
424 424
425 // 110x xxxx 425 // 110x xxxx
426 // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC 426 // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC
427 // 14496-3 audio stream number x xxxx 427 // 14496-3 audio stream number x xxxx
428 // (stream_id>>5)&0x07 == PES_audio_prefix 428 // (stream_id>>5)&0x07 == PES_audio_prefix
429 - PES_audio_prefix = 0b110, 429 + PES_audio_prefix = 0x06, // 0b110
430 430
431 // 1110 xxxx 431 // 1110 xxxx
432 // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC 432 // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC
433 // 14496-2 video stream number xxxx 433 // 14496-2 video stream number xxxx
434 // (stream_id>>4)&0x0f == PES_audio_prefix 434 // (stream_id>>4)&0x0f == PES_audio_prefix
435 - PES_video_prefix = 0b1110, 435 + PES_video_prefix = 0x0e, // 0b1110
436 436
437 - PES_ECM_stream = 0b11110000, // 0xf0  
438 - PES_EMM_stream = 0b11110001, // 0xf1  
439 - PES_DSMCC_stream = 0b11110010, // 0xf2  
440 - PES_13522_stream = 0b11110011, // 0xf3  
441 - PES_H_222_1_type_A = 0b11110100, // 0xf4  
442 - PES_H_222_1_type_B = 0b11110101, // 0xf5  
443 - PES_H_222_1_type_C = 0b11110110, // 0xf6  
444 - PES_H_222_1_type_D = 0b11110111, // 0xf7  
445 - PES_H_222_1_type_E = 0b11111000, // 0xf8  
446 - PES_ancillary_stream = 0b11111001, // 0xf9  
447 - PES_SL_packetized_stream = 0b11111010, // 0xfa  
448 - PES_FlexMux_stream = 0b11111011, // 0xfb 437 + PES_ECM_stream = 0xf0, // 0b11110000
  438 + PES_EMM_stream = 0xf1, // 0b11110001
  439 + PES_DSMCC_stream = 0xf2, // 0b11110010
  440 + PES_13522_stream = 0xf3, // 0b11110011
  441 + PES_H_222_1_type_A = 0xf4, // 0b11110100
  442 + PES_H_222_1_type_B = 0xf5, // 0b11110101
  443 + PES_H_222_1_type_C = 0xf6, // 0b11110110
  444 + PES_H_222_1_type_D = 0xf7, // 0b11110111
  445 + PES_H_222_1_type_E = 0xf8, // 0b11111000
  446 + PES_ancillary_stream = 0xf9, // 0b11111001
  447 + PES_SL_packetized_stream = 0xfa, // 0b11111010
  448 + PES_FlexMux_stream = 0xfb, // 0b11111011
449 // reserved data stream 449 // reserved data stream
450 // 1111 1100 … 1111 1110 450 // 1111 1100 … 1111 1110
451 - PES_program_stream_directory= 0b11111111, // 0xff 451 + PES_program_stream_directory= 0xff, // 0b11111111
452 }; 452 };
453 453
454 454
  1 +<<<<<<< HEAD
1 // for bw to init url 2 // for bw to init url
2 // url: scheme://host:port/path?query#fragment 3 // url: scheme://host:port/path?query#fragment
3 function srs_init_bwt(rtmp_url, hls_url) { 4 function srs_init_bwt(rtmp_url, hls_url) {
@@ -24,4 +25,141 @@ function srs_bwt_check_url(url) { @@ -24,4 +25,141 @@ function srs_bwt_check_url(url) {
24 function srs_bwt_build_default_url() { 25 function srs_bwt_build_default_url() {
25 var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"; 26 var url_default = "rtmp://" + window.location.host + ":" + 1935 + "/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com";
26 return url_default; 27 return url_default;
  28 +=======
  29 +/**
  30 +* the SrsBandwidth object.
  31 +* @param container the html container id.
  32 +* @param width a float value specifies the width of bandwidth.
  33 +* @param height a float value specifies the height of bandwidth.
  34 +* @param private_object [optional] an object that used as private object,
  35 +* for example, the logic chat object which owner this bandwidth.
  36 +*/
  37 +function SrsBandwidth(container, width, height, private_object) {
  38 + if (!SrsBandwidth.__id) {
  39 + SrsBandwidth.__id = 100;
  40 + }
  41 + if (!SrsBandwidth.__bandwidths) {
  42 + SrsBandwidth.__bandwidths = [];
  43 + }
  44 +
  45 + SrsBandwidth.__bandwidths.push(this);
  46 +
  47 + this.private_object = private_object;
  48 + this.container = container;
  49 + this.width = width;
  50 + this.height = height;
  51 + this.id = SrsBandwidth.__id++;
  52 + this.stream_url = null;
  53 + this.callbackObj = null;
  54 +
  55 + // the callback set data.
  56 + this.percent = 0;
  57 + this.status = "";
  58 +}
  59 +/**
  60 +* user can set some callback, then start the bandwidth.
  61 +* @param url the bandwidth test url.
  62 +* callbacks:
  63 +* on_bandwidth_ready():void, when srs bandwidth ready, user can play.
  64 +* on_update_progress(percent:Number):void, when srs bandwidth update the progress.
  65 +* percent:Number 100 means 100%.
  66 +* on_update_status(status:String):void, when srs bandwidth update the status.
  67 +* status:String the human readable status text.
  68 +*/
  69 +SrsBandwidth.prototype.start = function(url) {
  70 + if (url) {
  71 + this.stream_url = url;
  72 + }
  73 +
  74 + // embed the flash.
  75 + var flashvars = {};
  76 + flashvars.id = this.id;
  77 + flashvars.on_bandwidth_ready = "__srs_on_bandwidth_ready";
  78 + flashvars.on_update_progress = "__srs_on_update_progress";
  79 + flashvars.on_update_status = "__srs_on_update_status";
  80 +
  81 + var params = {};
  82 + params.wmode = "opaque";
  83 + params.allowFullScreen = "true";
  84 + params.allowScriptAccess = "always";
  85 +
  86 + var attributes = {};
  87 +
  88 + var self = this;
  89 +
  90 + swfobject.embedSWF(
  91 + "srs_bwt/release/srs_bwt.swf?_version="+srs_get_version_code(),
  92 + this.container,
  93 + this.width, this.height,
  94 + "11.1.0", "js/AdobeFlashbandwidthInstall.swf",
  95 + flashvars, params, attributes,
  96 + function(callbackObj){
  97 + self.callbackObj = callbackObj;
  98 + }
  99 + );
  100 +
  101 + return this;
  102 +}
  103 +/**
  104 +* play the stream.
  105 +* @param stream_url the url of stream, rtmp or http.
  106 +* @param volume the volume, 0 is mute, 1 is 100%, 2 is 200%.
  107 +*/
  108 +SrsBandwidth.prototype.check_bandwidth = function(url) {
  109 + this.stop();
  110 + SrsBandwidth.__bandwidths.push(this);
  111 +
  112 + if (url) {
  113 + this.stream_url = url;
  114 + }
  115 +
  116 + this.callbackObj.ref.__check_bandwidth(this.stream_url);
  117 +}
  118 +SrsBandwidth.prototype.stop = function(url) {
  119 + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) {
  120 + var bandwidth = SrsBandwidth.__bandwidths[i];
  121 +
  122 + if (bandwidth.id != this.id) {
  123 + continue;
  124 + }
  125 +
  126 + SrsBandwidth.__bandwidths.splice(i, 1);
  127 + break;
  128 + }
  129 +
  130 + this.callbackObj.ref.__stop();
  131 +}
  132 +SrsBandwidth.prototype.on_bandwidth_ready = function() {
  133 +}
  134 +SrsBandwidth.prototype.on_update_progress = function(percent) {
  135 +}
  136 +SrsBandwidth.prototype.on_update_status = function(status) {
  137 +}
  138 +function __srs_find_bandwidth(id) {
  139 + for (var i = 0; i < SrsBandwidth.__bandwidths.length; i++) {
  140 + var bandwidth = SrsBandwidth.__bandwidths[i];
  141 +
  142 + if (bandwidth.id != id) {
  143 + continue;
  144 + }
  145 +
  146 + return bandwidth;
  147 + }
  148 +
  149 + throw new Error("bandwidth not found. id=" + id);
  150 +}
  151 +function __srs_on_bandwidth_ready(id) {
  152 + var bandwidth = __srs_find_bandwidth(id);
  153 + bandwidth.on_bandwidth_ready();
  154 +}
  155 +function __srs_on_update_progress(id, percent) {
  156 + var bandwidth = __srs_find_bandwidth(id);
  157 + bandwidth.percent = percent;
  158 + bandwidth.on_update_progress(percent);
  159 +}
  160 +function __srs_on_update_status(id, status) {
  161 + var bandwidth = __srs_find_bandwidth(id);
  162 + bandwidth.status = status;
  163 + bandwidth.on_update_status(status);
  164 +>>>>>>> upstream/master
27 } 165 }
@@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; } @@ -10,7 +10,7 @@ function srs_get_player_width() { return srs_get_player_modal() - 30; }
10 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; } 10 function srs_get_player_height() { return srs_get_player_width() * 9 / 19; }
11 11
12 // to query the swf anti cache. 12 // to query the swf anti cache.
13 -function srs_get_version_code() { return "1.17"; } 13 +function srs_get_version_code() { return "1.19"; }
14 // get the default vhost for players. 14 // get the default vhost for players.
15 function srs_get_player_vhost() { return "players"; } 15 function srs_get_player_vhost() { return "players"; }
16 // the api server port, for chat room. 16 // the api server port, for chat room.
@@ -80,6 +80,18 @@ function build_default_publish_rtmp_url() { @@ -80,6 +80,18 @@ function build_default_publish_rtmp_url() {
80 return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream; 80 return "rtmp://" + server + ":" + port + "/" + app + "...vhost..." + vhost + "/" + stream;
81 } 81 }
82 } 82 }
  83 +// for the bandwidth tool to init page
  84 +function build_default_bandwidth_rtmp_url() {
  85 + var query = parse_query_string();
  86 +
  87 + var server = (query.server == undefined)? window.location.hostname:query.server;
  88 + var port = (query.port == undefined)? 1935:query.port;
  89 + var vhost = "bandcheck.srs.com";
  90 + var app = (query.app == undefined)? "app":query.app;
  91 + var key = (query.key == undefined)? "35c9b402c12a7246868752e2878f7e0e":query.key;
  92 +
  93 + return "rtmp://" + server + ":" + port + "/" + app + "?key=" + key + "&vhost=" + vhost;
  94 +}
83 95
84 /** 96 /**
85 @param server the ip of server. default to window.location.hostname 97 @param server the ip of server. default to window.location.hostname
@@ -139,6 +151,15 @@ function srs_init_publish(rtmp_url) { @@ -139,6 +151,15 @@ function srs_init_publish(rtmp_url) {
139 $(rtmp_url).val(build_default_publish_rtmp_url()); 151 $(rtmp_url).val(build_default_publish_rtmp_url());
140 } 152 }
141 } 153 }
  154 +// for bw to init url
  155 +// url: scheme://host:port/path?query#fragment
  156 +function srs_init_bwt(rtmp_url, hls_url) {
  157 + update_nav();
  158 +
  159 + if (rtmp_url) {
  160 + $(rtmp_url).val(build_default_bandwidth_rtmp_url());
  161 + }
  162 +}
142 163
143 // check whether can republish 164 // check whether can republish
144 function srs_can_republish() { 165 function srs_can_republish() {
@@ -63,7 +63,7 @@ SrsPlayer.prototype.start = function(url) { @@ -63,7 +63,7 @@ SrsPlayer.prototype.start = function(url) {
63 "srs_player/release/srs_player.swf?_version="+srs_get_version_code(), 63 "srs_player/release/srs_player.swf?_version="+srs_get_version_code(),
64 this.container, 64 this.container,
65 this.width, this.height, 65 this.width, this.height,
66 - "11.1", "js/AdobeFlashPlayerInstall.swf", 66 + "11.1.0", "js/AdobeFlashPlayerInstall.swf",
67 flashvars, params, attributes, 67 flashvars, params, attributes,
68 function(callbackObj){ 68 function(callbackObj){
69 self.callbackObj = callbackObj; 69 self.callbackObj = callbackObj;
@@ -73,7 +73,7 @@ SrsPublisher.prototype.start = function() { @@ -73,7 +73,7 @@ SrsPublisher.prototype.start = function() {
73 "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(), 73 "srs_publisher/release/srs_publisher.swf?_version="+srs_get_version_code(),
74 this.container, 74 this.container,
75 this.width, this.height, 75 this.width, this.height,
76 - "11.1", "js/AdobeFlashPlayerInstall.swf", 76 + "11.1.0", "js/AdobeFlashPlayerInstall.swf",
77 flashvars, params, attributes, 77 flashvars, params, attributes,
78 function(callbackObj){ 78 function(callbackObj){
79 self.callbackObj = callbackObj; 79 self.callbackObj = callbackObj;
@@ -13,6 +13,21 @@ function padding(number, length, prefix) { @@ -13,6 +13,21 @@ function padding(number, length, prefix) {
13 13
14 /** 14 /**
15 * parse the query string to object. 15 * parse the query string to object.
  16 +* parse the url location object as: host(hostname:http_port), pathname(dir/filename)
  17 +* for example, url http://192.168.1.168:1980/ui/players.html?vhost=player.vhost.com&app=test&stream=livestream
  18 +* parsed to object:
  19 +{
  20 + host : "192.168.1.168:1980",
  21 + hostname : "192.168.1.168",
  22 + http_port : 1980,
  23 + pathname : "/ui/players.html",
  24 + dir : "/ui",
  25 + filename : "/players.html",
  26 +
  27 + vhost : "player.vhost.com",
  28 + app : "test",
  29 + stream : "livestream"
  30 +}
16 */ 31 */
17 function parse_query_string(){ 32 function parse_query_string(){
18 var obj = {}; 33 var obj = {};
@@ -12,13 +12,18 @@ @@ -12,13 +12,18 @@
12 <script type="text/javascript" src="js/srs.player.js"></script> 12 <script type="text/javascript" src="js/srs.player.js"></script>
13 <script type="text/javascript" src="js/srs.publisher.js"></script> 13 <script type="text/javascript" src="js/srs.publisher.js"></script>
14 <script type="text/javascript" src="js/srs.utility.js"></script> 14 <script type="text/javascript" src="js/srs.utility.js"></script>
  15 +<<<<<<< HEAD
15 <script type="text/javascript" src="js/srs.utility.js"></script> 16 <script type="text/javascript" src="js/srs.utility.js"></script>
16 <script type="text/javascript" src="js/srs.bandwidth.js"></script> 17 <script type="text/javascript" src="js/srs.bandwidth.js"></script>
  18 +=======
  19 + <script type="text/javascript" src="js/srs.bandwidth.js"></script>
  20 +>>>>>>> upstream/master
17 <style> 21 <style>
18 body{ 22 body{
19 padding-top: 55px; 23 padding-top: 55px;
20 } 24 }
21 #main_modal { 25 #main_modal {
  26 +<<<<<<< HEAD
22 width: 600px; 27 width: 600px;
23 margin-left: -300px; 28 margin-left: -300px;
24 } 29 }
@@ -119,6 +124,56 @@ @@ -119,6 +124,56 @@
119 } 124 }
120 ); 125 );
121 }); 126 });
  127 +=======
  128 + width: 700px;
  129 + margin-left: -350px;
  130 + }
  131 + </style>
  132 + <script type="text/javascript">
  133 + var bandwidth = null;
  134 +
  135 + $(function(){
  136 + srs_init_bwt("#txt_url");
  137 +
  138 + $("#btn_play").click(on_click_play);
  139 + $("#main_modal").on("show", on_start_bandwidth_test);
  140 + $("#main_modal").on("hide", on_stop_bandwidth_test);
  141 + });
  142 +
  143 + function on_click_play() {
  144 + $("#check_status").text("");
  145 + $("#progress_bar").width("0%");
  146 + $("#main_modal").modal({show:true, keyboard:false});
  147 + }
  148 + function on_start_bandwidth_test() {
  149 + $("#div_container").remove();
  150 +
  151 + var div_container = $("<div/>");
  152 + $(div_container).attr("id", "div_container");
  153 + $("#player").append(div_container);
  154 +
  155 + var player = $("<div/>");
  156 + $(player).attr("id", "player_id");
  157 + $(div_container).append(player);
  158 +
  159 + var url = $("#txt_url").val();
  160 +
  161 + bandwidth = new SrsBandwidth("player_id", 100, 1);
  162 + bandwidth.on_bandwidth_ready = function() {
  163 + this.check_bandwidth(url);
  164 + }
  165 + bandwidth.on_update_progress = function(percent) {
  166 + $("#progress_bar").width(percent + "%");
  167 + }
  168 + bandwidth.on_update_status = function(status) {
  169 + $("#check_status").text(status);
  170 + }
  171 + bandwidth.start(url);
  172 + }
  173 + function on_stop_bandwidth_test() {
  174 + bandwidth.stop();
  175 + }
  176 +>>>>>>> upstream/master
122 </script> 177 </script>
123 </head> 178 </head>
124 <body> 179 <body>
@@ -141,6 +196,7 @@ @@ -141,6 +196,7 @@
141 </div> 196 </div>
142 </div> 197 </div>
143 <div class="container"> 198 <div class="container">
  199 +<<<<<<< HEAD
144 200
145 <div class="form-inline"> 201 <div class="form-inline">
146 URL: 202 URL:
@@ -164,15 +220,49 @@ @@ -164,15 +220,49 @@
164 </div> 220 </div>
165 <span id="check_status1"><font ><strong id="check_status">status</strong></font> </span> 221 <span id="check_status1"><font ><strong id="check_status">status</strong></font> </span>
166 222
  223 +=======
  224 + <div class="alert alert-info fade in">
  225 + <button type="button" class="close" data-dismiss="alert">×</button>
  226 + <strong><span>Usage:</span></strong> <span>点击“开始测速”即可测带宽,最大可测试带宽由服务器限制</span>
  227 + </div>
  228 + <div class="form-inline">
  229 + URL:
  230 + <input type="text" id="txt_url" class="input-xxlarge" value=""></input>
  231 + <button class="btn btn-primary" id="btn_play">开始测速</button>
  232 + </div>
  233 + <div id="main_modal" class="modal hide fade">
  234 + <div class="modal-header">
  235 + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
  236 + <h3>SRS Bandwidth Check</h3>
  237 + </div>
  238 + <div class="modal-body">
  239 + <div class="row-fluid">
  240 + <div class="span1"></div>
  241 + <div class="span10">
  242 + <div class="progress progress-striped active" id="pb_buffer_bg">
  243 + <div class="bar" style="width: 0%;" id="progress_bar"></div>
  244 + </div>
  245 + </div>
  246 + <div class="span1"></div>
  247 + </div>
  248 + <span id="check_status">status</span>
  249 + </div>
  250 +>>>>>>> upstream/master
167 <div class="modal-footer"> 251 <div class="modal-footer">
168 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button> 252 <button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button>
169 </div> 253 </div>
170 </div> 254 </div>
  255 +<<<<<<< HEAD
171 256
  257 +=======
  258 +>>>>>>> upstream/master
172 <hr> 259 <hr>
173 <footer> 260 <footer>
174 <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team &copy; 2013</a></p> 261 <p><a href="https://github.com/winlinvip/simple-rtmp-server">SRS Team &copy; 2013</a></p>
175 </footer> 262 </footer>
  263 + <div class="container">
  264 + <div id="player"></div>
  265 + </div>
176 </div> 266 </div>
177 </body> 267 </body>
178 268
1 <?xml version="1.0" encoding="UTF-8" standalone="no"?> 1 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2 <actionScriptProperties analytics="false" mainApplicationPath="srs_bwt.as" projectUUID="00251213-e6a2-4dd5-a033-125cc78f843c" version="10"> 2 <actionScriptProperties analytics="false" mainApplicationPath="srs_bwt.as" projectUUID="00251213-e6a2-4dd5-a033-125cc78f843c" version="10">
  3 +<<<<<<< HEAD
3 <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin-debug" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true"> 4 <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="true" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="bin-debug" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
  5 +=======
  6 + <compiler additionalCompilerArguments="-locale en_US" autoRSLOrdering="true" copyDependentFiles="true" fteInMXComponents="false" generateAccessible="true" htmlExpressInstall="true" htmlGenerate="false" htmlHistoryManagement="true" htmlPlayerVersionCheck="true" includeNetmonSwc="false" outputFolderPath="release" removeUnusedRSL="true" sourceFolderPath="src" strict="true" targetPlayerVersion="0.0.0" useApolloConfig="false" useDebugRSLSwfs="true" verifyDigests="true" warn="true">
  7 +>>>>>>> upstream/master
4 <compilerSourcePath/> 8 <compilerSourcePath/>
5 <libraryPath defaultLinkType="0"> 9 <libraryPath defaultLinkType="0">
6 <libraryPathEntry kind="4" path=""> 10 <libraryPathEntry kind="4" path="">
@@ -17,6 +21,7 @@ @@ -17,6 +21,7 @@
17 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/> 21 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark.swc" useDefaultLinkType="false"/>
18 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/> 22 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/sparkskins.swc" useDefaultLinkType="false"/>
19 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/> 23 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/rpc.swc" useDefaultLinkType="false"/>
  24 +<<<<<<< HEAD
20 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/> 25 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/>
21 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/> 26 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/>
22 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/> 27 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
@@ -24,6 +29,15 @@ @@ -24,6 +29,15 @@
24 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/> 29 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
25 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/> 30 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/>
26 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/> 31 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
  32 +=======
  33 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/datavisualization.swc" useDefaultLinkType="false"/>
  34 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/qtp_air.swc" useDefaultLinkType="false"/>
  35 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/videoPlayer.swc" useDefaultLinkType="false"/>
  36 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/spark_dmv.swc" useDefaultLinkType="false"/>
  37 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation.swc" useDefaultLinkType="false"/>
  38 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_dmv.swc" useDefaultLinkType="false"/>
  39 + <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/flash-integration.swc" useDefaultLinkType="false"/>
  40 +>>>>>>> upstream/master
27 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/> 41 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_flashflexkit.swc" useDefaultLinkType="false"/>
28 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/> 42 <libraryPathEntry kind="3" linkType="1" path="${PROJECT_FRAMEWORKS}/libs/automation_agent.swc" useDefaultLinkType="false"/>
29 </excludedEntries> 43 </excludedEntries>
@@ -20,10 +20,22 @@ package @@ -20,10 +20,22 @@ package
20 20
21 public class srs_bwt extends Sprite 21 public class srs_bwt extends Sprite
22 { 22 {
  23 +<<<<<<< HEAD
23 private var connection:NetConnection; 24 private var connection:NetConnection;
24 25
25 private var updatePlayProgressTimer:Timer; 26 private var updatePlayProgressTimer:Timer;
26 private var elapTimer:SrsElapsedTimer; 27 private var elapTimer:SrsElapsedTimer;
  28 +=======
  29 + private var connection:NetConnection = null;
  30 +
  31 + private var updatePlayProgressTimer:Timer = null;
  32 + private var elapTimer:SrsElapsedTimer = null;
  33 +
  34 + // user set id.
  35 + private var js_id:String = null;
  36 + // play param url.
  37 + private var user_url:String = null;
  38 +>>>>>>> upstream/master
27 39
28 // server ip get from server 40 // server ip get from server
29 private var server_ip:String; 41 private var server_ip:String;
@@ -32,8 +44,13 @@ package @@ -32,8 +44,13 @@ package
32 private var stop_pub:Boolean = false; 44 private var stop_pub:Boolean = false;
33 45
34 // js interface 46 // js interface
  47 +<<<<<<< HEAD
35 private var js_update_progress:String; 48 private var js_update_progress:String;
36 private var js_progress_reset:String; 49 private var js_progress_reset:String;
  50 +=======
  51 + private var js_on_player_ready:String;
  52 + private var js_update_progress:String;
  53 +>>>>>>> upstream/master
37 private var js_update_status:String; 54 private var js_update_status:String;
38 55
39 private var value_progressbar:Number = 0; 56 private var value_progressbar:Number = 0;
@@ -44,10 +61,26 @@ package @@ -44,10 +61,26 @@ package
44 61
45 public function srs_bwt() 62 public function srs_bwt()
46 { 63 {
  64 +<<<<<<< HEAD
  65 +=======
  66 + if (!this.stage) {
  67 + this.addEventListener(Event.ADDED_TO_STAGE, this.system_on_add_to_stage);
  68 + } else {
  69 + this.system_on_add_to_stage(null);
  70 + }
  71 + }
  72 +
  73 + /**
  74 + * system event callback, when this control added to stage.
  75 + * the main function.
  76 + */
  77 + private function system_on_add_to_stage(evt:Event):void {
  78 +>>>>>>> upstream/master
47 this.stage.scaleMode = StageScaleMode.NO_SCALE; 79 this.stage.scaleMode = StageScaleMode.NO_SCALE;
48 this.stage.align = StageAlign.TOP_LEFT; 80 this.stage.align = StageAlign.TOP_LEFT;
49 81
50 var flashvars:Object = this.root.loaderInfo.parameters; 82 var flashvars:Object = this.root.loaderInfo.parameters;
  83 +<<<<<<< HEAD
51 this.js_update_progress = flashvars.update_progress; 84 this.js_update_progress = flashvars.update_progress;
52 this.js_progress_reset = flashvars.progress_reset; 85 this.js_progress_reset = flashvars.progress_reset;
53 this.js_update_status = flashvars.update_status; 86 this.js_update_status = flashvars.update_status;
@@ -58,11 +91,56 @@ package @@ -58,11 +91,56 @@ package
58 myMenu.customItems.push(new ContextMenuItem("Srs 带宽测试工具 0.1", true)); 91 myMenu.customItems.push(new ContextMenuItem("Srs 带宽测试工具 0.1", true));
59 this.contextMenu = myMenu; 92 this.contextMenu = myMenu;
60 93
  94 +=======
  95 +
  96 + if (!flashvars.hasOwnProperty("id")) {
  97 + throw new Error("must specifies the id");
  98 + }
  99 +
  100 + this.js_id = flashvars.id;
  101 + this.js_on_player_ready = flashvars.on_bandwidth_ready;
  102 + this.js_update_progress = flashvars.on_update_progress;
  103 + this.js_update_status = flashvars.on_update_status;
  104 +
  105 + // init context menu
  106 + var myMenu:ContextMenu = new ContextMenu();
  107 + myMenu.hideBuiltInItems();
  108 + myMenu.customItems.push(new ContextMenuItem("SRS 带宽测试工具", true));
  109 + this.contextMenu = myMenu;
  110 +
  111 + flash.utils.setTimeout(this.system_on_js_ready, 0);
  112 + }
  113 +
  114 + /**
  115 + * system callack event, when js ready, register callback for js.
  116 + * the actual main function.
  117 + */
  118 + private function system_on_js_ready():void {
  119 + if (!flash.external.ExternalInterface.available) {
  120 + trace("js not ready, try later.");
  121 + flash.utils.setTimeout(this.system_on_js_ready, 100);
  122 + return;
  123 + }
  124 +
  125 + flash.external.ExternalInterface.addCallback("__check_bandwidth", this.js_call_check_bandwidth);
  126 + flash.external.ExternalInterface.addCallback("__stop", this.js_call_stop);
  127 +
  128 + flash.external.ExternalInterface.call(this.js_on_player_ready, this.js_id);
  129 + }
  130 +
  131 + private function js_call_check_bandwidth(url:String):void {
  132 + js_call_stop();
  133 +
  134 +>>>>>>> upstream/master
61 // init connection 135 // init connection
62 connection = new NetConnection; 136 connection = new NetConnection;
63 connection.client = this; 137 connection.client = this;
64 connection.addEventListener(NetStatusEvent.NET_STATUS, onStatus); 138 connection.addEventListener(NetStatusEvent.NET_STATUS, onStatus);
  139 +<<<<<<< HEAD
65 connection.connect(flashvars.url); 140 connection.connect(flashvars.url);
  141 +=======
  142 + connection.connect(url);
  143 +>>>>>>> upstream/master
66 //connection.connect("rtmp://192.168.8.234:1935/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com"); 144 //connection.connect("rtmp://192.168.8.234:1935/app?key=35c9b402c12a7246868752e2878f7e0e&vhost=bandcheck.srs.com");
67 145
68 // for play to update progress bar 146 // for play to update progress bar
@@ -73,10 +151,43 @@ package @@ -73,10 +151,43 @@ package
73 updatePlayProgressTimer.addEventListener(TimerEvent.TIMER, onTimerTimeout); 151 updatePlayProgressTimer.addEventListener(TimerEvent.TIMER, onTimerTimeout);
74 updatePlayProgressTimer.start(); 152 updatePlayProgressTimer.start();
75 } 153 }
  154 +<<<<<<< HEAD
76 155
77 // get NetConnection NetStatusEvent 156 // get NetConnection NetStatusEvent
78 public function onStatus(evt:NetStatusEvent) : void{ 157 public function onStatus(evt:NetStatusEvent) : void{
79 trace(evt.info.code); 158 trace(evt.info.code);
  159 +=======
  160 + private function js_call_stop():void {
  161 + if (connection) {
  162 + connection.close();
  163 + connection = null;
  164 + }
  165 + if (updatePlayProgressTimer) {
  166 + updatePlayProgressTimer.stop();
  167 + updatePlayProgressTimer = null;
  168 + }
  169 + if (elapTimer) {
  170 + elapTimer.restart();
  171 + }
  172 + }
  173 +
  174 + // get NetConnection NetStatusEvent
  175 + public function onStatus(evt:NetStatusEvent) : void{
  176 + trace(evt.info.code);
  177 +
  178 + if (evt.info.hasOwnProperty("data") && evt.info.data) {
  179 + // for context menu
  180 + var customItems:Array = [new ContextMenuItem("SrsPlayer")];
  181 + if (evt.info.data.hasOwnProperty("srs_server")) {
  182 + customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server));
  183 + }
  184 + if (evt.info.data.hasOwnProperty("srs_primary_authors")) {
  185 + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors));
  186 + }
  187 + contextMenu.customItems = customItems;
  188 + }
  189 +
  190 +>>>>>>> upstream/master
80 switch(evt.info.code){ 191 switch(evt.info.code){
81 case "NetConnection.Connect.Failed": 192 case "NetConnection.Connect.Failed":
82 updateState("连接服务器失败!"); 193 updateState("连接服务器失败!");
@@ -92,8 +203,18 @@ package @@ -92,8 +203,18 @@ package
92 //updateState("连接已断开!"); 203 //updateState("连接已断开!");
93 break; 204 break;
94 } 205 }
  206 +<<<<<<< HEAD
95 207
96 } 208 }
  209 +=======
  210 + }
  211 +
  212 + public function onTimerTimeout(evt:TimerEvent):void
  213 + {
  214 + value_progressbar = elapTimer.elapsed();
  215 + updateProgess(value_progressbar, max_progressbar);
  216 + }
  217 +>>>>>>> upstream/master
97 218
98 /** 219 /**
99 * NetConnection callback this function, when recv server call "onSrsBandCheckStartPlayBytes" 220 * NetConnection callback this function, when recv server call "onSrsBandCheckStartPlayBytes"
@@ -104,13 +225,18 @@ package @@ -104,13 +225,18 @@ package
104 var interval_ms:Number = evt.interval_ms; 225 var interval_ms:Number = evt.interval_ms;
105 226
106 connection.call("onSrsBandCheckStartingPlayBytes", null); 227 connection.call("onSrsBandCheckStartingPlayBytes", null);
  228 +<<<<<<< HEAD
107 updateState("测试下行带宽(" + server_ip + ")"); 229 updateState("测试下行带宽(" + server_ip + ")");
  230 +=======
  231 + updateState("开始测试下行带宽,服务器IP:" + server_ip);
  232 +>>>>>>> upstream/master
108 233
109 // we suppose play duration_ms = pub duration_ms 234 // we suppose play duration_ms = pub duration_ms
110 max_progressbar = duration_ms * 2; 235 max_progressbar = duration_ms * 2;
111 } 236 }
112 237
113 public function onSrsBandCheckPlaying(evt:Object):void{ 238 public function onSrsBandCheckPlaying(evt:Object):void{
  239 +<<<<<<< HEAD
114 240
115 } 241 }
116 242
@@ -118,6 +244,8 @@ package @@ -118,6 +244,8 @@ package
118 { 244 {
119 value_progressbar = elapTimer.elapsed(); 245 value_progressbar = elapTimer.elapsed();
120 updateProgess(value_progressbar, max_progressbar); 246 updateProgess(value_progressbar, max_progressbar);
  247 +=======
  248 +>>>>>>> upstream/master
121 } 249 }
122 250
123 public function onSrsBandCheckStopPlayBytes(evt:Object):void{ 251 public function onSrsBandCheckStopPlayBytes(evt:Object):void{
@@ -133,6 +261,10 @@ package @@ -133,6 +261,10 @@ package
133 kbps = (int(kbps * 10))/10.0; 261 kbps = (int(kbps * 10))/10.0;
134 262
135 flash.utils.setTimeout(stopPlayTest, 0); 263 flash.utils.setTimeout(stopPlayTest, 0);
  264 +<<<<<<< HEAD
  265 +=======
  266 + updateState("下行带宽测试完毕,服务器: " + server_ip + "," + kbps + "kbps,开始测试上行带宽。");
  267 +>>>>>>> upstream/master
136 } 268 }
137 269
138 private function stopPlayTest():void{ 270 private function stopPlayTest():void{
@@ -144,7 +276,10 @@ package @@ -144,7 +276,10 @@ package
144 var interval_ms:Number = evt.interval_ms; 276 var interval_ms:Number = evt.interval_ms;
145 277
146 connection.call("onSrsBandCheckStartingPublishBytes", null); 278 connection.call("onSrsBandCheckStartingPublishBytes", null);
  279 +<<<<<<< HEAD
147 updateState("测试上行带宽(" + server_ip + ")"); 280 updateState("测试上行带宽(" + server_ip + ")");
  281 +=======
  282 +>>>>>>> upstream/master
148 283
149 flash.utils.setTimeout(publisher, 0); 284 flash.utils.setTimeout(publisher, 0);
150 } 285 }
@@ -208,6 +343,7 @@ package @@ -208,6 +343,7 @@ package
208 connection.call("finalClientPacket", null); 343 connection.call("finalClientPacket", null);
209 } 344 }
210 345
  346 +<<<<<<< HEAD
211 public function onBWDone():void{ 347 public function onBWDone():void{
212 // do nothing 348 // do nothing
213 } 349 }
@@ -215,13 +351,27 @@ package @@ -215,13 +351,27 @@ package
215 // update progressBar's value 351 // update progressBar's value
216 private function updateProgess(value:Number, maxValue:Number):void{ 352 private function updateProgess(value:Number, maxValue:Number):void{
217 flash.external.ExternalInterface.call(this.js_update_progress, value * 100 / maxValue + "%"); 353 flash.external.ExternalInterface.call(this.js_update_progress, value * 100 / maxValue + "%");
  354 +=======
  355 + // update progressBar's value
  356 + private function updateProgess(value:Number, maxValue:Number):void{
  357 + flash.external.ExternalInterface.call(this.js_update_progress, this.js_id, value * 100 / maxValue);
  358 +>>>>>>> upstream/master
218 trace(value + "-" + maxValue + "-" + value * 100 / maxValue + "%"); 359 trace(value + "-" + maxValue + "-" + value * 100 / maxValue + "%");
219 } 360 }
220 361
221 // update checking status 362 // update checking status
222 private function updateState(text:String):void{ 363 private function updateState(text:String):void{
  364 +<<<<<<< HEAD
223 flash.external.ExternalInterface.call(this.js_update_status, text); 365 flash.external.ExternalInterface.call(this.js_update_status, text);
224 trace(text); 366 trace(text);
225 } 367 }
  368 +=======
  369 + flash.external.ExternalInterface.call(this.js_update_status, this.js_id, text);
  370 + trace(text);
  371 + }
  372 +
  373 + public function onBWDone():void{
  374 + }
  375 +>>>>>>> upstream/master
226 } 376 }
227 } 377 }
@@ -305,8 +305,8 @@ package @@ -305,8 +305,8 @@ package
305 if (evt.info.data.hasOwnProperty("srs_server")) { 305 if (evt.info.data.hasOwnProperty("srs_server")) {
306 customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); 306 customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server));
307 } 307 }
308 - if (evt.info.data.hasOwnProperty("srs_contributor")) {  
309 - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); 308 + if (evt.info.data.hasOwnProperty("srs_primary_authors")) {
  309 + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors));
310 } 310 }
311 contextMenu.customItems = customItems; 311 contextMenu.customItems = customItems;
312 } 312 }
@@ -334,7 +334,7 @@ package @@ -334,7 +334,7 @@ package
334 if (url.indexOf("http") == 0) { 334 if (url.indexOf("http") == 0) {
335 media_stream.play(url); 335 media_stream.play(url);
336 } else { 336 } else {
337 - var streamName:String = url.substr(url.lastIndexOf("/")); 337 + var streamName:String = url.substr(url.lastIndexOf("/") + 1);
338 media_stream.play(streamName); 338 media_stream.play(streamName);
339 } 339 }
340 340
@@ -192,8 +192,8 @@ package @@ -192,8 +192,8 @@ package
192 if (evt.info.data.hasOwnProperty("srs_server")) { 192 if (evt.info.data.hasOwnProperty("srs_server")) {
193 customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server)); 193 customItems.push(new ContextMenuItem("Server: " + evt.info.data.srs_server));
194 } 194 }
195 - if (evt.info.data.hasOwnProperty("srs_contributor")) {  
196 - customItems.push(new ContextMenuItem("Contributor: " + evt.info.data.srs_contributor)); 195 + if (evt.info.data.hasOwnProperty("srs_primary_authors")) {
  196 + customItems.push(new ContextMenuItem("PrimaryAuthors: " + evt.info.data.srs_primary_authors));
197 } 197 }
198 contextMenu.customItems = customItems; 198 contextMenu.customItems = customItems;
199 } 199 }
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -76,10 +76,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
76 #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT 76 #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT
77 #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" 77 #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server"
78 #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" 78 #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin"
79 -#define RTMP_SIG_SRS_EMAIL "winterserver@126.com" 79 +#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com"
80 #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" 80 #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)"
81 -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013 winlin"  
82 -#define RTMP_SIG_SRS_CONTRIBUTOR "winlin,wenjiegit" 81 +#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2014 winlin"
  82 +#define RTMP_SIG_SRS_PRIMARY_AUTHROS "winlin,wenjiegit"
83 83
84 // compare 84 // compare
85 #define srs_min(a, b) (((a) < (b))? (a) : (b)) 85 #define srs_min(a, b) (((a) < (b))? (a) : (b))
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 wenjiegit 4 +Copyright (c) 2013-2014 wenjiegit
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 wenjiegit 4 +Copyright (c) 2013-2014 wenjiegit
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -42,11 +42,6 @@ using namespace std; @@ -42,11 +42,6 @@ using namespace std;
42 #include <srs_core_http.hpp> 42 #include <srs_core_http.hpp>
43 #include <srs_core_bandwidth.hpp> 43 #include <srs_core_bandwidth.hpp>
44 44
45 -#define SRS_PULSE_TIMEOUT_MS 100  
46 -#define SRS_SEND_TIMEOUT_US 5000000L  
47 -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US  
48 -#define SRS_STREAM_BUSY_SLEEP_MS 2000  
49 -  
50 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd) 45 SrsClient::SrsClient(SrsServer* srs_server, st_netfd_t client_stfd)
51 : SrsConnection(srs_server, client_stfd) 46 : SrsConnection(srs_server, client_stfd)
52 { 47 {
@@ -198,7 +193,7 @@ int SrsClient::service_cycle() @@ -198,7 +193,7 @@ int SrsClient::service_cycle()
198 srs_warn("stream %s is already publishing. ret=%d", 193 srs_warn("stream %s is already publishing. ret=%d",
199 req->get_stream_url().c_str(), ret); 194 req->get_stream_url().c_str(), ret);
200 // to delay request 195 // to delay request
201 - st_usleep(SRS_STREAM_BUSY_SLEEP_MS * 1000); 196 + st_usleep(SRS_STREAM_BUSY_SLEEP_US);
202 return ret; 197 return ret;
203 } 198 }
204 199
@@ -324,12 +319,12 @@ int SrsClient::playing(SrsSource* source) @@ -324,12 +319,12 @@ int SrsClient::playing(SrsSource* source)
324 SrsAutoFree(SrsConsumer, consumer, false); 319 SrsAutoFree(SrsConsumer, consumer, false);
325 srs_verbose("consumer created success."); 320 srs_verbose("consumer created success.");
326 321
327 - rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); 322 + rtmp->set_recv_timeout(SRS_PULSE_TIMEOUT_US);
328 323
329 SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER); 324 SrsPithyPrint pithy_print(SRS_STAGE_PLAY_USER);
330 325
331 while (true) { 326 while (true) {
332 - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); 327 + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);
333 328
334 // switch to other st-threads. 329 // switch to other st-threads.
335 st_usleep(0); 330 st_usleep(0);
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -735,9 +735,9 @@ int SrsConfig::parse_argv(int& i, char** argv) @@ -735,9 +735,9 @@ int SrsConfig::parse_argv(int& i, char** argv)
735 735
736 void SrsConfig::print_help(char** argv) 736 void SrsConfig::print_help(char** argv)
737 { 737 {
738 - printf(RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION  
739 - " Copyright (c) 2013 winlin\n"  
740 - "Contributors: "RTMP_SIG_SRS_CONTRIBUTOR"\n" 738 + printf(
  739 + RTMP_SIG_SRS_NAME" "RTMP_SIG_SRS_VERSION" "RTMP_SIG_SRS_COPYRIGHT"\n"
  740 + "Primary Authors: "RTMP_SIG_SRS_PRIMARY_AUTHROS"\n"
741 "Build: "SRS_BUILD_DATE" Configuration: "SRS_CONFIGURE"\n" 741 "Build: "SRS_BUILD_DATE" Configuration: "SRS_CONFIGURE"\n"
742 "Usage: %s [-h?vV] [-c <filename>]\n" 742 "Usage: %s [-h?vV] [-c <filename>]\n"
743 "\n" 743 "\n"
@@ -1664,4 +1664,3 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b) @@ -1664,4 +1664,3 @@ bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b)
1664 1664
1665 return true; 1665 return true;
1666 } 1666 }
1667 -  
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -57,7 +57,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
57 // the interval in seconds for bandwidth check 57 // the interval in seconds for bandwidth check
58 #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000 58 #define SRS_CONF_DEFAULT_BANDWIDTH_LIMIT_KBPS 1000
59 59
60 -#define SRS_CONF_DEFAULT_CHUNK_SIZE 4096 60 +// the default chunk size for system.
  61 +#define SRS_CONF_DEFAULT_CHUNK_SIZE 60000
61 62
62 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300 63 #define SRS_STAGE_PLAY_USER_INTERVAL_MS 1300
63 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100 64 #define SRS_STAGE_PUBLISH_USER_INTERVAL_MS 1100
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -37,11 +37,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 #include <srs_core_config.hpp> 37 #include <srs_core_config.hpp>
38 #include <srs_core_rtmp.hpp> 38 #include <srs_core_rtmp.hpp>
39 #include <srs_core_pithy_print.hpp> 39 #include <srs_core_pithy_print.hpp>
  40 +#include <srs_core_protocol.hpp>
40 41
41 #ifdef SRS_FFMPEG 42 #ifdef SRS_FFMPEG
42 43
43 -#define SRS_ENCODER_SLEEP_MS 2000  
44 -  
45 #define SRS_ENCODER_COPY "copy" 44 #define SRS_ENCODER_COPY "copy"
46 #define SRS_ENCODER_VCODEC "libx264" 45 #define SRS_ENCODER_VCODEC "libx264"
47 #define SRS_ENCODER_ACODEC "libaacplus" 46 #define SRS_ENCODER_ACODEC "libaacplus"
@@ -483,7 +482,7 @@ void SrsFFMPEG::stop() @@ -483,7 +482,7 @@ void SrsFFMPEG::stop()
483 482
484 SrsEncoder::SrsEncoder() 483 SrsEncoder::SrsEncoder()
485 { 484 {
486 - pthread = new SrsThread(this, SRS_ENCODER_SLEEP_MS); 485 + pthread = new SrsThread(this, SRS_ENCODER_SLEEP_US);
487 pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER); 486 pithy_print = new SrsPithyPrint(SRS_STAGE_ENCODER);
488 } 487 }
489 488
@@ -549,7 +548,7 @@ int SrsEncoder::cycle() @@ -549,7 +548,7 @@ int SrsEncoder::cycle()
549 548
550 // pithy print 549 // pithy print
551 encoder(); 550 encoder();
552 - pithy_print->elapse(SRS_ENCODER_SLEEP_MS); 551 + pithy_print->elapse(SRS_ENCODER_SLEEP_US / 1000);
553 552
554 return ret; 553 return ret;
555 } 554 }
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -38,11 +38,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #include <srs_core_source.hpp> 38 #include <srs_core_source.hpp>
39 #include <srs_core_autofree.hpp> 39 #include <srs_core_autofree.hpp>
40 40
41 -#define SRS_PULSE_TIMEOUT_MS 100  
42 -#define SRS_FORWARDER_SLEEP_MS 2000  
43 -#define SRS_SEND_TIMEOUT_US 3000000L  
44 -#define SRS_RECV_TIMEOUT_US SRS_SEND_TIMEOUT_US  
45 -  
46 SrsForwarder::SrsForwarder(SrsSource* _source) 41 SrsForwarder::SrsForwarder(SrsSource* _source)
47 { 42 {
48 source = _source; 43 source = _source;
@@ -51,7 +46,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source) @@ -51,7 +46,7 @@ SrsForwarder::SrsForwarder(SrsSource* _source)
51 stfd = NULL; 46 stfd = NULL;
52 stream_id = 0; 47 stream_id = 0;
53 48
54 - pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_MS); 49 + pthread = new SrsThread(this, SRS_FORWARDER_SLEEP_US);
55 queue = new SrsMessageQueue(); 50 queue = new SrsMessageQueue();
56 jitter = new SrsRtmpJitter(); 51 jitter = new SrsRtmpJitter();
57 } 52 }
@@ -286,11 +281,11 @@ int SrsForwarder::forward() @@ -286,11 +281,11 @@ int SrsForwarder::forward()
286 { 281 {
287 int ret = ERROR_SUCCESS; 282 int ret = ERROR_SUCCESS;
288 283
289 - client->set_recv_timeout(SRS_PULSE_TIMEOUT_MS * 1000); 284 + client->set_recv_timeout(SRS_PULSE_TIMEOUT_US);
290 285
291 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER); 286 SrsPithyPrint pithy_print(SRS_STAGE_FORWARDER);
292 287
293 - while (true) { 288 + while (pthread->can_loop()) {
294 // switch to other st-threads. 289 // switch to other st-threads.
295 st_usleep(0); 290 st_usleep(0);
296 291
@@ -322,7 +317,7 @@ int SrsForwarder::forward() @@ -322,7 +317,7 @@ int SrsForwarder::forward()
322 SrsAutoFree(SrsSharedPtrMessage*, msgs, true); 317 SrsAutoFree(SrsSharedPtrMessage*, msgs, true);
323 318
324 // pithy print 319 // pithy print
325 - pithy_print.elapse(SRS_PULSE_TIMEOUT_MS); 320 + pithy_print.elapse(SRS_PULSE_TIMEOUT_US / 1000);
326 if (pithy_print.can_print()) { 321 if (pithy_print.can_print()) {
327 srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d", 322 srs_trace("-> time=%"PRId64", msgs=%d, obytes=%"PRId64", ibytes=%"PRId64", okbps=%d, ikbps=%d",
328 pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps()); 323 pithy_print.get_age(), count, client->get_send_bytes(), client->get_recv_bytes(), client->get_send_kbps(), client->get_recv_kbps());
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -36,6 +36,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 #include <srs_core_log.hpp> 36 #include <srs_core_log.hpp>
37 #include <srs_core_error.hpp> 37 #include <srs_core_error.hpp>
38 38
  39 +// the following is the timeout for rtmp protocol,
  40 +// to avoid death connection.
  41 +
  42 +// when got a messae header, there must be some data,
  43 +// increase recv timeout to got an entire message.
  44 +#define SRS_MIN_RECV_TIMEOUT_US 60*1000*1000L
  45 +
  46 +// the timeout to wait for client control message,
  47 +// if timeout, we generally ignore and send the data to client,
  48 +// generally, it's the pulse time for data seding.
  49 +#define SRS_PULSE_TIMEOUT_US 200*1000L
  50 +
  51 +// the timeout to wait client data,
  52 +// if timeout, close the connection.
  53 +#define SRS_SEND_TIMEOUT_US 30*1000*1000L
  54 +
  55 +// the timeout to send data to client,
  56 +// if timeout, close the connection.
  57 +#define SRS_RECV_TIMEOUT_US 30*1000*1000L
  58 +
  59 +// when stream is busy, for example, streaming is already
  60 +// publishing, when a new client to request to publish,
  61 +// sleep a while and close the connection.
  62 +#define SRS_STREAM_BUSY_SLEEP_US 3*1000*1000L
  63 +
  64 +// when error, forwarder sleep for a while and retry.
  65 +#define SRS_FORWARDER_SLEEP_US 3*1000*1000L
  66 +
  67 +// when error, encoder sleep for a while and retry.
  68 +#define SRS_ENCODER_SLEEP_US 3*1000*1000L
  69 +
39 class SrsSocket; 70 class SrsSocket;
40 class SrsBuffer; 71 class SrsBuffer;
41 class SrsPacket; 72 class SrsPacket;
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -391,12 +391,44 @@ int SrsRtmpClient::play(string stream, int stream_id) @@ -391,12 +391,44 @@ int SrsRtmpClient::play(string stream, int stream_id)
391 } 391 }
392 } 392 }
393 393
  394 + // SetChunkSize
  395 + if (true) {
  396 + SrsCommonMessage* msg = new SrsCommonMessage();
  397 + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
  398 +
  399 + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE;
  400 + msg->set_packet(pkt, 0);
  401 +
  402 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  403 + srs_error("send set chunk size failed. "
  404 + "stream=%s, chunk_size=%d, ret=%d",
  405 + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret);
  406 + return ret;
  407 + }
  408 + }
  409 +
394 return ret; 410 return ret;
395 } 411 }
396 412
397 int SrsRtmpClient::publish(string stream, int stream_id) 413 int SrsRtmpClient::publish(string stream, int stream_id)
398 { 414 {
399 int ret = ERROR_SUCCESS; 415 int ret = ERROR_SUCCESS;
  416 +
  417 + // SetChunkSize
  418 + if (true) {
  419 + SrsCommonMessage* msg = new SrsCommonMessage();
  420 + SrsSetChunkSizePacket* pkt = new SrsSetChunkSizePacket();
  421 +
  422 + pkt->chunk_size = SRS_CONF_DEFAULT_CHUNK_SIZE;
  423 + msg->set_packet(pkt, 0);
  424 +
  425 + if ((ret = protocol->send_message(msg)) != ERROR_SUCCESS) {
  426 + srs_error("send set chunk size failed. "
  427 + "stream=%s, chunk_size=%d, ret=%d",
  428 + stream.c_str(), SRS_CONF_DEFAULT_CHUNK_SIZE, ret);
  429 + return ret;
  430 + }
  431 + }
400 432
401 // publish(stream) 433 // publish(stream)
402 if (true) { 434 if (true) {
@@ -617,7 +649,7 @@ int SrsRtmp::response_connect_app(SrsRequest *req, const char* server_ip) @@ -617,7 +649,7 @@ int SrsRtmp::response_connect_app(SrsRequest *req, const char* server_ip)
617 data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB)); 649 data->set("srs_site", new SrsAmf0String(RTMP_SIG_SRS_WEB));
618 data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL)); 650 data->set("srs_email", new SrsAmf0String(RTMP_SIG_SRS_EMAIL));
619 data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT)); 651 data->set("srs_copyright", new SrsAmf0String(RTMP_SIG_SRS_COPYRIGHT));
620 - data->set("srs_contributor", new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); 652 + data->set("srs_primary_authors", new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS));
621 653
622 if (server_ip) { 654 if (server_ip) {
623 data->set("srs_server_ip", new SrsAmf0String(server_ip)); 655 data->set("srs_server_ip", new SrsAmf0String(server_ip));
@@ -1194,4 +1226,3 @@ int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType& @@ -1194,4 +1226,3 @@ int SrsRtmp::identify_flash_publish_client(SrsPublishPacket* req, SrsClientType&
1194 1226
1195 return ret; 1227 return ret;
1196 } 1228 }
1197 -  
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -110,7 +110,7 @@ enum SrsClientType @@ -110,7 +110,7 @@ enum SrsClientType
110 */ 110 */
111 class SrsRtmpClient 111 class SrsRtmpClient
112 { 112 {
113 -private: 113 +protected:
114 SrsProtocol* protocol; 114 SrsProtocol* protocol;
115 st_netfd_t stfd; 115 st_netfd_t stfd;
116 public: 116 public:
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -35,7 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #include <srs_core_client.hpp> 35 #include <srs_core_client.hpp>
36 #include <srs_core_config.hpp> 36 #include <srs_core_config.hpp>
37 37
38 -#define SERVER_LISTEN_BACKLOG 10 38 +#define SERVER_LISTEN_BACKLOG 512
39 #define SRS_TIME_RESOLUTION_MS 500 39 #define SRS_TIME_RESOLUTION_MS 500
40 40
41 SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type) 41 SrsListener::SrsListener(SrsServer* _server, SrsListenerType _type)
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -642,7 +642,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata @@ -642,7 +642,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
642 metadata->metadata->set("server", new SrsAmf0String( 642 metadata->metadata->set("server", new SrsAmf0String(
643 RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")")); 643 RTMP_SIG_SRS_KEY" "RTMP_SIG_SRS_VERSION" ("RTMP_SIG_SRS_URL_SHORT")"));
644 metadata->metadata->set("contributor", 644 metadata->metadata->set("contributor",
645 - new SrsAmf0String(RTMP_SIG_SRS_CONTRIBUTOR)); 645 + new SrsAmf0String(RTMP_SIG_SRS_PRIMARY_AUTHROS));
646 646
647 SrsAmf0Any* prop = NULL; 647 SrsAmf0Any* prop = NULL;
648 if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { 648 if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) {
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
@@ -54,10 +54,10 @@ void ISrsThreadHandler::on_leave_loop() @@ -54,10 +54,10 @@ void ISrsThreadHandler::on_leave_loop()
54 { 54 {
55 } 55 }
56 56
57 -SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms) 57 +SrsThread::SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us)
58 { 58 {
59 handler = thread_handler; 59 handler = thread_handler;
60 - cycle_interval_milliseconds = interval_ms; 60 + cycle_interval_us = interval_us;
61 61
62 tid = NULL; 62 tid = NULL;
63 loop = false; 63 loop = false;
@@ -102,6 +102,11 @@ void SrsThread::stop() @@ -102,6 +102,11 @@ void SrsThread::stop()
102 } 102 }
103 } 103 }
104 104
  105 +bool SrsThread::can_loop()
  106 +{
  107 + return loop;
  108 +}
  109 +
105 void SrsThread::thread_cycle() 110 void SrsThread::thread_cycle()
106 { 111 {
107 int ret = ERROR_SUCCESS; 112 int ret = ERROR_SUCCESS;
@@ -138,7 +143,7 @@ failed: @@ -138,7 +143,7 @@ failed:
138 break; 143 break;
139 } 144 }
140 145
141 - st_usleep(cycle_interval_milliseconds * 1000); 146 + st_usleep(cycle_interval_us);
142 } 147 }
143 148
144 handler->on_leave_loop(); 149 handler->on_leave_loop();
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 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. @@ -43,6 +43,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
43 * when stop, the thread will interrupt the st_thread, 43 * when stop, the thread will interrupt the st_thread,
44 * which will cause the socket to return error and 44 * which will cause the socket to return error and
45 * terminate the cycle thread. 45 * terminate the cycle thread.
  46 +*
  47 +* when thread interrupt, the socket maybe not got EINT,
  48 +* espectially on st_usleep(), so the cycle must check the loop,
  49 +* when handler->cycle() has loop itself, for example:
  50 +* handler->cycle() is:
  51 +* while (true):
  52 +* st_usleep(0);
  53 +* if (read_from_socket(skt) < 0) break;
  54 +* if thread stop when read_from_socket, it's ok, the loop will break,
  55 +* but when thread stop interrupt the s_usleep(0), then the loop is
  56 +* death loop.
  57 +* in a word, the handler->cycle() must:
  58 +* handler->cycle() is:
  59 +* while (pthread->can_loop()):
  60 +* st_usleep(0);
  61 +* if (read_from_socket(skt) < 0) break;
  62 +* check the loop, then it works.
46 */ 63 */
47 class ISrsThreadHandler 64 class ISrsThreadHandler
48 { 65 {
@@ -68,14 +85,14 @@ private: @@ -68,14 +85,14 @@ private:
68 bool loop; 85 bool loop;
69 private: 86 private:
70 ISrsThreadHandler* handler; 87 ISrsThreadHandler* handler;
71 - int64_t cycle_interval_milliseconds; 88 + int64_t cycle_interval_us;
72 public: 89 public:
73 /** 90 /**
74 * initialize the thread. 91 * initialize the thread.
75 * @param thread_handler, the cycle handler for the thread. 92 * @param thread_handler, the cycle handler for the thread.
76 - * @param interval_ms, the sleep interval when cycle finished. 93 + * @param interval_us, the sleep interval when cycle finished.
77 */ 94 */
78 - SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_ms); 95 + SrsThread(ISrsThreadHandler* thread_handler, int64_t interval_us);
79 virtual ~SrsThread(); 96 virtual ~SrsThread();
80 public: 97 public:
81 /** 98 /**
@@ -90,6 +107,12 @@ public: @@ -90,6 +107,12 @@ public:
90 * @remark user can stop multiple times, ignore if already stopped. 107 * @remark user can stop multiple times, ignore if already stopped.
91 */ 108 */
92 virtual void stop(); 109 virtual void stop();
  110 + /**
  111 + * whether the thread should loop,
  112 + * used for handler->cycle() which has a loop method,
  113 + * to check this method, break if false.
  114 + */
  115 + virtual bool can_loop();
93 private: 116 private:
94 virtual void thread_cycle(); 117 virtual void thread_cycle();
95 static void* thread_fun(void* arg); 118 static void* thread_fun(void* arg);
1 -/*  
2 -The MIT License (MIT)  
3 -  
4 -Copyright (c) 2013 wenjiegit  
5 -  
6 -Permission is hereby granted, free of charge, to any person obtaining a copy of  
7 -this software and associated documentation files (the "Software"), to deal in  
8 -the Software without restriction, including without limitation the rights to  
9 -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of  
10 -the Software, and to permit persons to whom the Software is furnished to do so,  
11 -subject to the following conditions:  
12 -  
13 -The above copyright notice and this permission notice shall be included in all  
14 -copies or substantial portions of the Software.  
15 -  
16 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
17 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS  
18 -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR  
19 -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER  
20 -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  
21 -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
22 -*/  
23 -  
24 -#include <sys/socket.h>  
25 -#include <netinet/in.h>  
26 -#include <arpa/inet.h>  
27 -#include <sstream>  
28 -#include <getopt.h>  
29 -#include <stdlib.h>  
30 -  
31 -#include <srs_core_rtmp.hpp>  
32 -#include <srs_core_protocol.hpp>  
33 -#include <srs_core_error.hpp>  
34 -#include <srs_core_amf0.hpp>  
35 -#include <srs_core_autofree.hpp>  
36 -#include <srs_core_stream.hpp>  
37 -  
38 -#include <st.h>  
39 -  
40 -// server play control  
41 -#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes"  
42 -#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes"  
43 -#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes"  
44 -#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes"  
45 -  
46 -// server publish control  
47 -#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes"  
48 -#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes"  
49 -#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes"  
50 -#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes"  
51 -  
52 -// EOF control.  
53 -#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished"  
54 -#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket"  
55 -  
56 -// client only  
57 -#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying"  
58 -#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing"  
59 -  
60 -/**  
61 -* @brief class of Linux version band check client  
62 -* check play and publish speed.  
63 -*/  
64 -class SrsBandCheckClient : public SrsRtmpClient  
65 -{  
66 -public:  
67 - SrsBandCheckClient(st_netfd_t _stfd);  
68 - ~SrsBandCheckClient();  
69 -  
70 -public:  
71 - /**  
72 - * @brief test play  
73 - *  
74 - */  
75 - int check_play();  
76 - /**  
77 - * @brief test publish  
78 - *  
79 - */  
80 - int check_publish();  
81 -  
82 -private:  
83 - /**  
84 - * @brief just return success.  
85 - */  
86 - int create_stream(int& stream_id);  
87 - /**  
88 - * @brief just return success.  
89 - */  
90 - int play(std::string stream, int stream_id);  
91 - /**  
92 - * @brief just return success.  
93 - */  
94 - int publish(std::string stream, int stream_id);  
95 -  
96 -private:  
97 - int expect_start_play();  
98 - int send_starting_play();  
99 - int expect_stop_play();  
100 - int send_stopped_play();  
101 - int expect_start_pub();  
102 - int send_starting_pub();  
103 - int send_pub_data();  
104 - int expect_stop_pub();  
105 - /**  
106 - * @brief expect result.  
107 - * because the core module has no method to decode this packet  
108 - * so we must get the internal data and decode it here.  
109 - */  
110 - int expect_finished();  
111 - int send_stopped_pub();  
112 - /**  
113 - * @brief notify server the check procedure is over.  
114 - */  
115 - int send_final();  
116 -};  
117 -  
118 -/**  
119 -* @brief class of band check  
120 -* used to check band width with a client @param bandCheck_Client  
121 -*/  
122 -class SrsBandCheck  
123 -{  
124 -public:  
125 - SrsBandCheck();  
126 - ~SrsBandCheck();  
127 -  
128 -public:  
129 - /**  
130 - * @brief band check method  
131 - *  
132 - * connect to server------>rtmp handshake------>rtmp connect------>play------>publish  
133 - * @retval ERROR_SUCCESS when success.  
134 - */  
135 - int check(const std::string& app, const std::string& tcUrl);  
136 -  
137 - /**  
138 - * @brief set the address and port of test server  
139 - *  
140 - * @param server server address, domain or ip  
141 - * @param server listened port ,default is 1935  
142 - */  
143 - void set_server(const std::string& server, int port = 1935);  
144 -  
145 -private:  
146 - int connect_server();  
147 -  
148 -private:  
149 - SrsBandCheckClient* bandCheck_Client;  
150 - std::string server_address;  
151 - int server_port;  
152 -};  
153 -  
154 -/**  
155 -* @brief init st lib  
156 -*/  
157 -static int init_st();  
158 -static void print_help();  
159 -static void print_version();  
160 -  
161 -/**  
162 -* @brief get user option  
163 -* @internal ip Mandatory arguments  
164 -* @internal key Mandatory arguments  
165 -* @internal port default 1935  
166 -* @internal vhost default bandcheck.srs.com  
167 -*/  
168 -static int get_opt(int argc ,char* argv[]);  
169 -  
170 -/**  
171 -* global var.  
172 -*/  
173 -static struct option long_options[] =  
174 -{  
175 - {"ip", required_argument, 0, 'i'},  
176 - {"port", optional_argument, 0, 'p'},  
177 - {"key", required_argument, 0, 'k'},  
178 - {"vhost", optional_argument, 0, 'v'},  
179 - {"help", no_argument, 0, 'h'},  
180 - {"version", no_argument, 0, 'V'},  
181 -};  
182 -  
183 -static const char* short_options = "i:p::k:v::hV";  
184 -  
185 -static std::string g_ip;  
186 -static int g_port = 1935;  
187 -static std::string g_key;  
188 -static std::string g_vhost = "bandcheck.srs.com";  
189 -  
190 -#define BUILD_VERSION "srs band check 0.1"  
191 -  
192 -int main(int argc ,char* argv[])  
193 -{  
194 - int ret = ERROR_SUCCESS;  
195 -  
196 - if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) {  
197 - return -1;  
198 - }  
199 -  
200 - // check param  
201 - if (g_ip.empty()) {  
202 - printf("ip address should not be empty.");  
203 - return -1;  
204 - }  
205 -  
206 - if (g_key.empty()) {  
207 - printf("test key should not be empty.");  
208 - return -1;  
209 - }  
210 -  
211 - if ((ret = init_st()) != ERROR_SUCCESS) {  
212 - srs_error("band check init failed. ret=%d", ret);  
213 - return ret;  
214 - }  
215 -  
216 - std::string app = "app?key=" + g_key + "&vhost=" + g_vhost;  
217 -  
218 - char tcUrl_buffer[1024] = {0};  
219 - sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str());  
220 - std::string tcUrl = tcUrl_buffer;  
221 -  
222 - SrsBandCheck band_check;  
223 - band_check.set_server(g_ip, g_port);  
224 - if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) {  
225 - srs_error("band check failed. address=%s ret=%d", "xx.com", ret);  
226 - return -1;  
227 - }  
228 -  
229 - return 0;  
230 -}  
231 -  
232 -SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd)  
233 - : SrsRtmpClient(_stfd)  
234 -{  
235 -}  
236 -  
237 -SrsBandCheckClient::~SrsBandCheckClient()  
238 -{  
239 -}  
240 -  
241 -int SrsBandCheckClient::check_play()  
242 -{  
243 - int ret = ERROR_SUCCESS;  
244 -  
245 - if ((ret = expect_start_play()) != ERROR_SUCCESS) {  
246 - srs_error("expect_start_play failed. ret=%d", ret);  
247 - return ret;  
248 - }  
249 -  
250 - if ((ret = send_starting_play()) != ERROR_SUCCESS) {  
251 - srs_error("send starting play failed. ret=%d", ret);  
252 - return ret;  
253 - }  
254 -  
255 - if ((ret = expect_stop_play()) != ERROR_SUCCESS) {  
256 - srs_error("expect stop play failed. ret=%d", ret);  
257 - return ret;  
258 - }  
259 -  
260 - if ((ret = send_stopped_play()) != ERROR_SUCCESS) {  
261 - srs_error("send stopped play failed. ret=%d", ret);  
262 - return ret;  
263 - }  
264 -  
265 - return ret;  
266 -}  
267 -  
268 -int SrsBandCheckClient::check_publish()  
269 -{  
270 - int ret = ERROR_SUCCESS;  
271 -  
272 - if ((ret = expect_start_pub()) != ERROR_SUCCESS) {  
273 - srs_error("expect start pub failed. ret=%d", ret);  
274 - return ret;  
275 - }  
276 -  
277 - if ((ret = send_starting_pub())!= ERROR_SUCCESS) {  
278 - srs_error("send starting pub failed. ret=%d", ret);  
279 - return ret;  
280 - }  
281 -  
282 - if ((ret = send_pub_data()) != ERROR_SUCCESS) {  
283 - srs_error("publish data failed. ret=%d", ret);  
284 - return ret;  
285 - }  
286 -  
287 - if ((ret = send_stopped_pub()) != ERROR_SUCCESS) {  
288 - srs_error("send stopped pub failed. ret=%d", ret);  
289 - return ret;  
290 - }  
291 -  
292 - if ((ret = expect_finished()) != ERROR_SUCCESS) {  
293 - srs_error("expect finished msg failed. ret=%d", ret);  
294 - return ret;  
295 - }  
296 -  
297 - if ((ret = send_final()) != ERROR_SUCCESS) {  
298 - srs_error("send final msg failed. ret=%d", ret);  
299 - return ret;  
300 - }  
301 -  
302 - return ret;  
303 -}  
304 -  
305 -int SrsBandCheckClient::create_stream(int &stream_id)  
306 -{  
307 - return ERROR_SUCCESS;  
308 -}  
309 -  
310 -int SrsBandCheckClient::play(std::string stream, int stream_id)  
311 -{  
312 - return ERROR_SUCCESS;  
313 -}  
314 -  
315 -int SrsBandCheckClient::publish(std::string stream, int stream_id)  
316 -{  
317 - return ERROR_SUCCESS;  
318 -}  
319 -  
320 -int SrsBandCheckClient::expect_start_play()  
321 -{  
322 - int ret = ERROR_SUCCESS;  
323 -  
324 - // expect connect _result  
325 - SrsCommonMessage* msg = NULL;  
326 - SrsBandwidthPacket* pkt = NULL;  
327 - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) {  
328 - srs_error("expect bandcheck start play message failed. ret=%d", ret);  
329 - return ret;  
330 - }  
331 - SrsAutoFree(SrsCommonMessage, msg, false);  
332 - srs_info("get bandcheck start play message");  
333 -  
334 - if (pkt->command_name != SRS_BW_CHECK_START_PLAY) {  
335 - srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str());  
336 - return -1;  
337 - }  
338 -  
339 - return ret;  
340 -}  
341 -  
342 -int SrsBandCheckClient::send_starting_play()  
343 -{  
344 - int ret = ERROR_SUCCESS;  
345 -  
346 - SrsCommonMessage* msg = new SrsCommonMessage;  
347 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
348 - pkt->command_name = SRS_BW_CHECK_STARTING_PLAY;  
349 - msg->set_packet(pkt, 0);  
350 -  
351 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
352 - srs_error("send starting play msg failed. ret=%d", ret);  
353 - return ret;  
354 - }  
355 -  
356 - return ret;  
357 -}  
358 -  
359 -int SrsBandCheckClient::expect_stop_play()  
360 -{  
361 - int ret = ERROR_SUCCESS;  
362 -  
363 - while (true) {  
364 - SrsCommonMessage* msg = NULL;  
365 - SrsBandwidthPacket* pkt = NULL;  
366 - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) {  
367 - srs_error("expect stop play message failed. ret=%d", ret);  
368 - return ret;  
369 - }  
370 - SrsAutoFree(SrsCommonMessage, msg, false);  
371 - srs_info("get bandcheck stop play message");  
372 -  
373 - if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) {  
374 - break;  
375 - }  
376 - }  
377 -  
378 - return ret;  
379 -}  
380 -  
381 -int SrsBandCheckClient::send_stopped_play()  
382 -{  
383 - int ret = ERROR_SUCCESS;  
384 -  
385 - SrsCommonMessage* msg = new SrsCommonMessage;  
386 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
387 - pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY;  
388 - msg->set_packet(pkt, 0);  
389 -  
390 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
391 - srs_error("send stopped play msg failed. ret=%d", ret);  
392 - return ret;  
393 - }  
394 -  
395 - return ret;  
396 -}  
397 -  
398 -int SrsBandCheckClient::expect_start_pub()  
399 -{  
400 - int ret = ERROR_SUCCESS;  
401 -  
402 - while (true) {  
403 - SrsCommonMessage* msg = NULL;  
404 - SrsBandwidthPacket* pkt = NULL;  
405 - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) {  
406 - srs_error("expect start pub message failed. ret=%d", ret);  
407 - return ret;  
408 - }  
409 - SrsAutoFree(SrsCommonMessage, msg, false);  
410 - srs_info("get bandcheck start pub message");  
411 -  
412 - if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) {  
413 - break;  
414 - }  
415 - }  
416 -  
417 - return ret;  
418 -}  
419 -  
420 -int SrsBandCheckClient::send_starting_pub()  
421 -{  
422 - int ret = ERROR_SUCCESS;  
423 -  
424 - SrsCommonMessage* msg = new SrsCommonMessage;  
425 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
426 - pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH;  
427 - msg->set_packet(pkt, 0);  
428 -  
429 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
430 - srs_error("send starting play msg failed. ret=%d", ret);  
431 - return ret;  
432 - }  
433 - srs_info("send starting play msg success.");  
434 -  
435 - return ret;  
436 -}  
437 -  
438 -int SrsBandCheckClient::send_pub_data()  
439 -{  
440 - int ret = ERROR_SUCCESS;  
441 -  
442 - int data_count = 100;  
443 - while (true) {  
444 - SrsCommonMessage* msg = new SrsCommonMessage;  
445 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
446 - pkt->command_name = SRS_BW_CHECK_PUBLISHING;  
447 - msg->set_packet(pkt, 0);  
448 -  
449 - for (int i = 0; i < data_count; ++i) {  
450 - std::stringstream seq;  
451 - seq << i;  
452 - std::string play_data = "SrS band check data from client's publishing......";  
453 - pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str()));  
454 - }  
455 - data_count += 100;  
456 -  
457 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
458 - srs_error("send publish message failed.ret=%d", ret);  
459 - return ret;  
460 - }  
461 -  
462 - if ((ret = expect_stop_pub()) == ERROR_SUCCESS) {  
463 - break;  
464 - }  
465 - }  
466 -  
467 - return ret;  
468 -}  
469 -  
470 -int SrsBandCheckClient::expect_stop_pub()  
471 -{  
472 - int ret = ERROR_SUCCESS;  
473 -  
474 - while (true) {  
475 - if ((ret = st_netfd_poll(get_st_fd(), POLLIN, 1000)) == ERROR_SUCCESS) {  
476 - SrsCommonMessage* msg = 0;  
477 - if ((ret = recv_message(&msg)) != ERROR_SUCCESS)  
478 - {  
479 - srs_error("recv message failed while expect stop pub. ret=%d", ret);  
480 - return ret;  
481 - }  
482 -  
483 - if ((ret = msg->decode_packet(get_protocol())) != ERROR_SUCCESS) {  
484 - srs_error("decode packet error while expect stop pub. ret=%d", ret);  
485 - return ret;  
486 - }  
487 -  
488 - SrsBandwidthPacket* pkt = dynamic_cast<SrsBandwidthPacket*>(msg->get_packet());  
489 - if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) {  
490 -  
491 - return ret;  
492 - }  
493 - } else {  
494 - break;  
495 - }  
496 - }  
497 -  
498 - return ret;  
499 -}  
500 -  
501 -int SrsBandCheckClient::expect_finished()  
502 -{  
503 - int ret = ERROR_SUCCESS;  
504 -  
505 - while (true) {  
506 - SrsCommonMessage* msg = NULL;  
507 - SrsBandwidthPacket* pkt = NULL;  
508 - if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(get_protocol(), &msg, &pkt)) != ERROR_SUCCESS) {  
509 - srs_error("expect finished message failed. ret=%d", ret);  
510 - return ret;  
511 - }  
512 - SrsAutoFree(SrsCommonMessage, msg, false);  
513 - srs_info("get bandcheck finished message");  
514 -  
515 - if (pkt->command_name == SRS_BW_CHECK_FINISHED) {  
516 - SrsStream *stream = new SrsStream;  
517 - SrsAutoFree(SrsStream, stream, false);  
518 -  
519 - if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) {  
520 - srs_error("initialize stream error. ret=%d", ret);  
521 - return ret;  
522 - }  
523 -  
524 - std::string command_name;  
525 - if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {  
526 - srs_error("amfo read string error. ret=%d", ret);  
527 - return ret;  
528 - }  
529 -  
530 - double action_id;  
531 - if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) {  
532 - srs_error("amfo read number error. ret=%d", ret);  
533 - return ret;  
534 - }  
535 -  
536 - if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) {  
537 - srs_error("amfo read number error. ret=%d", ret);  
538 - return ret;  
539 - }  
540 -  
541 - SrsAmf0Object* object;  
542 - if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) {  
543 - srs_error("amfo read object error. ret=%d", ret);  
544 - return ret;  
545 - }  
546 -  
547 - int64_t start_time = 0;  
548 - int64_t end_time = 0;  
549 -  
550 - SrsAmf0Any* start_time_any = object->get_property("start_time");  
551 - if (start_time_any && start_time_any->is_number()) {  
552 - SrsAmf0Number* start_time_number = dynamic_cast<SrsAmf0Number*> (start_time_any);  
553 - if (start_time_number) {  
554 - start_time = start_time_number->value;  
555 - }  
556 - }  
557 -  
558 - SrsAmf0Any* end_time_any = object->get_property("end_time");  
559 - if (end_time_any && end_time_any->is_number()) {  
560 - SrsAmf0Number* end_time_number = dynamic_cast<SrsAmf0Number*> (end_time_any);  
561 - if (end_time_number) {  
562 - end_time = end_time_number->value;  
563 - }  
564 - }  
565 -  
566 - int play_kbps = 0;  
567 - int pub_kbps = 0;  
568 - SrsAmf0Any* play_kbp_any = object->get_property("play_kbps");  
569 - if (play_kbp_any && play_kbp_any->is_number()) {  
570 - SrsAmf0Number* play_kbps_number = dynamic_cast<SrsAmf0Number*> (play_kbp_any);  
571 - if (play_kbps_number) {  
572 - play_kbps = play_kbps_number->value;  
573 - }  
574 - }  
575 -  
576 - SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps");  
577 - if (pub_kbp_any && pub_kbp_any->is_number()) {  
578 - SrsAmf0Number* pub_kbps_number = dynamic_cast<SrsAmf0Number*> (pub_kbp_any);  
579 - if (pub_kbps_number) {  
580 - pub_kbps = pub_kbps_number->value;  
581 - }  
582 - }  
583 -  
584 - float time_elapsed;  
585 - if (end_time - start_time > 0) {  
586 - time_elapsed = (end_time - start_time) / 1000.00;  
587 - }  
588 -  
589 - srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n"  
590 - , play_kbps, pub_kbps, time_elapsed);  
591 -  
592 - break;  
593 - }  
594 - }  
595 -  
596 - return ret;  
597 -}  
598 -  
599 -int SrsBandCheckClient::send_stopped_pub()  
600 -{  
601 - int ret = ERROR_SUCCESS;  
602 -  
603 - SrsCommonMessage* msg = new SrsCommonMessage;  
604 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
605 - pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH;  
606 - msg->set_packet(pkt, 0);  
607 -  
608 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
609 - srs_error("send stopped pub msg failed. ret=%d", ret);  
610 - return ret;  
611 - }  
612 - srs_info("send stopped pub msg success.");  
613 -  
614 - return ret;  
615 -}  
616 -  
617 -int SrsBandCheckClient::send_final()  
618 -{  
619 - int ret = ERROR_SUCCESS;  
620 -  
621 - SrsCommonMessage* msg = new SrsCommonMessage;  
622 - SrsBandwidthPacket* pkt = new SrsBandwidthPacket;  
623 - pkt->command_name = SRS_BW_CHECK_FLASH_FINAL;  
624 - msg->set_packet(pkt, 0);  
625 -  
626 - if ((ret = send_message(msg)) != ERROR_SUCCESS) {  
627 - srs_error("send final msg failed. ret=%d", ret);  
628 - return ret;  
629 - }  
630 - srs_info("send final msg success.");  
631 -  
632 - return ret;  
633 -}  
634 -  
635 -SrsBandCheck::SrsBandCheck()  
636 - : bandCheck_Client(0)  
637 -{  
638 -}  
639 -  
640 -SrsBandCheck::~SrsBandCheck()  
641 -{  
642 - if (bandCheck_Client) {  
643 - srs_freep(bandCheck_Client);  
644 - }  
645 -}  
646 -  
647 -int SrsBandCheck::check(const std::string &app, const std::string &tcUrl)  
648 -{  
649 - int ret = ERROR_SUCCESS;  
650 -  
651 - if ((ret = connect_server()) != ERROR_SUCCESS) {  
652 - srs_error("connect to server failed. ret = %d", ret);  
653 - return ret;  
654 - }  
655 -  
656 - if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) {  
657 - srs_error("handshake failed. ret = %d", ret);  
658 - return ret;  
659 - }  
660 -  
661 - if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) {  
662 - srs_error("handshake failed. ret = %d", ret);  
663 - return ret;  
664 - }  
665 -  
666 - if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) {  
667 - srs_error("band check play failed.");  
668 - return ret;  
669 - }  
670 -  
671 - if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) {  
672 - srs_error("band check publish failed.");  
673 - return ret;  
674 - }  
675 -  
676 - return ret;  
677 -}  
678 -  
679 -void SrsBandCheck::set_server(const std::string &server, int port)  
680 -{  
681 - server_address = server;  
682 - server_port = port;  
683 -}  
684 -  
685 -int SrsBandCheck::connect_server()  
686 -{  
687 - int ret = ERROR_SUCCESS;  
688 -  
689 - int sock = socket(AF_INET, SOCK_STREAM, 0);  
690 - if(sock == -1){  
691 - ret = ERROR_SOCKET_CREATE;  
692 - srs_error("create socket error. ret=%d", ret);  
693 - return ret;  
694 - }  
695 -  
696 - st_netfd_t stfd = st_netfd_open_socket(sock);  
697 - if(stfd == NULL){  
698 - ret = ERROR_ST_OPEN_SOCKET;  
699 - srs_error("st_netfd_open_socket failed. ret=%d", ret);  
700 - return ret;  
701 - }  
702 -  
703 - bandCheck_Client = new SrsBandCheckClient(stfd);  
704 -  
705 - // connect to server.  
706 - std::string ip = srs_dns_resolve(server_address);  
707 - if (ip.empty()) {  
708 - ret = ERROR_SYSTEM_IP_INVALID;  
709 - srs_error("dns resolve server error, ip empty. ret=%d", ret);  
710 - return ret;  
711 - }  
712 -  
713 - sockaddr_in addr;  
714 - addr.sin_family = AF_INET;  
715 - addr.sin_port = htons(server_port);  
716 - addr.sin_addr.s_addr = inet_addr(ip.c_str());  
717 -  
718 - if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){  
719 - ret = ERROR_ST_CONNECT;  
720 - srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret);  
721 - return ret;  
722 - }  
723 - srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port);  
724 -  
725 - return ret;  
726 -}  
727 -  
728 -int init_st()  
729 -{  
730 - int ret = ERROR_SUCCESS;  
731 -  
732 - if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) {  
733 - ret = ERROR_ST_SET_EPOLL;  
734 - srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret);  
735 - return ret;  
736 - }  
737 -  
738 - if(st_init() != 0){  
739 - ret = ERROR_ST_INITIALIZE;  
740 - srs_error("st_init failed. ret=%d", ret);  
741 - return ret;  
742 - }  
743 -  
744 - return ret;  
745 -}  
746 -  
747 -void print_help()  
748 -{  
749 - const char *help = "Usage: srs-bandcheck [OPTION]...\n"  
750 - "test band width from client to rtmp server.\n"  
751 -  
752 - "Mandatory arguments to long options are mandatory for short options too.\n"  
753 - " -i, --ip the ip or domain that to test\n"  
754 - " -p, --port the port that server listen \n"  
755 - " -k, --key the key used to test \n"  
756 - " -v, --vhost the vhost used to test \n"  
757 - " -V, --version output version information and exit \n"  
758 - " -h, --help display this help and exit \n"  
759 - "\n\n\n"  
760 - "Exit status:\n"  
761 - "0 if OK,\n"  
762 - "other if error occured, and the detail should be printed.\n"  
763 - "\n\n"  
764 - "srs home page: <winlin(winterserver): http://blog.csdn.net/win_lin>\n"  
765 - "srs home page: <http://blog.chinaunix.net/uid/25006789.html>\n";  
766 -  
767 - printf("%s", help);  
768 -}  
769 -  
770 -void print_version()  
771 -{  
772 - const char *version = ""  
773 - "srs_bandcheck "BUILD_VERSION"\n"  
774 - "Copyright (C) 2013 wenjiegit.\n"  
775 - "License MIT\n"  
776 - "This is free software: you are free to change and redistribute it.\n"  
777 - "There is NO WARRANTY, to the extent permitted by law.\n"  
778 - "\n"  
779 - "Written by wenjie.\n";  
780 -  
781 - printf("%s", version);  
782 -}  
783 -  
784 -int get_opt(int argc, char *argv[])  
785 -{  
786 - int ret = ERROR_SUCCESS;  
787 -  
788 - int c;  
789 - while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) {  
790 - switch (c) {  
791 - case 'i':  
792 - if (optarg) {  
793 - g_ip = optarg;  
794 - }  
795 - break;  
796 - case 'p':  
797 - if (optarg) {  
798 - g_port = atoi(optarg);  
799 - }  
800 - break;  
801 - case 'k':  
802 - if (optarg) {  
803 - g_key = optarg;  
804 - }  
805 - break;  
806 - case 'v':  
807 - if (optarg) {  
808 - g_vhost = optarg;  
809 - }  
810 - break;  
811 - case 'V':  
812 - print_version();  
813 - exit(0);  
814 - break;  
815 - case 'h':  
816 - print_help();  
817 - exit(0);  
818 - break;  
819 - default:  
820 - printf("see --help or -h\n");  
821 - ret = -1;  
822 - }  
823 - }  
824 -  
825 - return ret;  
826 -} 1 +/*
  2 +The MIT License (MIT)
  3 +
  4 +Copyright (c) 2013-2014 wenjiegit
  5 +
  6 +Permission is hereby granted, free of charge, to any person obtaining a copy of
  7 +this software and associated documentation files (the "Software"), to deal in
  8 +the Software without restriction, including without limitation the rights to
  9 +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  10 +the Software, and to permit persons to whom the Software is furnished to do so,
  11 +subject to the following conditions:
  12 +
  13 +The above copyright notice and this permission notice shall be included in all
  14 +copies or substantial portions of the Software.
  15 +
  16 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  18 +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  19 +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  20 +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22 +*/
  23 +
  24 +#include <sys/socket.h>
  25 +#include <netinet/in.h>
  26 +#include <arpa/inet.h>
  27 +#include <sstream>
  28 +#include <getopt.h>
  29 +#include <stdlib.h>
  30 +
  31 +#include <srs_core_rtmp.hpp>
  32 +#include <srs_core_protocol.hpp>
  33 +#include <srs_core_error.hpp>
  34 +#include <srs_core_amf0.hpp>
  35 +#include <srs_core_autofree.hpp>
  36 +#include <srs_core_stream.hpp>
  37 +
  38 +#include <st.h>
  39 +
  40 +// server play control
  41 +#define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes"
  42 +#define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes"
  43 +#define SRS_BW_CHECK_STOP_PLAY "onSrsBandCheckStopPlayBytes"
  44 +#define SRS_BW_CHECK_STOPPED_PLAY "onSrsBandCheckStoppedPlayBytes"
  45 +
  46 +// server publish control
  47 +#define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes"
  48 +#define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes"
  49 +#define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes"
  50 +#define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes"
  51 +
  52 +// EOF control.
  53 +#define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished"
  54 +#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket"
  55 +
  56 +// client only
  57 +#define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying"
  58 +#define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing"
  59 +
  60 +/**
  61 +* @brief class of Linux version band check client
  62 +* check play and publish speed.
  63 +*/
  64 +class SrsBandCheckClient : public SrsRtmpClient
  65 +{
  66 +public:
  67 + SrsBandCheckClient(st_netfd_t _stfd);
  68 + ~SrsBandCheckClient();
  69 +
  70 +public:
  71 + /**
  72 + * @brief test play
  73 + *
  74 + */
  75 + int check_play();
  76 + /**
  77 + * @brief test publish
  78 + *
  79 + */
  80 + int check_publish();
  81 +
  82 +private:
  83 + /**
  84 + * @brief just return success.
  85 + */
  86 + int create_stream(int& stream_id);
  87 + /**
  88 + * @brief just return success.
  89 + */
  90 + int play(std::string stream, int stream_id);
  91 + /**
  92 + * @brief just return success.
  93 + */
  94 + int publish(std::string stream, int stream_id);
  95 +
  96 +private:
  97 + int expect_start_play();
  98 + int send_starting_play();
  99 + int expect_stop_play();
  100 + int send_stopped_play();
  101 + int expect_start_pub();
  102 + int send_starting_pub();
  103 + int send_pub_data();
  104 + int expect_stop_pub();
  105 + /**
  106 + * @brief expect result.
  107 + * because the core module has no method to decode this packet
  108 + * so we must get the internal data and decode it here.
  109 + */
  110 + int expect_finished();
  111 + int send_stopped_pub();
  112 + /**
  113 + * @brief notify server the check procedure is over.
  114 + */
  115 + int send_final();
  116 +};
  117 +
  118 +/**
  119 +* @brief class of band check
  120 +* used to check band width with a client @param bandCheck_Client
  121 +*/
  122 +class SrsBandCheck
  123 +{
  124 +public:
  125 + SrsBandCheck();
  126 + ~SrsBandCheck();
  127 +
  128 +public:
  129 + /**
  130 + * @brief band check method
  131 + *
  132 + * connect to server------>rtmp handshake------>rtmp connect------>play------>publish
  133 + * @retval ERROR_SUCCESS when success.
  134 + */
  135 + int check(const std::string& app, const std::string& tcUrl);
  136 +
  137 + /**
  138 + * @brief set the address and port of test server
  139 + *
  140 + * @param server server address, domain or ip
  141 + * @param server listened port ,default is 1935
  142 + */
  143 + void set_server(const std::string& server, int port = 1935);
  144 +
  145 +private:
  146 + int connect_server();
  147 +
  148 +private:
  149 + SrsBandCheckClient* bandCheck_Client;
  150 + std::string server_address;
  151 + int server_port;
  152 +};
  153 +
  154 +/**
  155 +* @brief init st lib
  156 +*/
  157 +static int init_st();
  158 +static void print_help(char** argv);
  159 +static void print_version();
  160 +
  161 +/**
  162 +* @brief get user option
  163 +* @internal ip Mandatory arguments
  164 +* @internal key Mandatory arguments
  165 +* @internal port default 1935
  166 +* @internal vhost default bandcheck.srs.com
  167 +*/
  168 +static int get_opt(int argc ,char* argv[]);
  169 +
  170 +/**
  171 +* global var.
  172 +*/
  173 +static struct option long_options[] =
  174 +{
  175 + {"ip", required_argument, 0, 'i'},
  176 + {"port", optional_argument, 0, 'p'},
  177 + {"key", required_argument, 0, 'k'},
  178 + {"vhost", optional_argument, 0, 'v'},
  179 + {"help", no_argument, 0, 'h'},
  180 + {"version", no_argument, 0, 'V'},
  181 +};
  182 +
  183 +static const char* short_options = "i:p::k:v::hV";
  184 +
  185 +static std::string g_ip;
  186 +static int g_port = 1935;
  187 +static std::string g_key;
  188 +static std::string g_vhost = "bandcheck.srs.com";
  189 +
  190 +#define BUILD_VERSION "srs band check 0.1"
  191 +
  192 +int main(int argc ,char* argv[])
  193 +{
  194 + int ret = ERROR_SUCCESS;
  195 +
  196 + if (argc <= 1) {
  197 + print_help(argv);
  198 + exit(1);
  199 + }
  200 +
  201 + if ((ret = get_opt(argc, argv)) != ERROR_SUCCESS) {
  202 + return -1;
  203 + }
  204 +
  205 + // check param
  206 + if (g_ip.empty()) {
  207 + printf("ip address should not be empty.\n");
  208 + return -1;
  209 + }
  210 +
  211 + if (g_key.empty()) {
  212 + printf("test key should not be empty.\n");
  213 + return -1;
  214 + }
  215 +
  216 + if ((ret = init_st()) != ERROR_SUCCESS) {
  217 + srs_error("band check init failed. ret=%d", ret);
  218 + return ret;
  219 + }
  220 +
  221 + std::string app = "app?key=" + g_key + "&vhost=" + g_vhost;
  222 +
  223 + char tcUrl_buffer[1024] = {0};
  224 + sprintf(tcUrl_buffer, "rtmp://%s:%d/%s", g_ip.c_str(), g_port, app.c_str());
  225 + std::string tcUrl = tcUrl_buffer;
  226 +
  227 + SrsBandCheck band_check;
  228 + band_check.set_server(g_ip, g_port);
  229 + if ((ret = band_check.check(app, tcUrl)) != ERROR_SUCCESS) {
  230 + srs_error("band check failed. address=%s ret=%d", "xx.com", ret);
  231 + return -1;
  232 + }
  233 +
  234 + return 0;
  235 +}
  236 +
  237 +SrsBandCheckClient::SrsBandCheckClient(st_netfd_t _stfd)
  238 + : SrsRtmpClient(_stfd)
  239 +{
  240 +}
  241 +
  242 +SrsBandCheckClient::~SrsBandCheckClient()
  243 +{
  244 +}
  245 +
  246 +int SrsBandCheckClient::check_play()
  247 +{
  248 + int ret = ERROR_SUCCESS;
  249 +
  250 + if ((ret = expect_start_play()) != ERROR_SUCCESS) {
  251 + srs_error("expect_start_play failed. ret=%d", ret);
  252 + return ret;
  253 + }
  254 +
  255 + if ((ret = send_starting_play()) != ERROR_SUCCESS) {
  256 + srs_error("send starting play failed. ret=%d", ret);
  257 + return ret;
  258 + }
  259 +
  260 + if ((ret = expect_stop_play()) != ERROR_SUCCESS) {
  261 + srs_error("expect stop play failed. ret=%d", ret);
  262 + return ret;
  263 + }
  264 +
  265 + if ((ret = send_stopped_play()) != ERROR_SUCCESS) {
  266 + srs_error("send stopped play failed. ret=%d", ret);
  267 + return ret;
  268 + }
  269 +
  270 + return ret;
  271 +}
  272 +
  273 +int SrsBandCheckClient::check_publish()
  274 +{
  275 + int ret = ERROR_SUCCESS;
  276 +
  277 + if ((ret = expect_start_pub()) != ERROR_SUCCESS) {
  278 + srs_error("expect start pub failed. ret=%d", ret);
  279 + return ret;
  280 + }
  281 +
  282 + if ((ret = send_starting_pub())!= ERROR_SUCCESS) {
  283 + srs_error("send starting pub failed. ret=%d", ret);
  284 + return ret;
  285 + }
  286 +
  287 + if ((ret = send_pub_data()) != ERROR_SUCCESS) {
  288 + srs_error("publish data failed. ret=%d", ret);
  289 + return ret;
  290 + }
  291 +
  292 + if ((ret = send_stopped_pub()) != ERROR_SUCCESS) {
  293 + srs_error("send stopped pub failed. ret=%d", ret);
  294 + return ret;
  295 + }
  296 +
  297 + if ((ret = expect_finished()) != ERROR_SUCCESS) {
  298 + srs_error("expect finished msg failed. ret=%d", ret);
  299 + return ret;
  300 + }
  301 +
  302 + if ((ret = send_final()) != ERROR_SUCCESS) {
  303 + srs_error("send final msg failed. ret=%d", ret);
  304 + return ret;
  305 + }
  306 +
  307 + return ret;
  308 +}
  309 +
  310 +int SrsBandCheckClient::create_stream(int &stream_id)
  311 +{
  312 + return ERROR_SUCCESS;
  313 +}
  314 +
  315 +int SrsBandCheckClient::play(std::string stream, int stream_id)
  316 +{
  317 + return ERROR_SUCCESS;
  318 +}
  319 +
  320 +int SrsBandCheckClient::publish(std::string stream, int stream_id)
  321 +{
  322 + return ERROR_SUCCESS;
  323 +}
  324 +
  325 +int SrsBandCheckClient::expect_start_play()
  326 +{
  327 + int ret = ERROR_SUCCESS;
  328 +
  329 + // expect connect _result
  330 + SrsCommonMessage* msg = NULL;
  331 + SrsBandwidthPacket* pkt = NULL;
  332 + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  333 + srs_error("expect bandcheck start play message failed. ret=%d", ret);
  334 + return ret;
  335 + }
  336 + SrsAutoFree(SrsCommonMessage, msg, false);
  337 + srs_info("get bandcheck start play message");
  338 +
  339 + if (pkt->command_name != SRS_BW_CHECK_START_PLAY) {
  340 + srs_error("pkt error. expect=%s, actual=%s", SRS_BW_CHECK_START_PLAY, pkt->command_name.c_str());
  341 + return -1;
  342 + }
  343 +
  344 + return ret;
  345 +}
  346 +
  347 +int SrsBandCheckClient::send_starting_play()
  348 +{
  349 + int ret = ERROR_SUCCESS;
  350 +
  351 + SrsCommonMessage* msg = new SrsCommonMessage;
  352 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  353 + pkt->command_name = SRS_BW_CHECK_STARTING_PLAY;
  354 + msg->set_packet(pkt, 0);
  355 +
  356 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  357 + srs_error("send starting play msg failed. ret=%d", ret);
  358 + return ret;
  359 + }
  360 +
  361 + return ret;
  362 +}
  363 +
  364 +int SrsBandCheckClient::expect_stop_play()
  365 +{
  366 + int ret = ERROR_SUCCESS;
  367 +
  368 + while (true) {
  369 + SrsCommonMessage* msg = NULL;
  370 + SrsBandwidthPacket* pkt = NULL;
  371 + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  372 + srs_error("expect stop play message failed. ret=%d", ret);
  373 + return ret;
  374 + }
  375 + SrsAutoFree(SrsCommonMessage, msg, false);
  376 + srs_info("get bandcheck stop play message");
  377 +
  378 + if (pkt->command_name == SRS_BW_CHECK_STOP_PLAY) {
  379 + break;
  380 + }
  381 + }
  382 +
  383 + return ret;
  384 +}
  385 +
  386 +int SrsBandCheckClient::send_stopped_play()
  387 +{
  388 + int ret = ERROR_SUCCESS;
  389 +
  390 + SrsCommonMessage* msg = new SrsCommonMessage;
  391 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  392 + pkt->command_name = SRS_BW_CHECK_STOPPED_PLAY;
  393 + msg->set_packet(pkt, 0);
  394 +
  395 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  396 + srs_error("send stopped play msg failed. ret=%d", ret);
  397 + return ret;
  398 + }
  399 +
  400 + return ret;
  401 +}
  402 +
  403 +int SrsBandCheckClient::expect_start_pub()
  404 +{
  405 + int ret = ERROR_SUCCESS;
  406 +
  407 + while (true) {
  408 + SrsCommonMessage* msg = NULL;
  409 + SrsBandwidthPacket* pkt = NULL;
  410 + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  411 + srs_error("expect start pub message failed. ret=%d", ret);
  412 + return ret;
  413 + }
  414 + SrsAutoFree(SrsCommonMessage, msg, false);
  415 + srs_info("get bandcheck start pub message");
  416 +
  417 + if (pkt->command_name == SRS_BW_CHECK_START_PUBLISH) {
  418 + break;
  419 + }
  420 + }
  421 +
  422 + return ret;
  423 +}
  424 +
  425 +int SrsBandCheckClient::send_starting_pub()
  426 +{
  427 + int ret = ERROR_SUCCESS;
  428 +
  429 + SrsCommonMessage* msg = new SrsCommonMessage;
  430 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  431 + pkt->command_name = SRS_BW_CHECK_STARTING_PUBLISH;
  432 + msg->set_packet(pkt, 0);
  433 +
  434 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  435 + srs_error("send starting play msg failed. ret=%d", ret);
  436 + return ret;
  437 + }
  438 + srs_info("send starting play msg success.");
  439 +
  440 + return ret;
  441 +}
  442 +
  443 +int SrsBandCheckClient::send_pub_data()
  444 +{
  445 + int ret = ERROR_SUCCESS;
  446 +
  447 + int data_count = 100;
  448 + while (true) {
  449 + SrsCommonMessage* msg = new SrsCommonMessage;
  450 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  451 + pkt->command_name = SRS_BW_CHECK_PUBLISHING;
  452 + msg->set_packet(pkt, 0);
  453 +
  454 + for (int i = 0; i < data_count; ++i) {
  455 + std::stringstream seq;
  456 + seq << i;
  457 + std::string play_data = "SrS band check data from client's publishing......";
  458 + pkt->data->set(seq.str(), new SrsAmf0String(play_data.c_str()));
  459 + }
  460 + data_count += 100;
  461 +
  462 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  463 + srs_error("send publish message failed.ret=%d", ret);
  464 + return ret;
  465 + }
  466 +
  467 + if ((ret = expect_stop_pub()) == ERROR_SUCCESS) {
  468 + break;
  469 + }
  470 + }
  471 +
  472 + return ret;
  473 +}
  474 +
  475 +int SrsBandCheckClient::expect_stop_pub()
  476 +{
  477 + int ret = ERROR_SUCCESS;
  478 +
  479 + while (true) {
  480 + if ((ret = st_netfd_poll(stfd, POLLIN, 1000)) == ERROR_SUCCESS) {
  481 + SrsCommonMessage* msg = 0;
  482 + if ((ret = recv_message(&msg)) != ERROR_SUCCESS)
  483 + {
  484 + srs_error("recv message failed while expect stop pub. ret=%d", ret);
  485 + return ret;
  486 + }
  487 +
  488 + if ((ret = msg->decode_packet(protocol)) != ERROR_SUCCESS) {
  489 + srs_error("decode packet error while expect stop pub. ret=%d", ret);
  490 + return ret;
  491 + }
  492 +
  493 + SrsBandwidthPacket* pkt = dynamic_cast<SrsBandwidthPacket*>(msg->get_packet());
  494 + if (pkt && pkt->command_name == SRS_BW_CHECK_STOP_PUBLISH) {
  495 +
  496 + return ret;
  497 + }
  498 + } else {
  499 + break;
  500 + }
  501 + }
  502 +
  503 + return ret;
  504 +}
  505 +
  506 +int SrsBandCheckClient::expect_finished()
  507 +{
  508 + int ret = ERROR_SUCCESS;
  509 +
  510 + while (true) {
  511 + SrsCommonMessage* msg = NULL;
  512 + SrsBandwidthPacket* pkt = NULL;
  513 + if ((ret = srs_rtmp_expect_message<SrsBandwidthPacket>(protocol, &msg, &pkt)) != ERROR_SUCCESS) {
  514 + srs_error("expect finished message failed. ret=%d", ret);
  515 + return ret;
  516 + }
  517 + SrsAutoFree(SrsCommonMessage, msg, false);
  518 + srs_info("get bandcheck finished message");
  519 +
  520 + if (pkt->command_name == SRS_BW_CHECK_FINISHED) {
  521 + SrsStream *stream = new SrsStream;
  522 + SrsAutoFree(SrsStream, stream, false);
  523 +
  524 + if ((ret = stream->initialize((char*)msg->payload, msg->size)) != ERROR_SUCCESS) {
  525 + srs_error("initialize stream error. ret=%d", ret);
  526 + return ret;
  527 + }
  528 +
  529 + std::string command_name;
  530 + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {
  531 + srs_error("amfo read string error. ret=%d", ret);
  532 + return ret;
  533 + }
  534 +
  535 + double action_id;
  536 + if ((ret = srs_amf0_read_number(stream, action_id)) != ERROR_SUCCESS) {
  537 + srs_error("amfo read number error. ret=%d", ret);
  538 + return ret;
  539 + }
  540 +
  541 + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) {
  542 + srs_error("amfo read number error. ret=%d", ret);
  543 + return ret;
  544 + }
  545 +
  546 + SrsAmf0Object* object;
  547 + if ((ret = srs_amf0_read_object(stream, object)) != ERROR_SUCCESS) {
  548 + srs_error("amfo read object error. ret=%d", ret);
  549 + return ret;
  550 + }
  551 +
  552 + int64_t start_time = 0;
  553 + int64_t end_time = 0;
  554 +
  555 + SrsAmf0Any* start_time_any = object->get_property("start_time");
  556 + if (start_time_any && start_time_any->is_number()) {
  557 + SrsAmf0Number* start_time_number = dynamic_cast<SrsAmf0Number*> (start_time_any);
  558 + if (start_time_number) {
  559 + start_time = start_time_number->value;
  560 + }
  561 + }
  562 +
  563 + SrsAmf0Any* end_time_any = object->get_property("end_time");
  564 + if (end_time_any && end_time_any->is_number()) {
  565 + SrsAmf0Number* end_time_number = dynamic_cast<SrsAmf0Number*> (end_time_any);
  566 + if (end_time_number) {
  567 + end_time = end_time_number->value;
  568 + }
  569 + }
  570 +
  571 + int play_kbps = 0;
  572 + int pub_kbps = 0;
  573 + SrsAmf0Any* play_kbp_any = object->get_property("play_kbps");
  574 + if (play_kbp_any && play_kbp_any->is_number()) {
  575 + SrsAmf0Number* play_kbps_number = dynamic_cast<SrsAmf0Number*> (play_kbp_any);
  576 + if (play_kbps_number) {
  577 + play_kbps = play_kbps_number->value;
  578 + }
  579 + }
  580 +
  581 + SrsAmf0Any* pub_kbp_any = object->get_property("publish_kbps");
  582 + if (pub_kbp_any && pub_kbp_any->is_number()) {
  583 + SrsAmf0Number* pub_kbps_number = dynamic_cast<SrsAmf0Number*> (pub_kbp_any);
  584 + if (pub_kbps_number) {
  585 + pub_kbps = pub_kbps_number->value;
  586 + }
  587 + }
  588 +
  589 + float time_elapsed;
  590 + if (end_time - start_time > 0) {
  591 + time_elapsed = (end_time - start_time) / 1000.00;
  592 + }
  593 +
  594 + srs_trace("result: play %d kbps, publish %d kbps, check time %.4f S\n"
  595 + , play_kbps, pub_kbps, time_elapsed);
  596 +
  597 + break;
  598 + }
  599 + }
  600 +
  601 + return ret;
  602 +}
  603 +
  604 +int SrsBandCheckClient::send_stopped_pub()
  605 +{
  606 + int ret = ERROR_SUCCESS;
  607 +
  608 + SrsCommonMessage* msg = new SrsCommonMessage;
  609 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  610 + pkt->command_name = SRS_BW_CHECK_STOPPED_PUBLISH;
  611 + msg->set_packet(pkt, 0);
  612 +
  613 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  614 + srs_error("send stopped pub msg failed. ret=%d", ret);
  615 + return ret;
  616 + }
  617 + srs_info("send stopped pub msg success.");
  618 +
  619 + return ret;
  620 +}
  621 +
  622 +int SrsBandCheckClient::send_final()
  623 +{
  624 + int ret = ERROR_SUCCESS;
  625 +
  626 + SrsCommonMessage* msg = new SrsCommonMessage;
  627 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket;
  628 + pkt->command_name = SRS_BW_CHECK_FLASH_FINAL;
  629 + msg->set_packet(pkt, 0);
  630 +
  631 + if ((ret = send_message(msg)) != ERROR_SUCCESS) {
  632 + srs_error("send final msg failed. ret=%d", ret);
  633 + return ret;
  634 + }
  635 + srs_info("send final msg success.");
  636 +
  637 + return ret;
  638 +}
  639 +
  640 +SrsBandCheck::SrsBandCheck()
  641 + : bandCheck_Client(0)
  642 +{
  643 +}
  644 +
  645 +SrsBandCheck::~SrsBandCheck()
  646 +{
  647 + if (bandCheck_Client) {
  648 + srs_freep(bandCheck_Client);
  649 + }
  650 +}
  651 +
  652 +int SrsBandCheck::check(const std::string &app, const std::string &tcUrl)
  653 +{
  654 + int ret = ERROR_SUCCESS;
  655 +
  656 + if ((ret = connect_server()) != ERROR_SUCCESS) {
  657 + srs_error("connect to server failed. ret = %d", ret);
  658 + return ret;
  659 + }
  660 +
  661 + if ((ret = bandCheck_Client->handshake()) != ERROR_SUCCESS) {
  662 + srs_error("handshake failed. ret = %d", ret);
  663 + return ret;
  664 + }
  665 +
  666 + if ((ret = bandCheck_Client->connect_app(app, tcUrl)) != ERROR_SUCCESS) {
  667 + srs_error("handshake failed. ret = %d", ret);
  668 + return ret;
  669 + }
  670 +
  671 + if ((ret = bandCheck_Client->check_play()) != ERROR_SUCCESS) {
  672 + srs_error("band check play failed.");
  673 + return ret;
  674 + }
  675 +
  676 + if ((ret = bandCheck_Client->check_publish()) != ERROR_SUCCESS) {
  677 + srs_error("band check publish failed.");
  678 + return ret;
  679 + }
  680 +
  681 + return ret;
  682 +}
  683 +
  684 +void SrsBandCheck::set_server(const std::string &server, int port)
  685 +{
  686 + server_address = server;
  687 + server_port = port;
  688 +}
  689 +
  690 +int SrsBandCheck::connect_server()
  691 +{
  692 + int ret = ERROR_SUCCESS;
  693 +
  694 + int sock = socket(AF_INET, SOCK_STREAM, 0);
  695 + if(sock == -1){
  696 + ret = ERROR_SOCKET_CREATE;
  697 + srs_error("create socket error. ret=%d", ret);
  698 + return ret;
  699 + }
  700 +
  701 + st_netfd_t stfd = st_netfd_open_socket(sock);
  702 + if(stfd == NULL){
  703 + ret = ERROR_ST_OPEN_SOCKET;
  704 + srs_error("st_netfd_open_socket failed. ret=%d", ret);
  705 + return ret;
  706 + }
  707 +
  708 + bandCheck_Client = new SrsBandCheckClient(stfd);
  709 +
  710 + // connect to server.
  711 + std::string ip = srs_dns_resolve(server_address);
  712 + if (ip.empty()) {
  713 + ret = ERROR_SYSTEM_IP_INVALID;
  714 + srs_error("dns resolve server error, ip empty. ret=%d", ret);
  715 + return ret;
  716 + }
  717 +
  718 + sockaddr_in addr;
  719 + addr.sin_family = AF_INET;
  720 + addr.sin_port = htons(server_port);
  721 + addr.sin_addr.s_addr = inet_addr(ip.c_str());
  722 +
  723 + if (st_connect(stfd, (const struct sockaddr*)&addr, sizeof(sockaddr_in), ST_UTIME_NO_TIMEOUT) == -1){
  724 + ret = ERROR_ST_CONNECT;
  725 + srs_error("connect to server error. ip=%s, port=%d, ret=%d", ip.c_str(), server_port, ret);
  726 + return ret;
  727 + }
  728 + srs_trace("connect to server success. server=%s, ip=%s, port=%d", server_address.c_str(), ip.c_str(), server_port);
  729 +
  730 + return ret;
  731 +}
  732 +
  733 +int init_st()
  734 +{
  735 + int ret = ERROR_SUCCESS;
  736 +
  737 + if (st_set_eventsys(ST_EVENTSYS_ALT) == -1) {
  738 + ret = ERROR_ST_SET_EPOLL;
  739 + srs_error("st_set_eventsys use linux epoll failed. ret=%d", ret);
  740 + return ret;
  741 + }
  742 +
  743 + if(st_init() != 0){
  744 + ret = ERROR_ST_INITIALIZE;
  745 + srs_error("st_init failed. ret=%d", ret);
  746 + return ret;
  747 + }
  748 +
  749 + return ret;
  750 +}
  751 +
  752 +void print_help(char** argv)
  753 +{
  754 + printf(
  755 + "Usage: %s [OPTION]...\n"
  756 + "test band width from client to rtmp server.\n"
  757 + "Mandatory arguments to long options are mandatory for short options too.\n"
  758 + " -i, --ip the ip or domain that to test\n"
  759 + " -p, --port the port that server listen \n"
  760 + " -k, --key the key used to test \n"
  761 + " -v, --vhost the vhost used to test \n"
  762 + " -V, --version output version information and exit \n"
  763 + " -h, --help display this help and exit \n"
  764 + "\n"
  765 + "For example:\n"
  766 + " %s -i 192.168.1.248 -p 1935 -v bandcheck.srs.com -k 35c9b402c12a7246868752e2878f7e0e"
  767 + "\n\n"
  768 + "Exit status:\n"
  769 + "0 if OK,\n"
  770 + "other if error occured, and the detail should be printed.\n"
  771 + "\n\n"
  772 + "srs home page: <http://blog.chinaunix.net/uid/25006789.html>\n",
  773 + argv[0], argv[0]);
  774 +}
  775 +
  776 +void print_version()
  777 +{
  778 + const char *version = ""
  779 + "srs_bandcheck "BUILD_VERSION"\n"
  780 + "Copyright (c) 2013-2014 wenjiegit.\n"
  781 + "License MIT\n"
  782 + "This is free software: you are free to change and redistribute it.\n"
  783 + "There is NO WARRANTY, to the extent permitted by law.\n"
  784 + "\n"
  785 + "Written by wenjie.\n";
  786 +
  787 + printf("%s", version);
  788 +}
  789 +
  790 +int get_opt(int argc, char *argv[])
  791 +{
  792 + int ret = ERROR_SUCCESS;
  793 +
  794 + int c;
  795 + while ((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1) {
  796 + switch (c) {
  797 + case 'i':
  798 + if (optarg) {
  799 + g_ip = optarg;
  800 + }
  801 + break;
  802 + case 'p':
  803 + if (optarg) {
  804 + g_port = atoi(optarg);
  805 + }
  806 + break;
  807 + case 'k':
  808 + if (optarg) {
  809 + g_key = optarg;
  810 + }
  811 + break;
  812 + case 'v':
  813 + if (optarg) {
  814 + g_vhost = optarg;
  815 + }
  816 + break;
  817 + case 'V':
  818 + print_version();
  819 + exit(0);
  820 + break;
  821 + case 'h':
  822 + print_help(argv);
  823 + exit(0);
  824 + break;
  825 + default:
  826 + printf("see --help or -h\n");
  827 + ret = -1;
  828 + }
  829 + }
  830 +
  831 + return ret;
  832 +}
1 /* 1 /*
2 The MIT License (MIT) 2 The MIT License (MIT)
3 3
4 -Copyright (c) 2013 winlin 4 +Copyright (c) 2013-2014 winlin
5 5
6 Permission is hereby granted, free of charge, to any person obtaining a copy of 6 Permission is hereby granted, free of charge, to any person obtaining a copy of
7 this software and associated documentation files (the "Software"), to deal in 7 this software and associated documentation files (the "Software"), to deal in
1 file 1 file
2 main readonly separator, 2 main readonly separator,
3 ..\main\srs_main_server.cpp, 3 ..\main\srs_main_server.cpp,
  4 + ..\main\srs_main_bandcheck.cpp,
4 auto readonly separator, 5 auto readonly separator,
5 ..\..\objs\srs_auto_headers.hpp, 6 ..\..\objs\srs_auto_headers.hpp,
6 core readonly separator, 7 core readonly separator,
@@ -57,7 +58,7 @@ file @@ -57,7 +58,7 @@ file
57 ..\core\srs_core_source.hpp, 58 ..\core\srs_core_source.hpp,
58 ..\core\srs_core_source.cpp, 59 ..\core\srs_core_source.cpp,
59 research readonly separator, 60 research readonly separator,
60 - ..\..\research\ts_info.cc; 61 + ..\..\research\hls\ts_info.cc;
61 62
62 mainconfig 63 mainconfig
63 "" = "MAIN"; 64 "" = "MAIN";