初步实现twcc rtcp发送

This commit is contained in:
xiongziliang 2021-10-07 14:22:12 +08:00
parent ea1fa03f13
commit 29cc6a94f2
4 changed files with 35 additions and 15 deletions

View File

@ -19,10 +19,10 @@ enum class ExtSeqStatus : int {
jumped, jumped,
}; };
void TwccContext::onRtp(uint16_t twcc_ext_seq) { void TwccContext::onRtp(uint32_t ssrc, uint16_t twcc_ext_seq) {
switch ((ExtSeqStatus) checkSeqStatus(twcc_ext_seq)) { switch ((ExtSeqStatus) checkSeqStatus(twcc_ext_seq)) {
case ExtSeqStatus::jumped: /*回环后收到回环前的大ext seq包,过滤掉*/ return; case ExtSeqStatus::jumped: /*回环后收到回环前的大ext seq包,过滤掉*/ return;
case ExtSeqStatus::looped: /*回环触发发送twcc rtcp*/ onSendTwcc(); break; case ExtSeqStatus::looped: /*回环触发发送twcc rtcp*/ onSendTwcc(ssrc); break;
case ExtSeqStatus::normal: break; case ExtSeqStatus::normal: break;
default: /*不可达*/assert(0); break; default: /*不可达*/assert(0); break;
} }
@ -40,7 +40,7 @@ void TwccContext::onRtp(uint16_t twcc_ext_seq) {
if (checkIfNeedSendTwcc()) { if (checkIfNeedSendTwcc()) {
//其他匹配条件立即发送twcc //其他匹配条件立即发送twcc
onSendTwcc(); onSendTwcc(ssrc);
} }
} }
@ -76,11 +76,12 @@ int TwccContext::checkSeqStatus(uint16_t twcc_ext_seq) const {
return (int) ExtSeqStatus::normal; return (int) ExtSeqStatus::normal;
} }
void TwccContext::onSendTwcc() { void TwccContext::onSendTwcc(uint32_t ssrc) {
auto max = _rtp_recv_status.rbegin()->first; auto max = _rtp_recv_status.rbegin()->first;
auto begin = _rtp_recv_status.begin(); auto begin = _rtp_recv_status.begin();
auto min = begin->first; auto min = begin->first;
auto ref_time = begin->second; auto ref_time = begin->second >> 6;
auto last_time = ref_time << 6;
FCI_TWCC::TwccPacketStatus status; FCI_TWCC::TwccPacketStatus status;
for (auto seq = min; seq <= max; ++seq) { for (auto seq = min; seq <= max; ++seq) {
int16_t delta = 0; int16_t delta = 0;
@ -88,20 +89,20 @@ void TwccContext::onSendTwcc() {
auto it = _rtp_recv_status.find(seq); auto it = _rtp_recv_status.find(seq);
if (it != _rtp_recv_status.end()) { if (it != _rtp_recv_status.end()) {
//recv delta,单位为250us,1ms等于4x250us //recv delta,单位为250us,1ms等于4x250us
delta = (int16_t) (4 * ((int64_t) it->second - (int64_t) ref_time)); delta = (int16_t) (4 * ((int64_t) it->second - (int64_t) last_time));
if (delta < 0 || delta > 0xFF) { if (delta < 0 || delta > 0xFF) {
symbol = SymbolStatus::large_delta; symbol = SymbolStatus::large_delta;
} else { } else {
symbol = SymbolStatus::small_delta; symbol = SymbolStatus::small_delta;
} }
ref_time = it->second; last_time = it->second;
} }
status.emplace(seq, std::make_pair(symbol, delta)); status.emplace(seq, std::make_pair(symbol, delta));
} }
auto fci = FCI_TWCC::create(ref_time / 64, _twcc_pkt_count, status); auto fci = FCI_TWCC::create(ref_time, _twcc_pkt_count++, status);
InfoL << ((FCI_TWCC *) (fci.data()))->dumpString(fci.size()); if (_cb) {
_cb(ssrc, std::move(fci));
++_twcc_pkt_count; }
clearStatus(); clearStatus();
} }
@ -109,3 +110,7 @@ void TwccContext::clearStatus() {
_rtp_recv_status.clear(); _rtp_recv_status.clear();
_min_stamp = 0; _min_stamp = 0;
} }
void TwccContext::setOnSendTwccCB(TwccContext::onSendTwccCB cb) {
_cb = std::move(cb);
}

View File

@ -18,18 +18,20 @@ using namespace toolkit;
class TwccContext { class TwccContext {
public: public:
using onSendTwccCB = function<void(uint32_t ssrc, string fci)>;
//每个twcc rtcp包最多表明的rtp ext seq增量 //每个twcc rtcp包最多表明的rtp ext seq增量
static constexpr size_t kMaxSeqDelta = 20; static constexpr size_t kMaxSeqDelta = 20;
//每个twcc rtcp包发送的最大时间间隔单位毫秒 //每个twcc rtcp包发送的最大时间间隔单位毫秒
static constexpr size_t kMaxTimeDelta = 64; static constexpr size_t kMaxTimeDelta = 256;
TwccContext() = default; TwccContext() = default;
~TwccContext() = default; ~TwccContext() = default;
void onRtp(uint16_t twcc_ext_seq); void onRtp(uint32_t ssrc, uint16_t twcc_ext_seq);
void setOnSendTwccCB(onSendTwccCB cb);
private: private:
void onSendTwcc(); void onSendTwcc(uint32_t ssrc);
bool checkIfNeedSendTwcc() const; bool checkIfNeedSendTwcc() const;
int checkSeqStatus(uint16_t twcc_ext_seq) const; int checkSeqStatus(uint16_t twcc_ext_seq) const;
void clearStatus(); void clearStatus();
@ -40,6 +42,7 @@ private:
uint64_t _max_stamp; uint64_t _max_stamp;
std::map<uint32_t /*twcc_ext_seq*/, uint64_t/*recv time in ms*/> _rtp_recv_status; std::map<uint32_t /*twcc_ext_seq*/, uint64_t/*recv time in ms*/> _rtp_recv_status;
uint8_t _twcc_pkt_count = 0; uint8_t _twcc_pkt_count = 0;
onSendTwccCB _cb;
}; };

View File

@ -332,6 +332,10 @@ void WebRtcTransportImp::onCreate(){
} }
return true; return true;
}, getPoller()); }, getPoller());
_twcc_ctx.setOnSendTwccCB([this](uint32_t ssrc, string fci) {
onSendTwcc(ssrc, fci);
});
} }
WebRtcTransportImp::WebRtcTransportImp(const EventPoller::Ptr &poller) : WebRtcTransport(poller) { WebRtcTransportImp::WebRtcTransportImp(const EventPoller::Ptr &poller) : WebRtcTransport(poller) {
@ -810,7 +814,7 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) {
string rid; string rid;
auto twcc_ext = track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc); auto twcc_ext = track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc);
if (twcc_ext && !is_rtx) { if (twcc_ext && !is_rtx) {
_twcc_ctx.onRtp(twcc_ext.getTransportCCSeq()); _twcc_ctx.onRtp(ssrc, twcc_ext.getTransportCCSeq());
} }
auto &ref = track->rtp_channel[rid]; auto &ref = track->rtp_channel[rid];
@ -865,6 +869,13 @@ void WebRtcTransportImp::onSendNack(MediaTrack &track, const FCI_NACK &nack, uin
sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true); sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true);
} }
void WebRtcTransportImp::onSendTwcc(uint32_t ssrc, const string &twcc_fci) {
auto rtcp = RtcpFB::create(RTPFBType::RTCP_RTPFB_TWCC, twcc_fci.data(), twcc_fci.size());
rtcp->ssrc = htons(0);
rtcp->ssrc_media = htonl(ssrc);
sendRtcpPacket((char *) rtcp.get(), rtcp->getSize(), true);
}
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp) { void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp) {

View File

@ -217,6 +217,7 @@ private:
void onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp); void onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp);
void onSendNack(MediaTrack &track, const FCI_NACK &nack, uint32_t ssrc); void onSendNack(MediaTrack &track, const FCI_NACK &nack, uint32_t ssrc);
void onSendTwcc(uint32_t ssrc, const string &twcc_fci);
void createRtpChannel(const string &rid, uint32_t ssrc, MediaTrack &track); void createRtpChannel(const string &rid, uint32_t ssrc, MediaTrack &track);
void registerSelf(); void registerSelf();
void unregisterSelf(); void unregisterSelf();