完善对rtp负载为空处理逻辑:#1661
This commit is contained in:
parent
6596eec069
commit
fd4145a622
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
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){
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
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,7 +15,6 @@ 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() {
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
//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 {
|
||||||
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:
|
||||||
//返回有效负载指针,跳过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;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue