winlin

use librtmp to implemnts the bandwidth linux tool. 0.9.158

@@ -40,16 +40,27 @@ int main(int argc, char** argv) @@ -40,16 +40,27 @@ int main(int argc, char** argv)
40 char* data; 40 char* data;
41 41
42 // srs debug info. 42 // srs debug info.
  43 + char srs_server_ip[128];
43 char srs_server[128]; 44 char srs_server[128];
44 char srs_primary_authors[128]; 45 char srs_primary_authors[128];
45 - char srs_id[64];  
46 - char srs_pid[64];  
47 - char srs_server_ip[128]; 46 + char srs_version[32];
  47 + int srs_id = 0;
  48 + int srs_pid = 0;
48 // bandwidth test data. 49 // bandwidth test data.
49 - int64_t start_time, end_time;  
50 - int play_kbps, publish_kbps;  
51 - int play_bytes, publish_bytes;  
52 - int play_duration, publish_duration; 50 + int64_t start_time = 0;
  51 + int64_t end_time = 0;
  52 + int play_kbps = 0;
  53 + int publish_kbps = 0;
  54 + int play_bytes = 0;
  55 + int publish_bytes = 0;
  56 + int play_duration = 0;
  57 + int publish_duration = 0;
  58 +
  59 + // set to zero.
  60 + srs_server_ip[0] = 0;
  61 + srs_server[0] = 0;
  62 + srs_primary_authors[0] = 0;
  63 + srs_version[0] = 0;
53 64
54 if (argc <= 1) { 65 if (argc <= 1) {
55 printf("RTMP bandwidth check/test with server.\n" 66 printf("RTMP bandwidth check/test with server.\n"
@@ -57,8 +68,9 @@ int main(int argc, char** argv) @@ -57,8 +68,9 @@ int main(int argc, char** argv)
57 " rtmp_url RTMP bandwidth url to check. format: rtmp://server:port/app?key=xxx&&vhost=xxx\n" 68 " rtmp_url RTMP bandwidth url to check. format: rtmp://server:port/app?key=xxx&&vhost=xxx\n"
58 "For example:\n" 69 "For example:\n"
59 " %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com\n" 70 " %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com\n"
  71 + " %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com>/dev/null\n"
60 "@remark, output text to stdout, while json to stderr.\n", 72 "@remark, output text to stdout, while json to stderr.\n",
61 - argv[0], argv[0]); 73 + argv[0], argv[0], argv[0]);
62 ret = 1; 74 ret = 1;
63 exit(ret); 75 exit(ret);
64 return ret; 76 return ret;
@@ -77,15 +89,14 @@ int main(int argc, char** argv) @@ -77,15 +89,14 @@ int main(int argc, char** argv)
77 } 89 }
78 printf("simple handshake success\n"); 90 printf("simple handshake success\n");
79 91
80 - if ((ret = srs_connect_app(rtmp)) != 0) { 92 + if ((ret = srs_connect_app2(rtmp,
  93 + srs_server_ip, srs_server, srs_primary_authors, srs_version, &srs_id, &srs_pid)) != 0) {
81 printf("connect vhost/app failed.\n"); 94 printf("connect vhost/app failed.\n");
82 goto rtmp_destroy; 95 goto rtmp_destroy;
83 } 96 }
84 printf("connect vhost/app success\n"); 97 printf("connect vhost/app success\n");
85 98
86 if ((ret = srs_bandwidth_check(rtmp, 99 if ((ret = srs_bandwidth_check(rtmp,
87 - srs_server, srs_primary_authors,  
88 - srs_id, srs_pid, srs_server_ip,  
89 &start_time, &end_time, &play_kbps, &publish_kbps, 100 &start_time, &end_time, &play_kbps, &publish_kbps,
90 &play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0 101 &play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0
91 ) { 102 ) {
@@ -95,12 +106,12 @@ int main(int argc, char** argv) @@ -95,12 +106,12 @@ int main(int argc, char** argv)
95 printf("bandwidth check/test success\n"); 106 printf("bandwidth check/test success\n");
96 107
97 printf("\n%s, %s\n" 108 printf("\n%s, %s\n"
98 - "%s, srs_pid=%s, srs_id=%s\n" 109 + "%s, %s, srs_pid=%d, srs_id=%d\n"
99 "duration: %dms(%d+%d)\n" 110 "duration: %dms(%d+%d)\n"
100 "play: %dkbps\n" 111 "play: %dkbps\n"
101 "publish: %dkbps\n\n", 112 "publish: %dkbps\n\n",
102 (char*)srs_server, (char*)srs_primary_authors, 113 (char*)srs_server, (char*)srs_primary_authors,
103 - (char*)srs_server_ip, (char*)srs_pid, (char*)srs_id, 114 + (char*)srs_server_ip, (char*)srs_version, srs_pid, srs_id,
104 (int)(end_time - start_time), play_duration, publish_duration, 115 (int)(end_time - start_time), play_duration, publish_duration,
105 play_kbps, 116 play_kbps,
106 publish_kbps); 117 publish_kbps);
@@ -108,6 +119,24 @@ int main(int argc, char** argv) @@ -108,6 +119,24 @@ int main(int argc, char** argv)
108 rtmp_destroy: 119 rtmp_destroy:
109 srs_rtmp_destroy(rtmp); 120 srs_rtmp_destroy(rtmp);
110 121
111 - printf("terminate with ret=%d\n", ret); 122 + printf("terminate with ret=%d\n\n", ret);
  123 +
  124 + fprintf(stderr, "{\"code\":%d,"
  125 + "\"srs_server\":\"%s\", "
  126 + "\"srs_primary_authors\":\"%s\", "
  127 + "\"srs_server_ip\":\"%s\", "
  128 + "\"srs_version\":\"%s\", "
  129 + "\"srs_pid\":%d, "
  130 + "\"srs_id\":%d, "
  131 + "\"duration\":%d, "
  132 + "\"play_duration\":%d, "
  133 + "\"play_kbps\":%d, "
  134 + "\"publish_kbps\":%d"
  135 + "}",
  136 + ret,
  137 + (char*)srs_server, (char*)srs_primary_authors,
  138 + (char*)srs_server_ip, (char*)srs_version, srs_pid, srs_id,
  139 + (int)(end_time - start_time), play_duration, publish_duration,
  140 + play_kbps, publish_kbps);
112 return ret; 141 return ret;
113 } 142 }
@@ -100,7 +100,7 @@ int _srs_expect_bandwidth_packet(SrsRtmpServer* rtmp, _CheckPacketType pfn) @@ -100,7 +100,7 @@ int _srs_expect_bandwidth_packet(SrsRtmpServer* rtmp, _CheckPacketType pfn)
100 } 100 }
101 SrsAutoFree(SrsMessage, msg); 101 SrsAutoFree(SrsMessage, msg);
102 SrsAutoFree(SrsBandwidthPacket, pkt); 102 SrsAutoFree(SrsBandwidthPacket, pkt);
103 - srs_info("get final message success."); 103 + srs_info("get bwtc message success.");
104 104
105 if (pfn(pkt)) { 105 if (pfn(pkt)) {
106 return ret; 106 return ret;
@@ -147,6 +147,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io @@ -147,6 +147,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io
147 static int64_t last_check_time = 0; 147 static int64_t last_check_time = 0;
148 int interval_ms = _srs_config->get_bw_check_interval_ms(_req->vhost); 148 int interval_ms = _srs_config->get_bw_check_interval_ms(_req->vhost);
149 149
  150 + srs_update_system_time_ms();
150 int64_t time_now = srs_get_system_time_ms(); 151 int64_t time_now = srs_get_system_time_ms();
151 // reject the connection in the interval window. 152 // reject the connection in the interval window.
152 if (last_check_time > 0 && time_now - last_check_time < interval_ms) { 153 if (last_check_time > 0 && time_now - last_check_time < interval_ms) {
@@ -185,10 +186,11 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) @@ -185,10 +186,11 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
185 SrsBandwidthSample publish_sample; 186 SrsBandwidthSample publish_sample;
186 187
187 // timeout for a packet. 188 // timeout for a packet.
188 - _rtmp->set_send_timeout(play_sample.duration_ms * 1000);  
189 - _rtmp->set_recv_timeout(publish_sample.duration_ms * 1000); 189 + _rtmp->set_send_timeout(play_sample.duration_ms * 1000 * 2);
  190 + _rtmp->set_recv_timeout(publish_sample.duration_ms * 1000 * 2);
190 191
191 // start test. 192 // start test.
  193 + srs_update_system_time_ms();
192 int64_t start_time = srs_get_system_time_ms(); 194 int64_t start_time = srs_get_system_time_ms();
193 195
194 // sample play 196 // sample play
@@ -228,6 +230,7 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) @@ -228,6 +230,7 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit)
228 srs_info("stop publish test. kbps=%d", publish_sample.kbps); 230 srs_info("stop publish test. kbps=%d", publish_sample.kbps);
229 231
230 // stop test. 232 // stop test.
  233 + srs_update_system_time_ms();
231 int64_t end_time = srs_get_system_time_ms(); 234 int64_t end_time = srs_get_system_time_ms();
232 235
233 srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", 236 srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps",
@@ -279,6 +282,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) @@ -279,6 +282,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
279 memset(random_data, 'A', size); 282 memset(random_data, 'A', size);
280 283
281 int data_count = 1; 284 int data_count = 1;
  285 + srs_update_system_time_ms();
282 int64_t starttime = srs_get_system_time_ms(); 286 int64_t starttime = srs_get_system_time_ms();
283 while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { 287 while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) {
284 st_usleep(sample->interval_ms); 288 st_usleep(sample->interval_ms);
@@ -302,6 +306,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) @@ -302,6 +306,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit)
302 306
303 limit->send_limit(); 307 limit->send_limit();
304 } 308 }
  309 + srs_update_system_time_ms();
305 sample->calc_kbps(_rtmp->get_send_bytes(), srs_get_system_time_ms() - starttime); 310 sample->calc_kbps(_rtmp->get_send_bytes(), srs_get_system_time_ms() - starttime);
306 srs_info("BW check send play bytes over."); 311 srs_info("BW check send play bytes over.");
307 312
@@ -367,19 +372,26 @@ int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* lim @@ -367,19 +372,26 @@ int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* lim
367 int ret = ERROR_SUCCESS; 372 int ret = ERROR_SUCCESS;
368 373
369 // recv publish msgs until @duration_ms ms 374 // recv publish msgs until @duration_ms ms
  375 + srs_update_system_time_ms();
370 int64_t starttime = srs_get_system_time_ms(); 376 int64_t starttime = srs_get_system_time_ms();
371 while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { 377 while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) {
372 - st_usleep(sample->interval_ms);  
373 -  
374 SrsMessage* msg = NULL; 378 SrsMessage* msg = NULL;
375 - if ((ret = _rtmp->recv_message(&msg)) != ERROR_SUCCESS) {  
376 - srs_error("recv message failed. ret=%d", ret); 379 + SrsBandwidthPacket* pkt = NULL;
  380 + if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
377 return ret; 381 return ret;
378 } 382 }
379 SrsAutoFree(SrsMessage, msg); 383 SrsAutoFree(SrsMessage, msg);
  384 + SrsAutoFree(SrsBandwidthPacket, pkt);
  385 + srs_info("get publish message success.");
  386 +
  387 + // client requires to stop.
  388 + if (pkt->is_stop_publish()) {
  389 + break;
  390 + }
380 391
381 limit->recv_limit(); 392 limit->recv_limit();
382 } 393 }
  394 + srs_update_system_time_ms();
383 sample->calc_kbps(_rtmp->get_recv_bytes(), srs_get_system_time_ms() - starttime); 395 sample->calc_kbps(_rtmp->get_recv_bytes(), srs_get_system_time_ms() - starttime);
384 srs_info("BW check recv publish data over."); 396 srs_info("BW check recv publish data over.");
385 397
@@ -102,7 +102,7 @@ public: @@ -102,7 +102,7 @@ public:
102 * | | 102 * | |
103 * | <-call(start publish) | onSrsBandCheckStartPublishBytes 103 * | <-call(start publish) | onSrsBandCheckStartPublishBytes
104 * | result(publishing)--> | onSrsBandCheckStartingPublishBytes 104 * | result(publishing)--> | onSrsBandCheckStartingPublishBytes
105 -* | data(publishing)----> | onSrsBandCheckStartingPublishBytes 105 +* | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes
106 * | <--call(stop publish) | onSrsBandCheckStopPublishBytes 106 * | <--call(stop publish) | onSrsBandCheckStopPublishBytes
107 * | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes 107 * | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes
108 * | | 108 * | |
@@ -114,6 +114,9 @@ public: @@ -114,6 +114,9 @@ public:
114 * for the flash client queue is fullfill with other packets. 114 * for the flash client queue is fullfill with other packets.
115 * 2. when flash client, server never wait the final packet, 115 * 2. when flash client, server never wait the final packet,
116 * for the flash client directly close when got report packet. 116 * for the flash client directly close when got report packet.
  117 +* 3. for linux client, it will send the publish data then send a stop publish,
  118 +* for the linux client donot know when to stop the publish.
  119 +* when server got publishing and stop publish, stop publish.
117 */ 120 */
118 class SrsBandwidth 121 class SrsBandwidth
119 { 122 {
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "157" 34 +#define VERSION_REVISION "158"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"
@@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
86 #define ERROR_RTMP_EDGE_RELOAD 323 86 #define ERROR_RTMP_EDGE_RELOAD 323
87 // aggregate message parse failed. 87 // aggregate message parse failed.
88 #define ERROR_RTMP_AGGREGATE 324 88 #define ERROR_RTMP_AGGREGATE 324
  89 +#define ERROR_RTMP_BWTC_DATA 325
89 90
90 #define ERROR_SYSTEM_PACKET_INVALID 401 91 #define ERROR_SYSTEM_PACKET_INVALID 401
91 #define ERROR_SYSTEM_CLIENT_INVALID 402 92 #define ERROR_SYSTEM_CLIENT_INVALID 402
@@ -23,11 +23,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -23,11 +23,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 23
24 #include <srs_lib_bandwidth.hpp> 24 #include <srs_lib_bandwidth.hpp>
25 25
  26 +#include <sstream>
  27 +using namespace std;
  28 +
26 #include <srs_kernel_error.hpp> 29 #include <srs_kernel_error.hpp>
27 #include <srs_protocol_stack.hpp> 30 #include <srs_protocol_stack.hpp>
28 #include <srs_protocol_rtmp.hpp> 31 #include <srs_protocol_rtmp.hpp>
29 #include <srs_core_autofree.hpp> 32 #include <srs_core_autofree.hpp>
30 #include <srs_kernel_utility.hpp> 33 #include <srs_kernel_utility.hpp>
  34 +#include <srs_protocol_amf0.hpp>
31 35
32 /** 36 /**
33 * recv bandwidth helper. 37 * recv bandwidth helper.
@@ -45,6 +49,10 @@ bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt) @@ -45,6 +49,10 @@ bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt)
45 { 49 {
46 return pkt->is_start_publish(); 50 return pkt->is_start_publish();
47 } 51 }
  52 +bool _bandwidth_is_stop_publish(SrsBandwidthPacket* pkt)
  53 +{
  54 + return pkt->is_stop_publish();
  55 +}
48 bool _bandwidth_is_finish(SrsBandwidthPacket* pkt) 56 bool _bandwidth_is_finish(SrsBandwidthPacket* pkt)
49 { 57 {
50 return pkt->is_finish(); 58 return pkt->is_finish();
@@ -70,6 +78,29 @@ int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn) @@ -70,6 +78,29 @@ int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn)
70 78
71 return ret; 79 return ret;
72 } 80 }
  81 +int _srs_expect_bandwidth_packet2(SrsRtmpClient* rtmp, _CheckPacketType pfn, SrsBandwidthPacket** ppkt)
  82 +{
  83 + int ret = ERROR_SUCCESS;
  84 +
  85 + while (true) {
  86 + SrsMessage* msg = NULL;
  87 + SrsBandwidthPacket* pkt = NULL;
  88 + if ((ret = rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
  89 + return ret;
  90 + }
  91 + SrsAutoFree(SrsMessage, msg);
  92 + srs_info("get final message success.");
  93 +
  94 + if (pfn(pkt)) {
  95 + *ppkt = pkt;
  96 + return ret;
  97 + }
  98 +
  99 + srs_freep(pkt);
  100 + }
  101 +
  102 + return ret;
  103 +}
73 104
74 SrsBandwidthClient::SrsBandwidthClient() 105 SrsBandwidthClient::SrsBandwidthClient()
75 { 106 {
@@ -88,8 +119,6 @@ int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp) @@ -88,8 +119,6 @@ int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp)
88 } 119 }
89 120
90 int SrsBandwidthClient::bandwidth_check( 121 int SrsBandwidthClient::bandwidth_check(
91 - char srs_server[128], char srs_primary_authors[128],  
92 - char srs_id[64], char srs_pid[64], char srs_server_ip[128],  
93 int64_t* start_time, int64_t* end_time, 122 int64_t* start_time, int64_t* end_time,
94 int* play_kbps, int* publish_kbps, 123 int* play_kbps, int* publish_kbps,
95 int* play_bytes, int* publish_bytes, 124 int* play_bytes, int* publish_bytes,
@@ -97,30 +126,72 @@ int SrsBandwidthClient::bandwidth_check( @@ -97,30 +126,72 @@ int SrsBandwidthClient::bandwidth_check(
97 ) { 126 ) {
98 int ret = ERROR_SUCCESS; 127 int ret = ERROR_SUCCESS;
99 128
  129 + srs_update_system_time_ms();
100 *start_time = srs_get_system_time_ms(); 130 *start_time = srs_get_system_time_ms();
101 131
102 // play 132 // play
  133 + int duration_delta = 0;
  134 + int bytes_delta = 0;
103 if ((ret = play_start()) != ERROR_SUCCESS) { 135 if ((ret = play_start()) != ERROR_SUCCESS) {
104 return ret; 136 return ret;
105 } 137 }
106 if ((ret = play_checking()) != ERROR_SUCCESS) { 138 if ((ret = play_checking()) != ERROR_SUCCESS) {
107 return ret; 139 return ret;
108 } 140 }
109 - if ((ret = play_stop()) != ERROR_SUCCESS) { 141 + if ((ret = play_stop(duration_delta, bytes_delta)) != ERROR_SUCCESS) {
110 return ret; 142 return ret;
111 } 143 }
112 144
  145 + // play kbps used to refer for publish
  146 + int actual_play_kbps = 0;
  147 + if (duration_delta > 0) {
  148 + actual_play_kbps = bytes_delta * 8 / duration_delta;
  149 + }
  150 + // max publish kbps, we set to 1.2*play_kbps:
  151 + actual_play_kbps = (int)(actual_play_kbps * 1.2);
  152 +
113 // publish 153 // publish
114 - if ((ret = publish_start()) != ERROR_SUCCESS) { 154 + int duration_ms = 0;
  155 + if ((ret = publish_start(duration_ms)) != ERROR_SUCCESS) {
115 return ret; 156 return ret;
116 } 157 }
117 - if ((ret = publish_checking()) != ERROR_SUCCESS) { 158 + if ((ret = publish_checking(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) {
118 return ret; 159 return ret;
119 } 160 }
120 if ((ret = publish_stop()) != ERROR_SUCCESS) { 161 if ((ret = publish_stop()) != ERROR_SUCCESS) {
121 return ret; 162 return ret;
122 } 163 }
  164 +
  165 + SrsBandwidthPacket* pkt = NULL;
  166 + if ((ret = final(&pkt)) != ERROR_SUCCESS) {
  167 + return ret;
  168 + }
  169 + SrsAutoFree(SrsBandwidthPacket, pkt);
  170 +
  171 + // get data
  172 + if (true ) {
  173 + SrsAmf0Any* prop = NULL;
  174 + if ((prop = pkt->data->ensure_property_number("play_kbps")) != NULL) {
  175 + *play_kbps = (int)prop->to_number();
  176 + }
  177 + if ((prop = pkt->data->ensure_property_number("publish_kbps")) != NULL) {
  178 + *publish_kbps = (int)prop->to_number();
  179 + }
  180 + if ((prop = pkt->data->ensure_property_number("play_bytes")) != NULL) {
  181 + *play_bytes = (int)prop->to_number();
  182 + }
  183 + if ((prop = pkt->data->ensure_property_number("publish_bytes")) != NULL) {
  184 + *publish_bytes = (int)prop->to_number();
  185 + }
  186 + if ((prop = pkt->data->ensure_property_number("play_time")) != NULL) {
  187 + *play_duration = (int)prop->to_number();
  188 + }
  189 + if ((prop = pkt->data->ensure_property_number("publish_time")) != NULL) {
  190 + *publish_duration = (int)prop->to_number();
  191 + }
  192 + }
123 193
  194 + srs_update_system_time_ms();
124 *end_time = srs_get_system_time_ms(); 195 *end_time = srs_get_system_time_ms();
125 196
126 return ret; 197 return ret;
@@ -155,18 +226,30 @@ int SrsBandwidthClient::play_checking() @@ -155,18 +226,30 @@ int SrsBandwidthClient::play_checking()
155 return ret; 226 return ret;
156 } 227 }
157 228
158 -int SrsBandwidthClient::play_stop() 229 +int SrsBandwidthClient::play_stop(int& duration_delta, int& bytes_delta)
159 { 230 {
160 int ret = ERROR_SUCCESS; 231 int ret = ERROR_SUCCESS;
161 232
162 - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) {  
163 - return ret; 233 + if (true) {
  234 + SrsBandwidthPacket* pkt = NULL;
  235 + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_stop_play, &pkt)) != ERROR_SUCCESS) {
  236 + return ret;
  237 + }
  238 + SrsAutoFree(SrsBandwidthPacket, pkt);
  239 +
  240 + SrsAmf0Any* prop = NULL;
  241 + if ((prop = pkt->data->ensure_property_number("duration_delta")) != NULL) {
  242 + duration_delta = (int)prop->to_number();
  243 + }
  244 + if ((prop = pkt->data->ensure_property_number("bytes_delta")) != NULL) {
  245 + bytes_delta = (int)prop->to_number();
  246 + }
164 } 247 }
165 srs_info("BW check recv play stop request."); 248 srs_info("BW check recv play stop request.");
166 249
167 if (true) { 250 if (true) {
168 // send stop play response to server. 251 // send stop play response to server.
169 - SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play(); 252 + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play();
170 253
171 if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 254 if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
172 srs_error("send bandwidth check stop play message failed. ret=%d", ret); 255 srs_error("send bandwidth check stop play message failed. ret=%d", ret);
@@ -178,12 +261,21 @@ int SrsBandwidthClient::play_stop() @@ -178,12 +261,21 @@ int SrsBandwidthClient::play_stop()
178 return ret; 261 return ret;
179 } 262 }
180 263
181 -int SrsBandwidthClient::publish_start() 264 +int SrsBandwidthClient::publish_start(int& duration_ms)
182 { 265 {
183 int ret = ERROR_SUCCESS; 266 int ret = ERROR_SUCCESS;
184 267
185 - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) {  
186 - return ret; 268 + if (true) {
  269 + SrsBandwidthPacket* pkt = NULL;
  270 + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) {
  271 + return ret;
  272 + }
  273 + SrsAutoFree(SrsBandwidthPacket, pkt);
  274 +
  275 + SrsAmf0Any* prop = NULL;
  276 + if ((prop = pkt->data->ensure_property_number("duration_ms")) != NULL) {
  277 + duration_ms = (int)prop->to_number();
  278 + }
187 } 279 }
188 srs_info("BW check recv publish begin request."); 280 srs_info("BW check recv publish begin request.");
189 281
@@ -201,24 +293,89 @@ int SrsBandwidthClient::publish_start() @@ -201,24 +293,89 @@ int SrsBandwidthClient::publish_start()
201 return ret; 293 return ret;
202 } 294 }
203 295
204 -int SrsBandwidthClient::publish_checking() 296 +int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps)
205 { 297 {
206 int ret = ERROR_SUCCESS; 298 int ret = ERROR_SUCCESS;
  299 +
  300 + if (duration_ms <= 0) {
  301 + ret = ERROR_RTMP_BWTC_DATA;
  302 + srs_error("server must specifies the duration, ret=%d", ret);
  303 + return ret;
  304 + }
  305 +
  306 + if (play_kbps <= 0) {
  307 + ret = ERROR_RTMP_BWTC_DATA;
  308 + srs_error("server must specifies the play kbp, ret=%d", ret);
  309 + return ret;
  310 + }
  311 +
  312 + // send play data to client
  313 + int size = 1024; // TODO: FIXME: magic number
  314 + char random_data[size];
  315 + memset(random_data, 'A', size);
  316 +
  317 + int data_count = 1;
  318 + srs_update_system_time_ms();
  319 + int64_t starttime = srs_get_system_time_ms();
  320 + while ((srs_get_system_time_ms() - starttime) < duration_ms) {
  321 + // TODO: FIXME: use shared ptr message.
  322 + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing();
  323 +
  324 + // TODO: FIXME: magic number
  325 + for (int i = 0; i < data_count; ++i) {
  326 + std::stringstream seq;
  327 + seq << i;
  328 + std::string play_data = "SRS band check data from server's publishing......";
  329 + pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
  330 + }
  331 + data_count += 2;
  332 +
  333 + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
  334 + srs_error("send bandwidth check publish messages failed. ret=%d", ret);
  335 + return ret;
  336 + }
  337 +
  338 + // use the play kbps to control the publish
  339 + srs_update_system_time_ms();
  340 + int elaps = srs_get_system_time_ms() - starttime;
  341 + if (elaps > 0) {
  342 + int current_kbps = _rtmp->get_send_bytes() * 8 / elaps;
  343 + while (current_kbps > play_kbps) {
  344 + srs_update_system_time_ms();
  345 + elaps = srs_get_system_time_ms() - starttime;
  346 + current_kbps = _rtmp->get_send_bytes() * 8 / elaps;
  347 + usleep(100 * 1000); // TODO: FIXME: magic number.
  348 + }
  349 + }
  350 + }
  351 + srs_info("BW check send publish bytes over.");
  352 +
207 return ret; 353 return ret;
208 } 354 }
209 355
210 int SrsBandwidthClient::publish_stop() 356 int SrsBandwidthClient::publish_stop()
211 { 357 {
212 int ret = ERROR_SUCCESS; 358 int ret = ERROR_SUCCESS;
  359 +
  360 + if (true) {
  361 + // send start publish response to server.
  362 + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish();
  363 +
  364 + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
  365 + srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
  366 + return ret;
  367 + }
  368 + }
  369 + srs_info("BW client stop publish request.");
213 370
214 - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) { 371 + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) {
215 return ret; 372 return ret;
216 } 373 }
217 srs_info("BW check recv publish stop request."); 374 srs_info("BW check recv publish stop request.");
218 375
219 if (true) { 376 if (true) {
220 // send start publish response to server. 377 // send start publish response to server.
221 - SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish(); 378 + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish();
222 379
223 if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 380 if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
224 srs_error("send bandwidth check stop publish message failed. ret=%d", ret); 381 srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
@@ -230,12 +387,15 @@ int SrsBandwidthClient::publish_stop() @@ -230,12 +387,15 @@ int SrsBandwidthClient::publish_stop()
230 return ret; 387 return ret;
231 } 388 }
232 389
233 -int SrsBandwidthClient::finial() 390 +int SrsBandwidthClient::final(SrsBandwidthPacket** ppkt)
234 { 391 {
235 int ret = ERROR_SUCCESS; 392 int ret = ERROR_SUCCESS;
236 393
237 - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_finish)) != ERROR_SUCCESS) {  
238 - return ret; 394 + if (true) {
  395 + SrsBandwidthPacket* pkt = NULL;
  396 + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) {
  397 + return ret;
  398 + }
239 } 399 }
240 srs_info("BW check recv finish/report request."); 400 srs_info("BW check recv finish/report request.");
241 401
@@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 #include <srs_core.hpp> 31 #include <srs_core.hpp>
32 32
33 class SrsRtmpClient; 33 class SrsRtmpClient;
  34 +class SrsBandwidthPacket;
34 35
35 /** 36 /**
36 * bandwith client library for srs-librtmp. 37 * bandwith client library for srs-librtmp.
@@ -50,13 +51,6 @@ public: @@ -50,13 +51,6 @@ public:
50 /** 51 /**
51 * do bandwidth check. 52 * do bandwidth check.
52 * 53 *
53 - * SRS debug info:  
54 - * @param srs_server, 128bytes, server info.  
55 - * @param srs_primary_authors, 128bytes, primary authors.  
56 - * @param srs_id, 64bytes, debug info, client id in server log.  
57 - * @param srs_pid, 64bytes, debug info, server pid in log.  
58 - * @param srs_server_ip, 128bytes, debug info, server ip client connected at.  
59 - *  
60 * bandwidth info: 54 * bandwidth info:
61 * @param start_time, output the start time, in ms. 55 * @param start_time, output the start time, in ms.
62 * @param end_time, output the end time, in ms. 56 * @param end_time, output the end time, in ms.
@@ -68,8 +62,6 @@ public: @@ -68,8 +62,6 @@ public:
68 * @param publish_duration, output the publish/upload test duration, in ms. 62 * @param publish_duration, output the publish/upload test duration, in ms.
69 */ 63 */
70 virtual int bandwidth_check( 64 virtual int bandwidth_check(
71 - char srs_server[128], char srs_primary_authors[128],  
72 - char srs_id[64], char srs_pid[64], char srs_server_ip[128],  
73 int64_t* start_time, int64_t* end_time, 65 int64_t* start_time, int64_t* end_time,
74 int* play_kbps, int* publish_kbps, 66 int* play_kbps, int* publish_kbps,
75 int* play_bytes, int* publish_bytes, 67 int* play_bytes, int* publish_bytes,
@@ -81,17 +73,17 @@ private: @@ -81,17 +73,17 @@ private:
81 */ 73 */
82 virtual int play_start(); 74 virtual int play_start();
83 virtual int play_checking(); 75 virtual int play_checking();
84 - virtual int play_stop(); 76 + virtual int play_stop(int& duration_delta, int& bytes_delta);
85 /** 77 /**
86 * publish check/test, publishing bandwidth kbps. 78 * publish check/test, publishing bandwidth kbps.
87 */ 79 */
88 - virtual int publish_start();  
89 - virtual int publish_checking(); 80 + virtual int publish_start(int& duration_ms);
  81 + virtual int publish_checking(int duration_ms, int play_kbps);
90 virtual int publish_stop(); 82 virtual int publish_stop();
91 /** 83 /**
92 * report and final packet 84 * report and final packet
93 */ 85 */
94 - virtual int finial(); 86 + virtual int final(SrsBandwidthPacket** ppkt);
95 }; 87 };
96 88
97 #endif 89 #endif
@@ -260,6 +260,42 @@ int srs_connect_app(srs_rtmp_t rtmp) @@ -260,6 +260,42 @@ int srs_connect_app(srs_rtmp_t rtmp)
260 return ret; 260 return ret;
261 } 261 }
262 262
  263 +int srs_connect_app2(srs_rtmp_t rtmp,
  264 + char srs_server_ip[128],char srs_server[128], char srs_primary_authors[128],
  265 + char srs_version[32], int* srs_id, int* srs_pid
  266 +) {
  267 + srs_server_ip[0] = 0;
  268 + srs_server[0] = 0;
  269 + srs_primary_authors[0] = 0;
  270 + srs_version[0] = 0;
  271 + *srs_id = 0;
  272 + *srs_pid = 0;
  273 +
  274 + int ret = ERROR_SUCCESS;
  275 +
  276 + srs_assert(rtmp != NULL);
  277 + Context* context = (Context*)rtmp;
  278 +
  279 + string tcUrl = srs_generate_tc_url(
  280 + context->ip, context->vhost, context->app, context->port,
  281 + context->param
  282 + );
  283 +
  284 + std::string sip, sserver, sauthors, sversion;
  285 +
  286 + if ((ret = context->rtmp->connect_app2(context->app, tcUrl, NULL,
  287 + sip, sserver, sauthors, sversion, *srs_id, *srs_pid)) != ERROR_SUCCESS) {
  288 + return ret;
  289 + }
  290 +
  291 + snprintf(srs_server_ip, 128, "%s", sip.c_str());
  292 + snprintf(srs_server, 128, "%s", sserver.c_str());
  293 + snprintf(srs_primary_authors, 128, "%s", sauthors.c_str());
  294 + snprintf(srs_version, 32, "%s", sversion.c_str());
  295 +
  296 + return ret;
  297 +}
  298 +
263 int srs_play_stream(srs_rtmp_t rtmp) 299 int srs_play_stream(srs_rtmp_t rtmp)
264 { 300 {
265 int ret = ERROR_SUCCESS; 301 int ret = ERROR_SUCCESS;
@@ -309,19 +345,11 @@ const char* srs_type2string(int type) @@ -309,19 +345,11 @@ const char* srs_type2string(int type)
309 } 345 }
310 346
311 int srs_bandwidth_check(srs_rtmp_t rtmp, 347 int srs_bandwidth_check(srs_rtmp_t rtmp,
312 - char srs_server[128], char srs_primary_authors[128],  
313 - char srs_id[64], char srs_pid[64], char srs_server_ip[128],  
314 int64_t* start_time, int64_t* end_time, 348 int64_t* start_time, int64_t* end_time,
315 int* play_kbps, int* publish_kbps, 349 int* play_kbps, int* publish_kbps,
316 int* play_bytes, int* publish_bytes, 350 int* play_bytes, int* publish_bytes,
317 int* play_duration, int* publish_duration 351 int* play_duration, int* publish_duration
318 ) { 352 ) {
319 - srs_server[0] = 0;  
320 - srs_primary_authors[0] = 0;  
321 - srs_id[0] = 0;  
322 - srs_pid[0] = 0;  
323 - srs_server_ip[0] = 0;  
324 -  
325 *start_time = 0; 353 *start_time = 0;
326 *end_time = 0; 354 *end_time = 0;
327 *play_kbps = 0; 355 *play_kbps = 0;
@@ -343,8 +371,6 @@ int srs_bandwidth_check(srs_rtmp_t rtmp, @@ -343,8 +371,6 @@ int srs_bandwidth_check(srs_rtmp_t rtmp,
343 } 371 }
344 372
345 if ((ret = client.bandwidth_check( 373 if ((ret = client.bandwidth_check(
346 - srs_server, srs_primary_authors,  
347 - srs_id, srs_pid, srs_server_ip,  
348 start_time, end_time, play_kbps, publish_kbps, 374 start_time, end_time, play_kbps, publish_kbps,
349 play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS 375 play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS
350 ) { 376 ) {
@@ -102,6 +102,22 @@ int __srs_do_simple_handshake(srs_rtmp_t rtmp); @@ -102,6 +102,22 @@ int __srs_do_simple_handshake(srs_rtmp_t rtmp);
102 int srs_connect_app(srs_rtmp_t rtmp); 102 int srs_connect_app(srs_rtmp_t rtmp);
103 103
104 /** 104 /**
  105 +* connect to server, get the debug srs info.
  106 +*
  107 +* SRS debug info:
  108 +* @param srs_server_ip, 128bytes, debug info, server ip client connected at.
  109 +* @param srs_server, 128bytes, server info.
  110 +* @param srs_primary_authors, 128bytes, primary authors.
  111 +* @param srs_version, 32bytes, server version.
  112 +* @param srs_id, int, debug info, client id in server log.
  113 +* @param srs_pid, int, debug info, server pid in log.
  114 +*/
  115 +int srs_connect_app2(srs_rtmp_t rtmp,
  116 + char srs_server_ip[128], char srs_server[128], char srs_primary_authors[128],
  117 + char srs_version[32], int* srs_id, int* srs_pid
  118 +);
  119 +
  120 +/**
105 * play a live/vod stream. 121 * play a live/vod stream.
106 * category: play 122 * category: play
107 * previous: connect-app 123 * previous: connect-app
@@ -122,13 +138,6 @@ int srs_publish_stream(srs_rtmp_t rtmp); @@ -122,13 +138,6 @@ int srs_publish_stream(srs_rtmp_t rtmp);
122 /** 138 /**
123 * do bandwidth check with srs server. 139 * do bandwidth check with srs server.
124 * 140 *
125 -* SRS debug info:  
126 -* @param srs_server, 128bytes, server info.  
127 -* @param srs_primary_authors, 128bytes, primary authors.  
128 -* @param srs_id, 64bytes, debug info, client id in server log.  
129 -* @param srs_pid, 64bytes, debug info, server pid in log.  
130 -* @param srs_server_ip, 128bytes, debug info, server ip client connected at.  
131 -*  
132 * bandwidth info: 141 * bandwidth info:
133 * @param start_time, output the start time, in ms. 142 * @param start_time, output the start time, in ms.
134 * @param end_time, output the end time, in ms. 143 * @param end_time, output the end time, in ms.
@@ -140,8 +149,6 @@ int srs_publish_stream(srs_rtmp_t rtmp); @@ -140,8 +149,6 @@ int srs_publish_stream(srs_rtmp_t rtmp);
140 * @param publish_duration, output the publish/upload test duration, in ms. 149 * @param publish_duration, output the publish/upload test duration, in ms.
141 */ 150 */
142 int srs_bandwidth_check(srs_rtmp_t rtmp, 151 int srs_bandwidth_check(srs_rtmp_t rtmp,
143 - char srs_server[128], char srs_primary_authors[128],  
144 - char srs_id[64], char srs_pid[64], char srs_server_ip[128],  
145 int64_t* start_time, int64_t* end_time, 152 int64_t* start_time, int64_t* end_time,
146 int* play_kbps, int* publish_kbps, 153 int* play_kbps, int* publish_kbps,
147 int* play_bytes, int* publish_bytes, 154 int* play_bytes, int* publish_bytes,
@@ -438,6 +438,25 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req) @@ -438,6 +438,25 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req)
438 { 438 {
439 int ret = ERROR_SUCCESS; 439 int ret = ERROR_SUCCESS;
440 440
  441 + std::string srs_server_ip;
  442 + std::string srs_server;
  443 + std::string srs_primary_authors;
  444 + std::string srs_version;
  445 + int srs_id = 0;
  446 + int srs_pid = 0;
  447 +
  448 + return connect_app2(app, tc_url, req,
  449 + srs_server_ip, srs_server, srs_primary_authors,
  450 + srs_version, srs_id, srs_pid);
  451 +}
  452 +
  453 +int SrsRtmpClient::connect_app2(
  454 + string app, string tc_url, SrsRequest* req,
  455 + string& srs_server_ip, string& srs_server, string& srs_primary_authors,
  456 + string& srs_version, int& srs_id, int& srs_pid
  457 +){
  458 + int ret = ERROR_SUCCESS;
  459 +
441 // Connect(vhost, app) 460 // Connect(vhost, app)
442 if (true) { 461 if (true) {
443 SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); 462 SrsConnectAppPacket* pkt = new SrsConnectAppPacket();
@@ -492,22 +511,23 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req) @@ -492,22 +511,23 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req)
492 SrsAutoFree(SrsConnectAppResPacket, pkt); 511 SrsAutoFree(SrsConnectAppResPacket, pkt);
493 512
494 // server info 513 // server info
495 - std::string srs_version;  
496 - std::string srs_server_ip;  
497 - int srs_id = 0;  
498 - int srs_pid = 0;  
499 -  
500 SrsAmf0Any* data = pkt->info->get_property("data"); 514 SrsAmf0Any* data = pkt->info->get_property("data");
501 if (data && data->is_ecma_array()) { 515 if (data && data->is_ecma_array()) {
502 SrsAmf0EcmaArray* arr = data->to_ecma_array(); 516 SrsAmf0EcmaArray* arr = data->to_ecma_array();
503 517
504 SrsAmf0Any* prop = NULL; 518 SrsAmf0Any* prop = NULL;
  519 + if ((prop = arr->ensure_property_string("srs_primary_authors")) != NULL) {
  520 + srs_primary_authors = prop->to_str();
  521 + }
505 if ((prop = arr->ensure_property_string("srs_version")) != NULL) { 522 if ((prop = arr->ensure_property_string("srs_version")) != NULL) {
506 srs_version = prop->to_str(); 523 srs_version = prop->to_str();
507 } 524 }
508 if ((prop = arr->ensure_property_string("srs_server_ip")) != NULL) { 525 if ((prop = arr->ensure_property_string("srs_server_ip")) != NULL) {
509 srs_server_ip = prop->to_str(); 526 srs_server_ip = prop->to_str();
510 } 527 }
  528 + if ((prop = arr->ensure_property_string("srs_server")) != NULL) {
  529 + srs_server = prop->to_str();
  530 + }
511 if ((prop = arr->ensure_property_number("srs_id")) != NULL) { 531 if ((prop = arr->ensure_property_number("srs_id")) != NULL) {
512 srs_id = (int)prop->to_number(); 532 srs_id = (int)prop->to_number();
513 } 533 }
@@ -249,6 +249,25 @@ public: @@ -249,6 +249,25 @@ public:
249 */ 249 */
250 virtual int connect_app(std::string app, std::string tc_url, SrsRequest* req=NULL); 250 virtual int connect_app(std::string app, std::string tc_url, SrsRequest* req=NULL);
251 /** 251 /**
  252 + * connect to server, get the debug srs info.
  253 + *
  254 + * @param app, the app to connect at.
  255 + * @param tc_url, the tcUrl to connect at.
  256 + * @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore.
  257 + *
  258 + * SRS debug info:
  259 + * @param srs_server_ip, debug info, server ip client connected at.
  260 + * @param srs_server, server info.
  261 + * @param srs_primary_authors, primary authors.
  262 + * @param srs_id, int, debug info, client id in server log.
  263 + * @param srs_pid, int, debug info, server pid in log.
  264 + */
  265 + virtual int connect_app2(
  266 + std::string app, std::string tc_url, SrsRequest* req,
  267 + std::string& srs_server_ip, std::string& srs_server, std::string& srs_primary_authors,
  268 + std::string& srs_version, int& srs_id, int& srs_pid
  269 + );
  270 + /**
252 * create a stream, then play/publish data over this stream. 271 * create a stream, then play/publish data over this stream.
253 */ 272 */
254 virtual int create_stream(int& stream_id); 273 virtual int create_stream(int& stream_id);
@@ -3199,21 +3199,28 @@ int SrsBandwidthPacket::decode(SrsStream *stream) @@ -3199,21 +3199,28 @@ int SrsBandwidthPacket::decode(SrsStream *stream)
3199 int ret = ERROR_SUCCESS; 3199 int ret = ERROR_SUCCESS;
3200 3200
3201 if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { 3201 if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) {
3202 - srs_error("amf0 decode play command_name failed. ret=%d", ret); 3202 + srs_error("amf0 decode bwtc command_name failed. ret=%d", ret);
3203 return ret; 3203 return ret;
3204 } 3204 }
3205 3205
3206 if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { 3206 if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) {
3207 - srs_error("amf0 decode play transaction_id failed. ret=%d", ret); 3207 + srs_error("amf0 decode bwtc transaction_id failed. ret=%d", ret);
3208 return ret; 3208 return ret;
3209 } 3209 }
3210 3210
3211 if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { 3211 if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) {
3212 - srs_error("amf0 decode play command_object failed. ret=%d", ret); 3212 + srs_error("amf0 decode bwtc command_object failed. ret=%d", ret);
3213 return ret; 3213 return ret;
3214 } 3214 }
3215 3215
3216 // @remark, for bandwidth test, ignore the data field. 3216 // @remark, for bandwidth test, ignore the data field.
  3217 + // only decode the stop-play, start-publish and finish packet.
  3218 + if (is_stop_play() || is_start_publish() || is_finish()) {
  3219 + if ((ret = data->read(stream)) != ERROR_SUCCESS) {
  3220 + srs_error("amf0 decode bwtc command_object failed. ret=%d", ret);
  3221 + return ret;
  3222 + }
  3223 + }
3217 3224
3218 srs_info("decode SrsBandwidthPacket success."); 3225 srs_info("decode SrsBandwidthPacket success.");
3219 3226
@@ -3343,6 +3350,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_play() @@ -3343,6 +3350,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_play()
3343 return pkt->set_command(SRS_BW_CHECK_STOP_PLAY); 3350 return pkt->set_command(SRS_BW_CHECK_STOP_PLAY);
3344 } 3351 }
3345 3352
  3353 +SrsBandwidthPacket* SrsBandwidthPacket::create_stopped_play()
  3354 +{
  3355 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
  3356 + return pkt->set_command(SRS_BW_CHECK_STOPPED_PLAY);
  3357 +}
  3358 +
3346 SrsBandwidthPacket* SrsBandwidthPacket::create_start_publish() 3359 SrsBandwidthPacket* SrsBandwidthPacket::create_start_publish()
3347 { 3360 {
3348 SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); 3361 SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
@@ -3367,6 +3380,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_publish() @@ -3367,6 +3380,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_publish()
3367 return pkt->set_command(SRS_BW_CHECK_STOP_PUBLISH); 3380 return pkt->set_command(SRS_BW_CHECK_STOP_PUBLISH);
3368 } 3381 }
3369 3382
  3383 +SrsBandwidthPacket* SrsBandwidthPacket::create_stopped_publish()
  3384 +{
  3385 + SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
  3386 + return pkt->set_command(SRS_BW_CHECK_STOPPED_PUBLISH);
  3387 +}
  3388 +
3370 SrsBandwidthPacket* SrsBandwidthPacket::create_finish() 3389 SrsBandwidthPacket* SrsBandwidthPacket::create_finish()
3371 { 3390 {
3372 SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); 3391 SrsBandwidthPacket* pkt = new SrsBandwidthPacket();
@@ -1244,10 +1244,12 @@ public: @@ -1244,10 +1244,12 @@ public:
1244 static SrsBandwidthPacket* create_starting_play(); 1244 static SrsBandwidthPacket* create_starting_play();
1245 static SrsBandwidthPacket* create_playing(); 1245 static SrsBandwidthPacket* create_playing();
1246 static SrsBandwidthPacket* create_stop_play(); 1246 static SrsBandwidthPacket* create_stop_play();
  1247 + static SrsBandwidthPacket* create_stopped_play();
1247 static SrsBandwidthPacket* create_start_publish(); 1248 static SrsBandwidthPacket* create_start_publish();
1248 static SrsBandwidthPacket* create_starting_publish(); 1249 static SrsBandwidthPacket* create_starting_publish();
1249 static SrsBandwidthPacket* create_publishing(); 1250 static SrsBandwidthPacket* create_publishing();
1250 static SrsBandwidthPacket* create_stop_publish(); 1251 static SrsBandwidthPacket* create_stop_publish();
  1252 + static SrsBandwidthPacket* create_stopped_publish();
1251 static SrsBandwidthPacket* create_finish(); 1253 static SrsBandwidthPacket* create_finish();
1252 static SrsBandwidthPacket* create_final(); 1254 static SrsBandwidthPacket* create_final();
1253 private: 1255 private: