From 9135aa117c58df8a5e609edd2166c19c2ebfca14 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 13 Jul 2014 19:16:18 +0800 Subject: [PATCH] use librtmp to implemnts the bandwidth linux tool. 0.9.158 --- trunk/research/librtmp/srs_bandwidth_check.c | 57 ++++-- trunk/src/app/srs_app_bandwidth.cpp | 26 ++- trunk/src/app/srs_app_bandwidth.hpp | 5 +- trunk/src/core/srs_core.hpp | 2 +- trunk/src/kernel/srs_kernel_error.hpp | 1 + trunk/src/libs/srs_lib_bandwidth.cpp | 196 +++++++++++++++++-- trunk/src/libs/srs_lib_bandwidth.hpp | 18 +- trunk/src/libs/srs_librtmp.cpp | 46 ++++- trunk/src/libs/srs_librtmp.hpp | 25 ++- trunk/src/rtmp/srs_protocol_rtmp.cpp | 30 ++- trunk/src/rtmp/srs_protocol_rtmp.hpp | 19 ++ trunk/src/rtmp/srs_protocol_stack.cpp | 25 ++- trunk/src/rtmp/srs_protocol_stack.hpp | 2 + 13 files changed, 371 insertions(+), 81 deletions(-) diff --git a/trunk/research/librtmp/srs_bandwidth_check.c b/trunk/research/librtmp/srs_bandwidth_check.c index 223048a29..20e0ee1e9 100644 --- a/trunk/research/librtmp/srs_bandwidth_check.c +++ b/trunk/research/librtmp/srs_bandwidth_check.c @@ -40,16 +40,27 @@ int main(int argc, char** argv) char* data; // srs debug info. + char srs_server_ip[128]; char srs_server[128]; char srs_primary_authors[128]; - char srs_id[64]; - char srs_pid[64]; - char srs_server_ip[128]; + char srs_version[32]; + int srs_id = 0; + int srs_pid = 0; // bandwidth test data. - int64_t start_time, end_time; - int play_kbps, publish_kbps; - int play_bytes, publish_bytes; - int play_duration, publish_duration; + int64_t start_time = 0; + int64_t end_time = 0; + int play_kbps = 0; + int publish_kbps = 0; + int play_bytes = 0; + int publish_bytes = 0; + int play_duration = 0; + int publish_duration = 0; + + // set to zero. + srs_server_ip[0] = 0; + srs_server[0] = 0; + srs_primary_authors[0] = 0; + srs_version[0] = 0; if (argc <= 1) { printf("RTMP bandwidth check/test with server.\n" @@ -57,8 +68,9 @@ int main(int argc, char** argv) " rtmp_url RTMP bandwidth url to check. format: rtmp://server:port/app?key=xxx&&vhost=xxx\n" "For example:\n" " %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com\n" + " %s rtmp://127.0.0.1:1935/app?key=35c9b402c12a7246868752e2878f7e0e,vhost=bandcheck.srs.com>/dev/null\n" "@remark, output text to stdout, while json to stderr.\n", - argv[0], argv[0]); + argv[0], argv[0], argv[0]); ret = 1; exit(ret); return ret; @@ -77,15 +89,14 @@ int main(int argc, char** argv) } printf("simple handshake success\n"); - if ((ret = srs_connect_app(rtmp)) != 0) { + if ((ret = srs_connect_app2(rtmp, + srs_server_ip, srs_server, srs_primary_authors, srs_version, &srs_id, &srs_pid)) != 0) { printf("connect vhost/app failed.\n"); goto rtmp_destroy; } printf("connect vhost/app success\n"); if ((ret = srs_bandwidth_check(rtmp, - srs_server, srs_primary_authors, - srs_id, srs_pid, srs_server_ip, &start_time, &end_time, &play_kbps, &publish_kbps, &play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0 ) { @@ -95,12 +106,12 @@ int main(int argc, char** argv) printf("bandwidth check/test success\n"); printf("\n%s, %s\n" - "%s, srs_pid=%s, srs_id=%s\n" + "%s, %s, srs_pid=%d, srs_id=%d\n" "duration: %dms(%d+%d)\n" "play: %dkbps\n" "publish: %dkbps\n\n", (char*)srs_server, (char*)srs_primary_authors, - (char*)srs_server_ip, (char*)srs_pid, (char*)srs_id, + (char*)srs_server_ip, (char*)srs_version, srs_pid, srs_id, (int)(end_time - start_time), play_duration, publish_duration, play_kbps, publish_kbps); @@ -108,6 +119,24 @@ int main(int argc, char** argv) rtmp_destroy: srs_rtmp_destroy(rtmp); - printf("terminate with ret=%d\n", ret); + printf("terminate with ret=%d\n\n", ret); + + fprintf(stderr, "{\"code\":%d," + "\"srs_server\":\"%s\", " + "\"srs_primary_authors\":\"%s\", " + "\"srs_server_ip\":\"%s\", " + "\"srs_version\":\"%s\", " + "\"srs_pid\":%d, " + "\"srs_id\":%d, " + "\"duration\":%d, " + "\"play_duration\":%d, " + "\"play_kbps\":%d, " + "\"publish_kbps\":%d" + "}", + ret, + (char*)srs_server, (char*)srs_primary_authors, + (char*)srs_server_ip, (char*)srs_version, srs_pid, srs_id, + (int)(end_time - start_time), play_duration, publish_duration, + play_kbps, publish_kbps); return ret; } diff --git a/trunk/src/app/srs_app_bandwidth.cpp b/trunk/src/app/srs_app_bandwidth.cpp index 4c55d0619..c196df835 100644 --- a/trunk/src/app/srs_app_bandwidth.cpp +++ b/trunk/src/app/srs_app_bandwidth.cpp @@ -100,7 +100,7 @@ int _srs_expect_bandwidth_packet(SrsRtmpServer* rtmp, _CheckPacketType pfn) } SrsAutoFree(SrsMessage, msg); SrsAutoFree(SrsBandwidthPacket, pkt); - srs_info("get final message success."); + srs_info("get bwtc message success."); if (pfn(pkt)) { return ret; @@ -147,6 +147,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io static int64_t last_check_time = 0; int interval_ms = _srs_config->get_bw_check_interval_ms(_req->vhost); + srs_update_system_time_ms(); int64_t time_now = srs_get_system_time_ms(); // reject the connection in the interval window. if (last_check_time > 0 && time_now - last_check_time < interval_ms) { @@ -185,10 +186,11 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) SrsBandwidthSample publish_sample; // timeout for a packet. - _rtmp->set_send_timeout(play_sample.duration_ms * 1000); - _rtmp->set_recv_timeout(publish_sample.duration_ms * 1000); + _rtmp->set_send_timeout(play_sample.duration_ms * 1000 * 2); + _rtmp->set_recv_timeout(publish_sample.duration_ms * 1000 * 2); // start test. + srs_update_system_time_ms(); int64_t start_time = srs_get_system_time_ms(); // sample play @@ -228,6 +230,7 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) srs_info("stop publish test. kbps=%d", publish_sample.kbps); // stop test. + srs_update_system_time_ms(); int64_t end_time = srs_get_system_time_ms(); srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", @@ -279,6 +282,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) memset(random_data, 'A', size); int data_count = 1; + srs_update_system_time_ms(); int64_t starttime = srs_get_system_time_ms(); while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { st_usleep(sample->interval_ms); @@ -302,6 +306,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) limit->send_limit(); } + srs_update_system_time_ms(); sample->calc_kbps(_rtmp->get_send_bytes(), srs_get_system_time_ms() - starttime); srs_info("BW check send play bytes over."); @@ -367,19 +372,26 @@ int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* lim int ret = ERROR_SUCCESS; // recv publish msgs until @duration_ms ms + srs_update_system_time_ms(); int64_t starttime = srs_get_system_time_ms(); while ((srs_get_system_time_ms() - starttime) < sample->duration_ms) { - st_usleep(sample->interval_ms); - SrsMessage* msg = NULL; - if ((ret = _rtmp->recv_message(&msg)) != ERROR_SUCCESS) { - srs_error("recv message failed. ret=%d", ret); + SrsBandwidthPacket* pkt = NULL; + if ((ret = _rtmp->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { return ret; } SrsAutoFree(SrsMessage, msg); + SrsAutoFree(SrsBandwidthPacket, pkt); + srs_info("get publish message success."); + + // client requires to stop. + if (pkt->is_stop_publish()) { + break; + } limit->recv_limit(); } + srs_update_system_time_ms(); sample->calc_kbps(_rtmp->get_recv_bytes(), srs_get_system_time_ms() - starttime); srs_info("BW check recv publish data over."); diff --git a/trunk/src/app/srs_app_bandwidth.hpp b/trunk/src/app/srs_app_bandwidth.hpp index 2ac99d5ec..ae1a884d1 100644 --- a/trunk/src/app/srs_app_bandwidth.hpp +++ b/trunk/src/app/srs_app_bandwidth.hpp @@ -102,7 +102,7 @@ public: * | | * | <-call(start publish) | onSrsBandCheckStartPublishBytes * | result(publishing)--> | onSrsBandCheckStartingPublishBytes -* | data(publishing)----> | onSrsBandCheckStartingPublishBytes +* | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes * | <--call(stop publish) | onSrsBandCheckStopPublishBytes * | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes * | | @@ -114,6 +114,9 @@ public: * for the flash client queue is fullfill with other packets. * 2. when flash client, server never wait the final packet, * for the flash client directly close when got report packet. +* 3. for linux client, it will send the publish data then send a stop publish, +* for the linux client donot know when to stop the publish. +* when server got publishing and stop publish, stop publish. */ class SrsBandwidth { diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index f74066b6c..dd20685fe 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "157" +#define VERSION_REVISION "158" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "SRS" diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 3fcb6b452..06a427998 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -86,6 +86,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_RTMP_EDGE_RELOAD 323 // aggregate message parse failed. #define ERROR_RTMP_AGGREGATE 324 +#define ERROR_RTMP_BWTC_DATA 325 #define ERROR_SYSTEM_PACKET_INVALID 401 #define ERROR_SYSTEM_CLIENT_INVALID 402 diff --git a/trunk/src/libs/srs_lib_bandwidth.cpp b/trunk/src/libs/srs_lib_bandwidth.cpp index 8c00ad253..b1ae8119a 100644 --- a/trunk/src/libs/srs_lib_bandwidth.cpp +++ b/trunk/src/libs/srs_lib_bandwidth.cpp @@ -23,11 +23,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include +#include +using namespace std; + #include #include #include #include #include +#include /** * recv bandwidth helper. @@ -45,6 +49,10 @@ bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt) { return pkt->is_start_publish(); } +bool _bandwidth_is_stop_publish(SrsBandwidthPacket* pkt) +{ + return pkt->is_stop_publish(); +} bool _bandwidth_is_finish(SrsBandwidthPacket* pkt) { return pkt->is_finish(); @@ -70,6 +78,29 @@ int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn) return ret; } +int _srs_expect_bandwidth_packet2(SrsRtmpClient* rtmp, _CheckPacketType pfn, SrsBandwidthPacket** ppkt) +{ + int ret = ERROR_SUCCESS; + + while (true) { + SrsMessage* msg = NULL; + SrsBandwidthPacket* pkt = NULL; + if ((ret = rtmp->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { + return ret; + } + SrsAutoFree(SrsMessage, msg); + srs_info("get final message success."); + + if (pfn(pkt)) { + *ppkt = pkt; + return ret; + } + + srs_freep(pkt); + } + + return ret; +} SrsBandwidthClient::SrsBandwidthClient() { @@ -88,8 +119,6 @@ int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp) } int SrsBandwidthClient::bandwidth_check( - char srs_server[128], char srs_primary_authors[128], - char srs_id[64], char srs_pid[64], char srs_server_ip[128], int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, @@ -97,30 +126,72 @@ int SrsBandwidthClient::bandwidth_check( ) { int ret = ERROR_SUCCESS; + srs_update_system_time_ms(); *start_time = srs_get_system_time_ms(); // play + int duration_delta = 0; + int bytes_delta = 0; if ((ret = play_start()) != ERROR_SUCCESS) { return ret; } if ((ret = play_checking()) != ERROR_SUCCESS) { return ret; } - if ((ret = play_stop()) != ERROR_SUCCESS) { + if ((ret = play_stop(duration_delta, bytes_delta)) != ERROR_SUCCESS) { return ret; } + // play kbps used to refer for publish + int actual_play_kbps = 0; + if (duration_delta > 0) { + actual_play_kbps = bytes_delta * 8 / duration_delta; + } + // max publish kbps, we set to 1.2*play_kbps: + actual_play_kbps = (int)(actual_play_kbps * 1.2); + // publish - if ((ret = publish_start()) != ERROR_SUCCESS) { + int duration_ms = 0; + if ((ret = publish_start(duration_ms)) != ERROR_SUCCESS) { return ret; } - if ((ret = publish_checking()) != ERROR_SUCCESS) { + if ((ret = publish_checking(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) { return ret; } if ((ret = publish_stop()) != ERROR_SUCCESS) { return ret; } + + SrsBandwidthPacket* pkt = NULL; + if ((ret = final(&pkt)) != ERROR_SUCCESS) { + return ret; + } + SrsAutoFree(SrsBandwidthPacket, pkt); + + // get data + if (true ) { + SrsAmf0Any* prop = NULL; + if ((prop = pkt->data->ensure_property_number("play_kbps")) != NULL) { + *play_kbps = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("publish_kbps")) != NULL) { + *publish_kbps = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("play_bytes")) != NULL) { + *play_bytes = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("publish_bytes")) != NULL) { + *publish_bytes = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("play_time")) != NULL) { + *play_duration = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("publish_time")) != NULL) { + *publish_duration = (int)prop->to_number(); + } + } + srs_update_system_time_ms(); *end_time = srs_get_system_time_ms(); return ret; @@ -155,18 +226,30 @@ int SrsBandwidthClient::play_checking() return ret; } -int SrsBandwidthClient::play_stop() +int SrsBandwidthClient::play_stop(int& duration_delta, int& bytes_delta) { int ret = ERROR_SUCCESS; - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) { - return ret; + if (true) { + SrsBandwidthPacket* pkt = NULL; + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_stop_play, &pkt)) != ERROR_SUCCESS) { + return ret; + } + SrsAutoFree(SrsBandwidthPacket, pkt); + + SrsAmf0Any* prop = NULL; + if ((prop = pkt->data->ensure_property_number("duration_delta")) != NULL) { + duration_delta = (int)prop->to_number(); + } + if ((prop = pkt->data->ensure_property_number("bytes_delta")) != NULL) { + bytes_delta = (int)prop->to_number(); + } } srs_info("BW check recv play stop request."); if (true) { // send stop play response to server. - SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play(); + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play(); if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop play message failed. ret=%d", ret); @@ -178,12 +261,21 @@ int SrsBandwidthClient::play_stop() return ret; } -int SrsBandwidthClient::publish_start() +int SrsBandwidthClient::publish_start(int& duration_ms) { int ret = ERROR_SUCCESS; - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) { - return ret; + if (true) { + SrsBandwidthPacket* pkt = NULL; + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) { + return ret; + } + SrsAutoFree(SrsBandwidthPacket, pkt); + + SrsAmf0Any* prop = NULL; + if ((prop = pkt->data->ensure_property_number("duration_ms")) != NULL) { + duration_ms = (int)prop->to_number(); + } } srs_info("BW check recv publish begin request."); @@ -201,24 +293,89 @@ int SrsBandwidthClient::publish_start() return ret; } -int SrsBandwidthClient::publish_checking() +int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) { int ret = ERROR_SUCCESS; + + if (duration_ms <= 0) { + ret = ERROR_RTMP_BWTC_DATA; + srs_error("server must specifies the duration, ret=%d", ret); + return ret; + } + + if (play_kbps <= 0) { + ret = ERROR_RTMP_BWTC_DATA; + srs_error("server must specifies the play kbp, ret=%d", ret); + return ret; + } + + // send play data to client + int size = 1024; // TODO: FIXME: magic number + char random_data[size]; + memset(random_data, 'A', size); + + int data_count = 1; + srs_update_system_time_ms(); + int64_t starttime = srs_get_system_time_ms(); + while ((srs_get_system_time_ms() - starttime) < duration_ms) { + // TODO: FIXME: use shared ptr message. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing(); + + // TODO: FIXME: magic number + for (int i = 0; i < data_count; ++i) { + std::stringstream seq; + seq << i; + std::string play_data = "SRS band check data from server's publishing......"; + pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str())); + } + data_count += 2; + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check publish messages failed. ret=%d", ret); + return ret; + } + + // use the play kbps to control the publish + srs_update_system_time_ms(); + int elaps = srs_get_system_time_ms() - starttime; + if (elaps > 0) { + int current_kbps = _rtmp->get_send_bytes() * 8 / elaps; + while (current_kbps > play_kbps) { + srs_update_system_time_ms(); + elaps = srs_get_system_time_ms() - starttime; + current_kbps = _rtmp->get_send_bytes() * 8 / elaps; + usleep(100 * 1000); // TODO: FIXME: magic number. + } + } + } + srs_info("BW check send publish bytes over."); + return ret; } int SrsBandwidthClient::publish_stop() { int ret = ERROR_SUCCESS; + + if (true) { + // send start publish response to server. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish(); + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check stop publish message failed. ret=%d", ret); + return ret; + } + } + srs_info("BW client stop publish request."); - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) { + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) { return ret; } srs_info("BW check recv publish stop request."); if (true) { // send start publish response to server. - SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish(); + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish(); if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop publish message failed. ret=%d", ret); @@ -230,12 +387,15 @@ int SrsBandwidthClient::publish_stop() return ret; } -int SrsBandwidthClient::finial() +int SrsBandwidthClient::final(SrsBandwidthPacket** ppkt) { int ret = ERROR_SUCCESS; - if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_finish)) != ERROR_SUCCESS) { - return ret; + if (true) { + SrsBandwidthPacket* pkt = NULL; + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) { + return ret; + } } srs_info("BW check recv finish/report request."); diff --git a/trunk/src/libs/srs_lib_bandwidth.hpp b/trunk/src/libs/srs_lib_bandwidth.hpp index 1fa7fcfa3..0d86df5a4 100644 --- a/trunk/src/libs/srs_lib_bandwidth.hpp +++ b/trunk/src/libs/srs_lib_bandwidth.hpp @@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include class SrsRtmpClient; +class SrsBandwidthPacket; /** * bandwith client library for srs-librtmp. @@ -50,13 +51,6 @@ public: /** * do bandwidth check. * - * SRS debug info: - * @param srs_server, 128bytes, server info. - * @param srs_primary_authors, 128bytes, primary authors. - * @param srs_id, 64bytes, debug info, client id in server log. - * @param srs_pid, 64bytes, debug info, server pid in log. - * @param srs_server_ip, 128bytes, debug info, server ip client connected at. - * * bandwidth info: * @param start_time, output the start time, in ms. * @param end_time, output the end time, in ms. @@ -68,8 +62,6 @@ public: * @param publish_duration, output the publish/upload test duration, in ms. */ virtual int bandwidth_check( - char srs_server[128], char srs_primary_authors[128], - char srs_id[64], char srs_pid[64], char srs_server_ip[128], int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, @@ -81,17 +73,17 @@ private: */ virtual int play_start(); virtual int play_checking(); - virtual int play_stop(); + virtual int play_stop(int& duration_delta, int& bytes_delta); /** * publish check/test, publishing bandwidth kbps. */ - virtual int publish_start(); - virtual int publish_checking(); + virtual int publish_start(int& duration_ms); + virtual int publish_checking(int duration_ms, int play_kbps); virtual int publish_stop(); /** * report and final packet */ - virtual int finial(); + virtual int final(SrsBandwidthPacket** ppkt); }; #endif diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 291e4fcc6..fa7f76736 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -260,6 +260,42 @@ int srs_connect_app(srs_rtmp_t rtmp) return ret; } +int srs_connect_app2(srs_rtmp_t rtmp, + char srs_server_ip[128],char srs_server[128], char srs_primary_authors[128], + char srs_version[32], int* srs_id, int* srs_pid +) { + srs_server_ip[0] = 0; + srs_server[0] = 0; + srs_primary_authors[0] = 0; + srs_version[0] = 0; + *srs_id = 0; + *srs_pid = 0; + + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + string tcUrl = srs_generate_tc_url( + context->ip, context->vhost, context->app, context->port, + context->param + ); + + std::string sip, sserver, sauthors, sversion; + + if ((ret = context->rtmp->connect_app2(context->app, tcUrl, NULL, + sip, sserver, sauthors, sversion, *srs_id, *srs_pid)) != ERROR_SUCCESS) { + return ret; + } + + snprintf(srs_server_ip, 128, "%s", sip.c_str()); + snprintf(srs_server, 128, "%s", sserver.c_str()); + snprintf(srs_primary_authors, 128, "%s", sauthors.c_str()); + snprintf(srs_version, 32, "%s", sversion.c_str()); + + return ret; +} + int srs_play_stream(srs_rtmp_t rtmp) { int ret = ERROR_SUCCESS; @@ -309,19 +345,11 @@ const char* srs_type2string(int type) } int srs_bandwidth_check(srs_rtmp_t rtmp, - char srs_server[128], char srs_primary_authors[128], - char srs_id[64], char srs_pid[64], char srs_server_ip[128], int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, int* play_duration, int* publish_duration ) { - srs_server[0] = 0; - srs_primary_authors[0] = 0; - srs_id[0] = 0; - srs_pid[0] = 0; - srs_server_ip[0] = 0; - *start_time = 0; *end_time = 0; *play_kbps = 0; @@ -343,8 +371,6 @@ int srs_bandwidth_check(srs_rtmp_t rtmp, } if ((ret = client.bandwidth_check( - srs_server, srs_primary_authors, - srs_id, srs_pid, srs_server_ip, start_time, end_time, play_kbps, publish_kbps, play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS ) { diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index 086403a38..35186cd1d 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -101,6 +101,22 @@ int __srs_do_simple_handshake(srs_rtmp_t rtmp); */ int srs_connect_app(srs_rtmp_t rtmp); +/** +* connect to server, get the debug srs info. +* +* SRS debug info: +* @param srs_server_ip, 128bytes, debug info, server ip client connected at. +* @param srs_server, 128bytes, server info. +* @param srs_primary_authors, 128bytes, primary authors. +* @param srs_version, 32bytes, server version. +* @param srs_id, int, debug info, client id in server log. +* @param srs_pid, int, debug info, server pid in log. +*/ +int srs_connect_app2(srs_rtmp_t rtmp, + char srs_server_ip[128], char srs_server[128], char srs_primary_authors[128], + char srs_version[32], int* srs_id, int* srs_pid +); + /** * play a live/vod stream. * category: play @@ -122,13 +138,6 @@ int srs_publish_stream(srs_rtmp_t rtmp); /** * do bandwidth check with srs server. * -* SRS debug info: -* @param srs_server, 128bytes, server info. -* @param srs_primary_authors, 128bytes, primary authors. -* @param srs_id, 64bytes, debug info, client id in server log. -* @param srs_pid, 64bytes, debug info, server pid in log. -* @param srs_server_ip, 128bytes, debug info, server ip client connected at. -* * bandwidth info: * @param start_time, output the start time, in ms. * @param end_time, output the end time, in ms. @@ -140,8 +149,6 @@ int srs_publish_stream(srs_rtmp_t rtmp); * @param publish_duration, output the publish/upload test duration, in ms. */ int srs_bandwidth_check(srs_rtmp_t rtmp, - char srs_server[128], char srs_primary_authors[128], - char srs_id[64], char srs_pid[64], char srs_server_ip[128], int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, diff --git a/trunk/src/rtmp/srs_protocol_rtmp.cpp b/trunk/src/rtmp/srs_protocol_rtmp.cpp index 90363fc0a..40a006f35 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.cpp @@ -438,6 +438,25 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req) { int ret = ERROR_SUCCESS; + std::string srs_server_ip; + std::string srs_server; + std::string srs_primary_authors; + std::string srs_version; + int srs_id = 0; + int srs_pid = 0; + + return connect_app2(app, tc_url, req, + srs_server_ip, srs_server, srs_primary_authors, + srs_version, srs_id, srs_pid); +} + +int SrsRtmpClient::connect_app2( + string app, string tc_url, SrsRequest* req, + string& srs_server_ip, string& srs_server, string& srs_primary_authors, + string& srs_version, int& srs_id, int& srs_pid +){ + int ret = ERROR_SUCCESS; + // Connect(vhost, app) if (true) { SrsConnectAppPacket* pkt = new SrsConnectAppPacket(); @@ -492,22 +511,23 @@ int SrsRtmpClient::connect_app(string app, string tc_url, SrsRequest* req) SrsAutoFree(SrsConnectAppResPacket, pkt); // server info - std::string srs_version; - std::string srs_server_ip; - int srs_id = 0; - int srs_pid = 0; - SrsAmf0Any* data = pkt->info->get_property("data"); if (data && data->is_ecma_array()) { SrsAmf0EcmaArray* arr = data->to_ecma_array(); SrsAmf0Any* prop = NULL; + if ((prop = arr->ensure_property_string("srs_primary_authors")) != NULL) { + srs_primary_authors = prop->to_str(); + } if ((prop = arr->ensure_property_string("srs_version")) != NULL) { srs_version = prop->to_str(); } if ((prop = arr->ensure_property_string("srs_server_ip")) != NULL) { srs_server_ip = prop->to_str(); } + if ((prop = arr->ensure_property_string("srs_server")) != NULL) { + srs_server = prop->to_str(); + } if ((prop = arr->ensure_property_number("srs_id")) != NULL) { srs_id = (int)prop->to_number(); } diff --git a/trunk/src/rtmp/srs_protocol_rtmp.hpp b/trunk/src/rtmp/srs_protocol_rtmp.hpp index 2e907bcc1..f00e1dcc9 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.hpp @@ -249,6 +249,25 @@ public: */ virtual int connect_app(std::string app, std::string tc_url, SrsRequest* req=NULL); /** + * connect to server, get the debug srs info. + * + * @param app, the app to connect at. + * @param tc_url, the tcUrl to connect at. + * @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore. + * + * SRS debug info: + * @param srs_server_ip, debug info, server ip client connected at. + * @param srs_server, server info. + * @param srs_primary_authors, primary authors. + * @param srs_id, int, debug info, client id in server log. + * @param srs_pid, int, debug info, server pid in log. + */ + virtual int connect_app2( + std::string app, std::string tc_url, SrsRequest* req, + std::string& srs_server_ip, std::string& srs_server, std::string& srs_primary_authors, + std::string& srs_version, int& srs_id, int& srs_pid + ); + /** * create a stream, then play/publish data over this stream. */ virtual int create_stream(int& stream_id); diff --git a/trunk/src/rtmp/srs_protocol_stack.cpp b/trunk/src/rtmp/srs_protocol_stack.cpp index 118757a50..5070a2635 100644 --- a/trunk/src/rtmp/srs_protocol_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_stack.cpp @@ -3199,21 +3199,28 @@ int SrsBandwidthPacket::decode(SrsStream *stream) int ret = ERROR_SUCCESS; if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { - srs_error("amf0 decode play command_name failed. ret=%d", ret); + srs_error("amf0 decode bwtc command_name failed. ret=%d", ret); return ret; } if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { - srs_error("amf0 decode play transaction_id failed. ret=%d", ret); + srs_error("amf0 decode bwtc transaction_id failed. ret=%d", ret); return ret; } if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { - srs_error("amf0 decode play command_object failed. ret=%d", ret); + srs_error("amf0 decode bwtc command_object failed. ret=%d", ret); return ret; } // @remark, for bandwidth test, ignore the data field. + // only decode the stop-play, start-publish and finish packet. + if (is_stop_play() || is_start_publish() || is_finish()) { + if ((ret = data->read(stream)) != ERROR_SUCCESS) { + srs_error("amf0 decode bwtc command_object failed. ret=%d", ret); + return ret; + } + } srs_info("decode SrsBandwidthPacket success."); @@ -3343,6 +3350,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_play() return pkt->set_command(SRS_BW_CHECK_STOP_PLAY); } +SrsBandwidthPacket* SrsBandwidthPacket::create_stopped_play() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_STOPPED_PLAY); +} + SrsBandwidthPacket* SrsBandwidthPacket::create_start_publish() { SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); @@ -3367,6 +3380,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_stop_publish() return pkt->set_command(SRS_BW_CHECK_STOP_PUBLISH); } +SrsBandwidthPacket* SrsBandwidthPacket::create_stopped_publish() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_STOPPED_PUBLISH); +} + SrsBandwidthPacket* SrsBandwidthPacket::create_finish() { SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); diff --git a/trunk/src/rtmp/srs_protocol_stack.hpp b/trunk/src/rtmp/srs_protocol_stack.hpp index a235032e0..73665fc1b 100644 --- a/trunk/src/rtmp/srs_protocol_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_stack.hpp @@ -1244,10 +1244,12 @@ public: static SrsBandwidthPacket* create_starting_play(); static SrsBandwidthPacket* create_playing(); static SrsBandwidthPacket* create_stop_play(); + static SrsBandwidthPacket* create_stopped_play(); static SrsBandwidthPacket* create_start_publish(); static SrsBandwidthPacket* create_starting_publish(); static SrsBandwidthPacket* create_publishing(); static SrsBandwidthPacket* create_stop_publish(); + static SrsBandwidthPacket* create_stopped_publish(); static SrsBandwidthPacket* create_finish(); static SrsBandwidthPacket* create_final(); private: