mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-26 04:31:37 +08:00
实现rtc转rtsp
This commit is contained in:
parent
130a06897f
commit
2abb5078f9
@ -82,6 +82,11 @@ string RtcpHeader::dumpString() const {
|
|||||||
RtcpSdes *rtcp = (RtcpSdes *)this;
|
RtcpSdes *rtcp = (RtcpSdes *)this;
|
||||||
return rtcp->dumpString();
|
return rtcp->dumpString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RtcpType::RTCP_PSFB: {
|
||||||
|
RtcpPli *rtcp = (RtcpPli *)this;
|
||||||
|
return rtcp->dumpString();
|
||||||
|
}
|
||||||
default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), length << 2);
|
default: return StrPrinter << dumpHeader() << hexdump((char *)this + sizeof(*this), length << 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,6 +110,12 @@ void RtcpHeader::net2Host(size_t len){
|
|||||||
sdes->net2Host(len);
|
sdes->net2Host(len);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case RtcpType::RTCP_PSFB: {
|
||||||
|
RtcpPli *pli = (RtcpPli *)this;
|
||||||
|
pli->net2Host(len);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt));
|
default: throw std::runtime_error(StrPrinter << "未处理的rtcp包:" << rtcpTypeToStr((RtcpType) this->pt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +132,7 @@ vector<RtcpHeader *> RtcpHeader::loadFromBytes(char *data, size_t len){
|
|||||||
ret.emplace_back(rtcp);
|
ret.emplace_back(rtcp);
|
||||||
} catch (std::exception &ex) {
|
} catch (std::exception &ex) {
|
||||||
//不能处理的rtcp包,或者无法解析的rtcp包,忽略掉
|
//不能处理的rtcp包,或者无法解析的rtcp包,忽略掉
|
||||||
WarnL << ex.what();
|
WarnL << ex.what() << ",长度为:" << rtcp_len;
|
||||||
}
|
}
|
||||||
ptr += rtcp_len;
|
ptr += rtcp_len;
|
||||||
remain -= rtcp_len;
|
remain -= rtcp_len;
|
||||||
@ -402,4 +413,31 @@ vector<SdesItem *> RtcpSdes::getItemList() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::shared_ptr<RtcpPli> RtcpPli::create() {
|
||||||
|
auto bytes = alignSize(sizeof(RtcpPli));
|
||||||
|
auto ptr = (RtcpRR *) new char[bytes];
|
||||||
|
setupHeader(ptr, RtcpType::RTCP_PSFB, 1, bytes);
|
||||||
|
return std::shared_ptr<RtcpPli>((RtcpPli *) ptr, [](RtcpPli *ptr) {
|
||||||
|
delete[] (char *) ptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
string RtcpPli::dumpString() const {
|
||||||
|
_StrPrinter printer;
|
||||||
|
printer << RtcpHeader::dumpHeader();
|
||||||
|
printer << "ssrc:" << ssrc << "\r\n";
|
||||||
|
printer << "ssrc_media:" << ssrc_media;
|
||||||
|
return std::move(printer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RtcpPli::net2Host(size_t size) {
|
||||||
|
static const size_t kMinSize = sizeof(RtcpPli);
|
||||||
|
CHECK_MIN_SIZE(size, kMinSize);
|
||||||
|
RtcpHeader::net2Host();
|
||||||
|
ssrc = ntohl(ssrc);
|
||||||
|
ssrc_media = ntohl(ssrc_media);
|
||||||
|
}
|
||||||
|
|
||||||
}//namespace mediakit
|
}//namespace mediakit
|
@ -456,6 +456,35 @@ private:
|
|||||||
void net2Host(size_t size);
|
void net2Host(size_t size);
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
|
//PLI
|
||||||
|
class RtcpPli : public RtcpHeader {
|
||||||
|
public:
|
||||||
|
friend class RtcpHeader;
|
||||||
|
uint32_t ssrc;
|
||||||
|
uint32_t ssrc_media;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* 创建SDES包,只赋值了RtcpHeader以及SdesItem对象的length和text部分
|
||||||
|
* @param item_text SdesItem列表,只赋值length和text部分
|
||||||
|
* @return SDES包
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<RtcpPli> create();
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* 打印字段详情
|
||||||
|
* 使用net2Host转换成主机字节序后才可使用此函数
|
||||||
|
*/
|
||||||
|
string dumpString() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网络字节序转换为主机字节序
|
||||||
|
* @param size 字节长度,防止内存越界
|
||||||
|
*/
|
||||||
|
void net2Host(size_t size);
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
#endif // defined(_WIN32)
|
#endif // defined(_WIN32)
|
||||||
|
@ -253,6 +253,9 @@ void WebRtcTransportImp::onStartWebRTC() {
|
|||||||
_push_src->setSdp(rtsp_sdp);
|
_push_src->setSdp(rtsp_sdp);
|
||||||
|
|
||||||
for (auto &m : getSdp(SdpType::offer).media) {
|
for (auto &m : getSdp(SdpType::offer).media) {
|
||||||
|
if (m.type == TrackVideo) {
|
||||||
|
_recv_video_ssrc = m.rtp_ssrc.ssrc;
|
||||||
|
}
|
||||||
for (auto &plan : m.plan) {
|
for (auto &plan : m.plan) {
|
||||||
auto hit_pan = getSdp(SdpType::answer).getMedia(m.type)->getPlan(plan.pt);
|
auto hit_pan = getSdp(SdpType::answer).getMedia(m.type)->getPlan(plan.pt);
|
||||||
if (!hit_pan) {
|
if (!hit_pan) {
|
||||||
@ -416,6 +419,10 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
|
|||||||
//todo 此处应该销毁对象
|
//todo 此处应该销毁对象
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case RtcpType::RTCP_PSFB: {
|
||||||
|
// InfoL << rtcp->dumpString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -434,18 +441,6 @@ void WebRtcTransportImp::onRtp(const char *buf, size_t len) {
|
|||||||
info.receiver->inputRtp(info.media->type, info.plan->sample_rate, (uint8_t *) buf, len);
|
info.receiver->inputRtp(info.media->type, info.plan->sample_rate, (uint8_t *) buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int makeRtcpPli(char *packet, int len) {
|
|
||||||
if (packet == NULL || len != 12)
|
|
||||||
return -1;
|
|
||||||
memset(packet, 0, len);
|
|
||||||
RtcpHeader *rtcp = (RtcpHeader *) packet;
|
|
||||||
rtcp->version = 2;
|
|
||||||
rtcp->pt = (uint8_t) RtcpType::RTCP_PSFB;
|
|
||||||
rtcp->report_count = 1;
|
|
||||||
rtcp->length = htons((len / 4) - 1);
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr rtp) {
|
void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr rtp) {
|
||||||
@ -457,9 +452,10 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
|
|||||||
if (_pli_ticker.elapsedTime() > 2000) {
|
if (_pli_ticker.elapsedTime() > 2000) {
|
||||||
//todo 定期发送pli
|
//todo 定期发送pli
|
||||||
_pli_ticker.resetTime();
|
_pli_ticker.resetTime();
|
||||||
char rtcpbuf[12];
|
auto pli = RtcpPli::create();
|
||||||
makeRtcpPli(rtcpbuf, 12);
|
pli->ssrc = htonl(0);
|
||||||
sendRtcpPacket(rtcpbuf, 12, true);
|
pli->ssrc_media = htonl(_recv_video_ssrc);
|
||||||
|
sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true);
|
||||||
InfoL << "send pli";
|
InfoL << "send pli";
|
||||||
}
|
}
|
||||||
_push_src->onWrite(std::move(rtp), false);
|
_push_src->onWrite(std::move(rtp), false);
|
||||||
|
@ -157,6 +157,7 @@ private:
|
|||||||
RtspMediaSourceImp::Ptr _push_src;
|
RtspMediaSourceImp::Ptr _push_src;
|
||||||
unordered_map<uint8_t, RtpPayloadInfo> _rtp_receiver;
|
unordered_map<uint8_t, RtpPayloadInfo> _rtp_receiver;
|
||||||
unordered_map<uint32_t, RtpPayloadInfo*> _ssrc_info;
|
unordered_map<uint32_t, RtpPayloadInfo*> _ssrc_info;
|
||||||
|
uint32_t _recv_video_ssrc;
|
||||||
Ticker _pli_ticker;
|
Ticker _pli_ticker;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user