mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
支持remb控制推流比特率
This commit is contained in:
parent
9396270ce2
commit
726e909601
@ -211,6 +211,8 @@ timeoutSec=15
|
||||
timeoutSec=15
|
||||
#本机对rtc客户端的可见ip,作为服务器时一般为公网ip,置空时,会自动获取网卡ip
|
||||
externIP=
|
||||
#设置remb比特率,非0时关闭twcc并开启remb。该设置在rtc推流时有效,可以控制推流画质
|
||||
rembBitRate=1000000
|
||||
|
||||
[rtsp]
|
||||
#rtsp专有鉴权方式是采用base64还是md5方式
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user