mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[fix] fix decoding error caused by padding packets
This commit is contained in:
@@ -228,6 +228,15 @@ class RtpPacket {
|
|||||||
extension.data.push_back(abs_send_time & 0xFF);
|
extension.data.push_back(abs_send_time & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UpdateSequenceNumber(uint16_t sequence_number) {
|
||||||
|
// Ensure the buffer is large enough to contain the sequence number
|
||||||
|
if (buffer_.size() >= 4) {
|
||||||
|
buffer_[2] = (sequence_number >> 8) & 0xFF;
|
||||||
|
buffer_[3] = sequence_number & 0xFF;
|
||||||
|
sequence_number_ = sequence_number;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Get Header
|
// Get Header
|
||||||
uint32_t Version() const { return version_; }
|
uint32_t Version() const { return version_; }
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ RtpVideoReceiver::~RtpVideoReceiver() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet, bool padding) {
|
void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet) {
|
||||||
if (!rtp_statistics_) {
|
if (!rtp_statistics_) {
|
||||||
rtp_statistics_ = std::make_unique<RtpStatistics>();
|
rtp_statistics_ = std::make_unique<RtpStatistics>();
|
||||||
rtp_statistics_->Start();
|
rtp_statistics_->Start();
|
||||||
@@ -194,16 +194,14 @@ void RtpVideoReceiver::InsertRtpPacket(RtpPacket& rtp_packet, bool padding) {
|
|||||||
// // SendRtcpRR(rtcp_rr);
|
// // SendRtcpRR(rtcp_rr);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (padding) {
|
if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1 ||
|
||||||
return;
|
rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1 - 1) {
|
||||||
}
|
|
||||||
|
|
||||||
if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::AV1) {
|
|
||||||
RtpPacketAv1 rtp_packet_av1;
|
RtpPacketAv1 rtp_packet_av1;
|
||||||
rtp_packet_av1.Build(rtp_packet.Buffer().data(), rtp_packet.Size());
|
rtp_packet_av1.Build(rtp_packet.Buffer().data(), rtp_packet.Size());
|
||||||
rtp_packet_av1.GetFrameHeaderInfo();
|
rtp_packet_av1.GetFrameHeaderInfo();
|
||||||
ProcessAv1RtpPacket(rtp_packet_av1);
|
ProcessAv1RtpPacket(rtp_packet_av1);
|
||||||
} else {
|
} else if (rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::H264 ||
|
||||||
|
rtp_packet.PayloadType() == rtp::PAYLOAD_TYPE::H264 - 1) {
|
||||||
RtpPacketH264 rtp_packet_h264;
|
RtpPacketH264 rtp_packet_h264;
|
||||||
if (rtp_packet_h264.Build(rtp_packet.Buffer().data(), rtp_packet.Size())) {
|
if (rtp_packet_h264.Build(rtp_packet.Buffer().data(), rtp_packet.Size())) {
|
||||||
rtp_packet_h264.GetFrameHeaderInfo();
|
rtp_packet_h264.GetFrameHeaderInfo();
|
||||||
@@ -228,6 +226,8 @@ void RtpVideoReceiver::ProcessH264RtpPacket(RtpPacketH264& rtp_packet_h264) {
|
|||||||
if (!complete) {
|
if (!complete) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (rtp::PAYLOAD_TYPE::H264 - 1 == rtp_packet_h264.PayloadType()) {
|
||||||
|
padding_sequence_numbers_.insert(rtp_packet_h264.SequenceNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// else {
|
// else {
|
||||||
@@ -364,10 +364,12 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(
|
|||||||
while (end_seq--) {
|
while (end_seq--) {
|
||||||
auto it = incomplete_h264_frame_list_.find(end_seq);
|
auto it = incomplete_h264_frame_list_.find(end_seq);
|
||||||
if (it == incomplete_h264_frame_list_.end()) {
|
if (it == incomplete_h264_frame_list_.end()) {
|
||||||
// The last fragment has already received. If all fragments are in
|
if (padding_sequence_numbers_.find(end_seq) ==
|
||||||
// order, then some fragments lost in tranmission and need to be
|
padding_sequence_numbers_.end()) {
|
||||||
// repaired using FEC
|
return false;
|
||||||
return false;
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
} else if (!it->second.FuAStart()) {
|
} else if (!it->second.FuAStart()) {
|
||||||
continue;
|
continue;
|
||||||
} else if (it->second.FuAStart()) {
|
} else if (it->second.FuAStart()) {
|
||||||
@@ -380,7 +382,13 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(
|
|||||||
uint16_t start = it->first;
|
uint16_t start = it->first;
|
||||||
uint16_t end = rtp_packet_h264.SequenceNumber();
|
uint16_t end = rtp_packet_h264.SequenceNumber();
|
||||||
for (uint16_t seq = start; seq <= end; seq++) {
|
for (uint16_t seq = start; seq <= end; seq++) {
|
||||||
complete_frame_size += incomplete_h264_frame_list_[seq].PayloadSize();
|
if (padding_sequence_numbers_.find(seq) ==
|
||||||
|
padding_sequence_numbers_.end()) {
|
||||||
|
complete_frame_size +=
|
||||||
|
incomplete_h264_frame_list_[seq].PayloadSize();
|
||||||
|
} else {
|
||||||
|
padding_sequence_numbers_.erase(seq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nv12_data_) {
|
if (!nv12_data_) {
|
||||||
@@ -393,8 +401,10 @@ bool RtpVideoReceiver::CheckIsH264FrameCompleted(
|
|||||||
uint8_t* dest = nv12_data_;
|
uint8_t* dest = nv12_data_;
|
||||||
for (uint16_t seq = start; seq <= end; seq++) {
|
for (uint16_t seq = start; seq <= end; seq++) {
|
||||||
size_t payload_size = incomplete_h264_frame_list_[seq].PayloadSize();
|
size_t payload_size = incomplete_h264_frame_list_[seq].PayloadSize();
|
||||||
memcpy(dest, incomplete_h264_frame_list_[seq].Payload(),
|
if (payload_size) {
|
||||||
payload_size);
|
memcpy(dest, incomplete_h264_frame_list_[seq].Payload(),
|
||||||
|
payload_size);
|
||||||
|
}
|
||||||
dest += payload_size;
|
dest += payload_size;
|
||||||
incomplete_h264_frame_list_.erase(seq);
|
incomplete_h264_frame_list_.erase(seq);
|
||||||
frame_fragment_count++;
|
frame_fragment_count++;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "api/clock/clock.h"
|
#include "api/clock/clock.h"
|
||||||
#include "clock/system_clock.h"
|
#include "clock/system_clock.h"
|
||||||
@@ -36,7 +37,7 @@ class RtpVideoReceiver : public ThreadBase,
|
|||||||
virtual ~RtpVideoReceiver();
|
virtual ~RtpVideoReceiver();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void InsertRtpPacket(RtpPacket& rtp_packet, bool padding);
|
void InsertRtpPacket(RtpPacket& rtp_packet);
|
||||||
|
|
||||||
void SetSendDataFunc(std::function<int(const char*, size_t)> data_send_func);
|
void SetSendDataFunc(std::function<int(const char*, size_t)> data_send_func);
|
||||||
|
|
||||||
@@ -111,6 +112,7 @@ class RtpVideoReceiver : public ThreadBase,
|
|||||||
// std::map<uint32_t, std::map<uint16_t, RtpPacket>> fec_repair_symbol_list_;
|
// std::map<uint32_t, std::map<uint16_t, RtpPacket>> fec_repair_symbol_list_;
|
||||||
std::set<uint64_t> incomplete_fec_frame_list_;
|
std::set<uint64_t> incomplete_fec_frame_list_;
|
||||||
std::map<uint64_t, std::map<uint16_t, RtpPacket>> incomplete_fec_packet_list_;
|
std::map<uint64_t, std::map<uint16_t, RtpPacket>> incomplete_fec_packet_list_;
|
||||||
|
std::unordered_set<int> padding_sequence_numbers_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::thread rtcp_thread_;
|
std::thread rtcp_thread_;
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ void VideoChannelReceive::Destroy() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size,
|
int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size) {
|
||||||
bool padding) {
|
|
||||||
if (ice_io_statistics_) {
|
if (ice_io_statistics_) {
|
||||||
ice_io_statistics_->UpdateVideoInboundBytes((uint32_t)size);
|
ice_io_statistics_->UpdateVideoInboundBytes((uint32_t)size);
|
||||||
}
|
}
|
||||||
@@ -59,7 +58,7 @@ int VideoChannelReceive::OnReceiveRtpPacket(const char *data, size_t size,
|
|||||||
if (rtp_video_receiver_) {
|
if (rtp_video_receiver_) {
|
||||||
RtpPacket rtp_packet;
|
RtpPacket rtp_packet;
|
||||||
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
rtp_packet.Build((uint8_t *)data, (uint32_t)size);
|
||||||
rtp_video_receiver_->InsertRtpPacket(rtp_packet, padding);
|
rtp_video_receiver_->InsertRtpPacket(rtp_packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class VideoChannelReceive {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OnReceiveRtpPacket(const char *data, size_t size, bool padding);
|
int OnReceiveRtpPacket(const char *data, size_t size);
|
||||||
|
|
||||||
void OnSenderReport(const SenderReport &sender_report) {
|
void OnSenderReport(const SenderReport &sender_report) {
|
||||||
if (rtp_video_receiver_) {
|
if (rtp_video_receiver_) {
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ void IceTransport::OnReceiveBuffer(NiceAgent *agent, guint stream_id,
|
|||||||
if (!is_closed_) {
|
if (!is_closed_) {
|
||||||
if (CheckIsRtpPacket(buffer, size)) {
|
if (CheckIsRtpPacket(buffer, size)) {
|
||||||
if (CheckIsVideoPacket(buffer, size) && ice_transport_controller_) {
|
if (CheckIsVideoPacket(buffer, size) && ice_transport_controller_) {
|
||||||
ice_transport_controller_->OnReceiveVideoRtpPacket(buffer, size, false);
|
ice_transport_controller_->OnReceiveVideoRtpPacket(buffer, size);
|
||||||
} else if (CheckIsAudioPacket(buffer, size) &&
|
} else if (CheckIsAudioPacket(buffer, size) &&
|
||||||
ice_transport_controller_) {
|
ice_transport_controller_) {
|
||||||
ice_transport_controller_->OnReceiveAudioRtpPacket(buffer, size);
|
ice_transport_controller_->OnReceiveAudioRtpPacket(buffer, size);
|
||||||
@@ -205,8 +205,6 @@ void IceTransport::OnReceiveBuffer(NiceAgent *agent, guint stream_id,
|
|||||||
// LOG_ERROR("Rtcp packet [{}]", (uint8_t)(buffer[1]));
|
// LOG_ERROR("Rtcp packet [{}]", (uint8_t)(buffer[1]));
|
||||||
RtcpPacketInfo rtcp_packet_info;
|
RtcpPacketInfo rtcp_packet_info;
|
||||||
ParseRtcpPacket((const uint8_t *)buffer, size, &rtcp_packet_info);
|
ParseRtcpPacket((const uint8_t *)buffer, size, &rtcp_packet_info);
|
||||||
} else if (CheckIsRtpPaddingPacket(buffer, size)) {
|
|
||||||
ice_transport_controller_->OnReceiveVideoRtpPacket(buffer, size, true);
|
|
||||||
} else {
|
} else {
|
||||||
LOG_ERROR("Unknown packet");
|
LOG_ERROR("Unknown packet");
|
||||||
}
|
}
|
||||||
@@ -928,19 +926,8 @@ uint8_t IceTransport::CheckIsRtpPacket(const char *buffer, size_t size) {
|
|||||||
if (payload_type == 96 || payload_type == 99 || payload_type == 111 ||
|
if (payload_type == 96 || payload_type == 99 || payload_type == 111 ||
|
||||||
payload_type == 127) {
|
payload_type == 127) {
|
||||||
return payload_type;
|
return payload_type;
|
||||||
} else {
|
} else if (payload_type == 95 || payload_type == 98 || payload_type == 110 ||
|
||||||
return 0;
|
payload_type == 126) {
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t IceTransport::CheckIsRtpPaddingPacket(const char *buffer, size_t size) {
|
|
||||||
if (size < 2) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t payload_type = buffer[1] & 0x7F;
|
|
||||||
if (payload_type == 95 || payload_type == 98 || payload_type == 110 ||
|
|
||||||
payload_type == 126) {
|
|
||||||
return payload_type;
|
return payload_type;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -972,10 +959,12 @@ uint8_t IceTransport::CheckIsVideoPacket(const char *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t pt = buffer[1] & 0x7F;
|
uint8_t pt = buffer[1] & 0x7F;
|
||||||
if (rtp::PAYLOAD_TYPE::H264 == pt ||
|
if (rtp::PAYLOAD_TYPE::H264 == pt || (rtp::PAYLOAD_TYPE::H264 - 1) == pt ||
|
||||||
rtp::PAYLOAD_TYPE::H264_FEC_SOURCE == pt ||
|
rtp::PAYLOAD_TYPE::H264_FEC_SOURCE == pt ||
|
||||||
|
(rtp::PAYLOAD_TYPE::H264_FEC_SOURCE - 1) == pt ||
|
||||||
rtp::PAYLOAD_TYPE::H264_FEC_REPAIR == pt ||
|
rtp::PAYLOAD_TYPE::H264_FEC_REPAIR == pt ||
|
||||||
rtp::PAYLOAD_TYPE::AV1 == pt) {
|
(rtp::PAYLOAD_TYPE::H264_FEC_REPAIR - 1) == pt ||
|
||||||
|
rtp::PAYLOAD_TYPE::AV1 == pt || (rtp::PAYLOAD_TYPE::AV1 - 1) == pt) {
|
||||||
return pt;
|
return pt;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -105,7 +105,6 @@ class IceTransport {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t CheckIsRtpPacket(const char *buffer, size_t size);
|
uint8_t CheckIsRtpPacket(const char *buffer, size_t size);
|
||||||
uint8_t CheckIsRtpPaddingPacket(const char *buffer, size_t size);
|
|
||||||
uint8_t CheckIsRtcpPacket(const char *buffer, size_t size);
|
uint8_t CheckIsRtcpPacket(const char *buffer, size_t size);
|
||||||
uint8_t CheckIsVideoPacket(const char *buffer, size_t size);
|
uint8_t CheckIsVideoPacket(const char *buffer, size_t size);
|
||||||
uint8_t CheckIsAudioPacket(const char *buffer, size_t size);
|
uint8_t CheckIsAudioPacket(const char *buffer, size_t size);
|
||||||
|
|||||||
@@ -239,9 +239,9 @@ void IceTransportController::UpdateNetworkAvaliablity(bool network_available) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int IceTransportController::OnReceiveVideoRtpPacket(const char* data,
|
int IceTransportController::OnReceiveVideoRtpPacket(const char* data,
|
||||||
size_t size, bool padding) {
|
size_t size) {
|
||||||
if (video_channel_receive_) {
|
if (video_channel_receive_) {
|
||||||
return video_channel_receive_->OnReceiveRtpPacket(data, size, padding);
|
return video_channel_receive_->OnReceiveRtpPacket(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class IceTransportController
|
|||||||
|
|
||||||
void UpdateNetworkAvaliablity(bool network_available);
|
void UpdateNetworkAvaliablity(bool network_available);
|
||||||
|
|
||||||
int OnReceiveVideoRtpPacket(const char *data, size_t size, bool padding);
|
int OnReceiveVideoRtpPacket(const char *data, size_t size);
|
||||||
int OnReceiveAudioRtpPacket(const char *data, size_t size);
|
int OnReceiveAudioRtpPacket(const char *data, size_t size);
|
||||||
int OnReceiveDataRtpPacket(const char *data, size_t size);
|
int OnReceiveDataRtpPacket(const char *data, size_t size);
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,12 @@ class PacketSenderImp : public PacketSender,
|
|||||||
void SendPacket(std::unique_ptr<webrtc::RtpPacketToSend> packet,
|
void SendPacket(std::unique_ptr<webrtc::RtpPacketToSend> packet,
|
||||||
const webrtc::PacedPacketInfo& cluster_info) override {
|
const webrtc::PacedPacketInfo& cluster_info) override {
|
||||||
if (on_sent_packet_func_) {
|
if (on_sent_packet_func_) {
|
||||||
|
if (ssrc_seq_.find(packet->Ssrc()) == ssrc_seq_.end()) {
|
||||||
|
ssrc_seq_[packet->Ssrc()] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
packet->UpdateSequenceNumber(ssrc_seq_[packet->Ssrc()]++);
|
||||||
|
|
||||||
on_sent_packet_func_(*packet);
|
on_sent_packet_func_(*packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,6 +215,7 @@ class PacketSenderImp : public PacketSender,
|
|||||||
|
|
||||||
TaskQueue task_queue_;
|
TaskQueue task_queue_;
|
||||||
int64_t transport_seq_ = 0;
|
int64_t transport_seq_ = 0;
|
||||||
|
std::map<int32_t, int16_t> ssrc_seq_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user