mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 14:45:55 +08:00
初步实现twcc rtcp发送
This commit is contained in:
parent
ea1fa03f13
commit
29cc6a94f2
@ -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);
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user