mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
refactor: 梳理 rtx 处理逻辑
This commit is contained in:
parent
b13a0f5b79
commit
da0a7219e9
@ -385,10 +385,10 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
_ssrc_to_track[track->offer_ssrc_rtx] = track;
|
_ssrc_to_track[track->offer_ssrc_rtx] = track;
|
||||||
|
|
||||||
//rtp pt --> MediaTrack
|
//rtp pt --> MediaTrack
|
||||||
_pt_to_track.emplace(track->plan_rtp->pt, std::make_pair(false, track));
|
_pt_to_track.emplace(track->plan_rtp->pt, new WrappedRtpTrack(track, _twcc_ctx, *this));
|
||||||
if (track->plan_rtx) {
|
if (track->plan_rtx) {
|
||||||
//rtx pt --> MediaTrack
|
//rtx pt --> MediaTrack
|
||||||
_pt_to_track.emplace(track->plan_rtx->pt, std::make_pair(true, track));
|
_pt_to_track.emplace(track->plan_rtx->pt, new WrappedRtxTrack(track));
|
||||||
}
|
}
|
||||||
if (m_offer->type != TrackApplication) {
|
if (m_offer->type != TrackApplication) {
|
||||||
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
||||||
@ -691,28 +691,25 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
|
|||||||
WarnL << "unknown rtp pt:" << (int)rtp->pt;
|
WarnL << "unknown rtp pt:" << (int)rtp->pt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool is_rtx = it->second.first;
|
it->second->inputRtp(buf, len, stamp_ms, rtp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) {
|
||||||
auto ssrc = ntohl(rtp->ssrc);
|
auto ssrc = ntohl(rtp->ssrc);
|
||||||
auto &track = it->second.second;
|
|
||||||
|
|
||||||
//修改ext id至统一
|
//修改ext id至统一
|
||||||
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) {
|
||||||
_twcc_ctx.onRtp(ssrc, twcc_ext.getTransportCCSeq(), stamp_ms);
|
_twcc_ctx.onRtp(ssrc, twcc_ext.getTransportCCSeq(), stamp_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &ref = track->rtp_channel[rid];
|
auto &ref = track->rtp_channel[rid];
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
if (is_rtx) {
|
_transport.createRtpChannel(rid, ssrc, *track);
|
||||||
//再接收到对应的rtp前,丢弃rtx包
|
|
||||||
WarnL << "unknown rtx rtp, rid:" << rid << ", ssrc:" << ssrc << ", codec:" << track->plan_rtp->codec << ", seq:" << ntohs(rtp->seq);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
createRtpChannel(rid, ssrc, *track);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_rtx) {
|
|
||||||
//这是普通的rtp数据
|
//这是普通的rtp数据
|
||||||
#if 0
|
#if 0
|
||||||
auto seq = ntohs(rtp->seq);
|
auto seq = ntohs(rtp->seq);
|
||||||
@ -723,11 +720,22 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
|
|||||||
#endif
|
#endif
|
||||||
//解析并排序rtp
|
//解析并排序rtp
|
||||||
ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *) buf, len, false);
|
ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *) buf, len, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WrappedRtxTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) {
|
||||||
|
//修改ext id至统一
|
||||||
|
string rid;
|
||||||
|
track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc);
|
||||||
|
|
||||||
|
auto &ref = track->rtp_channel[rid];
|
||||||
|
if (!ref) {
|
||||||
|
//再接收到对应的rtp前,丢弃rtx包
|
||||||
|
WarnL << "unknown rtx rtp, rid:" << rid << ", ssrc:" << ntohl(rtp->ssrc) << ", codec:" << track->plan_rtp->codec << ", seq:" << ntohs(rtp->seq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//这里是rtx重传包
|
//这里是rtx重传包
|
||||||
//https://datatracker.ietf.org/doc/html/rfc4588#section-4
|
// https://datatracker.ietf.org/doc/html/rfc4588#section-4
|
||||||
auto payload = rtp->getPayloadData();
|
auto payload = rtp->getPayloadData();
|
||||||
auto size = rtp->getPayloadSize(len);
|
auto size = rtp->getPayloadSize(len);
|
||||||
if (size < 2) {
|
if (size < 2) {
|
||||||
@ -736,7 +744,7 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
|
|||||||
|
|
||||||
//前两个字节是原始的rtp的seq
|
//前两个字节是原始的rtp的seq
|
||||||
auto origin_seq = payload[0] << 8 | payload[1];
|
auto origin_seq = payload[0] << 8 | payload[1];
|
||||||
//rtx 转换为 rtp
|
// rtx 转换为 rtp
|
||||||
rtp->pt = track->plan_rtp->pt;
|
rtp->pt = track->plan_rtp->pt;
|
||||||
rtp->seq = htons(origin_seq);
|
rtp->seq = htons(origin_seq);
|
||||||
rtp->ssrc = htonl(ref->getSSRC());
|
rtp->ssrc = htonl(ref->getSSRC());
|
||||||
|
@ -189,6 +189,33 @@ public:
|
|||||||
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct WrappedMediaTrack {
|
||||||
|
MediaTrack::Ptr track;
|
||||||
|
explicit WrappedMediaTrack(MediaTrack::Ptr ptr): track(ptr) {}
|
||||||
|
virtual ~WrappedMediaTrack() {}
|
||||||
|
virtual void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WrappedRtxTrack: public WrappedMediaTrack {
|
||||||
|
explicit WrappedRtxTrack(MediaTrack::Ptr ptr)
|
||||||
|
: WrappedMediaTrack(std::move(ptr)) {}
|
||||||
|
void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WebRtcTransportImp;
|
||||||
|
|
||||||
|
struct WrappedRtpTrack : public WrappedMediaTrack {
|
||||||
|
explicit WrappedRtpTrack(MediaTrack::Ptr ptr, TwccContext& twcc, WebRtcTransportImp& t)
|
||||||
|
: WrappedMediaTrack(std::move(ptr))
|
||||||
|
, _twcc_ctx(twcc)
|
||||||
|
, _transport(t) {}
|
||||||
|
TwccContext& _twcc_ctx;
|
||||||
|
WebRtcTransportImp& _transport;
|
||||||
|
void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class WebRtcTransportImp : public WebRtcTransport {
|
class WebRtcTransportImp : public WebRtcTransport {
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
||||||
@ -202,6 +229,8 @@ public:
|
|||||||
bool canRecvRtp() const;
|
bool canRecvRtp() const;
|
||||||
void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false);
|
void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false);
|
||||||
|
|
||||||
|
void createRtpChannel(const string &rid, uint32_t ssrc, MediaTrack &track);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
WebRtcTransportImp(const EventPoller::Ptr &poller);
|
WebRtcTransportImp(const EventPoller::Ptr &poller);
|
||||||
void onStartWebRTC() override;
|
void onStartWebRTC() override;
|
||||||
@ -224,7 +253,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 onSendTwcc(uint32_t ssrc, const string &twcc_fci);
|
||||||
void createRtpChannel(const string &rid, uint32_t ssrc, MediaTrack &track);
|
|
||||||
void registerSelf();
|
void registerSelf();
|
||||||
void unregisterSelf();
|
void unregisterSelf();
|
||||||
void unrefSelf();
|
void unrefSelf();
|
||||||
@ -251,7 +280,7 @@ private:
|
|||||||
//根据rtcp的ssrc获取相关信息,收发rtp和rtx的ssrc都会记录
|
//根据rtcp的ssrc获取相关信息,收发rtp和rtx的ssrc都会记录
|
||||||
unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
|
unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
|
||||||
//根据接收rtp的pt获取相关信息
|
//根据接收rtp的pt获取相关信息
|
||||||
unordered_map<uint8_t/*pt*/, std::pair<bool/*is rtx*/,MediaTrack::Ptr> > _pt_to_track;
|
unordered_map<uint8_t/*pt*/, std::unique_ptr<WrappedMediaTrack>> _pt_to_track;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WebRtcTransportManager {
|
class WebRtcTransportManager {
|
||||||
|
Loading…
Reference in New Issue
Block a user