mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +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;
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -105,6 +110,12 @@ void RtcpHeader::net2Host(size_t len){
|
||||
sdes->net2Host(len);
|
||||
break;
|
||||
}
|
||||
|
||||
case RtcpType::RTCP_PSFB: {
|
||||
RtcpPli *pli = (RtcpPli *)this;
|
||||
pli->net2Host(len);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
} catch (std::exception &ex) {
|
||||
//不能处理的rtcp包,或者无法解析的rtcp包,忽略掉
|
||||
WarnL << ex.what();
|
||||
WarnL << ex.what() << ",长度为:" << rtcp_len;
|
||||
}
|
||||
ptr += rtcp_len;
|
||||
remain -= rtcp_len;
|
||||
@ -402,4 +413,31 @@ vector<SdesItem *> RtcpSdes::getItemList() {
|
||||
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
|
@ -456,6 +456,35 @@ private:
|
||||
void net2Host(size_t size);
|
||||
} 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)
|
||||
#pragma pack(pop)
|
||||
#endif // defined(_WIN32)
|
||||
|
@ -253,6 +253,9 @@ void WebRtcTransportImp::onStartWebRTC() {
|
||||
_push_src->setSdp(rtsp_sdp);
|
||||
|
||||
for (auto &m : getSdp(SdpType::offer).media) {
|
||||
if (m.type == TrackVideo) {
|
||||
_recv_video_ssrc = m.rtp_ssrc.ssrc;
|
||||
}
|
||||
for (auto &plan : m.plan) {
|
||||
auto hit_pan = getSdp(SdpType::answer).getMedia(m.type)->getPlan(plan.pt);
|
||||
if (!hit_pan) {
|
||||
@ -416,6 +419,10 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) {
|
||||
//todo 此处应该销毁对象
|
||||
break;
|
||||
}
|
||||
case RtcpType::RTCP_PSFB: {
|
||||
// InfoL << rtcp->dumpString();
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -457,9 +452,10 @@ void WebRtcTransportImp::onSortedRtp(const RtpPayloadInfo &info, RtpPacket::Ptr
|
||||
if (_pli_ticker.elapsedTime() > 2000) {
|
||||
//todo 定期发送pli
|
||||
_pli_ticker.resetTime();
|
||||
char rtcpbuf[12];
|
||||
makeRtcpPli(rtcpbuf, 12);
|
||||
sendRtcpPacket(rtcpbuf, 12, true);
|
||||
auto pli = RtcpPli::create();
|
||||
pli->ssrc = htonl(0);
|
||||
pli->ssrc_media = htonl(_recv_video_ssrc);
|
||||
sendRtcpPacket((char *) pli.get(), sizeof(RtcpPli), true);
|
||||
InfoL << "send pli";
|
||||
}
|
||||
_push_src->onWrite(std::move(rtp), false);
|
||||
|
@ -157,6 +157,7 @@ private:
|
||||
RtspMediaSourceImp::Ptr _push_src;
|
||||
unordered_map<uint8_t, RtpPayloadInfo> _rtp_receiver;
|
||||
unordered_map<uint32_t, RtpPayloadInfo*> _ssrc_info;
|
||||
uint32_t _recv_video_ssrc;
|
||||
Ticker _pli_ticker;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user