mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
use librtmp to implemnts the bandwidth linux tool. 0.9.158
This commit is contained in:
parent
cc62d254f0
commit
9135aa117c
13 changed files with 371 additions and 81 deletions
|
@ -23,11 +23,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include <srs_lib_bandwidth.hpp>
|
||||
|
||||
#include <sstream>
|
||||
using namespace std;
|
||||
|
||||
#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>
|
||||
#include <srs_protocol_amf0.hpp>
|
||||
|
||||
/**
|
||||
* 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<SrsBandwidthPacket>(&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.");
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <srs_core.hpp>
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
) {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue