mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
抽象RtpExtContext对象
This commit is contained in:
parent
964cf39145
commit
7406281c96
@ -562,3 +562,72 @@ void RtpExt::setType(RtpExtType type) {
|
|||||||
RtpExtType RtpExt::getType() const {
|
RtpExtType RtpExt::getType() const {
|
||||||
return _type;
|
return _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtpExtContext::RtpExtContext(const RtcMedia &m){
|
||||||
|
for (auto &ext : m.extmap) {
|
||||||
|
auto ext_type = RtpExt::getExtType(ext.ext);
|
||||||
|
_rtp_ext_id_to_type.emplace(ext.id, ext_type);
|
||||||
|
_rtp_ext_type_to_id.emplace(ext_type, ext.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string RtpExtContext::getRid(uint32_t ssrc) const{
|
||||||
|
auto it = _ssrc_to_rid.find(ssrc);
|
||||||
|
if (it == _ssrc_to_rid.end()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtpExtContext::changeRtpExtId(const RtpHeader *header, bool is_recv, string *rid_ptr) {
|
||||||
|
string rid, repaired_rid;
|
||||||
|
auto ext_map = RtpExt::getExtValue(header);
|
||||||
|
for (auto &pr : ext_map) {
|
||||||
|
if (is_recv) {
|
||||||
|
auto it = _rtp_ext_id_to_type.find(pr.first);
|
||||||
|
if (it == _rtp_ext_id_to_type.end()) {
|
||||||
|
WarnL << "接收rtp时,忽略不识别的rtp ext, id=" << (int) pr.first;
|
||||||
|
pr.second.clearExt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pr.second.setType(it->second);
|
||||||
|
//重新赋值ext id为 ext type,作为后面处理ext的统一中间类型
|
||||||
|
pr.second.setExtId((uint8_t) it->second);
|
||||||
|
switch (it->second) {
|
||||||
|
case RtpExtType::sdes_rtp_stream_id : rid = pr.second.getRtpStreamId(); break;
|
||||||
|
case RtpExtType::sdes_repaired_rtp_stream_id : repaired_rid = pr.second.getRepairedRtpStreamId(); break;
|
||||||
|
default : break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pr.second.setType((RtpExtType) pr.first);
|
||||||
|
auto it = _rtp_ext_type_to_id.find((RtpExtType) pr.first);
|
||||||
|
if (it == _rtp_ext_type_to_id.end()) {
|
||||||
|
WarnL << "发送rtp时, 忽略不被客户端支持rtp ext:" << pr.second.dumpString();
|
||||||
|
pr.second.clearExt();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//重新赋值ext id为客户端sdp声明的类型
|
||||||
|
pr.second.setExtId(it->second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_recv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rid.empty()) {
|
||||||
|
rid = repaired_rid;
|
||||||
|
}
|
||||||
|
auto ssrc = ntohl(header->ssrc);
|
||||||
|
if (rid.empty()) {
|
||||||
|
//获取rid
|
||||||
|
rid = _ssrc_to_rid[ssrc];
|
||||||
|
} else {
|
||||||
|
//设置rid
|
||||||
|
if (_ssrc_to_rid.emplace(ssrc, rid).second) {
|
||||||
|
InfoL << "rid of ssrc " << ssrc << " is:" << rid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rid_ptr) {
|
||||||
|
*rid_ptr = rid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -108,5 +108,23 @@ private:
|
|||||||
RtpExtType _type = RtpExtType::padding;
|
RtpExtType _type = RtpExtType::padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RtcMedia;
|
||||||
|
class RtpExtContext {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<RtpExtContext>;
|
||||||
|
RtpExtContext(const RtcMedia &media);
|
||||||
|
~RtpExtContext() = default;
|
||||||
|
|
||||||
|
string getRid(uint32_t ssrc) const;
|
||||||
|
void changeRtpExtId(const RtpHeader *header, bool is_recv, string *rid_ptr = nullptr);
|
||||||
|
|
||||||
|
private:
|
||||||
|
//发送rtp时需要修改rtp ext id
|
||||||
|
map<RtpExtType, uint8_t> _rtp_ext_type_to_id;
|
||||||
|
//接收rtp时需要修改rtp ext id
|
||||||
|
unordered_map<uint8_t, RtpExtType> _rtp_ext_id_to_type;
|
||||||
|
//ssrc --> rid
|
||||||
|
unordered_map<uint32_t/*simulcast ssrc*/, string/*rid*/> _ssrc_to_rid;
|
||||||
|
};
|
||||||
|
|
||||||
#endif //ZLMEDIAKIT_RTPEXT_H
|
#endif //ZLMEDIAKIT_RTPEXT_H
|
||||||
|
@ -424,11 +424,7 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
}
|
}
|
||||||
if (m_offer->type != TrackApplication) {
|
if (m_offer->type != TrackApplication) {
|
||||||
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
||||||
for (auto &ext : m_offer->extmap) {
|
info->rtp_ext_ctx = std::make_shared<RtpExtContext>(*m_offer);
|
||||||
auto ext_type = RtpExt::getExtType(ext.ext);
|
|
||||||
_rtp_ext_id_to_type.emplace(ext.id, ext_type);
|
|
||||||
_rtp_ext_type_to_id.emplace(ext_type, ext.id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -596,12 +592,8 @@ private:
|
|||||||
function<void(RtpPacket::Ptr rtp)> _on_sort;
|
function<void(RtpPacket::Ptr rtp)> _on_sort;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<RtpChannel> WebRtcTransportImp::MediaTrack::getRtpChannel(uint32_t ssrc) const{
|
std::shared_ptr<RtpChannel> MediaTrack::getRtpChannel(uint32_t ssrc) const{
|
||||||
auto it_rid = ssrc_to_rid.find(ssrc);
|
auto it_chn = rtp_channel.find(rtp_ext_ctx->getRid(ssrc));
|
||||||
if (it_rid == ssrc_to_rid.end()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto it_chn = rtp_channel.find(it_rid->second);
|
|
||||||
if (it_chn == rtp_channel.end()) {
|
if (it_chn == rtp_channel.end()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -694,59 +686,6 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void WebRtcTransportImp::changeRtpExtId(MediaTrack &info, const RtpHeader *header, bool is_recv, string *rid_ptr) const{
|
|
||||||
string rid, repaired_rid;
|
|
||||||
auto ext_map = RtpExt::getExtValue(header);
|
|
||||||
for (auto &pr : ext_map) {
|
|
||||||
if (is_recv) {
|
|
||||||
auto it = _rtp_ext_id_to_type.find(pr.first);
|
|
||||||
if (it == _rtp_ext_id_to_type.end()) {
|
|
||||||
WarnL << "接收rtp时,忽略不识别的rtp ext, id=" << (int) pr.first;
|
|
||||||
pr.second.clearExt();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pr.second.setType(it->second);
|
|
||||||
//重新赋值ext id为 ext type,作为后面处理ext的统一中间类型
|
|
||||||
pr.second.setExtId((uint8_t) it->second);
|
|
||||||
switch (it->second) {
|
|
||||||
case RtpExtType::sdes_rtp_stream_id : rid = pr.second.getRtpStreamId(); break;
|
|
||||||
case RtpExtType::sdes_repaired_rtp_stream_id : repaired_rid = pr.second.getRepairedRtpStreamId(); break;
|
|
||||||
default : break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pr.second.setType((RtpExtType) pr.first);
|
|
||||||
auto it = _rtp_ext_type_to_id.find((RtpExtType) pr.first);
|
|
||||||
if (it == _rtp_ext_type_to_id.end()) {
|
|
||||||
WarnL << "发送rtp时, 忽略不被客户端支持rtp ext:" << pr.second.dumpString();
|
|
||||||
pr.second.clearExt();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
//重新赋值ext id为客户端sdp声明的类型
|
|
||||||
pr.second.setExtId(it->second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_recv) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (rid.empty()) {
|
|
||||||
rid = repaired_rid;
|
|
||||||
}
|
|
||||||
auto ssrc = ntohl(header->ssrc);
|
|
||||||
if (rid.empty()) {
|
|
||||||
//获取rid
|
|
||||||
rid = info.ssrc_to_rid[ssrc];
|
|
||||||
} else {
|
|
||||||
//设置rid
|
|
||||||
if (info.ssrc_to_rid.emplace(ssrc, rid).second) {
|
|
||||||
InfoL << "rid of ssrc " << ssrc << " is:" << rid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rid_ptr) {
|
|
||||||
*rid_ptr = rid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &info) {
|
void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &info) {
|
||||||
//rid --> RtpReceiverImp
|
//rid --> RtpReceiverImp
|
||||||
auto &ref = info->rtp_channel[rid];
|
auto &ref = info->rtp_channel[rid];
|
||||||
@ -779,13 +718,8 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) {
|
|||||||
|
|
||||||
//修改ext id至统一
|
//修改ext id至统一
|
||||||
string rid;
|
string rid;
|
||||||
changeRtpExtId(*info, rtp, true, &rid);
|
info->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (rid.empty() && info->media->type == TrackVideo) {
|
|
||||||
WarnL << "ssrc:" << ssrc << ", rtx:" << is_rtx << ",seq:" << ntohs((uint16_t) rtp->seq);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
auto &ref = info->rtp_channel[rid];
|
auto &ref = info->rtp_channel[rid];
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
if (is_rtx) {
|
if (is_rtx) {
|
||||||
@ -910,12 +844,12 @@ void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, size_t &len, void *
|
|||||||
|
|
||||||
if (!pr->first || !pr->second->plan_rtx) {
|
if (!pr->first || !pr->second->plan_rtx) {
|
||||||
//普通的rtp,或者不支持rtx, 修改目标pt和ssrc
|
//普通的rtp,或者不支持rtx, 修改目标pt和ssrc
|
||||||
changeRtpExtId(*pr->second, header, false);
|
pr->second->rtp_ext_ctx->changeRtpExtId(header, false);
|
||||||
header->pt = pr->second->plan_rtp->pt;
|
header->pt = pr->second->plan_rtp->pt;
|
||||||
header->ssrc = htonl(pr->second->answer_ssrc_rtp);
|
header->ssrc = htonl(pr->second->answer_ssrc_rtp);
|
||||||
} else {
|
} else {
|
||||||
//重传的rtp, rtx
|
//重传的rtp, rtx
|
||||||
changeRtpExtId(*pr->second, header, false);
|
pr->second->rtp_ext_ctx->changeRtpExtId(header, false);
|
||||||
header->pt = pr->second->plan_rtx->pt;
|
header->pt = pr->second->plan_rtx->pt;
|
||||||
if (pr->second->answer_ssrc_rtx) {
|
if (pr->second->answer_ssrc_rtx) {
|
||||||
//有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc
|
//有rtx单独的ssrc,有些情况下,浏览器支持rtx,但是未指定rtx单独的ssrc
|
||||||
|
@ -272,6 +272,27 @@ private:
|
|||||||
uint16_t _last_max_seq = 0;
|
uint16_t _last_max_seq = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MediaTrack {
|
||||||
|
public:
|
||||||
|
using Ptr = std::shared_ptr<MediaTrack>;
|
||||||
|
const RtcCodecPlan *plan_rtp;
|
||||||
|
const RtcCodecPlan *plan_rtx;
|
||||||
|
uint32_t offer_ssrc_rtp = 0;
|
||||||
|
uint32_t offer_ssrc_rtx = 0;
|
||||||
|
uint32_t answer_ssrc_rtp = 0;
|
||||||
|
uint32_t answer_ssrc_rtx = 0;
|
||||||
|
const RtcMedia *media;
|
||||||
|
RtpExtContext::Ptr rtp_ext_ctx;
|
||||||
|
|
||||||
|
//for send rtp
|
||||||
|
NackList nack_list;
|
||||||
|
RtcpContext::Ptr rtcp_context_send;
|
||||||
|
|
||||||
|
//for recv rtp
|
||||||
|
unordered_map<string/*rid*/, std::shared_ptr<RtpChannel> > rtp_channel;
|
||||||
|
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
||||||
|
};
|
||||||
|
|
||||||
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
|
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
||||||
@ -337,27 +358,8 @@ private:
|
|||||||
bool canSendRtp() const;
|
bool canSendRtp() const;
|
||||||
bool canRecvRtp() const;
|
bool canRecvRtp() const;
|
||||||
|
|
||||||
class MediaTrack {
|
|
||||||
public:
|
|
||||||
using Ptr = std::shared_ptr<MediaTrack>;
|
|
||||||
const RtcCodecPlan *plan_rtp;
|
|
||||||
const RtcCodecPlan *plan_rtx;
|
|
||||||
uint32_t offer_ssrc_rtp = 0;
|
|
||||||
uint32_t offer_ssrc_rtx = 0;
|
|
||||||
uint32_t answer_ssrc_rtp = 0;
|
|
||||||
uint32_t answer_ssrc_rtx = 0;
|
|
||||||
const RtcMedia *media;
|
|
||||||
NackList nack_list;
|
|
||||||
RtcpContext::Ptr rtcp_context_send;
|
|
||||||
unordered_map<string/*rid*/, std::shared_ptr<RtpChannel> > rtp_channel;
|
|
||||||
unordered_map<uint32_t/*simulcast ssrc*/, string/*rid*/> ssrc_to_rid;
|
|
||||||
|
|
||||||
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
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 changeRtpExtId(MediaTrack &track, const RtpHeader *header, bool is_recv, string *rid_ptr = nullptr) const;
|
|
||||||
void createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &info);
|
void createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &info);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -389,8 +391,4 @@ private:
|
|||||||
unordered_map<uint8_t/*pt*/, std::pair<bool/*is rtx*/,MediaTrack::Ptr> > _pt_to_track;
|
unordered_map<uint8_t/*pt*/, std::pair<bool/*is rtx*/,MediaTrack::Ptr> > _pt_to_track;
|
||||||
//根据rtcp的ssrc获取相关信息,只记录rtp的ssrc,rtx的ssrc不记录
|
//根据rtcp的ssrc获取相关信息,只记录rtp的ssrc,rtx的ssrc不记录
|
||||||
unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
|
unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
|
||||||
//发送rtp时需要修改rtp ext id
|
|
||||||
map<RtpExtType, uint8_t> _rtp_ext_type_to_id;
|
|
||||||
//接收rtp时需要修改rtp ext id
|
|
||||||
unordered_map<uint8_t, RtpExtType> _rtp_ext_id_to_type;
|
|
||||||
};
|
};
|
Loading…
Reference in New Issue
Block a user