mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
完善ssrc处理逻辑
This commit is contained in:
parent
d4ce5b0091
commit
a42e5f6470
@ -185,6 +185,9 @@ void WebRtcTransport::onCheckSdp(SdpType type, RtcSession &sdp){
|
|||||||
if (sdp.group.mids.empty()) {
|
if (sdp.group.mids.empty()) {
|
||||||
throw std::invalid_argument("只支持group BUNDLE模式");
|
throw std::invalid_argument("只支持group BUNDLE模式");
|
||||||
}
|
}
|
||||||
|
if (type == SdpType::offer) {
|
||||||
|
sdp.checkValidSSRC();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransport::onRtcConfigure(RtcConfigure &configure) const {
|
void WebRtcTransport::onRtcConfigure(RtcConfigure &configure) const {
|
||||||
@ -390,6 +393,16 @@ bool WebRtcTransportImp::canRecvRtp() const{
|
|||||||
return _push_src && (sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::recvonly);
|
return _push_src && (sdp.media[0].direction == RtpDirection::sendrecv || sdp.media[0].direction == RtpDirection::recvonly);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RtcSession& WebRtcTransportImp::getSdpWithSSRC() const{
|
||||||
|
auto &offer = getSdp(SdpType::offer);
|
||||||
|
if (offer.haveSSRC()) {
|
||||||
|
return offer;
|
||||||
|
}
|
||||||
|
auto &answer = getSdp(SdpType::answer);
|
||||||
|
CHECK(answer.haveSSRC());
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
void WebRtcTransportImp::onStartWebRTC() {
|
void WebRtcTransportImp::onStartWebRTC() {
|
||||||
//获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息
|
//获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息
|
||||||
for (auto &m : getSdp(SdpType::offer).media) {
|
for (auto &m : getSdp(SdpType::offer).media) {
|
||||||
@ -398,11 +411,12 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
if (!hit_pan) {
|
if (!hit_pan) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
auto m_with_ssrc = getSdpWithSSRC().getMedia(m.type);
|
||||||
//获取offer端rtp的ssrc和pt相关信息
|
//获取offer端rtp的ssrc和pt相关信息
|
||||||
auto &ref = _rtp_info_pt[plan.pt];
|
auto &ref = _rtp_info_pt[plan.pt];
|
||||||
_rtp_info_ssrc[m.rtp_rtx_ssrc[0].ssrc] = &ref;
|
_rtp_info_ssrc[m_with_ssrc->rtp_rtx_ssrc[0].ssrc] = &ref;
|
||||||
ref.plan = &plan;
|
ref.plan = &plan;
|
||||||
ref.media = &m;
|
ref.media = m_with_ssrc;
|
||||||
ref.is_common_rtp = getCodecId(plan.codec) != CodecInvalid;
|
ref.is_common_rtp = getCodecId(plan.codec) != CodecInvalid;
|
||||||
ref.rtcp_context_recv = std::make_shared<RtcpContext>(ref.plan->sample_rate, true);
|
ref.rtcp_context_recv = std::make_shared<RtcpContext>(ref.plan->sample_rate, true);
|
||||||
ref.rtcp_context_send = std::make_shared<RtcpContext>(ref.plan->sample_rate, false);
|
ref.rtcp_context_send = std::make_shared<RtcpContext>(ref.plan->sample_rate, false);
|
||||||
@ -441,14 +455,16 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
|
|
||||||
RtcSession rtsp_send_sdp;
|
RtcSession rtsp_send_sdp;
|
||||||
rtsp_send_sdp.loadFrom(_play_src->getSdp(), false);
|
rtsp_send_sdp.loadFrom(_play_src->getSdp(), false);
|
||||||
for (auto &m : getSdp(SdpType::answer).media) {
|
for (auto &m : getSdp(SdpType::answer).media) {
|
||||||
if (m.type == TrackApplication) {
|
if (m.type == TrackApplication) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto rtsp_media = rtsp_send_sdp.getMedia(m.type);
|
auto rtsp_media = rtsp_send_sdp.getMedia(m.type);
|
||||||
if (rtsp_media && getCodecId(rtsp_media->plan[0].codec) == getCodecId(m.plan[0].codec)) {
|
if (rtsp_media && getCodecId(rtsp_media->plan[0].codec) == getCodecId(m.plan[0].codec)) {
|
||||||
//记录发送rtp时约定的pt,届时发送rtp时需要修改pt
|
auto it = _rtp_info_pt.find(m.plan[0].pt);
|
||||||
_send_rtp_pt[m.type] = m.plan[0].pt;
|
CHECK(it != _rtp_info_pt.end());
|
||||||
|
//记录发送rtp时约定的信息,届时发送rtp时需要修改pt和ssrc
|
||||||
|
_send_rtp_info[m.type] = &it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,10 +473,11 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){
|
void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){
|
||||||
WebRtcTransport::onCheckSdp(type, sdp);
|
WebRtcTransport::onCheckSdp(type, sdp);
|
||||||
if (type != SdpType::answer) {
|
if (type != SdpType::answer) {
|
||||||
|
//我们只修改answer sdp
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//修改sdp的ip、端口信息
|
//修改answer sdp的ip、端口信息
|
||||||
GET_CONFIG(string, extern_ip, RTC::kExternIP);
|
GET_CONFIG(string, extern_ip, RTC::kExternIP);
|
||||||
for (auto &m : sdp.media) {
|
for (auto &m : sdp.media) {
|
||||||
m.addr.reset();
|
m.addr.reset();
|
||||||
@ -472,7 +489,8 @@ void WebRtcTransportImp::onCheckSdp(SdpType type, RtcSession &sdp){
|
|||||||
sdp.origin.address = m.addr.address;
|
sdp.origin.address = m.addr.address;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canSendRtp()) {
|
if (!canSendRtp() || getSdp(SdpType::offer).haveSSRC()) {
|
||||||
|
//offer sdp未包含ssrc相关信息,那么我们才在answer sdp中回复ssrc相关信息
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,20 +704,23 @@ void WebRtcTransportImp::onBeforeSortedRtp(const RtpPayloadInfo &info, const Rtp
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush){
|
void WebRtcTransportImp::onSendRtp(const RtpPacket::Ptr &rtp, bool flush){
|
||||||
auto pt = _send_rtp_pt[rtp->type];
|
auto info = _send_rtp_info[rtp->type];
|
||||||
if (pt == 0xFF) {
|
if (!info) {
|
||||||
//忽略,对方不支持该编码类型
|
//忽略,对方不支持该编码类型
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_bytes_usage += rtp->size() - RtpPacket::kRtpTcpHeaderSize;
|
_bytes_usage += rtp->size() - RtpPacket::kRtpTcpHeaderSize;
|
||||||
sendRtpPacket(rtp->data() + RtpPacket::kRtpTcpHeaderSize, rtp->size() - RtpPacket::kRtpTcpHeaderSize, flush, rtp->type);
|
sendRtpPacket(rtp->data() + RtpPacket::kRtpTcpHeaderSize, rtp->size() - RtpPacket::kRtpTcpHeaderSize, flush, rtp->type);
|
||||||
//统计rtp发送情况,好做sr汇报
|
//统计rtp发送情况,好做sr汇报
|
||||||
_rtp_info_pt[pt].rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize);
|
_rtp_info_pt[info->plan->pt].rtcp_context_send->onRtp(rtp->getSeq(), rtp->getStampMS(), rtp->size() - RtpPacket::kRtpTcpHeaderSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, size_t len, TrackType type) {
|
void WebRtcTransportImp::onBeforeEncryptRtp(const char *buf, size_t len, TrackType type) {
|
||||||
auto header = (RtpHeader *)buf;
|
auto header = (RtpHeader *)buf;
|
||||||
header->pt = _send_rtp_pt[type];
|
auto info = _send_rtp_info[type];
|
||||||
|
//修改目标pt和ssrc
|
||||||
|
header->pt = info->plan->pt;
|
||||||
|
header->ssrc = htons(info->media->rtp_rtx_ssrc[0].ssrc);
|
||||||
changeRtpExtId(header, _rtp_ext_type_to_id);
|
changeRtpExtId(header, _rtp_ext_type_to_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +188,7 @@ private:
|
|||||||
SdpAttrCandidate::Ptr getIceCandidate() const;
|
SdpAttrCandidate::Ptr getIceCandidate() const;
|
||||||
bool canSendRtp() const;
|
bool canSendRtp() const;
|
||||||
bool canRecvRtp() const;
|
bool canRecvRtp() const;
|
||||||
|
const RtcSession& getSdpWithSSRC() const;
|
||||||
|
|
||||||
class RtpPayloadInfo {
|
class RtpPayloadInfo {
|
||||||
public:
|
public:
|
||||||
@ -215,8 +216,8 @@ private:
|
|||||||
Ticker _alive_ticker;
|
Ticker _alive_ticker;
|
||||||
//pli rtcp计时器
|
//pli rtcp计时器
|
||||||
Ticker _pli_ticker;
|
Ticker _pli_ticker;
|
||||||
//记录协商的rtp的pt类型
|
//记录协商的发送rtp的pt和ssrc
|
||||||
uint8_t _send_rtp_pt[2] = {0xFF, 0xFF};
|
RtpPayloadInfo* _send_rtp_info[2] = {nullptr, nullptr};
|
||||||
//复合udp端口,接收一切rtp与rtcp
|
//复合udp端口,接收一切rtp与rtcp
|
||||||
Socket::Ptr _socket;
|
Socket::Ptr _socket;
|
||||||
//推流的rtsp源
|
//推流的rtsp源
|
||||||
@ -226,9 +227,9 @@ private:
|
|||||||
//播放rtsp源的reader对象
|
//播放rtsp源的reader对象
|
||||||
RtspMediaSource::RingType::RingReader::Ptr _reader;
|
RtspMediaSource::RingType::RingReader::Ptr _reader;
|
||||||
//根据rtp的pt获取相关信息
|
//根据rtp的pt获取相关信息
|
||||||
unordered_map<uint8_t, RtpPayloadInfo> _rtp_info_pt;
|
unordered_map<uint8_t/*pt*/, RtpPayloadInfo> _rtp_info_pt;
|
||||||
//根据推流端rtcp的ssrc获取相关信息
|
//根据rtcp的ssrc获取相关信息
|
||||||
unordered_map<uint32_t, RtpPayloadInfo*> _rtp_info_ssrc;
|
unordered_map<uint32_t/*ssrc*/, RtpPayloadInfo*> _rtp_info_ssrc;
|
||||||
//发送rtp时需要修改rtp ext id
|
//发送rtp时需要修改rtp ext id
|
||||||
map<RtpExtType, uint8_t> _rtp_ext_type_to_id;
|
map<RtpExtType, uint8_t> _rtp_ext_type_to_id;
|
||||||
//接收rtp时需要修改rtp ext id
|
//接收rtp时需要修改rtp ext id
|
||||||
|
Loading…
Reference in New Issue
Block a user