Commit fd4145a6 by xiongziliang

完善对rtp负载为空处理逻辑:#1661

parent 6596eec0
...@@ -80,11 +80,17 @@ void AACRtpDecoder::obtainFrame() { ...@@ -80,11 +80,17 @@ void AACRtpDecoder::obtainFrame() {
} }
bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) { bool AACRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
auto payload_size = rtp->getPayloadSize();
if (payload_size <= 0) {
//无实际负载
return false;
}
auto stamp = rtp->getStampMS(); auto stamp = rtp->getStampMS();
//rtp数据开始部分 //rtp数据开始部分
auto ptr = rtp->getPayload(); auto ptr = rtp->getPayload();
//rtp数据末尾 //rtp数据末尾
auto end = ptr + rtp->getPayloadSize(); auto end = ptr + payload_size;
//首2字节表示Au-Header的个数,单位bit,所以除以16得到Au-Header个数 //首2字节表示Au-Header的个数,单位bit,所以除以16得到Au-Header个数
auto au_header_count = ((ptr[0] << 8) | ptr[1]) >> 4; auto au_header_count = ((ptr[0] << 8) | ptr[1]) >> 4;
//记录au_header起始指针 //记录au_header起始指针
......
...@@ -28,14 +28,14 @@ void CommonRtpDecoder::obtainFrame() { ...@@ -28,14 +28,14 @@ void CommonRtpDecoder::obtainFrame() {
} }
bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){ bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
auto payload = rtp->getPayload(); auto payload_size = rtp->getPayloadSize();
auto size = rtp->getPayloadSize(); if (payload_size <= 0) {
auto stamp = rtp->getStampMS();
auto seq = rtp->getSeq();
if (size <= 0) {
//无实际负载 //无实际负载
return false; return false;
} }
auto payload = rtp->getPayload();
auto stamp = rtp->getStampMS();
auto seq = rtp->getSeq();
if (_frame->_dts != stamp || _frame->_buffer.size() > _max_frame_size) { if (_frame->_dts != stamp || _frame->_buffer.size() > _max_frame_size) {
//时间戳发生变化或者缓存超过MAX_FRAME_SIZE,则清空上帧数据 //时间戳发生变化或者缓存超过MAX_FRAME_SIZE,则清空上帧数据
...@@ -56,7 +56,7 @@ bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){ ...@@ -56,7 +56,7 @@ bool CommonRtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool){
} }
if (!_drop_flag) { if (!_drop_flag) {
_frame->_buffer.append((char *)payload, size); _frame->_buffer.append((char *)payload, payload_size);
} }
_last_seq = seq; _last_seq = seq;
......
...@@ -141,8 +141,12 @@ bool H264RtpDecoder::mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssiz ...@@ -141,8 +141,12 @@ bool H264RtpDecoder::mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssiz
} }
bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) { bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
auto payload_size = rtp->getPayloadSize();
if (payload_size <= 0) {
//无实际负载
return false;
}
auto frame = rtp->getPayload(); auto frame = rtp->getPayload();
auto length = rtp->getPayloadSize();
auto stamp = rtp->getStampMS(); auto stamp = rtp->getStampMS();
auto seq = rtp->getSeq(); auto seq = rtp->getSeq();
int nal = H264_TYPE(frame[0]); int nal = H264_TYPE(frame[0]);
...@@ -150,16 +154,16 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) { ...@@ -150,16 +154,16 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
switch (nal) { switch (nal) {
case 24: case 24:
// 24 STAP-A Single-time aggregation packet 5.7.1 // 24 STAP-A Single-time aggregation packet 5.7.1
return unpackStapA(rtp, frame + 1, length - 1, stamp); return unpackStapA(rtp, frame + 1, payload_size - 1, stamp);
case 28: case 28:
// 28 FU-A Fragmentation unit // 28 FU-A Fragmentation unit
return mergeFu(rtp, frame, length, stamp, seq); return mergeFu(rtp, frame, payload_size, stamp, seq);
default: { default: {
if (nal < 24) { if (nal < 24) {
//Single NAL Unit Packets //Single NAL Unit Packets
return singleFrame(rtp, frame, length, stamp); return singleFrame(rtp, frame, payload_size, stamp);
} }
_gop_dropped = true; _gop_dropped = true;
WarnL << "不支持该类型的264 RTP包, nal type:" << nal << ", rtp:\r\n" << rtp->dumpString(); WarnL << "不支持该类型的264 RTP包, nal type:" << nal << ", rtp:\r\n" << rtp->dumpString();
......
...@@ -185,8 +185,12 @@ bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) { ...@@ -185,8 +185,12 @@ bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
} }
bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) { bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
auto payload_size = rtp->getPayloadSize();
if (payload_size <= 0) {
//无实际负载
return false;
}
auto frame = rtp->getPayload(); auto frame = rtp->getPayload();
auto length = rtp->getPayloadSize();
auto stamp = rtp->getStampMS(); auto stamp = rtp->getStampMS();
auto seq = rtp->getSeq(); auto seq = rtp->getSeq();
int nal = H265_TYPE(frame[0]); int nal = H265_TYPE(frame[0]);
...@@ -194,16 +198,16 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) { ...@@ -194,16 +198,16 @@ bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
switch (nal) { switch (nal) {
case 48: case 48:
// aggregated packet (AP) - with two or more NAL units // aggregated packet (AP) - with two or more NAL units
return unpackAp(rtp, frame, length, stamp); return unpackAp(rtp, frame, payload_size, stamp);
case 49: case 49:
// fragmentation unit (FU) // fragmentation unit (FU)
return mergeFu(rtp, frame, length, stamp, seq); return mergeFu(rtp, frame, payload_size, stamp, seq);
default: { default: {
if (nal < 48) { if (nal < 48) {
// Single NAL Unit Packets (p24) // Single NAL Unit Packets (p24)
return singleFrame(rtp, frame, length, stamp); return singleFrame(rtp, frame, payload_size, stamp);
} }
_gop_dropped = true; _gop_dropped = true;
WarnL << "不支持该类型的265 RTP包, nal type" << nal << ", rtp:\r\n" << rtp->dumpString(); WarnL << "不支持该类型的265 RTP包, nal type" << nal << ", rtp:\r\n" << rtp->dumpString();
......
...@@ -15,8 +15,7 @@ namespace mediakit { ...@@ -15,8 +15,7 @@ namespace mediakit {
RtpTrack::RtpTrack() { RtpTrack::RtpTrack() {
setOnSort([this](uint16_t seq, RtpPacket::Ptr &packet) { setOnSort([this](uint16_t seq, RtpPacket::Ptr &packet) {
if (packet->getPayloadSize()) onRtpSorted(std::move(packet));
onRtpSorted(std::move(packet));
}); });
} }
...@@ -32,8 +31,7 @@ void RtpTrack::clear() { ...@@ -32,8 +31,7 @@ void RtpTrack::clear() {
RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, size_t len) { RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, size_t len) {
if (len < RtpPacket::kRtpHeaderSize) { if (len < RtpPacket::kRtpHeaderSize) {
WarnL << "rtp包太小:" << len; throw BadRtpException("rtp size less than 12");
return nullptr;
} }
GET_CONFIG(uint32_t, rtpMaxSize, Rtp::kRtpMaxSize); GET_CONFIG(uint32_t, rtpMaxSize, Rtp::kRtpMaxSize);
if (len > 1024 * rtpMaxSize) { if (len > 1024 * rtpMaxSize) {
...@@ -46,12 +44,11 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, ...@@ -46,12 +44,11 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr,
} }
RtpHeader *header = (RtpHeader *) ptr; RtpHeader *header = (RtpHeader *) ptr;
if (header->version != RtpPacket::kRtpVersion) { if (header->version != RtpPacket::kRtpVersion) {
throw BadRtpException("非法的rtp,version字段非法"); throw BadRtpException("invalid rtp version");
} }
if (!header->getPayloadSize(len)) { if (header->getPayloadSize(len) < 0) {
//无有效负载的rtp包 //rtp有效负载小于0,非法
InfoL << "收到rtp空包:" << len << " seq:" << ntohs(header->seq); throw BadRtpException("invalid rtp payload size");
//return nullptr;
} }
//比对缓存ssrc //比对缓存ssrc
...@@ -60,7 +57,7 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, ...@@ -60,7 +57,7 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr,
if (_pt == 0xFF) { if (_pt == 0xFF) {
_pt = header->pt; _pt = header->pt;
} else if (header->pt != _pt) { } else if (header->pt != _pt) {
TraceL << "rtp pt 不匹配:" << (int) header->pt << " !=" << (int) _pt; //TraceL << "rtp pt mismatch:" << (int) header->pt << " !=" << (int) _pt;
return nullptr; return nullptr;
} }
...@@ -75,10 +72,10 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, ...@@ -75,10 +72,10 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr,
//ssrc错误 //ssrc错误
if (_ssrc_alive.elapsedTime() < 3 * 1000) { if (_ssrc_alive.elapsedTime() < 3 * 1000) {
//接受正确ssrc的rtp在10秒内,那么我们认为存在多路rtp,忽略掉ssrc不匹配的rtp //接受正确ssrc的rtp在10秒内,那么我们认为存在多路rtp,忽略掉ssrc不匹配的rtp
WarnL << "ssrc不匹配,rtp已丢弃:" << ssrc << " != " << _ssrc; WarnL << "ssrc mismatch, rtp dropped:" << ssrc << " != " << _ssrc;
return nullptr; return nullptr;
} }
InfoL << "rtp流ssrc切换:" << _ssrc << " -> " << ssrc; InfoL << "rtp ssrc changed:" << _ssrc << " -> " << ssrc;
_ssrc = ssrc; _ssrc = ssrc;
_ssrc_alive.resetTime(); _ssrc_alive.resetTime();
} }
......
...@@ -513,12 +513,9 @@ size_t RtpHeader::getPaddingSize(size_t rtp_size) const { ...@@ -513,12 +513,9 @@ size_t RtpHeader::getPaddingSize(size_t rtp_size) const {
return *end; return *end;
} }
size_t RtpHeader::getPayloadSize(size_t rtp_size) const { ssize_t RtpHeader::getPayloadSize(size_t rtp_size) const {
auto invalid_size = getPayloadOffset() + getPaddingSize(rtp_size); auto invalid_size = getPayloadOffset() + getPaddingSize(rtp_size);
if (invalid_size + RtpPacket::kRtpHeaderSize >= rtp_size) { return (ssize_t)rtp_size - invalid_size - RtpPacket::kRtpHeaderSize;
return 0;
}
return rtp_size - invalid_size - RtpPacket::kRtpHeaderSize;
} }
string RtpHeader::dumpString(size_t rtp_size) const { string RtpHeader::dumpString(size_t rtp_size) const {
......
...@@ -123,7 +123,7 @@ public: ...@@ -123,7 +123,7 @@ public:
//返回有效负载指针,跳过csrc、ext //返回有效负载指针,跳过csrc、ext
uint8_t* getPayloadData(); uint8_t* getPayloadData();
//返回有效负载总长度,不包括csrc、ext、padding //返回有效负载总长度,不包括csrc、ext、padding
size_t getPayloadSize(size_t rtp_size) const; ssize_t getPayloadSize(size_t rtp_size) const;
//打印调试信息 //打印调试信息
std::string dumpString(size_t rtp_size) const; std::string dumpString(size_t rtp_size) const;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论