2017-03-25 09:21:39 +00:00
|
|
|
/**
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
2019-01-01 13:37:28 +00:00
|
|
|
* Copyright (c) 2013-2019 Winlin
|
2017-03-25 09:21:39 +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.
|
|
|
|
*/
|
2015-01-04 14:47:12 +00:00
|
|
|
|
|
|
|
#include <srs_app_statistic.hpp>
|
|
|
|
|
2015-01-05 05:08:11 +00:00
|
|
|
#include <unistd.h>
|
2015-01-05 04:57:48 +00:00
|
|
|
#include <sstream>
|
|
|
|
using namespace std;
|
|
|
|
|
2015-06-13 08:04:59 +00:00
|
|
|
#include <srs_rtmp_stack.hpp>
|
2015-08-21 08:20:19 +00:00
|
|
|
#include <srs_protocol_json.hpp>
|
2015-05-23 01:58:00 +00:00
|
|
|
#include <srs_protocol_kbps.hpp>
|
2015-03-08 11:59:10 +00:00
|
|
|
#include <srs_app_conn.hpp>
|
2015-04-02 07:05:09 +00:00
|
|
|
#include <srs_app_config.hpp>
|
|
|
|
#include <srs_kernel_utility.hpp>
|
2015-09-22 01:05:21 +00:00
|
|
|
#include <srs_protocol_amf0.hpp>
|
2015-01-04 14:47:12 +00:00
|
|
|
|
2018-08-26 06:29:45 +00:00
|
|
|
int64_t srs_gvid = 0;
|
2015-01-05 05:08:11 +00:00
|
|
|
|
2015-03-21 03:55:28 +00:00
|
|
|
int64_t srs_generate_id()
|
2015-01-05 05:08:11 +00:00
|
|
|
{
|
2018-08-26 06:29:45 +00:00
|
|
|
if (srs_gvid == 0) {
|
|
|
|
srs_gvid = getpid() * 3;
|
|
|
|
}
|
2015-03-21 03:55:28 +00:00
|
|
|
return srs_gvid++;
|
2015-01-05 05:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticVhost::SrsStatisticVhost()
|
|
|
|
{
|
2015-03-21 03:55:28 +00:00
|
|
|
id = srs_generate_id();
|
2015-03-08 11:59:10 +00:00
|
|
|
|
2018-12-23 12:47:17 +00:00
|
|
|
clk = new SrsWallClock();
|
|
|
|
kbps = new SrsKbps(clk);
|
2015-03-08 11:59:10 +00:00
|
|
|
kbps->set_io(NULL, NULL);
|
2015-08-21 07:51:20 +00:00
|
|
|
|
|
|
|
nb_clients = 0;
|
2015-08-22 14:51:59 +00:00
|
|
|
nb_streams = 0;
|
2015-01-05 05:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticVhost::~SrsStatisticVhost()
|
|
|
|
{
|
2015-03-08 11:59:10 +00:00
|
|
|
srs_freep(kbps);
|
2018-12-23 12:47:17 +00:00
|
|
|
srs_freep(clk);
|
2015-01-05 05:08:11 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatisticVhost::dumps(SrsJsonObject* obj)
|
2015-08-21 07:51:20 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-08-21 07:51:20 +00:00
|
|
|
|
|
|
|
// dumps the config of vhost.
|
|
|
|
bool hls_enabled = _srs_config->get_hls_enabled(vhost);
|
2015-08-21 09:00:52 +00:00
|
|
|
bool enabled = _srs_config->get_vhost_enabled(vhost);
|
2015-08-21 07:51:20 +00:00
|
|
|
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("id", SrsJsonAny::integer(id));
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("name", SrsJsonAny::str(vhost.c_str()));
|
|
|
|
obj->set("enabled", SrsJsonAny::boolean(enabled));
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("clients", SrsJsonAny::integer(nb_clients));
|
|
|
|
obj->set("streams", SrsJsonAny::integer(nb_streams));
|
|
|
|
obj->set("send_bytes", SrsJsonAny::integer(kbps->get_send_bytes()));
|
|
|
|
obj->set("recv_bytes", SrsJsonAny::integer(kbps->get_recv_bytes()));
|
2015-08-28 06:39:29 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* okbps = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("kbps", okbps);
|
|
|
|
|
2015-09-19 06:40:32 +00:00
|
|
|
okbps->set("recv_30s", SrsJsonAny::integer(kbps->get_recv_kbps_30s()));
|
|
|
|
okbps->set("send_30s", SrsJsonAny::integer(kbps->get_send_kbps_30s()));
|
2015-08-28 06:39:29 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* hls = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("hls", hls);
|
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
hls->set("enabled", SrsJsonAny::boolean(hls_enabled));
|
2015-08-21 07:51:20 +00:00
|
|
|
if (hls_enabled) {
|
2015-09-19 04:27:31 +00:00
|
|
|
hls->set("fragment", SrsJsonAny::number(_srs_config->get_hls_fragment(vhost)));
|
2015-08-21 07:51:20 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-08-21 07:51:20 +00:00
|
|
|
}
|
|
|
|
|
2015-01-05 05:08:11 +00:00
|
|
|
SrsStatisticStream::SrsStatisticStream()
|
|
|
|
{
|
2015-03-21 03:55:28 +00:00
|
|
|
id = srs_generate_id();
|
2015-01-05 05:08:11 +00:00
|
|
|
vhost = NULL;
|
2015-08-22 05:03:10 +00:00
|
|
|
active = false;
|
|
|
|
connection_cid = -1;
|
2015-03-08 07:33:08 +00:00
|
|
|
|
|
|
|
has_video = false;
|
2017-02-12 12:38:39 +00:00
|
|
|
vcodec = SrsVideoCodecIdReserved;
|
2015-03-08 10:33:35 +00:00
|
|
|
avc_profile = SrsAvcProfileReserved;
|
|
|
|
avc_level = SrsAvcLevelReserved;
|
2015-03-08 07:33:08 +00:00
|
|
|
|
|
|
|
has_audio = false;
|
2017-02-12 12:38:39 +00:00
|
|
|
acodec = SrsAudioCodecIdReserved1;
|
|
|
|
asample_rate = SrsAudioSampleRateReserved;
|
2017-02-12 12:46:24 +00:00
|
|
|
asound_type = SrsAudioChannelsReserved;
|
2015-03-08 09:56:49 +00:00
|
|
|
aac_object = SrsAacObjectTypeReserved;
|
2015-08-28 10:00:24 +00:00
|
|
|
width = 0;
|
|
|
|
height = 0;
|
2015-03-08 11:59:10 +00:00
|
|
|
|
2018-12-23 12:47:17 +00:00
|
|
|
clk = new SrsWallClock();
|
|
|
|
kbps = new SrsKbps(clk);
|
2015-03-08 11:59:10 +00:00
|
|
|
kbps->set_io(NULL, NULL);
|
2015-08-21 07:51:20 +00:00
|
|
|
|
|
|
|
nb_clients = 0;
|
2017-04-23 12:55:51 +00:00
|
|
|
nb_frames = 0;
|
2015-01-05 05:08:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticStream::~SrsStatisticStream()
|
|
|
|
{
|
2015-03-08 11:59:10 +00:00
|
|
|
srs_freep(kbps);
|
2018-12-23 12:47:17 +00:00
|
|
|
srs_freep(clk);
|
2015-01-05 05:08:11 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatisticStream::dumps(SrsJsonObject* obj)
|
2015-08-21 07:51:20 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-08-21 07:51:20 +00:00
|
|
|
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("id", SrsJsonAny::integer(id));
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("name", SrsJsonAny::str(stream.c_str()));
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("vhost", SrsJsonAny::integer(vhost->id));
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("app", SrsJsonAny::str(app.c_str()));
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("live_ms", SrsJsonAny::integer(srs_get_system_time_ms()));
|
|
|
|
obj->set("clients", SrsJsonAny::integer(nb_clients));
|
2017-04-23 13:00:06 +00:00
|
|
|
obj->set("frames", SrsJsonAny::integer(nb_frames));
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("send_bytes", SrsJsonAny::integer(kbps->get_send_bytes()));
|
|
|
|
obj->set("recv_bytes", SrsJsonAny::integer(kbps->get_recv_bytes()));
|
2015-08-28 06:39:29 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* okbps = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("kbps", okbps);
|
|
|
|
|
2015-09-19 06:40:32 +00:00
|
|
|
okbps->set("recv_30s", SrsJsonAny::integer(kbps->get_recv_kbps_30s()));
|
|
|
|
okbps->set("send_30s", SrsJsonAny::integer(kbps->get_send_kbps_30s()));
|
2015-08-28 06:39:29 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* publish = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("publish", publish);
|
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
publish->set("active", SrsJsonAny::boolean(active));
|
2015-09-19 06:40:32 +00:00
|
|
|
publish->set("cid", SrsJsonAny::integer(connection_cid));
|
2015-08-21 07:51:20 +00:00
|
|
|
|
|
|
|
if (!has_video) {
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("video", SrsJsonAny::null());
|
2015-08-21 07:51:20 +00:00
|
|
|
} else {
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* video = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("video", video);
|
|
|
|
|
2017-02-12 12:38:39 +00:00
|
|
|
video->set("codec", SrsJsonAny::str(srs_video_codec_id2str(vcodec).c_str()));
|
|
|
|
video->set("profile", SrsJsonAny::str(srs_avc_profile2str(avc_profile).c_str()));
|
|
|
|
video->set("level", SrsJsonAny::str(srs_avc_level2str(avc_level).c_str()));
|
2015-09-19 06:40:32 +00:00
|
|
|
video->set("width", SrsJsonAny::integer(width));
|
|
|
|
video->set("height", SrsJsonAny::integer(height));
|
2015-08-21 07:51:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!has_audio) {
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("audio", SrsJsonAny::null());
|
2015-08-21 07:51:20 +00:00
|
|
|
} else {
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* audio = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
obj->set("audio", audio);
|
|
|
|
|
2017-02-12 12:38:39 +00:00
|
|
|
audio->set("codec", SrsJsonAny::str(srs_audio_codec_id2str(acodec).c_str()));
|
|
|
|
audio->set("sample_rate", SrsJsonAny::integer(srs_flv_srates[asample_rate]));
|
2015-09-19 06:40:32 +00:00
|
|
|
audio->set("channel", SrsJsonAny::integer(asound_type + 1));
|
2017-02-12 12:38:39 +00:00
|
|
|
audio->set("profile", SrsJsonAny::str(srs_aac_object2str(aac_object).c_str()));
|
2015-08-21 07:51:20 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-08-21 07:51:20 +00:00
|
|
|
}
|
|
|
|
|
2015-08-22 05:03:10 +00:00
|
|
|
void SrsStatisticStream::publish(int cid)
|
2015-05-08 08:45:25 +00:00
|
|
|
{
|
2015-08-22 05:03:10 +00:00
|
|
|
connection_cid = cid;
|
|
|
|
active = true;
|
2015-08-22 14:51:59 +00:00
|
|
|
|
|
|
|
vhost->nb_streams++;
|
2015-05-08 08:45:25 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
void SrsStatisticStream::close()
|
|
|
|
{
|
|
|
|
has_video = false;
|
|
|
|
has_audio = false;
|
2015-08-22 05:03:10 +00:00
|
|
|
active = false;
|
2015-08-22 14:51:59 +00:00
|
|
|
|
|
|
|
vhost->nb_streams--;
|
2015-03-08 07:33:08 +00:00
|
|
|
}
|
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
SrsStatisticClient::SrsStatisticClient()
|
|
|
|
{
|
|
|
|
id = 0;
|
2015-08-22 05:57:34 +00:00
|
|
|
stream = NULL;
|
|
|
|
conn = NULL;
|
|
|
|
req = NULL;
|
|
|
|
type = SrsRtmpConnUnknown;
|
|
|
|
create = srs_get_system_time_ms();
|
2015-08-21 09:00:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticClient::~SrsStatisticClient()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatisticClient::dumps(SrsJsonObject* obj)
|
2015-08-21 09:00:52 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-08-21 09:00:52 +00:00
|
|
|
|
2015-09-19 06:40:32 +00:00
|
|
|
obj->set("id", SrsJsonAny::integer(id));
|
|
|
|
obj->set("vhost", SrsJsonAny::integer(stream->vhost->id));
|
|
|
|
obj->set("stream", SrsJsonAny::integer(stream->id));
|
2015-09-19 04:27:31 +00:00
|
|
|
obj->set("ip", SrsJsonAny::str(req->ip.c_str()));
|
|
|
|
obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str()));
|
|
|
|
obj->set("swfUrl", SrsJsonAny::str(req->swfUrl.c_str()));
|
|
|
|
obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str()));
|
|
|
|
obj->set("url", SrsJsonAny::str(req->get_stream_url().c_str()));
|
|
|
|
obj->set("type", SrsJsonAny::str(srs_client_type_string(type).c_str()));
|
|
|
|
obj->set("publish", SrsJsonAny::boolean(srs_client_type_is_publish(type)));
|
|
|
|
obj->set("alive", SrsJsonAny::number((srs_get_system_time_ms() - create) / 1000.0));
|
2015-08-21 09:00:52 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-08-21 09:00:52 +00:00
|
|
|
}
|
|
|
|
|
2018-08-26 06:29:45 +00:00
|
|
|
SrsStatistic* SrsStatistic::_instance = NULL;
|
2015-01-04 14:47:12 +00:00
|
|
|
|
|
|
|
SrsStatistic::SrsStatistic()
|
|
|
|
{
|
2015-03-21 03:55:28 +00:00
|
|
|
_server_id = srs_generate_id();
|
2015-03-08 11:59:10 +00:00
|
|
|
|
2018-12-23 12:47:17 +00:00
|
|
|
clk = new SrsWallClock();
|
|
|
|
kbps = new SrsKbps(clk);
|
2015-03-08 11:59:10 +00:00
|
|
|
kbps->set_io(NULL, NULL);
|
2015-01-04 14:47:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatistic::~SrsStatistic()
|
|
|
|
{
|
2015-03-08 11:59:10 +00:00
|
|
|
srs_freep(kbps);
|
2018-12-23 12:47:17 +00:00
|
|
|
srs_freep(clk);
|
2015-03-08 11:59:10 +00:00
|
|
|
|
2015-01-05 04:40:38 +00:00
|
|
|
if (true) {
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
2015-01-05 04:40:38 +00:00
|
|
|
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
|
|
|
SrsStatisticVhost* vhost = it->second;
|
|
|
|
srs_freep(vhost);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (true) {
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
2015-01-05 04:40:38 +00:00
|
|
|
for (it = streams.begin(); it != streams.end(); it++) {
|
|
|
|
SrsStatisticStream* stream = it->second;
|
|
|
|
srs_freep(stream);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (true) {
|
|
|
|
std::map<int, SrsStatisticClient*>::iterator it;
|
|
|
|
for (it = clients.begin(); it != clients.end(); it++) {
|
|
|
|
SrsStatisticClient* client = it->second;
|
|
|
|
srs_freep(client);
|
|
|
|
}
|
2015-01-05 04:20:46 +00:00
|
|
|
}
|
2015-08-21 09:00:52 +00:00
|
|
|
|
|
|
|
vhosts.clear();
|
|
|
|
rvhosts.clear();
|
|
|
|
streams.clear();
|
|
|
|
rstreams.clear();
|
2015-01-05 04:20:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatistic* SrsStatistic::instance()
|
|
|
|
{
|
2018-08-26 06:29:45 +00:00
|
|
|
if (_instance == NULL) {
|
|
|
|
_instance = new SrsStatistic();
|
|
|
|
}
|
2015-01-05 04:20:46 +00:00
|
|
|
return _instance;
|
2015-01-04 14:47:12 +00:00
|
|
|
}
|
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
SrsStatisticVhost* SrsStatistic::find_vhost(int vid)
|
|
|
|
{
|
|
|
|
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
|
|
|
if ((it = vhosts.find(vid)) != vhosts.end()) {
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-27 15:55:59 +00:00
|
|
|
SrsStatisticVhost* SrsStatistic::find_vhost(string name)
|
|
|
|
{
|
2018-08-26 06:29:45 +00:00
|
|
|
if (rvhosts.empty()) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-27 15:55:59 +00:00
|
|
|
std::map<string, SrsStatisticVhost*>::iterator it;
|
|
|
|
if ((it = rvhosts.find(name)) != rvhosts.end()) {
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
SrsStatisticStream* SrsStatistic::find_stream(int sid)
|
|
|
|
{
|
|
|
|
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
|
|
|
if ((it = streams.find(sid)) != streams.end()) {
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticClient* SrsStatistic::find_client(int cid)
|
2015-08-11 07:23:46 +00:00
|
|
|
{
|
|
|
|
std::map<int, SrsStatisticClient*>::iterator it;
|
2015-08-21 09:00:52 +00:00
|
|
|
if ((it = clients.find(cid)) != clients.end()) {
|
|
|
|
return it->second;
|
2015-08-11 07:23:46 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height)
|
2017-03-25 09:21:39 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-01-05 04:57:48 +00:00
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
stream->has_video = true;
|
|
|
|
stream->vcodec = vcodec;
|
|
|
|
stream->avc_profile = avc_profile;
|
|
|
|
stream->avc_level = avc_level;
|
2015-01-05 04:57:48 +00:00
|
|
|
|
2015-08-28 10:00:24 +00:00
|
|
|
stream->width = width;
|
|
|
|
stream->height = height;
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-03-08 07:33:08 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object)
|
2017-03-25 09:21:39 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-01-05 04:57:48 +00:00
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
stream->has_audio = true;
|
|
|
|
stream->acodec = acodec;
|
|
|
|
stream->asample_rate = asample_rate;
|
|
|
|
stream->asound_type = asound_type;
|
2015-03-08 09:56:49 +00:00
|
|
|
stream->aac_object = aac_object;
|
2015-03-08 07:33:08 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-03-08 07:33:08 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::on_video_frames(SrsRequest* req, int nb_frames)
|
2017-04-23 12:55:51 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-04-23 12:55:51 +00:00
|
|
|
|
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
|
|
|
|
|
|
|
stream->nb_frames += nb_frames;
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2017-04-23 12:55:51 +00:00
|
|
|
}
|
|
|
|
|
2015-08-22 05:03:10 +00:00
|
|
|
void SrsStatistic::on_stream_publish(SrsRequest* req, int cid)
|
2015-05-08 08:45:25 +00:00
|
|
|
{
|
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-08-22 05:03:10 +00:00
|
|
|
stream->publish(cid);
|
2015-05-08 08:45:25 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
void SrsStatistic::on_stream_close(SrsRequest* req)
|
|
|
|
{
|
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
|
|
|
stream->close();
|
2017-03-11 08:28:18 +00:00
|
|
|
|
|
|
|
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
|
|
|
|
if (true) {
|
|
|
|
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
|
|
|
if ((it=streams.find(stream->id)) != streams.end()) {
|
|
|
|
streams.erase(it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: FIXME: Should fix https://github.com/ossrs/srs/issues/803
|
|
|
|
if (true) {
|
|
|
|
std::map<std::string, SrsStatisticStream*>::iterator it;
|
|
|
|
if ((it=rstreams.find(stream->url)) != rstreams.end()) {
|
|
|
|
rstreams.erase(it);
|
|
|
|
}
|
|
|
|
}
|
2015-03-08 07:33:08 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type)
|
2015-03-08 07:33:08 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-03-08 07:33:08 +00:00
|
|
|
|
|
|
|
SrsStatisticVhost* vhost = create_vhost(req);
|
|
|
|
SrsStatisticStream* stream = create_stream(vhost, req);
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-01-06 14:20:31 +00:00
|
|
|
// create client if not exists
|
|
|
|
SrsStatisticClient* client = NULL;
|
|
|
|
if (clients.find(id) == clients.end()) {
|
|
|
|
client = new SrsStatisticClient();
|
2015-05-22 03:20:25 +00:00
|
|
|
client->id = id;
|
2015-01-06 14:20:31 +00:00
|
|
|
client->stream = stream;
|
|
|
|
clients[id] = client;
|
|
|
|
} else {
|
|
|
|
client = clients[id];
|
|
|
|
}
|
2015-08-21 07:51:20 +00:00
|
|
|
|
|
|
|
// got client.
|
2015-08-22 05:36:15 +00:00
|
|
|
client->conn = conn;
|
2015-08-22 05:57:34 +00:00
|
|
|
client->req = req;
|
|
|
|
client->type = type;
|
2015-08-21 07:51:20 +00:00
|
|
|
stream->nb_clients++;
|
|
|
|
vhost->nb_clients++;
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-01-06 14:20:31 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
void SrsStatistic::on_disconnect(int id)
|
2015-01-06 14:20:31 +00:00
|
|
|
{
|
|
|
|
std::map<int, SrsStatisticClient*>::iterator it;
|
2015-08-21 07:51:20 +00:00
|
|
|
if ((it = clients.find(id)) == clients.end()) {
|
|
|
|
return;
|
2015-01-06 14:20:31 +00:00
|
|
|
}
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-08-21 07:51:20 +00:00
|
|
|
SrsStatisticClient* client = it->second;
|
|
|
|
SrsStatisticStream* stream = client->stream;
|
|
|
|
SrsStatisticVhost* vhost = stream->vhost;
|
|
|
|
|
|
|
|
srs_freep(client);
|
|
|
|
clients.erase(it);
|
|
|
|
|
|
|
|
stream->nb_clients--;
|
|
|
|
vhost->nb_clients--;
|
2015-01-06 14:20:31 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 11:59:10 +00:00
|
|
|
void SrsStatistic::kbps_add_delta(SrsConnection* conn)
|
|
|
|
{
|
|
|
|
int id = conn->srs_id();
|
|
|
|
if (clients.find(id) == clients.end()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticClient* client = clients[id];
|
|
|
|
|
|
|
|
// resample the kbps to collect the delta.
|
2019-01-01 09:36:27 +00:00
|
|
|
int64_t in, out;
|
|
|
|
conn->remark(&in, &out);
|
2015-03-08 11:59:10 +00:00
|
|
|
|
|
|
|
// add delta of connection to kbps.
|
|
|
|
// for next sample() of server kbps can get the stat.
|
2019-01-01 09:36:27 +00:00
|
|
|
kbps->add_delta(in, out);
|
|
|
|
client->stream->kbps->add_delta(in, out);
|
|
|
|
client->stream->vhost->kbps->add_delta(in, out);
|
2015-03-08 11:59:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
SrsKbps* SrsStatistic::kbps_sample()
|
|
|
|
{
|
|
|
|
kbps->sample();
|
|
|
|
if (true) {
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
2015-03-08 11:59:10 +00:00
|
|
|
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
|
|
|
SrsStatisticVhost* vhost = it->second;
|
|
|
|
vhost->kbps->sample();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (true) {
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
2015-03-08 11:59:10 +00:00
|
|
|
for (it = streams.begin(); it != streams.end(); it++) {
|
|
|
|
SrsStatisticStream* stream = it->second;
|
|
|
|
stream->kbps->sample();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return kbps;
|
|
|
|
}
|
|
|
|
|
2015-01-05 05:08:11 +00:00
|
|
|
int64_t SrsStatistic::server_id()
|
|
|
|
{
|
|
|
|
return _server_id;
|
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::dumps_vhosts(SrsJsonArray* arr)
|
2015-01-04 14:47:12 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticVhost*>::iterator it;
|
2015-01-05 04:57:48 +00:00
|
|
|
for (it = vhosts.begin(); it != vhosts.end(); it++) {
|
|
|
|
SrsStatisticVhost* vhost = it->second;
|
2015-08-21 07:51:20 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* obj = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
arr->append(obj);
|
2015-04-02 07:05:09 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
if ((err = vhost->dumps(obj)) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "dump vhost");
|
2015-08-17 08:34:11 +00:00
|
|
|
}
|
2015-01-05 04:57:48 +00:00
|
|
|
}
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-01-04 14:47:12 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::dumps_streams(SrsJsonArray* arr)
|
2015-01-04 14:47:12 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-01-05 04:57:48 +00:00
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
std::map<int64_t, SrsStatisticStream*>::iterator it;
|
2015-01-05 04:57:48 +00:00
|
|
|
for (it = streams.begin(); it != streams.end(); it++) {
|
|
|
|
SrsStatisticStream* stream = it->second;
|
2015-08-21 07:51:20 +00:00
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* obj = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
arr->append(obj);
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
if ((err = stream->dumps(obj)) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "dump stream");
|
2015-01-08 13:58:10 +00:00
|
|
|
}
|
2015-01-05 04:57:48 +00:00
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-01-05 04:40:38 +00:00
|
|
|
}
|
2015-03-08 07:33:08 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t SrsStatistic::dumps_clients(SrsJsonArray* arr, int start, int count)
|
2015-08-21 09:00:52 +00:00
|
|
|
{
|
2018-01-01 13:20:57 +00:00
|
|
|
srs_error_t err = srs_success;
|
2015-08-21 09:00:52 +00:00
|
|
|
|
|
|
|
std::map<int, SrsStatisticClient*>::iterator it = clients.begin();
|
2015-08-22 05:57:34 +00:00
|
|
|
for (int i = 0; i < start + count && it != clients.end(); it++, i++) {
|
2015-08-21 09:00:52 +00:00
|
|
|
if (i < start) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticClient* client = it->second;
|
|
|
|
|
2015-09-19 04:27:31 +00:00
|
|
|
SrsJsonObject* obj = SrsJsonAny::object();
|
2015-08-28 06:39:29 +00:00
|
|
|
arr->append(obj);
|
2015-08-21 09:00:52 +00:00
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
if ((err = client->dumps(obj)) != srs_success) {
|
|
|
|
return srs_error_wrap(err, "dump client");
|
2015-08-21 09:00:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-01 13:20:57 +00:00
|
|
|
return err;
|
2015-08-21 09:00:52 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 07:33:08 +00:00
|
|
|
SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
|
|
|
|
{
|
|
|
|
SrsStatisticVhost* vhost = NULL;
|
|
|
|
|
|
|
|
// create vhost if not exists.
|
2015-08-21 09:00:52 +00:00
|
|
|
if (rvhosts.find(req->vhost) == rvhosts.end()) {
|
2015-03-08 07:33:08 +00:00
|
|
|
vhost = new SrsStatisticVhost();
|
|
|
|
vhost->vhost = req->vhost;
|
2015-08-21 09:00:52 +00:00
|
|
|
rvhosts[req->vhost] = vhost;
|
|
|
|
vhosts[vhost->id] = vhost;
|
2015-03-08 07:33:08 +00:00
|
|
|
return vhost;
|
|
|
|
}
|
2017-03-25 09:21:39 +00:00
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
vhost = rvhosts[req->vhost];
|
2015-03-08 07:33:08 +00:00
|
|
|
|
|
|
|
return vhost;
|
|
|
|
}
|
|
|
|
|
|
|
|
SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsRequest* req)
|
|
|
|
{
|
|
|
|
std::string url = req->get_stream_url();
|
|
|
|
|
|
|
|
SrsStatisticStream* stream = NULL;
|
|
|
|
|
|
|
|
// create stream if not exists.
|
2015-08-21 09:00:52 +00:00
|
|
|
if (rstreams.find(url) == rstreams.end()) {
|
2015-03-08 07:33:08 +00:00
|
|
|
stream = new SrsStatisticStream();
|
|
|
|
stream->vhost = vhost;
|
|
|
|
stream->stream = req->stream;
|
2015-04-02 07:05:09 +00:00
|
|
|
stream->app = req->app;
|
2015-03-08 07:33:08 +00:00
|
|
|
stream->url = url;
|
2015-08-21 09:00:52 +00:00
|
|
|
rstreams[url] = stream;
|
|
|
|
streams[stream->id] = stream;
|
2015-03-08 07:33:08 +00:00
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|
2015-08-21 09:00:52 +00:00
|
|
|
stream = rstreams[url];
|
2015-03-08 07:33:08 +00:00
|
|
|
|
|
|
|
return stream;
|
|
|
|
}
|
|
|
|
|