2013-12-22 09:28:29 +00:00
|
|
|
/*
|
|
|
|
The MIT License (MIT)
|
|
|
|
|
2014-01-01 02:37:12 +00:00
|
|
|
Copyright (c) 2013-2014 wenjiegit
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2014-03-02 13:49:09 +00:00
|
|
|
#include <srs_app_bandwidth.hpp>
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
#include <arpa/inet.h>
|
2013-12-27 09:03:12 +00:00
|
|
|
#include <sstream>
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2014-03-01 06:03:02 +00:00
|
|
|
#include <srs_protocol_rtmp.hpp>
|
2014-03-01 02:30:16 +00:00
|
|
|
#include <srs_kernel_error.hpp>
|
2014-03-01 03:24:40 +00:00
|
|
|
#include <srs_protocol_amf0.hpp>
|
2014-07-12 00:47:47 +00:00
|
|
|
#include <srs_protocol_stack.hpp>
|
2014-03-02 13:49:09 +00:00
|
|
|
#include <srs_app_config.hpp>
|
2013-12-22 09:28:29 +00:00
|
|
|
#include <srs_core_autofree.hpp>
|
2014-03-21 09:56:27 +00:00
|
|
|
#include <srs_kernel_utility.hpp>
|
2014-05-27 08:45:02 +00:00
|
|
|
#include <srs_app_utility.hpp>
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
SrsBandwidth::SrsBandwidth()
|
|
|
|
{
|
2014-07-12 07:55:39 +00:00
|
|
|
_req = NULL;
|
|
|
|
_rtmp = NULL;
|
2013-12-22 09:28:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsBandwidth::~SrsBandwidth()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, SrsRequest* req, string local_ip)
|
2013-12-22 09:28:29 +00:00
|
|
|
{
|
2014-03-18 03:32:58 +00:00
|
|
|
int ret = ERROR_SUCCESS;
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
_rtmp = rtmp;
|
|
|
|
_req = req;
|
2014-03-18 03:32:58 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if (!_srs_config->get_bw_check_enabled(_req->vhost)) {
|
2014-03-18 03:32:58 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// validate the bandwidth check key
|
2014-07-12 07:55:39 +00:00
|
|
|
std::string key = "key=" + _srs_config->get_bw_check_key(_req->vhost);
|
|
|
|
if (_req->tcUrl.find(key) == std::string::npos) {
|
2014-03-18 03:32:58 +00:00
|
|
|
ret = ERROR_SYSTEM_BANDWIDTH_KEY;
|
|
|
|
srs_error("check the vhost=%s %s failed, tcUrl=%s, ret=%d",
|
2014-07-12 07:55:39 +00:00
|
|
|
_req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str(), ret);
|
2014-03-18 03:32:58 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// shared global last check time,
|
|
|
|
// to avoid attach by bandwidth check,
|
|
|
|
// if client request check in the window(specifeid by interval),
|
|
|
|
// directly reject the request.
|
2013-12-22 09:28:29 +00:00
|
|
|
static int64_t last_check_time = 0;
|
2014-07-12 07:55:39 +00:00
|
|
|
int interval_ms = _srs_config->get_bw_check_interval_ms(_req->vhost);
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
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) {
|
|
|
|
ret = ERROR_SYSTEM_BANDWIDTH_DENIED;
|
|
|
|
srs_trace("bandcheck denied, "
|
2014-03-18 03:32:58 +00:00
|
|
|
"last_check=%"PRId64", now=%"PRId64", interval=%d",
|
|
|
|
last_check_time, time_now, interval_ms);
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
_rtmp->response_connect_reject(_req, "bandcheck rejected");
|
2013-12-22 09:28:29 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// accept and do bandwidth check.
|
2014-03-18 03:32:58 +00:00
|
|
|
last_check_time = time_now;
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->response_connect_app(_req, local_ip.c_str())) != ERROR_SUCCESS) {
|
2013-12-22 09:28:29 +00:00
|
|
|
srs_error("response connect app failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return do_bandwidth_check();
|
|
|
|
}
|
|
|
|
|
|
|
|
int SrsBandwidth::do_bandwidth_check()
|
|
|
|
{
|
|
|
|
int ret = ERROR_SUCCESS;
|
|
|
|
|
|
|
|
int play_duration_ms = 3000;
|
|
|
|
int play_interval_ms = 0;
|
|
|
|
int play_actual_duration_ms = 0;
|
|
|
|
int play_bytes = 0;
|
|
|
|
|
|
|
|
int publish_duration_ms = 3000;
|
|
|
|
int publish_interval_ms = 0;
|
|
|
|
int publish_actual_duration_ms = 0;
|
|
|
|
int publish_bytes = 0;
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost);
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
int64_t start_time = srs_get_system_time_ms();
|
|
|
|
|
|
|
|
ret = check_play(play_duration_ms,
|
2014-03-18 03:32:58 +00:00
|
|
|
play_interval_ms, play_actual_duration_ms, play_bytes, limit_kbps);
|
2013-12-22 09:28:29 +00:00
|
|
|
if (ret != ERROR_SUCCESS) {
|
|
|
|
srs_error("band width play check failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = check_publish(publish_duration_ms,
|
2014-03-18 03:32:58 +00:00
|
|
|
publish_interval_ms, publish_actual_duration_ms, publish_bytes, limit_kbps);
|
2013-12-22 09:28:29 +00:00
|
|
|
if (ret != ERROR_SUCCESS) {
|
|
|
|
srs_error("band width publish check failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t end_time = srs_get_system_time_ms();
|
|
|
|
int play_kbps = play_bytes * 8 / play_actual_duration_ms;
|
|
|
|
int publish_kbps = publish_bytes * 8 / publish_actual_duration_ms;
|
|
|
|
|
2013-12-22 09:38:51 +00:00
|
|
|
srs_trace("bandwidth check finished. start=%"PRId64"ms, end=%"PRId64"ms, "
|
|
|
|
"duartion=%dms, play=%dkbps, publish=%dkbps, tcUrl=%s, ret=%#x",
|
|
|
|
start_time, end_time, (int)(end_time - start_time), play_kbps, publish_kbps,
|
2014-07-12 07:55:39 +00:00
|
|
|
_req->tcUrl.c_str(), ret);
|
2013-12-22 09:38:51 +00:00
|
|
|
|
2013-12-22 09:28:29 +00:00
|
|
|
// send finished msg
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_finish();
|
2014-03-08 06:38:19 +00:00
|
|
|
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_kbps));
|
|
|
|
pkt->data->set("publish_kbps", SrsAmf0Any::number(publish_kbps));
|
|
|
|
pkt->data->set("play_bytes", SrsAmf0Any::number(play_bytes));
|
|
|
|
pkt->data->set("play_time", SrsAmf0Any::number(play_actual_duration_ms));
|
|
|
|
pkt->data->set("publish_bytes", SrsAmf0Any::number(publish_bytes));
|
|
|
|
pkt->data->set("publish_time", SrsAmf0Any::number(publish_actual_duration_ms));
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2013-12-22 09:28:29 +00:00
|
|
|
srs_error("send bandwidth check finish message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if flash, we notice the result, and expect a final packet.
|
2014-03-18 03:32:58 +00:00
|
|
|
while (true) {
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-03-18 03:32:58 +00:00
|
|
|
SrsBandwidthPacket* pkt = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
// info level to ignore and return success.
|
|
|
|
srs_info("expect final message failed. ret=%d", ret);
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
|
|
|
SrsAutoFree(SrsBandwidthPacket, pkt);
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_info("get final message success.");
|
|
|
|
|
|
|
|
if (pkt->is_flash_final()) {
|
|
|
|
srs_info("BW check recv flash final response.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2013-12-22 09:38:51 +00:00
|
|
|
srs_info("BW check finished.");
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SrsBandwidth::check_play(
|
2014-03-18 03:32:58 +00:00
|
|
|
int duration_ms, int interval_ms, int& actual_duration_ms,
|
|
|
|
int& play_bytes, int max_play_kbps)
|
2013-12-22 09:28:29 +00:00
|
|
|
{
|
|
|
|
int ret = ERROR_SUCCESS;
|
2014-03-18 03:32:58 +00:00
|
|
|
|
|
|
|
if (true) {
|
|
|
|
// send start play command to client
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_play();
|
|
|
|
|
|
|
|
pkt->data->set("duration_ms", SrsAmf0Any::number(duration_ms));
|
|
|
|
pkt->data->set("interval_ms", SrsAmf0Any::number(interval_ms));
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("send bandwidth check start play message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
srs_info("BW check begin.");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
// recv client's starting play response
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-03-18 03:32:58 +00:00
|
|
|
SrsBandwidthPacket* pkt = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("expect bandwidth message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
|
|
|
SrsAutoFree(SrsBandwidthPacket, pkt);
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_info("get bandwidth message succes.");
|
|
|
|
|
|
|
|
if (pkt->is_starting_play()) {
|
|
|
|
srs_info("BW check recv play begin response.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
// send play data to client
|
|
|
|
int64_t current_time = srs_get_system_time_ms();
|
|
|
|
int size = 1024; // TODO: FIXME: magic number
|
|
|
|
char random_data[size];
|
2013-12-27 09:03:12 +00:00
|
|
|
memset(random_data, 'A', size);
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
int interval = 0;
|
2013-12-27 09:03:12 +00:00
|
|
|
int data_count = 1;
|
2014-07-12 07:55:39 +00:00
|
|
|
while ((srs_get_system_time_ms() - current_time) < duration_ms) {
|
2013-12-22 09:28:29 +00:00
|
|
|
st_usleep(interval);
|
|
|
|
|
|
|
|
// TODO: FIXME: use shared ptr message.
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing();
|
|
|
|
|
2013-12-27 09:03:12 +00:00
|
|
|
// TODO: FIXME: magic number
|
|
|
|
for (int i = 0; i < data_count; ++i) {
|
|
|
|
std::stringstream seq;
|
|
|
|
seq << i;
|
2014-07-12 07:55:39 +00:00
|
|
|
std::string play_data = "SRS band check data from server's playing......";
|
2014-03-08 05:57:08 +00:00
|
|
|
pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str()));
|
2013-12-22 09:28:29 +00:00
|
|
|
}
|
2013-12-27 09:03:12 +00:00
|
|
|
data_count += 2;
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-04-29 06:44:07 +00:00
|
|
|
// get length from the rtmp protocol stack.
|
2014-07-12 07:55:39 +00:00
|
|
|
play_bytes = _rtmp->get_send_bytes();
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2013-12-22 09:28:29 +00:00
|
|
|
srs_error("send bandwidth check play messages failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// sleep while current kbps <= max_play_kbps
|
|
|
|
int kbps = 0;
|
|
|
|
while (true) {
|
|
|
|
if(srs_get_system_time_ms() - current_time != 0)
|
|
|
|
kbps = play_bytes * 8 / (srs_get_system_time_ms() - current_time);
|
|
|
|
|
|
|
|
if (kbps > max_play_kbps) {
|
|
|
|
st_usleep(500);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actual_duration_ms = srs_get_system_time_ms() - current_time;
|
2013-12-22 09:38:51 +00:00
|
|
|
srs_info("BW check send play bytes over.");
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-03-18 03:32:58 +00:00
|
|
|
if (true) {
|
|
|
|
// notify client to stop play
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play();
|
2014-04-29 06:18:10 +00:00
|
|
|
|
2014-03-18 03:32:58 +00:00
|
|
|
pkt->data->set("duration_ms", SrsAmf0Any::number(duration_ms));
|
|
|
|
pkt->data->set("interval_ms", SrsAmf0Any::number(interval_ms));
|
|
|
|
pkt->data->set("duration_delta", SrsAmf0Any::number(actual_duration_ms));
|
|
|
|
pkt->data->set("bytes_delta", SrsAmf0Any::number(play_bytes));
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("send bandwidth check stop play message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
srs_info("BW check stop play bytes.");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
// recv client's stop play response.
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-03-18 03:32:58 +00:00
|
|
|
SrsBandwidthPacket* pkt = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("expect bandwidth message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
|
|
|
SrsAutoFree(SrsBandwidthPacket, pkt);
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_info("get bandwidth message succes.");
|
|
|
|
|
|
|
|
if (pkt->is_stopped_play()) {
|
|
|
|
srs_info("BW check recv stop play response.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
int SrsBandwidth::check_publish(
|
2014-03-18 03:32:58 +00:00
|
|
|
int duration_ms, int interval_ms, int& actual_duration_ms,
|
|
|
|
int& publish_bytes, int max_pub_kbps)
|
2013-12-22 09:28:29 +00:00
|
|
|
{
|
|
|
|
int ret = ERROR_SUCCESS;
|
2014-03-18 03:32:58 +00:00
|
|
|
|
|
|
|
if (true) {
|
|
|
|
// notify client to start publish
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_publish();
|
|
|
|
|
|
|
|
pkt->data->set("duration_ms", SrsAmf0Any::number(duration_ms));
|
|
|
|
pkt->data->set("interval_ms", SrsAmf0Any::number(interval_ms));
|
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("send bandwidth check start publish message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
srs_info("BW check publish begin.");
|
|
|
|
}
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
// read client's notification of starting publish
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-03-18 03:32:58 +00:00
|
|
|
SrsBandwidthPacket* pkt = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("expect bandwidth message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
|
|
|
SrsAutoFree(SrsBandwidthPacket, pkt);
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_info("get bandwidth message succes.");
|
|
|
|
|
|
|
|
if (pkt->is_starting_publish()) {
|
|
|
|
srs_info("BW check recv publish begin response.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
// recv publish msgs until @duration_ms ms
|
|
|
|
int64_t current_time = srs_get_system_time_ms();
|
|
|
|
while ( (srs_get_system_time_ms() - current_time) < duration_ms ) {
|
|
|
|
st_usleep(0);
|
|
|
|
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->recv_message(&msg)) != ERROR_SUCCESS) {
|
2013-12-22 09:28:29 +00:00
|
|
|
srs_error("recv message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
publish_bytes = _rtmp->get_recv_bytes();
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
int kbps = 0;
|
|
|
|
while (true) {
|
|
|
|
if(srs_get_system_time_ms() - current_time != 0)
|
|
|
|
kbps = publish_bytes * 8 / (srs_get_system_time_ms() - current_time);
|
|
|
|
|
|
|
|
if (kbps > max_pub_kbps) {
|
|
|
|
st_usleep(500);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actual_duration_ms = srs_get_system_time_ms() - current_time;
|
2013-12-22 09:38:51 +00:00
|
|
|
srs_info("BW check recv publish data over.");
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-03-18 03:32:58 +00:00
|
|
|
if (true) {
|
|
|
|
// notify client to stop publish
|
|
|
|
SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish();
|
|
|
|
pkt->data->set("duration_ms", SrsAmf0Any::number(duration_ms));
|
|
|
|
pkt->data->set("interval_ms", SrsAmf0Any::number(interval_ms));
|
|
|
|
pkt->data->set("duration_delta", SrsAmf0Any::number(actual_duration_ms));
|
|
|
|
pkt->data->set("bytes_delta", SrsAmf0Any::number(publish_bytes));
|
2013-12-22 09:28:29 +00:00
|
|
|
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("send bandwidth check stop publish message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
srs_info("BW check stop publish bytes.");
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
// expect client to stop publish
|
|
|
|
// if flash client, we never expect the client stop publish bytes,
|
|
|
|
// for the flash send call packet to test publish bandwidth,
|
|
|
|
// there are many many packets in the queue.
|
|
|
|
// we just ignore the packet and send the bandwidth test data.
|
|
|
|
// TODO: FIXME: check whether flash client.
|
2014-03-18 03:32:58 +00:00
|
|
|
while (false) {
|
|
|
|
// recv client's stop publish response.
|
2014-04-29 06:44:07 +00:00
|
|
|
SrsMessage* msg = NULL;
|
2014-03-18 03:32:58 +00:00
|
|
|
SrsBandwidthPacket* pkt = NULL;
|
2014-07-12 07:55:39 +00:00
|
|
|
if ((ret = _rtmp->expect_message<SrsBandwidthPacket>(&msg, &pkt)) != ERROR_SUCCESS) {
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_error("expect bandwidth message failed. ret=%d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
2014-05-14 01:41:41 +00:00
|
|
|
SrsAutoFree(SrsMessage, msg);
|
|
|
|
SrsAutoFree(SrsBandwidthPacket, pkt);
|
2014-03-18 03:32:58 +00:00
|
|
|
srs_info("get bandwidth message succes.");
|
|
|
|
|
|
|
|
if (pkt->is_stopped_publish()) {
|
|
|
|
srs_info("BW check recv stop publish response.");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-12-22 09:28:29 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|