mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
add librtmp bandwidth check/test client.
This commit is contained in:
parent
cf7a48e3da
commit
cc62d254f0
20 changed files with 725 additions and 87 deletions
254
trunk/src/libs/srs_lib_bandwidth.cpp
Normal file
254
trunk/src/libs/srs_lib_bandwidth.cpp
Normal file
|
@ -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 <srs_lib_bandwidth.hpp>
|
||||
|
||||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_protocol_stack.hpp>
|
||||
#include <srs_protocol_rtmp.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
|
||||
/**
|
||||
* 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<SrsBandwidthPacket>(&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;
|
||||
}
|
97
trunk/src/libs/srs_lib_bandwidth.hpp
Normal file
97
trunk/src/libs/srs_lib_bandwidth.hpp
Normal file
|
@ -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 <srs_lib_bandwidth.hpp>
|
||||
*/
|
||||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
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
|
|
@ -42,6 +42,7 @@ using namespace std;
|
|||
#include <srs_kernel_flv.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue