mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
RTC: Remove GSO for player, no premature optimization
This commit is contained in:
parent
5bd2812405
commit
4f6b24ea12
9 changed files with 13 additions and 375 deletions
|
@ -449,10 +449,6 @@ rtc_server {
|
|||
# @see https://github.com/ossrs/srs/issues/307#issuecomment-612806318
|
||||
# default: on
|
||||
merge_nalus on;
|
||||
# Whether enable GSO to send out RTP packets.
|
||||
# @remark Linux 4.18+ only, for other OS always disabled.
|
||||
# default: on
|
||||
gso on;
|
||||
# Whether pad first packet for GSO for padding bytes.
|
||||
# If 0, disable padding for GSO.
|
||||
# @remark The max padding size is 0x7f(127).
|
||||
|
|
|
@ -3644,7 +3644,7 @@ srs_error_t SrsConfig::check_normal_config()
|
|||
for (int i = 0; conf && i < (int)conf->directives.size(); i++) {
|
||||
string n = conf->at(i)->name;
|
||||
if (n != "enabled" && n != "listen" && n != "dir" && n != "candidate" && n != "ecdsa"
|
||||
&& n != "sendmmsg" && n != "encrypt" && n != "reuseport" && n != "gso" && n != "merge_nalus"
|
||||
&& n != "sendmmsg" && n != "encrypt" && n != "reuseport" && n != "merge_nalus"
|
||||
&& n != "padding" && n != "perf_stat" && n != "queue_length" && n != "black_hole"
|
||||
&& n != "ip_family") {
|
||||
return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal rtc_server.%s", n.c_str());
|
||||
|
@ -4868,53 +4868,6 @@ bool SrsConfig::get_rtc_server_merge_nalus()
|
|||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_server_gso()
|
||||
{
|
||||
bool v = get_rtc_server_gso2();
|
||||
|
||||
bool gso_disabled = false;
|
||||
#if !defined(__linux__)
|
||||
gso_disabled = true;
|
||||
if (v) {
|
||||
srs_warn("GSO is disabled, for Linux 4.18+ only");
|
||||
}
|
||||
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4,18,0)
|
||||
if (v) {
|
||||
utsname un;
|
||||
memset((void*)&un, 0, sizeof(utsname));
|
||||
|
||||
int r0 = uname(&un);
|
||||
if (r0 || strcmp(un.release, "4.18.0") < 0) {
|
||||
gso_disabled = true;
|
||||
srs_warn("GSO is disabled, for Linux 4.18+ only, r0=%d, kernel=%s", r0, un.release);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (v && gso_disabled) {
|
||||
v = false;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
bool SrsConfig::get_rtc_server_gso2()
|
||||
{
|
||||
static int DEFAULT = true;
|
||||
|
||||
SrsConfDirective* conf = root->get("rtc_server");
|
||||
if (!conf) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
conf = conf->get("gso");
|
||||
if (!conf || conf->arg0().empty()) {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
return SRS_CONF_PERFER_TRUE(conf->arg0());
|
||||
}
|
||||
|
||||
int SrsConfig::get_rtc_server_padding()
|
||||
{
|
||||
static int DEFAULT = 127;
|
||||
|
|
|
@ -531,7 +531,6 @@ public:
|
|||
virtual bool get_rtc_server_encrypt();
|
||||
virtual int get_rtc_server_reuseport();
|
||||
virtual bool get_rtc_server_merge_nalus();
|
||||
virtual bool get_rtc_server_gso();
|
||||
virtual int get_rtc_server_padding();
|
||||
virtual bool get_rtc_server_perf_stat();
|
||||
virtual int get_rtc_server_queue_length();
|
||||
|
@ -539,7 +538,6 @@ public:
|
|||
virtual std::string get_rtc_server_black_hole_publisher();
|
||||
private:
|
||||
virtual int get_rtc_server_reuseport2();
|
||||
virtual bool get_rtc_server_gso2();
|
||||
|
||||
public:
|
||||
SrsConfDirective* get_rtc(std::string vhost);
|
||||
|
|
|
@ -1335,7 +1335,7 @@ srs_error_t SrsGoApiPerf::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
|
|||
|
||||
p->set("target", SrsJsonAny::str(target.c_str()));
|
||||
p->set("reset", SrsJsonAny::str(reset.c_str()));
|
||||
p->set("help", SrsJsonAny::str("?target=avframes|rtc|rtp|gso|writev_iovs|sendmmsg|bytes|dropped"));
|
||||
p->set("help", SrsJsonAny::str("?target=avframes|rtc|rtp|writev_iovs|sendmmsg|bytes|dropped"));
|
||||
p->set("help2", SrsJsonAny::str("?reset=all"));
|
||||
}
|
||||
|
||||
|
@ -1371,15 +1371,6 @@ srs_error_t SrsGoApiPerf::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage*
|
|||
}
|
||||
}
|
||||
|
||||
if (target.empty() || target == "gso") {
|
||||
SrsJsonObject* p = SrsJsonAny::object();
|
||||
data->set("gso", p);
|
||||
if ((err = stat->dumps_perf_gso(p)) != srs_success) {
|
||||
int code = srs_error_code(err); srs_error_reset(err);
|
||||
return srs_api_response_code(w, r, code);
|
||||
}
|
||||
}
|
||||
|
||||
if (target.empty() || target == "sendmmsg") {
|
||||
SrsJsonObject* p = SrsJsonAny::object();
|
||||
data->set("sendmmsg", p);
|
||||
|
|
|
@ -33,13 +33,6 @@ using namespace std;
|
|||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <netinet/udp.h>
|
||||
// Define macro for UDP GSO.
|
||||
// @see https://github.com/torvalds/linux/blob/master/tools/testing/selftests/net/udpgso.c
|
||||
#ifndef UDP_SEGMENT
|
||||
#define UDP_SEGMENT 103
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <srs_core_autofree.hpp>
|
||||
|
@ -483,7 +476,6 @@ SrsRtcOutgoingInfo::SrsRtcOutgoingInfo()
|
|||
debug_id = 0;
|
||||
#endif
|
||||
|
||||
use_gso = false;
|
||||
nn_rtp_pkts = 0;
|
||||
nn_audios = nn_extras = 0;
|
||||
nn_videos = nn_samples = 0;
|
||||
|
@ -503,7 +495,6 @@ SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid)
|
|||
|
||||
session_ = s;
|
||||
|
||||
gso = false;
|
||||
max_padding = 0;
|
||||
|
||||
audio_timestamp = 0;
|
||||
|
@ -543,22 +534,20 @@ srs_error_t SrsRtcPlayer::initialize(const uint32_t& vssrc, const uint32_t& assr
|
|||
video_payload_type = v_pt;
|
||||
audio_payload_type = a_pt;
|
||||
|
||||
gso = _srs_config->get_rtc_server_gso();
|
||||
max_padding = _srs_config->get_rtc_server_padding();
|
||||
// TODO: FIXME: Support reload.
|
||||
nack_enabled_ = _srs_config->get_rtc_nack_enabled(session_->req->vhost);
|
||||
srs_trace("RTC publisher video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), gso=%d, padding=%d, nack=%d",
|
||||
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, gso, max_padding, nack_enabled_);
|
||||
srs_trace("RTC publisher video(ssrc=%d, pt=%d), audio(ssrc=%d, pt=%d), padding=%d, nack=%d",
|
||||
video_ssrc, video_payload_type, audio_ssrc, audio_payload_type, max_padding, nack_enabled_);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcPlayer::on_reload_rtc_server()
|
||||
{
|
||||
gso = _srs_config->get_rtc_server_gso();
|
||||
max_padding = _srs_config->get_rtc_server_padding();
|
||||
|
||||
srs_trace("Reload rtc_server gso=%d, max_padding=%d", gso, max_padding);
|
||||
srs_trace("Reload rtc_server max_padding=%d", max_padding);
|
||||
|
||||
return srs_success;
|
||||
}
|
||||
|
@ -698,8 +687,6 @@ srs_error_t SrsRtcPlayer::cycle()
|
|||
stat->perf_on_rtc_packets(nn_rtc_packets);
|
||||
// Stat the RAW RTP packets, which maybe group by GSO.
|
||||
stat->perf_on_rtp_packets(msg_count);
|
||||
// Stat the RTP packets going into kernel.
|
||||
stat->perf_on_gso_packets(info.nn_rtp_pkts);
|
||||
// Stat the bytes and paddings.
|
||||
stat->perf_on_rtc_bytes(info.nn_bytes, info.nn_rtp_bytes, info.nn_padding_bytes);
|
||||
// Stat the messages and dropped count.
|
||||
|
@ -729,18 +716,6 @@ srs_error_t SrsRtcPlayer::send_messages(SrsRtcSource* source, const vector<SrsRt
|
|||
return srs_error_wrap(err, "messages to packets");
|
||||
}
|
||||
|
||||
#ifndef SRS_OSX
|
||||
// If enabled GSO, send out some packets in a msghdr.
|
||||
// @remark When NACK simulator is on, we don't use GSO.
|
||||
// TODO: FIXME: Support GSO.
|
||||
if (info.use_gso && !nn_simulate_nack_drop) {
|
||||
if ((err = send_packets_gso(pkts, info)) != srs_success) {
|
||||
return srs_error_wrap(err, "gso send");
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
// By default, we send packets by sendmmsg.
|
||||
if ((err = send_packets(pkts, info)) != srs_success) {
|
||||
return srs_error_wrap(err, "raw send");
|
||||
|
@ -890,230 +865,6 @@ srs_error_t SrsRtcPlayer::send_packets(const std::vector<SrsRtpPacket2*>& pkts,
|
|||
return err;
|
||||
}
|
||||
|
||||
// TODO: FIXME: We can gather and pad audios, because they have similar size.
|
||||
srs_error_t SrsRtcPlayer::send_packets_gso(const vector<SrsRtpPacket2*>& pkts, SrsRtcOutgoingInfo& info)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// Cache the encrypt flag and sender.
|
||||
bool encrypt = session_->encrypt;
|
||||
ISrsUdpSender* sender = session_->sendonly_skt->sender();
|
||||
|
||||
// Previous handler, if has the same size, we can use GSO.
|
||||
srs_mmsghdr* gso_mhdr = NULL; int gso_size = 0; int gso_encrypt = 0; int gso_cursor = 0;
|
||||
// GSO, N packets has same length, the final one may not.
|
||||
bool using_gso = false; bool gso_final = false;
|
||||
// The message will marshal in iovec.
|
||||
iovec* iov = NULL;
|
||||
|
||||
int nn_packets = pkts.size();
|
||||
for (int i = 0; i < nn_packets; i++) {
|
||||
SrsRtpPacket2* packet = pkts.at(i);
|
||||
int nn_packet = packet->nb_bytes();
|
||||
int padding = 0;
|
||||
|
||||
SrsRtpPacket2* next_packet = NULL;
|
||||
int nn_next_packet = 0;
|
||||
if (max_padding > 0) {
|
||||
if (i < nn_packets - 1) {
|
||||
next_packet = (i < nn_packets - 1)? pkts.at(i + 1):NULL;
|
||||
nn_next_packet = next_packet? next_packet->nb_bytes() : 0;
|
||||
}
|
||||
|
||||
// Padding the packet to next or GSO size.
|
||||
if (next_packet) {
|
||||
if (!using_gso) {
|
||||
// Padding to the next packet to merge with it.
|
||||
if (nn_next_packet > nn_packet) {
|
||||
padding = nn_next_packet - nn_packet;
|
||||
}
|
||||
} else {
|
||||
// Padding to GSO size for next one to merge with us.
|
||||
if (nn_next_packet < gso_size) {
|
||||
padding = gso_size - nn_packet;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset padding if exceed max.
|
||||
if (padding > max_padding) {
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
if (padding > 0) {
|
||||
#if defined(SRS_DEBUG)
|
||||
srs_trace("#%d, Padding %d bytes %d=>%d, packets %d, max_padding %d", info.debug_id,
|
||||
padding, nn_packet, nn_packet + padding, nn_packets, max_padding);
|
||||
#endif
|
||||
packet->add_padding(padding);
|
||||
nn_packet += padding;
|
||||
info.nn_paddings++;
|
||||
info.nn_padding_bytes += padding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether we can use GSO to send it.
|
||||
if (using_gso && !gso_final) {
|
||||
gso_final = (gso_size != nn_packet);
|
||||
}
|
||||
|
||||
if (next_packet) {
|
||||
// If not GSO, maybe the first fresh packet, we should see whether the next packet is smaller than this one,
|
||||
// if smaller, we can still enter GSO.
|
||||
if (!using_gso) {
|
||||
using_gso = (nn_packet >= nn_next_packet);
|
||||
}
|
||||
|
||||
// If GSO, but next is bigger than this one, we must enter the final state.
|
||||
if (using_gso && !gso_final) {
|
||||
gso_final = (nn_packet < nn_next_packet);
|
||||
}
|
||||
}
|
||||
|
||||
// For GSO, reuse mhdr if possible.
|
||||
srs_mmsghdr* mhdr = gso_mhdr;
|
||||
if (!mhdr) {
|
||||
// Fetch a cached message from queue.
|
||||
// TODO: FIXME: Maybe encrypt in async, so the state of mhdr maybe not ready.
|
||||
if ((err = sender->fetch(&mhdr)) != srs_success) {
|
||||
return srs_error_wrap(err, "fetch msghdr");
|
||||
}
|
||||
|
||||
// Now, GSO will use this message and size.
|
||||
gso_mhdr = mhdr;
|
||||
gso_size = nn_packet;
|
||||
}
|
||||
|
||||
// For this message, select a new iovec.
|
||||
if (!iov) {
|
||||
iov = mhdr->msg_hdr.msg_iov;
|
||||
} else {
|
||||
iov++;
|
||||
}
|
||||
gso_cursor++;
|
||||
mhdr->msg_hdr.msg_iovlen = gso_cursor;
|
||||
|
||||
if (gso_cursor > SRS_PERF_RTC_GSO_IOVS && !iov->iov_base) {
|
||||
iov->iov_base = new char[kRtpPacketSize];
|
||||
}
|
||||
iov->iov_len = kRtpPacketSize;
|
||||
|
||||
// Marshal packet to bytes in iovec.
|
||||
if (true) {
|
||||
SrsBuffer stream((char*)iov->iov_base, iov->iov_len);
|
||||
if ((err = packet->encode(&stream)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode packet");
|
||||
}
|
||||
iov->iov_len = stream.pos();
|
||||
}
|
||||
|
||||
// Whether encrypt the RTP bytes.
|
||||
if (encrypt) {
|
||||
int nn_encrypt = (int)iov->iov_len;
|
||||
if ((err = session_->dtls_->protect_rtp2(iov->iov_base, &nn_encrypt)) != srs_success) {
|
||||
return srs_error_wrap(err, "srtp protect");
|
||||
}
|
||||
iov->iov_len = (size_t)nn_encrypt;
|
||||
}
|
||||
|
||||
// Put final RTP packet to NACK/ARQ queue.
|
||||
if (nack_enabled_) {
|
||||
SrsRtpPacket2* nack = new SrsRtpPacket2();
|
||||
nack->header = packet->header;
|
||||
|
||||
// TODO: FIXME: Should avoid memory copying.
|
||||
SrsRtpRawPayload* payload = new SrsRtpRawPayload();
|
||||
nack->payload = payload;
|
||||
|
||||
payload->nn_payload = (int)iov->iov_len;
|
||||
payload->payload = new char[payload->nn_payload];
|
||||
memcpy((void*)payload->payload, iov->iov_base, iov->iov_len);
|
||||
|
||||
if (nack->header.get_ssrc() == video_ssrc) {
|
||||
video_queue_->set(nack->header.get_sequence(), nack);
|
||||
} else {
|
||||
audio_queue_->set(nack->header.get_sequence(), nack);
|
||||
}
|
||||
}
|
||||
|
||||
info.nn_rtp_bytes += (int)iov->iov_len;
|
||||
|
||||
// If GSO, they must has same size, except the final one.
|
||||
if (using_gso && !gso_final && gso_encrypt && gso_encrypt != (int)iov->iov_len) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "GSO size=%d/%d, encrypt=%d/%d", gso_size, nn_packet, gso_encrypt, iov->iov_len);
|
||||
}
|
||||
|
||||
if (using_gso && !gso_final) {
|
||||
gso_encrypt = iov->iov_len;
|
||||
}
|
||||
|
||||
// If exceed the max GSO size, set to final.
|
||||
if (using_gso && gso_cursor + 1 >= SRS_PERF_RTC_GSO_MAX) {
|
||||
gso_final = true;
|
||||
}
|
||||
|
||||
// For last message, or final gso, or determined not using GSO, send it now.
|
||||
bool do_send = (i == nn_packets - 1 || gso_final || !using_gso);
|
||||
|
||||
#if defined(SRS_DEBUG)
|
||||
bool is_video = packet->header.get_payload_type() == video_payload_type;
|
||||
srs_trace("#%d, Packet %s SSRC=%d, SN=%d, %d/%d bytes", info.debug_id, is_video? "Video":"Audio",
|
||||
packet->header.get_ssrc(), packet->header.get_sequence(), nn_packet - padding, padding);
|
||||
if (do_send) {
|
||||
for (int j = 0; j < (int)mhdr->msg_hdr.msg_iovlen; j++) {
|
||||
iovec* iov = mhdr->msg_hdr.msg_iov + j;
|
||||
srs_trace("#%d, %s #%d/%d/%d, %d/%d bytes, size %d/%d", info.debug_id, (using_gso? "GSO":"RAW"), j,
|
||||
gso_cursor + 1, mhdr->msg_hdr.msg_iovlen, iov->iov_len, padding, gso_size, gso_encrypt);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (do_send) {
|
||||
// Set the address and control information.
|
||||
sockaddr_in* addr = (sockaddr_in*)session_->sendonly_skt->peer_addr();
|
||||
socklen_t addrlen = (socklen_t)session_->sendonly_skt->peer_addrlen();
|
||||
|
||||
mhdr->msg_hdr.msg_name = (sockaddr_in*)addr;
|
||||
mhdr->msg_hdr.msg_namelen = (socklen_t)addrlen;
|
||||
mhdr->msg_hdr.msg_controllen = 0;
|
||||
|
||||
#ifndef SRS_OSX
|
||||
if (using_gso) {
|
||||
mhdr->msg_hdr.msg_controllen = CMSG_SPACE(sizeof(uint16_t));
|
||||
if (!mhdr->msg_hdr.msg_control) {
|
||||
mhdr->msg_hdr.msg_control = new char[mhdr->msg_hdr.msg_controllen];
|
||||
}
|
||||
|
||||
cmsghdr* cm = CMSG_FIRSTHDR(&mhdr->msg_hdr);
|
||||
cm->cmsg_level = SOL_UDP;
|
||||
cm->cmsg_type = UDP_SEGMENT;
|
||||
cm->cmsg_len = CMSG_LEN(sizeof(uint16_t));
|
||||
*((uint16_t*)CMSG_DATA(cm)) = gso_encrypt;
|
||||
}
|
||||
#endif
|
||||
|
||||
// When we send out a packet, we commit a RTP packet.
|
||||
info.nn_rtp_pkts++;
|
||||
|
||||
if ((err = sender->sendmmsg(mhdr)) != srs_success) {
|
||||
return srs_error_wrap(err, "send msghdr");
|
||||
}
|
||||
|
||||
// Reset the GSO flag.
|
||||
gso_mhdr = NULL; gso_size = 0; gso_encrypt = 0; gso_cursor = 0;
|
||||
using_gso = gso_final = false; iov = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(SRS_DEBUG)
|
||||
srs_trace("#%d, RTC PLAY summary, rtp %d/%d, videos %d/%d, audios %d/%d, pad %d/%d/%d", info.debug_id, pkts.size(),
|
||||
info.nn_rtp_pkts, info.nn_videos, info.nn_samples, info.nn_audios, info.nn_extras, info.nn_paddings,
|
||||
info.nn_padding_bytes, info.nn_rtp_bytes);
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void SrsRtcPlayer::nack_fetch(vector<SrsRtpPacket2*>& pkts, uint32_t ssrc, uint16_t seq)
|
||||
{
|
||||
SrsRtpPacket2* pkt = NULL;
|
||||
|
|
|
@ -152,8 +152,6 @@ private:
|
|||
// TODO: FIXME: Rename to stat for RTP packets.
|
||||
class SrsRtcOutgoingInfo
|
||||
{
|
||||
public:
|
||||
bool use_gso;
|
||||
public:
|
||||
#if defined(SRS_DEBUG)
|
||||
// Debug id.
|
||||
|
@ -243,7 +241,6 @@ private:
|
|||
srs_error_t send_messages(SrsRtcSource* source, const std::vector<SrsRtpPacket2*>& pkts, SrsRtcOutgoingInfo& info);
|
||||
srs_error_t messages_to_packets(SrsRtcSource* source, const std::vector<SrsRtpPacket2*>& pkts, SrsRtcOutgoingInfo& info);
|
||||
srs_error_t send_packets(const std::vector<SrsRtpPacket2*>& pkts, SrsRtcOutgoingInfo& info);
|
||||
srs_error_t send_packets_gso(const std::vector<SrsRtpPacket2*>& pkts, SrsRtcOutgoingInfo& info);
|
||||
public:
|
||||
void nack_fetch(std::vector<SrsRtpPacket2*>& pkts, uint32_t ssrc, uint16_t seq);
|
||||
void simulate_nack_drop(int nn);
|
||||
|
|
|
@ -138,7 +138,6 @@ SrsUdpMuxSender::SrsUdpMuxSender(SrsRtcServer* s)
|
|||
queue_length = 0;
|
||||
extra_ratio = 0;
|
||||
extra_queue = 0;
|
||||
gso = false;
|
||||
nn_senders = 0;
|
||||
|
||||
_srs_config->subscribe(this);
|
||||
|
@ -171,17 +170,11 @@ srs_error_t SrsUdpMuxSender::initialize(srs_netfd_t fd, int senders)
|
|||
}
|
||||
|
||||
max_sendmmsg = _srs_config->get_rtc_server_sendmmsg();
|
||||
gso = _srs_config->get_rtc_server_gso();
|
||||
queue_length = srs_max(128, _srs_config->get_rtc_server_queue_length());
|
||||
nn_senders = senders;
|
||||
|
||||
// For no GSO, we need larger queue.
|
||||
if (!gso) {
|
||||
queue_length *= 2;
|
||||
}
|
||||
|
||||
srs_trace("RTC sender #%d init ok, max_sendmmsg=%d, gso=%d, queue_max=%dx%d, extra_ratio=%d/%d", srs_netfd_fileno(fd),
|
||||
max_sendmmsg, gso, queue_length, nn_senders, extra_ratio, extra_queue);
|
||||
srs_trace("RTC sender #%d init ok, max_sendmmsg=%d, queue_max=%dx%d, extra_ratio=%d/%d", srs_netfd_fileno(fd),
|
||||
max_sendmmsg, queue_length, nn_senders, extra_ratio, extra_queue);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -252,8 +245,8 @@ void SrsUdpMuxSender::set_extra_ratio(int r)
|
|||
extra_ratio = r;
|
||||
extra_queue = queue_length * r / 100;
|
||||
|
||||
srs_trace("RTC sender #%d extra queue, max_sendmmsg=%d, gso=%d, queue_max=%dx%d, extra_ratio=%d/%d, cache=%d/%d/%d", srs_netfd_fileno(lfd),
|
||||
max_sendmmsg, gso, queue_length, nn_senders, extra_ratio, extra_queue, cache_pos, (int)cache.size(), (int)hotspot.size());
|
||||
srs_trace("RTC sender #%d extra queue, max_sendmmsg=%d, queue_max=%dx%d, extra_ratio=%d/%d, cache=%d/%d/%d", srs_netfd_fileno(lfd),
|
||||
max_sendmmsg, queue_length, nn_senders, extra_ratio, extra_queue, cache_pos, (int)cache.size(), (int)hotspot.size());
|
||||
}
|
||||
|
||||
srs_error_t SrsUdpMuxSender::sendmmsg(srs_mmsghdr* hdr)
|
||||
|
@ -272,7 +265,6 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
|
||||
uint64_t nn_msgs = 0; uint64_t nn_msgs_last = 0; int nn_msgs_max = 0;
|
||||
uint64_t nn_bytes = 0; int nn_bytes_max = 0;
|
||||
uint64_t nn_gso_msgs = 0; uint64_t nn_gso_iovs = 0; int nn_gso_msgs_max = 0; int nn_gso_iovs_max = 0;
|
||||
int nn_loop = 0; int nn_wait = 0;
|
||||
srs_utime_t time_last = srs_get_system_time();
|
||||
|
||||
|
@ -290,7 +282,6 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
nn_loop++;
|
||||
|
||||
int pos = cache_pos;
|
||||
int gso_iovs = 0;
|
||||
if (pos <= 0) {
|
||||
waiting_msgs = true;
|
||||
nn_wait++;
|
||||
|
@ -302,7 +293,6 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
cache.swap(hotspot);
|
||||
cache_pos = 0;
|
||||
|
||||
int gso_pos = 0;
|
||||
int nn_writen = 0;
|
||||
if (pos > 0) {
|
||||
// Send out all messages.
|
||||
|
@ -322,22 +312,6 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
stat->perf_on_sendmmsg_packets(vlen);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect informations for GSO.
|
||||
if (stat_enabled) {
|
||||
// Stat the messages, iovs and bytes.
|
||||
// @see https://linux.die.net/man/2/sendmmsg
|
||||
// @see https://linux.die.net/man/2/sendmsg
|
||||
for (int i = 0; i < pos; i++) {
|
||||
srs_mmsghdr* mhdr = &hotspot[i];
|
||||
|
||||
nn_writen += (int)mhdr->msg_len;
|
||||
|
||||
int real_iovs = mhdr->msg_hdr.msg_iovlen;
|
||||
gso_pos++; nn_gso_msgs++; nn_gso_iovs += real_iovs;
|
||||
gso_iovs += real_iovs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!stat_enabled) {
|
||||
|
@ -345,12 +319,10 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
}
|
||||
|
||||
// Increase total messages.
|
||||
nn_msgs += pos + gso_iovs;
|
||||
nn_msgs += pos;
|
||||
nn_msgs_max = srs_max(pos, nn_msgs_max);
|
||||
nn_bytes += nn_writen;
|
||||
nn_bytes_max = srs_max(nn_bytes_max, nn_writen);
|
||||
nn_gso_msgs_max = srs_max(gso_pos, nn_gso_msgs_max);
|
||||
nn_gso_iovs_max = srs_max(gso_iovs, nn_gso_iovs_max);
|
||||
|
||||
pprint->elapse();
|
||||
if (pprint->can_print()) {
|
||||
|
@ -379,12 +351,11 @@ srs_error_t SrsUdpMuxSender::cycle()
|
|||
nn_cache += hdr->msg_hdr.msg_iovlen;
|
||||
}
|
||||
|
||||
srs_trace("-> RTC SEND #%d, sessions %d, udp %d/%d/%" PRId64 ", gso %d/%d/%" PRId64 ", iovs %d/%d/%" PRId64 ", pps %d/%d%s, cache %d/%d, bytes %d/%" PRId64,
|
||||
srs_netfd_fileno(lfd), (int)server->nn_sessions(), pos, nn_msgs_max, nn_msgs, gso_pos, nn_gso_msgs_max, nn_gso_msgs, gso_iovs,
|
||||
nn_gso_iovs_max, nn_gso_iovs, pps_average, pps_last, pps_unit.c_str(), (int)hotspot.size(), nn_cache, nn_bytes_max, nn_bytes);
|
||||
srs_trace("-> RTC SEND #%d, sessions %d, udp %d/%d/%" PRId64 ", pps %d/%d%s, cache %d/%d, bytes %d/%" PRId64,
|
||||
srs_netfd_fileno(lfd), (int)server->nn_sessions(), pos, nn_msgs_max, nn_msgs, pps_average, pps_last, pps_unit.c_str(),
|
||||
(int)hotspot.size(), nn_cache, nn_bytes_max, nn_bytes);
|
||||
nn_msgs_last = nn_msgs; time_last = srs_get_system_time();
|
||||
nn_loop = nn_wait = nn_msgs_max = 0;
|
||||
nn_gso_msgs_max = 0; nn_gso_iovs_max = 0;
|
||||
nn_bytes_max = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -268,7 +268,6 @@ SrsStatistic::SrsStatistic()
|
|||
perf_iovs = new SrsStatisticCategory();
|
||||
perf_msgs = new SrsStatisticCategory();
|
||||
perf_sendmmsg = new SrsStatisticCategory();
|
||||
perf_gso = new SrsStatisticCategory();
|
||||
perf_rtp = new SrsStatisticCategory();
|
||||
perf_rtc = new SrsStatisticCategory();
|
||||
perf_bytes = new SrsStatisticCategory();
|
||||
|
@ -310,7 +309,6 @@ SrsStatistic::~SrsStatistic()
|
|||
srs_freep(perf_iovs);
|
||||
srs_freep(perf_msgs);
|
||||
srs_freep(perf_sendmmsg);
|
||||
srs_freep(perf_gso);
|
||||
srs_freep(perf_rtp);
|
||||
srs_freep(perf_rtc);
|
||||
srs_freep(perf_bytes);
|
||||
|
@ -625,16 +623,6 @@ srs_error_t SrsStatistic::dumps_perf_rtp_packets(SrsJsonObject* obj)
|
|||
return dumps_perf(perf_rtp, obj);
|
||||
}
|
||||
|
||||
void SrsStatistic::perf_on_gso_packets(int nb_packets)
|
||||
{
|
||||
perf_on_packets(perf_gso, nb_packets);
|
||||
}
|
||||
|
||||
srs_error_t SrsStatistic::dumps_perf_gso(SrsJsonObject* obj)
|
||||
{
|
||||
return dumps_perf(perf_gso, obj);
|
||||
}
|
||||
|
||||
void SrsStatistic::perf_on_writev_iovs(int nb_iovs)
|
||||
{
|
||||
perf_on_packets(perf_iovs, nb_iovs);
|
||||
|
@ -706,7 +694,6 @@ void SrsStatistic::reset_perf()
|
|||
srs_freep(perf_iovs);
|
||||
srs_freep(perf_msgs);
|
||||
srs_freep(perf_sendmmsg);
|
||||
srs_freep(perf_gso);
|
||||
srs_freep(perf_rtp);
|
||||
srs_freep(perf_rtc);
|
||||
srs_freep(perf_bytes);
|
||||
|
@ -715,7 +702,6 @@ void SrsStatistic::reset_perf()
|
|||
perf_iovs = new SrsStatisticCategory();
|
||||
perf_msgs = new SrsStatisticCategory();
|
||||
perf_sendmmsg = new SrsStatisticCategory();
|
||||
perf_gso = new SrsStatisticCategory();
|
||||
perf_rtp = new SrsStatisticCategory();
|
||||
perf_rtc = new SrsStatisticCategory();
|
||||
perf_bytes = new SrsStatisticCategory();
|
||||
|
|
|
@ -248,11 +248,6 @@ public:
|
|||
// For example, a RTC/opus packet maybe package to three RTP packets.
|
||||
virtual void perf_on_rtp_packets(int nb_packets);
|
||||
virtual srs_error_t dumps_perf_rtp_packets(SrsJsonObject* obj);
|
||||
public:
|
||||
// Stat for packets UDP GSO, nb_packets is the merged RTP packets.
|
||||
// For example, three RTP/audio packets maybe GSO to one msghdr.
|
||||
virtual void perf_on_gso_packets(int nb_packets);
|
||||
virtual srs_error_t dumps_perf_gso(SrsJsonObject* obj);
|
||||
public:
|
||||
// Stat for TCP writev, nb_iovs is the total number of iovec.
|
||||
virtual void perf_on_writev_iovs(int nb_iovs);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue