[fix] fix h264 rtp packet parse

This commit is contained in:
dijunkun
2025-01-24 17:54:54 +08:00
parent 7b839ab773
commit 2d5749f93a
10 changed files with 253 additions and 54 deletions

View File

@@ -19,6 +19,130 @@ RtpPacketizerH264::~RtpPacketizerH264() {}
std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
uint32_t payload_size) {
if (payload_size <= MAX_NALU_LEN) {
return BuildNalu(payload, payload_size);
} else {
return BuildFua(payload, payload_size);
// return std::vector<RtpPacket>();
}
}
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | L=2 | Absolute Send Time |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ID (4 bits): The identifier of the extension header field. In WebRTC,
// the ID for Absolute Send Time is typically 3.
// L (4 bits): The length of the extension data in bytes minus 1. For
// Absolute Send Time: the length is 2 (indicating 3 bytes of data).
// Absolute Send Time (24 bits): The absolute send time, with a unit of
// 1/65536 seconds (approximately 15.258 microseconds).
void RtpPacketizerH264::AddAbsSendTimeExtension(
std::vector<uint8_t>& rtp_packet_frame) {
uint16_t extension_profile = 0xBEDE; // One-byte header extension
uint8_t sub_extension_id = 3; // ID for Absolute Send Time
uint8_t sub_extension_length =
2; // Length of the extension data in bytes minus 1
uint32_t abs_send_time =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
abs_send_time &= 0x00FFFFFF; // Absolute Send Time is 24 bits
// Add extension profile
rtp_packet_frame.push_back((extension_profile >> 8) & 0xFF);
rtp_packet_frame.push_back(extension_profile & 0xFF);
// Add extension length (in 32-bit words, minus one)
rtp_packet_frame.push_back(
0x00); // Placeholder for length, will be updated later
rtp_packet_frame.push_back(0x01); // One 32-bit word
// Add Absolute Send Time extension
rtp_packet_frame.push_back((sub_extension_id << 4) | sub_extension_length);
rtp_packet_frame.push_back((abs_send_time >> 16) & 0xFF);
rtp_packet_frame.push_back((abs_send_time >> 8) & 0xFF);
rtp_packet_frame.push_back(abs_send_time & 0xFF);
}
std::vector<RtpPacket> RtpPacketizerH264::BuildNalu(uint8_t* payload,
uint32_t payload_size) {
LOG_ERROR("payload_size_ = {}", payload_size);
std::vector<RtpPacket> rtp_packets;
version_ = kRtpVersion;
has_padding_ = false;
has_extension_ = true;
csrc_count_ = 0;
marker_ = 1;
payload_type_ = rtp::PAYLOAD_TYPE(payload_type_);
sequence_number_++;
timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
ssrc_ = ssrc_;
if (!csrc_count_) {
csrcs_ = csrcs_;
}
rtp::FU_INDICATOR fu_indicator;
fu_indicator.forbidden_bit = 0;
fu_indicator.nal_reference_idc = 1;
fu_indicator.nal_unit_type = rtp::NAL_UNIT_TYPE::NALU;
rtp_packet_frame_.clear();
rtp_packet_frame_.push_back((version_ << 6) | (has_padding_ << 5) |
(has_extension_ << 4) | csrc_count_);
rtp_packet_frame_.push_back((marker_ << 7) | payload_type_);
rtp_packet_frame_.push_back((sequence_number_ >> 8) & 0xFF);
rtp_packet_frame_.push_back(sequence_number_ & 0xFF);
rtp_packet_frame_.push_back((timestamp_ >> 24) & 0xFF);
rtp_packet_frame_.push_back((timestamp_ >> 16) & 0xFF);
rtp_packet_frame_.push_back((timestamp_ >> 8) & 0xFF);
rtp_packet_frame_.push_back(timestamp_ & 0xFF);
rtp_packet_frame_.push_back((ssrc_ >> 24) & 0xFF);
rtp_packet_frame_.push_back((ssrc_ >> 16) & 0xFF);
rtp_packet_frame_.push_back((ssrc_ >> 8) & 0xFF);
rtp_packet_frame_.push_back(ssrc_ & 0xFF);
for (uint32_t index = 0; index < csrc_count_ && !csrcs_.empty(); index++) {
rtp_packet_frame_.push_back((csrcs_[index] >> 24) & 0xFF);
rtp_packet_frame_.push_back((csrcs_[index] >> 16) & 0xFF);
rtp_packet_frame_.push_back((csrcs_[index] >> 8) & 0xFF);
rtp_packet_frame_.push_back(csrcs_[index] & 0xFF);
}
if (has_extension_) {
AddAbsSendTimeExtension(rtp_packet_frame_);
}
rtp_packet_frame_.push_back(fu_indicator.forbidden_bit << 7 |
fu_indicator.nal_reference_idc << 6 |
fu_indicator.nal_unit_type);
LOG_ERROR("1 [{} {} {}]", (int)fu_indicator.forbidden_bit,
(int)fu_indicator.nal_reference_idc,
(int)fu_indicator.nal_unit_type);
rtp_packet_frame_.insert(rtp_packet_frame_.end(), payload,
payload + payload_size);
RtpPacket rtp_packet;
rtp_packet.Build(rtp_packet_frame_.data(), rtp_packet_frame_.size());
rtp_packets.emplace_back(rtp_packet);
return rtp_packets;
}
std::vector<RtpPacket> RtpPacketizerH264::BuildFua(uint8_t* payload,
uint32_t payload_size) {
std::vector<RtpPacket> rtp_packets;
uint32_t last_packet_size = payload_size % MAX_NALU_LEN;
uint32_t packet_num =
payload_size / MAX_NALU_LEN + (last_packet_size ? 1 : 0);
@@ -28,7 +152,6 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
std::chrono::system_clock::now().time_since_epoch())
.count();
std::vector<RtpPacket> rtp_packets;
for (uint32_t index = 0; index < packet_num; index++) {
version_ = kRtpVersion;
has_padding_ = false;
@@ -78,41 +201,7 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
}
if (has_extension_) {
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | ID | L=2 | Absolute Send Time |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// ID (4 bits): The identifier of the extension header field. In WebRTC,
// the ID for Absolute Send Time is typically 3.
// L (4 bits): The length of the extension data in bytes minus 1. For
// Absolute Send Time: the length is 2 (indicating 3 bytes of data).
// Absolute Send Time (24 bits): The absolute send time, with a unit of
// 1/65536 seconds (approximately 15.258 microseconds).
extension_profile_ = kOneByteExtensionProfileId;
// 2 bytes for profile, 2 bytes for length, 3 bytes for abs_send_time, 1
// byte for id and sub extension length
extension_len_ = 8;
uint32_t abs_send_time =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
abs_send_time &= 0x00FFFFFF;
uint8_t sub_extension_id = 0;
uint8_t sub_extension_len = 2;
rtp_packet_frame_.push_back(extension_profile_ >> 8);
rtp_packet_frame_.push_back(extension_profile_ & 0xff);
rtp_packet_frame_.push_back((extension_len_ >> 8) & 0xFF);
rtp_packet_frame_.push_back(extension_len_ & 0xFF);
rtp_packet_frame_.push_back(sub_extension_id << 4 | sub_extension_len);
rtp_packet_frame_.push_back((abs_send_time >> 16) & 0xFF);
rtp_packet_frame_.push_back((abs_send_time >> 8) & 0xFF);
rtp_packet_frame_.push_back(abs_send_time & 0xFF);
AddAbsSendTimeExtension(rtp_packet_frame_);
}
rtp_packet_frame_.push_back(fu_indicator.forbidden_bit << 7 |
@@ -150,7 +239,8 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
// uint8_t num_of_source_packets = 0;
// unsigned int last_packet_size = 0;
// fec_encoder_.GetFecPacketsParams(payload_size, num_of_total_packets,
// num_of_source_packets, last_packet_size);
// num_of_source_packets,
// last_packet_size);
// timestamp_ = std::chrono::duration_cast<std::chrono::microseconds>(
// std::chrono::system_clock::now().time_since_epoch())
@@ -225,7 +315,8 @@ std::vector<RtpPacket> RtpPacketizerH264::Build(uint8_t* payload,
// rtp_packet.SetExtensionProfile(extension_profile_);
// rtp_packet.SetExtensionData(extension_data_, extension_len_);
// }
// rtp_packet.EncodeH264FecRepair(fec_packets[index], MAX_NALU_LEN, index,
// rtp_packet.EncodeH264FecRepair(fec_packets[index], MAX_NALU_LEN,
// index,
// num_of_source_packets);
// }
// packets.emplace_back(rtp_packet);