Commit 2abb5078 by xiongziliang

实现rtc转rtsp

parent 130a0689
......@@ -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
\ No newline at end of file
......@@ -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;
};
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论