支持remb控制推流比特率

This commit is contained in:
xia-chu 2021-04-28 15:41:36 +08:00
parent 9396270ce2
commit 726e909601
5 changed files with 47 additions and 6 deletions

View File

@ -211,6 +211,8 @@ timeoutSec=15
timeoutSec=15
#本机对rtc客户端的可见ip作为服务器时一般为公网ip置空时会自动获取网卡ip
externIP=
#设置remb比特率非0时关闭twcc并开启remb。该设置在rtc推流时有效可以控制推流画质
rembBitRate=1000000
[rtsp]
#rtsp专有鉴权方式是采用base64还是md5方式

View File

@ -1241,10 +1241,18 @@ const RtcMedia *RtcSession::getMedia(TrackType type) const{
return nullptr;
}
bool RtcSession::supportRtcpFb(const string &name, TrackType type) const {
auto media = getMedia(type);
if (!media) {
return false;
}
auto &ref = media->plan[0].rtcp_fb;
return ref.find(name) != ref.end();
}
static string const kTWCCRtcpFb = "transport-cc";
static string const kTWCCExtMap = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01";
void RtcConfigure::RtcTrackConfigure::enableTWCC(bool enable){
if (!enable) {
rtcp_fb.erase(kTWCCRtcpFb);

View File

@ -667,6 +667,7 @@ public:
string toString() const;
string toRtspSdp() const;
const RtcMedia *getMedia(TrackType type) const;
bool supportRtcpFb(const string &name, TrackType type = TrackType::TrackVideo) const;
private:
RtcSessionSdp::Ptr toRtcSessionSdp() const;

View File

@ -11,7 +11,9 @@
#include "WebRtcTransport.h"
#include <iostream>
#include "Rtcp/Rtcp.h"
#include "Rtcp/RtcpFCI.h"
#include "Rtsp/RtpReceiver.h"
#define RTX_SSRC_OFFSET 2
#define RTP_CNAME "zlmediakit-rtp"
#define RTX_CNAME "zlmediakit-rtx"
@ -23,10 +25,13 @@ namespace RTC {
const string kTimeOutSec = RTC_FIELD"timeoutSec";
//服务器外网ip
const string kExternIP = RTC_FIELD"externIP";
//设置remb比特率非0时关闭twcc并开启remb。该设置在rtc推流时有效可以控制推流画质
const string kRembBitRate = RTC_FIELD"rembBitRate";
static onceToken token([]() {
mINI::Instance()[kTimeOutSec] = 15;
mINI::Instance()[kExternIP] = "";
mINI::Instance()[kRembBitRate] = 0;
});
}//namespace RTC
@ -134,6 +139,22 @@ RTC::TransportTuple* WebRtcTransport::getSelectedTuple() const{
return _ice_server->GetSelectedTuple();
}
void WebRtcTransport::sendRtcpRemb(uint32_t ssrc, size_t bit_rate) {
auto remb = FCI_REMB::create({ssrc}, (uint32_t)bit_rate);
auto fb = RtcpFB::create(PSFBType::RTCP_PSFB_REMB, remb.data(), remb.size());
fb->ssrc = htonl(0);
fb->ssrc_media = htonl(ssrc);
sendRtcpPacket((char *) fb.get(), fb->getSize(), true);
TraceL << ssrc << " " << bit_rate;
}
void WebRtcTransport::sendRtcpPli(uint32_t ssrc) {
auto pli = RtcpFB::create(PSFBType::RTCP_PSFB_PLI);
pli->ssrc = htonl(0);
pli->ssrc_media = htonl(ssrc);
sendRtcpPacket((char *) pli.get(), pli->getSize(), true);
}
string getFingerprint(const string &algorithm_str, const std::shared_ptr<RTC::DtlsTransport> &transport){
auto algorithm = RTC::DtlsTransport::GetFingerprintAlgorithm(algorithm_str);
for (auto &finger_prints : transport->GetLocalFingerprints()) {
@ -163,6 +184,12 @@ void WebRtcTransport::onCheckSdp(SdpType type, RtcSession &sdp){
}
}
void WebRtcTransport::onRtcConfigure(RtcConfigure &configure) const {
//开启remb后关闭twcc因为开启twcc后remb无效
GET_CONFIG(size_t, remb_bit_rate, RTC::kRembBitRate);
configure.enableTWCC(!remb_bit_rate);
}
std::string WebRtcTransport::getAnswerSdp(const string &offer){
try {
//// 解析offer sdp ////
@ -389,6 +416,10 @@ void WebRtcTransportImp::onStartWebRTC() {
if (canRecvRtp()) {
_push_src->setSdp(getSdp(SdpType::answer).toRtspSdp());
GET_CONFIG(size_t, remb_bit_rate, RTC::kRembBitRate);
if (remb_bit_rate && getSdp(SdpType::answer).supportRtcpFb("goog-remb")) {
sendRtcpRemb(_recv_video_ssrc, remb_bit_rate);
}
}
if (canSendRtp()) {
_reader = _play_src->getRing()->attach(getPoller(), true);
@ -592,10 +623,7 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
if (_pli_ticker.elapsedTime() > 2000) {
//定期发送pli请求关键帧方便非rtc等协议
_pli_ticker.resetTime();
auto pli = RtcpFB::create(PSFBType::RTCP_PSFB_PLI);
pli->ssrc = htonl(0);
pli->ssrc_media = htonl(_recv_video_ssrc);
sendRtcpPacket((char *) pli.get(), pli->getSize(), true);
sendRtcpPli(_recv_video_ssrc);
}
if (_push_src) {
_push_src->onWrite(std::move(rtp), false);

View File

@ -93,7 +93,7 @@ protected:
protected:
virtual void onStartWebRTC() = 0;
virtual void onRtcConfigure(RtcConfigure &configure) const {}
virtual void onRtcConfigure(RtcConfigure &configure) const;
virtual void onCheckSdp(SdpType type, RtcSession &sdp);
virtual void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) = 0;
@ -104,6 +104,8 @@ protected:
protected:
const RtcSession& getSdp(SdpType type) const;
RTC::TransportTuple* getSelectedTuple() const;
void sendRtcpRemb(uint32_t ssrc, size_t bit_rate);
void sendRtcpPli(uint32_t ssrc);
private:
void onSendSockData(const char *buf, size_t len, bool flush = true);