From cc62d254f0c480d605edfa3499c747a248cd2595 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 13 Jul 2014 16:10:06 +0800 Subject: [PATCH] add librtmp bandwidth check/test client. --- trunk/auto/depends.sh | 6 +- trunk/configure | 2 +- trunk/research/librtmp/Makefile | 9 +- trunk/research/librtmp/srs_bandwidth_check.c | 113 ++++++++ .../players/srs_bwt/release/srs_bwt.swf | Bin 6460 -> 6481 bytes .../players/srs_bwt/src/SrsBandwidth.as | 3 +- trunk/src/app/srs_app_bandwidth.cpp | 14 +- trunk/src/app/srs_app_forward.cpp | 3 +- trunk/src/libs/srs_lib_bandwidth.cpp | 254 ++++++++++++++++++ trunk/src/libs/srs_lib_bandwidth.hpp | 97 +++++++ trunk/src/libs/srs_librtmp.cpp | 103 ++++--- trunk/src/libs/srs_librtmp.hpp | 41 +++ trunk/src/rtmp/srs_protocol_rtmp.cpp | 5 +- trunk/src/rtmp/srs_protocol_rtmp.hpp | 7 + trunk/src/rtmp/srs_protocol_stack.cpp | 72 ++++- trunk/src/rtmp/srs_protocol_stack.hpp | 13 +- trunk/src/rtmp/srs_protocol_utility.cpp | 18 +- trunk/src/rtmp/srs_protocol_utility.hpp | 11 +- trunk/src/srs/srs.upp | 3 + trunk/src/utest/srs_utest_protocol.cpp | 38 +-- 20 files changed, 725 insertions(+), 87 deletions(-) mode change 100644 => 100755 trunk/research/librtmp/Makefile create mode 100644 trunk/research/librtmp/srs_bandwidth_check.c create mode 100644 trunk/src/libs/srs_lib_bandwidth.cpp create mode 100644 trunk/src/libs/srs_lib_bandwidth.hpp diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index 0fd5997bd..614e0ee4b 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -561,7 +561,7 @@ else fi ##################################################################################### -# build research code +# build research code, librtmp ##################################################################################### if [ $SRS_RESEARCH = YES ]; then mkdir -p ${SRS_OBJS}/research @@ -571,6 +571,10 @@ if [ $SRS_RESEARCH = YES ]; then (cd research/ffempty && make ${SRS_JOBS} && mv ffempty ../../${SRS_OBJS}/research) ret=$?; if [[ $ret -ne 0 ]]; then echo "build research/ffempty failed, ret=$ret"; exit $ret; fi +fi + +if [ $SRS_LIBRTMP = YES ]; then + mkdir -p ${SRS_OBJS}/research # librtmp (cd research/librtmp && mkdir -p objs && ln -sf `pwd`/objs ../../${SRS_OBJS}/research/librtmp) diff --git a/trunk/configure b/trunk/configure index ed85ce46d..89a5e2506 100755 --- a/trunk/configure +++ b/trunk/configure @@ -483,7 +483,7 @@ APP_OBJS="${MODULE_OBJS[@]}" MODULE_ID="LIBS" MODULE_DEPENDS=("CORE" "KERNEL" "RTMP") ModuleLibIncs=(${SRS_OBJS}) -MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket") +MODULE_FILES=("srs_librtmp" "srs_lib_simple_socket" "srs_lib_bandwidth") LIBS_INCS="src/libs"; MODULE_DIR=${LIBS_INCS} . auto/modules.sh LIBS_OBJS="${MODULE_OBJS[@]}" # diff --git a/trunk/research/librtmp/Makefile b/trunk/research/librtmp/Makefile old mode 100644 new mode 100755 index 6002b139f..aeac262e5 --- a/trunk/research/librtmp/Makefile +++ b/trunk/research/librtmp/Makefile @@ -3,7 +3,10 @@ GCC = gcc ifeq ($(HANDSHAKE),) ST_ALL = help else - ST_ALL = objs/srs_flv_parser objs/srs_flv_injecter objs/srs_publish objs/srs_play objs/srs_ingest_flv objs/srs_ingest_rtmp objs/srs_detect_rtmp + ST_ALL = objs/srs_flv_parser \ + objs/srs_flv_injecter objs/srs_publish objs/srs_play \ + objs/srs_ingest_flv objs/srs_ingest_rtmp objs/srs_detect_rtmp \ + objs/srs_bandwidth_check endif .PHONY: default clean help ssl nossl @@ -24,6 +27,7 @@ help: @echo " srs_ingest_flv ingest flv file and publish to RTMP server." @echo " srs_ingest_rtmp ingest RTMP and publish to RTMP server." @echo " srs_detect_rtmp detect RTMP stream info." + @echo " srs_bandwidth_check bandwidth check/test tool." @echo "Remark: about simple/complex handshake, see: http://blog.csdn.net/win_lin/article/details/13006803" @echo "Remark: srs Makefile will auto invoke this by --with/without-ssl, " @echo " that is, if user specified ssl(by --with-ssl), srs will make this by 'make ssl'" @@ -88,3 +92,6 @@ objs/srs_ingest_rtmp: srs_ingest_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $( objs/srs_detect_rtmp: srs_detect_rtmp.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(GCC) srs_detect_rtmp.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_detect_rtmp + +objs/srs_bandwidth_check: srs_bandwidth_check.c $(SRS_RESEARCH_DEPS) $(SRS_LIBRTMP_I) $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) + $(GCC) srs_bandwidth_check.c $(SRS_LIBRTMP_L) $(SRS_LIBSSL_L) $(EXTRA_CXX_FLAG) -o objs/srs_bandwidth_check diff --git a/trunk/research/librtmp/srs_bandwidth_check.c b/trunk/research/librtmp/srs_bandwidth_check.c new file mode 100644 index 000000000..223048a29 --- /dev/null +++ b/trunk/research/librtmp/srs_bandwidth_check.c @@ -0,0 +1,113 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +/** +gcc srs_bandwidth_check.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_bandwidth_check +*/ + +#include +#include + +#include "../../objs/include/srs_librtmp.h" + +int main(int argc, char** argv) +{ + int ret = 0; + srs_rtmp_t rtmp; + + // packet data + int type, size; + u_int32_t timestamp = 0; + char* data; + + // srs debug info. + char srs_server[128]; + char srs_primary_authors[128]; + char srs_id[64]; + char srs_pid[64]; + char srs_server_ip[128]; + // bandwidth test data. + int64_t start_time, end_time; + int play_kbps, publish_kbps; + int play_bytes, publish_bytes; + int play_duration, publish_duration; + + if (argc <= 1) { + printf("RTMP bandwidth check/test with server.\n" + "Usage: %s \n" + " 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" + "@remark, output text to stdout, while json to stderr.\n", + argv[0], argv[0]); + ret = 1; + exit(ret); + return ret; + } + + rtmp = srs_rtmp_create2(argv[1]); + + printf("RTMP bandwidth check/test with server.\n"); + printf("srs(simple-rtmp-server) client librtmp library.\n"); + printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); + printf("bandwidth check/test url: %s\n", argv[1]); + + if ((ret = srs_simple_handshake(rtmp)) != 0) { + printf("simple handshake failed.\n"); + goto rtmp_destroy; + } + printf("simple handshake success\n"); + + if ((ret = srs_connect_app(rtmp)) != 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 + ) { + printf("bandwidth check/test failed.\n"); + goto rtmp_destroy; + } + printf("bandwidth check/test success\n"); + + printf("\n%s, %s\n" + "%s, srs_pid=%s, srs_id=%s\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, + (int)(end_time - start_time), play_duration, publish_duration, + play_kbps, + publish_kbps); + +rtmp_destroy: + srs_rtmp_destroy(rtmp); + + printf("terminate with ret=%d\n", ret); + return ret; +} diff --git a/trunk/research/players/srs_bwt/release/srs_bwt.swf b/trunk/research/players/srs_bwt/release/srs_bwt.swf index 3376abed054b5eba5232fb0a9b6efec786dc73f5..e0c6cd423e8416c589959fb35c1cf139292ce94c 100755 GIT binary patch literal 6481 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 literal 6460 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 W3uF$M6jjXrAJ$EHdH5f`uZLwr@X7=L diff --git a/trunk/research/players/srs_bwt/src/SrsBandwidth.as b/trunk/research/players/srs_bwt/src/SrsBandwidth.as index c0862ae13..e09e55ffc 100755 --- a/trunk/research/players/srs_bwt/src/SrsBandwidth.as +++ b/trunk/research/players/srs_bwt/src/SrsBandwidth.as @@ -429,8 +429,7 @@ package publish_timeout_handler = 0; } } - private function onSrsBandCheckFinished(evt:Object):void{ - var code:Number = evt.code; + private function onSrsBandCheckFinished(evt:Object):void{ var start_time:Number = evt.start_time; var end_time:Number = evt.end_time; var play_kbps:Number = evt.play_kbps; diff --git a/trunk/src/app/srs_app_bandwidth.cpp b/trunk/src/app/srs_app_bandwidth.cpp index 11f0569cb..4c55d0619 100644 --- a/trunk/src/app/srs_app_bandwidth.cpp +++ b/trunk/src/app/srs_app_bandwidth.cpp @@ -68,9 +68,9 @@ void SrsBandwidthSample::calc_kbps(int _bytes, int _duration) * recv bandwidth helper. */ typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); -bool _bandwidth_is_flash_final(SrsBandwidthPacket* pkt) +bool _bandwidth_is_final(SrsBandwidthPacket* pkt) { - return pkt->is_flash_final(); + return pkt->is_final(); } bool _bandwidth_is_starting_play(SrsBandwidthPacket* pkt) { @@ -183,7 +183,12 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) SrsBandwidthSample play_sample; 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); + // start test. int64_t start_time = srs_get_system_time_ms(); // sample play @@ -254,7 +259,7 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) return ret; } } - srs_info("BW check begin."); + srs_info("BW check play begin."); if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != ERROR_SUCCESS) { return ret; @@ -424,7 +429,6 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu // flash client will close connection when got this packet, // for the publish queue may contains packets. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_finish(); - pkt->data->set("code", SrsAmf0Any::number(ERROR_SUCCESS)); pkt->data->set("start_time", SrsAmf0Any::number(start_time)); pkt->data->set("end_time", SrsAmf0Any::number(end_time)); pkt->data->set("play_kbps", SrsAmf0Any::number(play_sample.kbps)); @@ -445,7 +449,7 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu bool is_flash = (_req->swfUrl != ""); if (!is_flash) { // ignore any error. - _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_flash_final); + _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_final); srs_info("BW check recv flash final response."); } diff --git a/trunk/src/app/srs_app_forward.cpp b/trunk/src/app/srs_app_forward.cpp index 1bd20fa97..7e80f1710 100644 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -97,11 +97,10 @@ int SrsForwarder::on_publish(SrsRequest* req, std::string forward_server) } // discovery vhost std::string vhost = req->vhost; - srs_vhost_resolve(vhost, s_port); port = ::atoi(s_port.c_str()); // generate tcUrl - tc_url = srs_generate_tc_url(forward_server, vhost, req->app, s_port); + tc_url = srs_generate_tc_url(forward_server, vhost, req->app, s_port, req->param); // dead loop check std::string source_ep = "rtmp://"; diff --git a/trunk/src/libs/srs_lib_bandwidth.cpp b/trunk/src/libs/srs_lib_bandwidth.cpp new file mode 100644 index 000000000..8c00ad253 --- /dev/null +++ b/trunk/src/libs/srs_lib_bandwidth.cpp @@ -0,0 +1,254 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include +#include +#include +#include +#include + +/** +* recv bandwidth helper. +*/ +typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); +bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt) +{ + return pkt->is_start_play(); +} +bool _bandwidth_is_stop_play(SrsBandwidthPacket* pkt) +{ + return pkt->is_stop_play(); +} +bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt) +{ + return pkt->is_start_publish(); +} +bool _bandwidth_is_finish(SrsBandwidthPacket* pkt) +{ + return pkt->is_finish(); +} +int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn) +{ + 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); + SrsAutoFree(SrsBandwidthPacket, pkt); + srs_info("get final message success."); + + if (pfn(pkt)) { + return ret; + } + } + + return ret; +} + +SrsBandwidthClient::SrsBandwidthClient() +{ + _rtmp = NULL; +} + +SrsBandwidthClient::~SrsBandwidthClient() +{ +} + +int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp) +{ + _rtmp = rtmp; + + return ERROR_SUCCESS; +} + +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, + int* play_duration, int* publish_duration +) { + int ret = ERROR_SUCCESS; + + *start_time = srs_get_system_time_ms(); + + // play + if ((ret = play_start()) != ERROR_SUCCESS) { + return ret; + } + if ((ret = play_checking()) != ERROR_SUCCESS) { + return ret; + } + if ((ret = play_stop()) != ERROR_SUCCESS) { + return ret; + } + + // publish + if ((ret = publish_start()) != ERROR_SUCCESS) { + return ret; + } + if ((ret = publish_checking()) != ERROR_SUCCESS) { + return ret; + } + if ((ret = publish_stop()) != ERROR_SUCCESS) { + return ret; + } + + *end_time = srs_get_system_time_ms(); + + return ret; +} + +int SrsBandwidthClient::play_start() +{ + int ret = ERROR_SUCCESS; + + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) { + return ret; + } + srs_info("BW check recv play begin request."); + + if (true) { + // send start play response to server. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play(); + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check start play message failed. ret=%d", ret); + return ret; + } + } + srs_info("BW check play begin."); + + return ret; +} + +int SrsBandwidthClient::play_checking() +{ + int ret = ERROR_SUCCESS; + return ret; +} + +int SrsBandwidthClient::play_stop() +{ + int ret = ERROR_SUCCESS; + + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) { + return ret; + } + srs_info("BW check recv play stop request."); + + if (true) { + // send stop play response to server. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play(); + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check stop play message failed. ret=%d", ret); + return ret; + } + } + srs_info("BW check play stop."); + + return ret; +} + +int SrsBandwidthClient::publish_start() +{ + int ret = ERROR_SUCCESS; + + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_publish)) != ERROR_SUCCESS) { + return ret; + } + srs_info("BW check recv publish begin request."); + + if (true) { + // send start publish response to server. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish(); + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check start publish message failed. ret=%d", ret); + return ret; + } + } + srs_info("BW check publish begin."); + + return ret; +} + +int SrsBandwidthClient::publish_checking() +{ + int ret = ERROR_SUCCESS; + return ret; +} + +int SrsBandwidthClient::publish_stop() +{ + int ret = ERROR_SUCCESS; + + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_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(); + + 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 check publish stop."); + + return ret; +} + +int SrsBandwidthClient::finial() +{ + int ret = ERROR_SUCCESS; + + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_finish)) != ERROR_SUCCESS) { + return ret; + } + srs_info("BW check recv finish/report request."); + + if (true) { + // send final response to server. + SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final(); + + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { + srs_error("send bandwidth check final message failed. ret=%d", ret); + return ret; + } + } + srs_info("BW check final."); + + return ret; +} diff --git a/trunk/src/libs/srs_lib_bandwidth.hpp b/trunk/src/libs/srs_lib_bandwidth.hpp new file mode 100644 index 000000000..1fa7fcfa3 --- /dev/null +++ b/trunk/src/libs/srs_lib_bandwidth.hpp @@ -0,0 +1,97 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2014 winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_LIB_BANDWIDTH_HPP +#define SRS_LIB_BANDWIDTH_HPP + +/* +#include +*/ + +#include + +class SrsRtmpClient; + +/** +* bandwith client library for srs-librtmp. +*/ +class SrsBandwidthClient +{ +private: + SrsRtmpClient* _rtmp; +public: + SrsBandwidthClient(); + virtual ~SrsBandwidthClient(); +public: + /** + * initialize the bandwidth check client. + */ + virtual int initialize(SrsRtmpClient* rtmp); + /** + * 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. + * @param play_kbps, output the play/download kbps. + * @param publish_kbps, output the publish/upload kbps. + * @param play_bytes, output the play/download bytes. + * @param publish_bytes, output the publish/upload bytes. + * @param play_duration, output the play/download test duration, in ms. + * @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, + int* play_duration, int* publish_duration + ); +private: + /** + * play check/test, downloading bandwidth kbps. + */ + virtual int play_start(); + virtual int play_checking(); + virtual int play_stop(); + /** + * publish check/test, publishing bandwidth kbps. + */ + virtual int publish_start(); + virtual int publish_checking(); + virtual int publish_stop(); + /** + * report and final packet + */ + virtual int finial(); +}; + +#endif diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 7cbac9a7c..291e4fcc6 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -42,6 +42,7 @@ using namespace std; #include #include #include +#include // if user want to define log, define the folowing macro. #ifndef SRS_RTMP_USER_DEFINED_LOG @@ -63,6 +64,7 @@ struct Context std::string vhost; std::string app; std::string stream; + std::string param; SrsRtmpClient* rtmp; SimpleSocketStream* skt; @@ -91,39 +93,11 @@ int srs_librtmp_context_parse_uri(Context* context) context->stream = uri.substr(pos + 1); context->tcUrl = uri = uri.substr(0, pos); } - // schema - if ((pos = uri.find("rtmp://")) != string::npos) { - uri = uri.substr(pos + 7); - } - // host/vhost/port - if ((pos = uri.find(":")) != string::npos) { - context->vhost = context->host = uri.substr(0, pos); - uri = uri.substr(pos + 1); - - if ((pos = uri.find("/")) != string::npos) { - context->port = uri.substr(0, pos); - uri = uri.substr(pos + 1); - } - } else { - if ((pos = uri.find("/")) != string::npos) { - context->vhost = context->host = uri.substr(0, pos); - uri = uri.substr(pos + 1); - } - context->port = RTMP_DEFAULT_PORT; - } - // app - context->app = uri; - // query of app - if ((pos = uri.find("?")) != string::npos) { - context->app = uri.substr(0, pos); - string query = uri.substr(pos + 1); - if ((pos = query.find("vhost=")) != string::npos) { - context->vhost = query.substr(pos + 6); - if ((pos = context->vhost.find("&")) != string::npos) { - context->vhost = context->vhost.substr(pos); - } - } - } + + std::string schema; + srs_discovery_tc_url(context->tcUrl, + schema, context->host, context->vhost, context->app, context->port, + context->param); return ret; } @@ -176,6 +150,18 @@ srs_rtmp_t srs_rtmp_create(const char* url) return context; } +srs_rtmp_t srs_rtmp_create2(const char* url) +{ + Context* context = new Context(); + + // use url as tcUrl. + context->url = url; + // auto append stream. + context->url += "/livestream"; + + return context; +} + void srs_rtmp_destroy(srs_rtmp_t rtmp) { srs_assert(rtmp != NULL); @@ -263,7 +249,10 @@ int srs_connect_app(srs_rtmp_t rtmp) srs_assert(rtmp != NULL); Context* context = (Context*)rtmp; - string tcUrl = srs_generate_tc_url(context->ip, context->vhost, context->app, context->port); + string tcUrl = srs_generate_tc_url( + context->ip, context->vhost, context->app, context->port, + context->param + ); if ((ret = context->rtmp->connect_app(context->app, tcUrl)) != ERROR_SUCCESS) { return ret; } @@ -319,6 +308,52 @@ const char* srs_type2string(int type) return unknown; } +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; + *publish_kbps = 0; + *play_bytes = 0; + *publish_bytes = 0; + *play_duration = 0; + *publish_duration = 0; + + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + SrsBandwidthClient client; + + if ((ret = client.initialize(context->rtmp)) != ERROR_SUCCESS) { + return ret; + } + + 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 + ) { + return ret; + } + + return ret; +} + int srs_read_packet(srs_rtmp_t rtmp, int* type, u_int32_t* timestamp, char** data, int* size) { *type = 0; diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index b3c02c90f..086403a38 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -52,6 +52,18 @@ typedef void* srs_rtmp_t; * @return a rtmp handler, or NULL if error occured. */ srs_rtmp_t srs_rtmp_create(const char* url); +/** +* create rtmp with url, used for connection specified application. +* @param url the tcUrl, for exmple: +* rtmp://127.0.0.1/live +* @remark this is used to create application connection-oriented, +* for example, the bandwidth client used this, no stream specified. +*/ +srs_rtmp_t srs_rtmp_create2(const char* url); +/** +* close and destroy the rtmp stack. +* @remark, user should use the rtmp again. +*/ void srs_rtmp_destroy(srs_rtmp_t rtmp); /** @@ -107,6 +119,35 @@ int srs_play_stream(srs_rtmp_t rtmp); */ 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. +* @param play_kbps, output the play/download kbps. +* @param publish_kbps, output the publish/upload kbps. +* @param play_bytes, output the play/download bytes. +* @param publish_bytes, output the publish/upload bytes. +* @param play_duration, output the play/download test duration, in ms. +* @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, + int* play_duration, int* publish_duration +); + /** * E.4.1 FLV Tag, page 75 */ diff --git a/trunk/src/rtmp/srs_protocol_rtmp.cpp b/trunk/src/rtmp/srs_protocol_rtmp.cpp index fc717ee63..90363fc0a 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.cpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.cpp @@ -95,6 +95,7 @@ SrsRequest* SrsRequest::copy() cp->pageUrl = pageUrl; cp->host = host; cp->port = port; + cp->param = param; cp->schema = schema; cp->stream = stream; cp->swfUrl = swfUrl; @@ -823,7 +824,9 @@ int SrsRtmpServer::connect_app(SrsRequest* req) srs_info("get connect app message params success."); - srs_discovery_tc_url(req->tcUrl, req->schema, req->host, req->vhost, req->app, req->port); + srs_discovery_tc_url(req->tcUrl, + req->schema, req->host, req->vhost, req->app, req->port, + req->param); req->strip(); return ret; diff --git a/trunk/src/rtmp/srs_protocol_rtmp.hpp b/trunk/src/rtmp/srs_protocol_rtmp.hpp index 4c31dd583..2e907bcc1 100644 --- a/trunk/src/rtmp/srs_protocol_rtmp.hpp +++ b/trunk/src/rtmp/srs_protocol_rtmp.hpp @@ -67,10 +67,17 @@ public: public: // discovery from tcUrl and play/publish. std::string schema; + // the vhost in tcUrl. std::string vhost; + // the host in tcUrl. std::string host; + // the port in tcUrl. std::string port; + // the app in tcUrl, without param. std::string app; + // the param in tcUrl(app). + std::string param; + // the stream in play/publish std::string stream; // for play live stream, // used to specified the stop when exceed the duration. diff --git a/trunk/src/rtmp/srs_protocol_stack.cpp b/trunk/src/rtmp/srs_protocol_stack.cpp index 62b87d6a8..118757a50 100644 --- a/trunk/src/rtmp/srs_protocol_stack.cpp +++ b/trunk/src/rtmp/srs_protocol_stack.cpp @@ -232,17 +232,16 @@ messages. #define SRS_BW_CHECK_START_PUBLISH "onSrsBandCheckStartPublishBytes" #define SRS_BW_CHECK_STARTING_PUBLISH "onSrsBandCheckStartingPublishBytes" #define SRS_BW_CHECK_STOP_PUBLISH "onSrsBandCheckStopPublishBytes" +// @remark, flash never send out this packet, for its queue is full. #define SRS_BW_CHECK_STOPPED_PUBLISH "onSrsBandCheckStoppedPublishBytes" // EOF control. +// the report packet when check finished. #define SRS_BW_CHECK_FINISHED "onSrsBandCheckFinished" -// for flash, it will sendout a final call, -// used to confirm got the report. -// actually, client send out this packet and close the connection, -// so server may cannot got this packet, ignore is ok. -#define SRS_BW_CHECK_FLASH_FINAL "finalClientPacket" +// @remark, flash never send out this packet, for its queue is full. +#define SRS_BW_CHECK_FINAL "finalClientPacket" -// client only +// data packets #define SRS_BW_CHECK_PLAYING "onSrsBandCheckPlaying" #define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" @@ -688,7 +687,7 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsStream* stream, || command == SRS_BW_CHECK_STOP_PLAY || command == SRS_BW_CHECK_STOP_PUBLISH || command == SRS_BW_CHECK_STOPPED_PUBLISH - || command == SRS_BW_CHECK_FLASH_FINAL) + || command == SRS_BW_CHECK_FINAL) { srs_info("decode the AMF0/AMF3 band width check message."); *ppacket = packet = new SrsBandwidthPacket(); @@ -3270,35 +3269,54 @@ int SrsBandwidthPacket::encode_packet(SrsStream* stream) return ret; } +bool SrsBandwidthPacket::is_start_play() +{ + return command_name == SRS_BW_CHECK_START_PLAY; +} + bool SrsBandwidthPacket::is_starting_play() { return command_name == SRS_BW_CHECK_STARTING_PLAY; } +bool SrsBandwidthPacket::is_stop_play() +{ + return command_name == SRS_BW_CHECK_STOP_PLAY; +} + bool SrsBandwidthPacket::is_stopped_play() { return command_name == SRS_BW_CHECK_STOPPED_PLAY; } +bool SrsBandwidthPacket::is_start_publish() +{ + return command_name == SRS_BW_CHECK_START_PUBLISH; +} + bool SrsBandwidthPacket::is_starting_publish() { return command_name == SRS_BW_CHECK_STARTING_PUBLISH; } +bool SrsBandwidthPacket::is_stop_publish() +{ + return command_name == SRS_BW_CHECK_STOP_PUBLISH; +} + bool SrsBandwidthPacket::is_stopped_publish() { return command_name == SRS_BW_CHECK_STOPPED_PUBLISH; } -bool SrsBandwidthPacket::is_flash_final() +bool SrsBandwidthPacket::is_finish() { - return command_name == SRS_BW_CHECK_FLASH_FINAL; + return command_name == SRS_BW_CHECK_FINISHED; } -SrsBandwidthPacket* SrsBandwidthPacket::create_finish() +bool SrsBandwidthPacket::is_final() { - SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); - return pkt->set_command(SRS_BW_CHECK_FINISHED); + return command_name == SRS_BW_CHECK_FINAL; } SrsBandwidthPacket* SrsBandwidthPacket::create_start_play() @@ -3307,6 +3325,12 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_start_play() return pkt->set_command(SRS_BW_CHECK_START_PLAY); } +SrsBandwidthPacket* SrsBandwidthPacket::create_starting_play() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_STARTING_PLAY); +} + SrsBandwidthPacket* SrsBandwidthPacket::create_playing() { SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); @@ -3325,12 +3349,36 @@ SrsBandwidthPacket* SrsBandwidthPacket::create_start_publish() return pkt->set_command(SRS_BW_CHECK_START_PUBLISH); } +SrsBandwidthPacket* SrsBandwidthPacket::create_starting_publish() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_STARTING_PUBLISH); +} + +SrsBandwidthPacket* SrsBandwidthPacket::create_publishing() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_PUBLISHING); +} + SrsBandwidthPacket* SrsBandwidthPacket::create_stop_publish() { SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); return pkt->set_command(SRS_BW_CHECK_STOP_PUBLISH); } +SrsBandwidthPacket* SrsBandwidthPacket::create_finish() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_FINISHED); +} + +SrsBandwidthPacket* SrsBandwidthPacket::create_final() +{ + SrsBandwidthPacket* pkt = new SrsBandwidthPacket(); + return pkt->set_command(SRS_BW_CHECK_FINAL); +} + SrsBandwidthPacket* SrsBandwidthPacket::set_command(string command) { command_name = command; diff --git a/trunk/src/rtmp/srs_protocol_stack.hpp b/trunk/src/rtmp/srs_protocol_stack.hpp index adfe81aac..a235032e0 100644 --- a/trunk/src/rtmp/srs_protocol_stack.hpp +++ b/trunk/src/rtmp/srs_protocol_stack.hpp @@ -1230,17 +1230,26 @@ protected: virtual int encode_packet(SrsStream* stream); // help function for bandwidth packet. public: + virtual bool is_start_play(); virtual bool is_starting_play(); + virtual bool is_stop_play(); virtual bool is_stopped_play(); + virtual bool is_start_publish(); virtual bool is_starting_publish(); + virtual bool is_stop_publish(); virtual bool is_stopped_publish(); - virtual bool is_flash_final(); - static SrsBandwidthPacket* create_finish(); + virtual bool is_finish(); + virtual bool is_final(); static SrsBandwidthPacket* create_start_play(); + static SrsBandwidthPacket* create_starting_play(); static SrsBandwidthPacket* create_playing(); static SrsBandwidthPacket* create_stop_play(); static SrsBandwidthPacket* create_start_publish(); + static SrsBandwidthPacket* create_starting_publish(); + static SrsBandwidthPacket* create_publishing(); static SrsBandwidthPacket* create_stop_publish(); + static SrsBandwidthPacket* create_finish(); + static SrsBandwidthPacket* create_final(); private: virtual SrsBandwidthPacket* set_command(std::string command); }; diff --git a/trunk/src/rtmp/srs_protocol_utility.cpp b/trunk/src/rtmp/srs_protocol_utility.cpp index f85c06b57..af850b380 100644 --- a/trunk/src/rtmp/srs_protocol_utility.cpp +++ b/trunk/src/rtmp/srs_protocol_utility.cpp @@ -32,7 +32,7 @@ using namespace std; void srs_discovery_tc_url( string tcUrl, string& schema, string& host, string& vhost, - string& app, string& port + string& app, string& port, std::string& param ) { size_t pos = std::string::npos; std::string url = tcUrl; @@ -58,16 +58,23 @@ void srs_discovery_tc_url( app = url; vhost = host; - srs_vhost_resolve(vhost, app); + srs_vhost_resolve(vhost, app, param); } -void srs_vhost_resolve(string& vhost, string& app) +void srs_vhost_resolve(string& vhost, string& app, string& param) { + // get original param + size_t pos = 0; + if ((pos = app.find("?")) != std::string::npos) { + param = app.substr(pos); + } + + // filter tcUrl + app = srs_string_replace(app, ",", "?"); app = srs_string_replace(app, "...", "?"); app = srs_string_replace(app, "&&", "?"); app = srs_string_replace(app, "=", "?"); - size_t pos = 0; if ((pos = app.find("?")) == std::string::npos) { return; } @@ -106,7 +113,7 @@ void srs_random_generate(char* bytes, int size) } } -string srs_generate_tc_url(string ip, string vhost, string app, string port) +string srs_generate_tc_url(string ip, string vhost, string app, string port, string param) { string tcUrl = "rtmp://"; @@ -123,6 +130,7 @@ string srs_generate_tc_url(string ip, string vhost, string app, string port) tcUrl += "/"; tcUrl += app; + tcUrl += param; return tcUrl; } diff --git a/trunk/src/rtmp/srs_protocol_utility.hpp b/trunk/src/rtmp/srs_protocol_utility.hpp index 5aff42108..38b4e125d 100644 --- a/trunk/src/rtmp/srs_protocol_utility.hpp +++ b/trunk/src/rtmp/srs_protocol_utility.hpp @@ -50,20 +50,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * @param app, for example, live * @param port, for example, 19350 * default to 1935 if not specified. +* param param, for example, vhost=vhost.ossrs.net */ extern void srs_discovery_tc_url( std::string tcUrl, std::string& schema, std::string& host, std::string& vhost, - std::string& app, std::string& port + std::string& app, std::string& port, std::string& param ); /** * resolve the vhost in query string +* @pram vhost, update the vhost if query contains the vhost. * @param app, may contains the vhost in query string format: * app?vhost=request_vhost * app...vhost...request_vhost +* @param param, the query, for example, ?vhost=xxx */ -extern void srs_vhost_resolve(std::string& vhost, std::string& app); +extern void srs_vhost_resolve(std::string& vhost, std::string& app, std::string& param); /** * generate ramdom data for handshake. @@ -72,12 +75,14 @@ extern void srs_random_generate(char* bytes, int size); /** * generate the tcUrl. +* @param param, the app parameters in tcUrl. for example, ?key=xxx,vhost=xxx * @return the tcUrl generated from ip/vhost/app/port. * @remark when vhost equals to __defaultVhost__, use ip as vhost. * @remark ignore port if port equals to default port 1935. */ extern std::string srs_generate_tc_url( - std::string ip, std::string vhost, std::string app, std::string port + std::string ip, std::string vhost, std::string app, std::string port, + std::string param ); /** diff --git a/trunk/src/srs/srs.upp b/trunk/src/srs/srs.upp index a759b5e10..2bb52dfba 100755 --- a/trunk/src/srs/srs.upp +++ b/trunk/src/srs/srs.upp @@ -7,6 +7,8 @@ file libs readonly separator, ..\libs\srs_librtmp.hpp, ..\libs\srs_librtmp.cpp, + ..\libs\srs_lib_bandwidth.hpp, + ..\libs\srs_lib_bandwidth.cpp, ..\libs\srs_lib_simple_socket.hpp, ..\libs\srs_lib_simple_socket.cpp, core readonly separator, @@ -121,6 +123,7 @@ file ..\utest\srs_utest_protocol.hpp, ..\utest\srs_utest_protocol.cpp, research readonly separator, + ..\..\research\librtmp\srs_bandwidth_check.c, ..\..\research\librtmp\srs_detect_rtmp.c, ..\..\research\librtmp\srs_flv_injecter.c, ..\..\research\librtmp\srs_flv_parser.c, diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index ba9421a38..a564864ee 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -429,27 +429,28 @@ VOID TEST(ProtocolUtilityTest, VhostResolve) { std::string vhost = "vhost"; std::string app = "app"; - srs_vhost_resolve(vhost, app); + std::string param; + srs_vhost_resolve(vhost, app, param); EXPECT_STREQ("vhost", vhost.c_str()); EXPECT_STREQ("app", app.c_str()); app = "app?vhost=changed"; - srs_vhost_resolve(vhost, app); + srs_vhost_resolve(vhost, app, param); EXPECT_STREQ("changed", vhost.c_str()); EXPECT_STREQ("app", app.c_str()); app = "app?vhost=changed1&&query=true"; - srs_vhost_resolve(vhost, app); + srs_vhost_resolve(vhost, app, param); EXPECT_STREQ("changed1", vhost.c_str()); EXPECT_STREQ("app", app.c_str()); app = "app?other=true&&vhost=changed2&&query=true"; - srs_vhost_resolve(vhost, app); + srs_vhost_resolve(vhost, app, param); EXPECT_STREQ("changed2", vhost.c_str()); EXPECT_STREQ("app", app.c_str()); app = "app...other...true...vhost...changed3...query...true"; - srs_vhost_resolve(vhost, app); + srs_vhost_resolve(vhost, app, param); EXPECT_STREQ("changed3", vhost.c_str()); EXPECT_STREQ("app", app.c_str()); } @@ -461,10 +462,10 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) { std::string tcUrl; std::string schema; std::string host; std::string vhost; - std::string app; std::string port; + std::string app; std::string port; std::string param; tcUrl = "rtmp://127.0.0.1:1935/live"; - srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port); + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param); EXPECT_STREQ("rtmp", schema.c_str()); EXPECT_STREQ("127.0.0.1", host.c_str()); EXPECT_STREQ("127.0.0.1", vhost.c_str()); @@ -472,7 +473,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) EXPECT_STREQ("1935", port.c_str()); tcUrl = "rtmp://127.0.0.1:19351/live"; - srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port); + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param); EXPECT_STREQ("rtmp", schema.c_str()); EXPECT_STREQ("127.0.0.1", host.c_str()); EXPECT_STREQ("127.0.0.1", vhost.c_str()); @@ -480,7 +481,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) EXPECT_STREQ("19351", port.c_str()); tcUrl = "rtmp://127.0.0.1:19351/live?vhost=demo"; - srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port); + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param); EXPECT_STREQ("rtmp", schema.c_str()); EXPECT_STREQ("127.0.0.1", host.c_str()); EXPECT_STREQ("demo", vhost.c_str()); @@ -488,7 +489,7 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) EXPECT_STREQ("19351", port.c_str()); tcUrl = "rtmp://127.0.0.1:19351/live/show?vhost=demo"; - srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port); + srs_discovery_tc_url(tcUrl, schema, host, vhost, app, port, param); EXPECT_STREQ("rtmp", schema.c_str()); EXPECT_STREQ("127.0.0.1", host.c_str()); EXPECT_STREQ("demo", vhost.c_str()); @@ -501,18 +502,18 @@ VOID TEST(ProtocolUtilityTest, DiscoveryTcUrl) */ VOID TEST(ProtocolUtilityTest, GenerateTcUrl) { - string ip; string vhost; string app; string port; string tcUrl; + string ip; string vhost; string app; string port; string tcUrl; string param; ip = "127.0.0.1"; vhost = "__defaultVhost__"; app = "live"; port = "1935"; - tcUrl = srs_generate_tc_url(ip, vhost, app, port); + tcUrl = srs_generate_tc_url(ip, vhost, app, port, param); EXPECT_STREQ("rtmp://127.0.0.1/live", tcUrl.c_str()); ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "1935"; - tcUrl = srs_generate_tc_url(ip, vhost, app, port); + tcUrl = srs_generate_tc_url(ip, vhost, app, port, param); EXPECT_STREQ("rtmp://demo/live", tcUrl.c_str()); ip = "127.0.0.1"; vhost = "demo"; app = "live"; port = "19351"; - tcUrl = srs_generate_tc_url(ip, vhost, app, port); + tcUrl = srs_generate_tc_url(ip, vhost, app, port, param); EXPECT_STREQ("rtmp://demo:19351/live", tcUrl.c_str()); } @@ -5375,10 +5376,11 @@ VOID TEST(ProtocolStackTest, ProtocolExcpectMessage) VOID TEST(ProtocolRTMPTest, RTMPRequest) { SrsRequest req; + std::string param; req.stream = "livestream"; srs_discovery_tc_url("rtmp://std.ossrs.net/live", - req.schema, req.host, req.vhost, req.app, req.port); + req.schema, req.host, req.vhost, req.app, req.port, param); req.strip(); EXPECT_STREQ("rtmp", req.schema.c_str()); EXPECT_STREQ("std.ossrs.net", req.host.c_str()); @@ -5388,7 +5390,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest) req.stream = "livestream"; srs_discovery_tc_url("rtmp://s td.os srs.n et/li v e", - req.schema, req.host, req.vhost, req.app, req.port); + req.schema, req.host, req.vhost, req.app, req.port, param); req.strip(); EXPECT_STREQ("rtmp", req.schema.c_str()); EXPECT_STREQ("std.ossrs.net", req.host.c_str()); @@ -5398,7 +5400,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest) req.stream = "livestream"; srs_discovery_tc_url("rtmp://s\ntd.o\rssrs.ne\nt/li\nve", - req.schema, req.host, req.vhost, req.app, req.port); + req.schema, req.host, req.vhost, req.app, req.port, param); req.strip(); EXPECT_STREQ("rtmp", req.schema.c_str()); EXPECT_STREQ("std.ossrs.net", req.host.c_str()); @@ -5408,7 +5410,7 @@ VOID TEST(ProtocolRTMPTest, RTMPRequest) req.stream = "livestream"; srs_discovery_tc_url("rtmp://std.ossrs.net/live ", - req.schema, req.host, req.vhost, req.app, req.port); + req.schema, req.host, req.vhost, req.app, req.port, param); req.strip(); EXPECT_STREQ("rtmp", req.schema.c_str()); EXPECT_STREQ("std.ossrs.net", req.host.c_str());