Commit 726e9096 by xia-chu

支持remb控制推流比特率

parent 9396270c
...@@ -211,6 +211,8 @@ timeoutSec=15 ...@@ -211,6 +211,8 @@ timeoutSec=15
timeoutSec=15 timeoutSec=15
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip #本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip
externIP= externIP=
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
rembBitRate=1000000
[rtsp] [rtsp]
#rtsp专有鉴权方式是采用base64还是md5方式 #rtsp专有鉴权方式是采用base64还是md5方式
......
...@@ -1241,10 +1241,18 @@ const RtcMedia *RtcSession::getMedia(TrackType type) const{ ...@@ -1241,10 +1241,18 @@ const RtcMedia *RtcSession::getMedia(TrackType type) const{
return nullptr; 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 kTWCCRtcpFb = "transport-cc";
static string const kTWCCExtMap = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01"; static string const kTWCCExtMap = "http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01";
void RtcConfigure::RtcTrackConfigure::enableTWCC(bool enable){ void RtcConfigure::RtcTrackConfigure::enableTWCC(bool enable){
if (!enable) { if (!enable) {
rtcp_fb.erase(kTWCCRtcpFb); rtcp_fb.erase(kTWCCRtcpFb);
......
...@@ -667,6 +667,7 @@ public: ...@@ -667,6 +667,7 @@ public:
string toString() const; string toString() const;
string toRtspSdp() const; string toRtspSdp() const;
const RtcMedia *getMedia(TrackType type) const; const RtcMedia *getMedia(TrackType type) const;
bool supportRtcpFb(const string &name, TrackType type = TrackType::TrackVideo) const;
private: private:
RtcSessionSdp::Ptr toRtcSessionSdp() const; RtcSessionSdp::Ptr toRtcSessionSdp() const;
......
...@@ -11,7 +11,9 @@ ...@@ -11,7 +11,9 @@
#include "WebRtcTransport.h" #include "WebRtcTransport.h"
#include <iostream> #include <iostream>
#include "Rtcp/Rtcp.h" #include "Rtcp/Rtcp.h"
#include "Rtcp/RtcpFCI.h"
#include "Rtsp/RtpReceiver.h" #include "Rtsp/RtpReceiver.h"
#define RTX_SSRC_OFFSET 2 #define RTX_SSRC_OFFSET 2
#define RTP_CNAME "zlmediakit-rtp" #define RTP_CNAME "zlmediakit-rtp"
#define RTX_CNAME "zlmediakit-rtx" #define RTX_CNAME "zlmediakit-rtx"
...@@ -23,10 +25,13 @@ namespace RTC { ...@@ -23,10 +25,13 @@ namespace RTC {
const string kTimeOutSec = RTC_FIELD"timeoutSec"; const string kTimeOutSec = RTC_FIELD"timeoutSec";
//服务器外网ip //服务器外网ip
const string kExternIP = RTC_FIELD"externIP"; const string kExternIP = RTC_FIELD"externIP";
//设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
const string kRembBitRate = RTC_FIELD"rembBitRate";
static onceToken token([]() { static onceToken token([]() {
mINI::Instance()[kTimeOutSec] = 15; mINI::Instance()[kTimeOutSec] = 15;
mINI::Instance()[kExternIP] = ""; mINI::Instance()[kExternIP] = "";
mINI::Instance()[kRembBitRate] = 0;
}); });
}//namespace RTC }//namespace RTC
...@@ -134,6 +139,22 @@ RTC::TransportTuple* WebRtcTransport::getSelectedTuple() const{ ...@@ -134,6 +139,22 @@ RTC::TransportTuple* WebRtcTransport::getSelectedTuple() const{
return _ice_server->GetSelectedTuple(); 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){ string getFingerprint(const string &algorithm_str, const std::shared_ptr<RTC::DtlsTransport> &transport){
auto algorithm = RTC::DtlsTransport::GetFingerprintAlgorithm(algorithm_str); auto algorithm = RTC::DtlsTransport::GetFingerprintAlgorithm(algorithm_str);
for (auto &finger_prints : transport->GetLocalFingerprints()) { for (auto &finger_prints : transport->GetLocalFingerprints()) {
...@@ -163,6 +184,12 @@ void WebRtcTransport::onCheckSdp(SdpType type, RtcSession &sdp){ ...@@ -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){ std::string WebRtcTransport::getAnswerSdp(const string &offer){
try { try {
//// 解析offer sdp //// //// 解析offer sdp ////
...@@ -389,6 +416,10 @@ void WebRtcTransportImp::onStartWebRTC() { ...@@ -389,6 +416,10 @@ void WebRtcTransportImp::onStartWebRTC() {
if (canRecvRtp()) { if (canRecvRtp()) {
_push_src->setSdp(getSdp(SdpType::answer).toRtspSdp()); _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()) { if (canSendRtp()) {
_reader = _play_src->getRing()->attach(getPoller(), true); _reader = _play_src->getRing()->attach(getPoller(), true);
...@@ -592,10 +623,7 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr ...@@ -592,10 +623,7 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
if (_pli_ticker.elapsedTime() > 2000) { if (_pli_ticker.elapsedTime() > 2000) {
//定期发送pli请求关键帧,方便非rtc等协议 //定期发送pli请求关键帧,方便非rtc等协议
_pli_ticker.resetTime(); _pli_ticker.resetTime();
auto pli = RtcpFB::create(PSFBType::RTCP_PSFB_PLI); sendRtcpPli(_recv_video_ssrc);
pli->ssrc = htonl(0);
pli->ssrc_media = htonl(_recv_video_ssrc);
sendRtcpPacket((char *) pli.get(), pli->getSize(), true);
} }
if (_push_src) { if (_push_src) {
_push_src->onWrite(std::move(rtp), false); _push_src->onWrite(std::move(rtp), false);
......
...@@ -93,7 +93,7 @@ protected: ...@@ -93,7 +93,7 @@ protected:
protected: protected:
virtual void onStartWebRTC() = 0; 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 onCheckSdp(SdpType type, RtcSession &sdp);
virtual void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) = 0; virtual void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) = 0;
...@@ -104,6 +104,8 @@ protected: ...@@ -104,6 +104,8 @@ protected:
protected: protected:
const RtcSession& getSdp(SdpType type) const; const RtcSession& getSdp(SdpType type) const;
RTC::TransportTuple* getSelectedTuple() const; RTC::TransportTuple* getSelectedTuple() const;
void sendRtcpRemb(uint32_t ssrc, size_t bit_rate);
void sendRtcpPli(uint32_t ssrc);
private: private:
void onSendSockData(const char *buf, size_t len, bool flush = true); void onSendSockData(const char *buf, size_t len, bool flush = true);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论