Implementation for FEC decoder module

This commit is contained in:
dijunkun
2023-11-15 22:01:05 -08:00
parent 31b5d7f2e3
commit b0bee226d1
12 changed files with 940 additions and 484 deletions

View File

@@ -12,8 +12,11 @@ void RtpPacket::TryToDecodeRtpPacket() {
} else if (NAL_UNIT_TYPE::FU_A == nal_unit_type_) {
DecodeH264Fua();
}
} else if (PAYLOAD_TYPE::H264_FEC == PAYLOAD_TYPE(buffer_[1] & 0x7F)) {
DecodeH264Fec();
} else if (PAYLOAD_TYPE::H264_FEC_SOURCE == PAYLOAD_TYPE(buffer_[1] & 0x7F)) {
nal_unit_type_ = NAL_UNIT_TYPE::FU_A;
DecodeH264FecSource();
} else if (PAYLOAD_TYPE::H264_FEC_REPAIR == PAYLOAD_TYPE(buffer_[1] & 0x7F)) {
DecodeH264FecRepair();
} else if (PAYLOAD_TYPE::DATA == PAYLOAD_TYPE(buffer_[1] & 0x7F)) {
DecodeData();
} else {
@@ -245,7 +248,9 @@ const uint8_t *RtpPacket::EncodeH264Fua(uint8_t *payload, size_t payload_size) {
return buffer_;
}
const uint8_t *RtpPacket::EncodeH264Fec(uint8_t *payload, size_t payload_size) {
const uint8_t *RtpPacket::EncodeH264FecSource(
uint8_t *payload, size_t payload_size, unsigned int fec_symbol_id,
unsigned int fec_source_symbol_num) {
buffer_[0] = (version_ << 6) | (has_padding_ << 5) | (has_extension_ << 4) |
total_csrc_number_;
buffer_[1] = (marker_ << 7) | payload_type_;
@@ -279,10 +284,75 @@ const uint8_t *RtpPacket::EncodeH264Fec(uint8_t *payload, size_t payload_size) {
}
uint32_t fec_symbol_id_offset =
extension_offset + (has_extension_ && extension_data_ ? 4 : 0);
buffer_[12 + fec_symbol_id_offset] = fec_symbol_id_;
(has_extension_ && extension_data_ ? extension_len_ : 0) +
extension_offset;
uint32_t payload_offset = fec_symbol_id_offset + 1;
buffer_[12 + fec_symbol_id_offset] = fec_symbol_id;
uint32_t fec_source_symbol_num_offset = fec_symbol_id_offset + 1;
buffer_[12 + fec_source_symbol_num_offset] = fec_source_symbol_num;
uint32_t payload_offset = fec_source_symbol_num_offset + 1;
buffer_[12 + payload_offset] = fu_indicator_.forbidden_bit << 7 |
fu_indicator_.nal_reference_idc << 6 |
fu_indicator_.nal_unit_type;
buffer_[13 + payload_offset] = fu_header_.start << 7 | fu_header_.end << 6 |
fu_header_.remain_bit << 1 |
fu_header_.nal_unit_type;
memcpy(buffer_ + 14 + payload_offset, payload, payload_size);
size_ = payload_size + (14 + payload_offset);
return buffer_;
}
const uint8_t *RtpPacket::EncodeH264FecRepair(
uint8_t *payload, size_t payload_size, unsigned int fec_symbol_id,
unsigned int fec_source_symbol_num) {
buffer_[0] = (version_ << 6) | (has_padding_ << 5) | (has_extension_ << 4) |
total_csrc_number_;
buffer_[1] = (marker_ << 7) | payload_type_;
buffer_[2] = (sequence_number_ >> 8) & 0xFF;
buffer_[3] = sequence_number_ & 0xFF;
buffer_[4] = (timestamp_ >> 24) & 0xFF;
buffer_[5] = (timestamp_ >> 16) & 0xFF;
buffer_[6] = (timestamp_ >> 8) & 0xFF;
buffer_[7] = timestamp_ & 0xFF;
buffer_[8] = (ssrc_ >> 24) & 0xFF;
buffer_[9] = (ssrc_ >> 16) & 0xFF;
buffer_[10] = (ssrc_ >> 8) & 0xFF;
buffer_[11] = ssrc_ & 0xFF;
for (uint32_t index = 0; index < total_csrc_number_ && !csrcs_.empty();
index++) {
buffer_[12 + index] = (csrcs_[index] >> 24) & 0xFF;
buffer_[13 + index] = (csrcs_[index] >> 16) & 0xFF;
buffer_[14 + index] = (csrcs_[index] >> 8) & 0xFF;
buffer_[15 + index] = csrcs_[index] & 0xFF;
}
uint32_t extension_offset =
total_csrc_number_ && !csrcs_.empty() ? total_csrc_number_ * 4 : 0;
if (has_extension_ && extension_data_) {
buffer_[12 + extension_offset] = extension_profile_ >> 8;
buffer_[13 + extension_offset] = extension_profile_ & 0xff;
buffer_[14 + extension_offset] = (extension_len_ >> 8) & 0xFF;
buffer_[15 + extension_offset] = extension_len_ & 0xFF;
memcpy(buffer_ + 16 + extension_offset, extension_data_, extension_len_);
}
uint32_t fec_symbol_id_offset =
(has_extension_ && extension_data_ ? extension_len_ : 0) +
extension_offset;
buffer_[12 + fec_symbol_id_offset] = fec_symbol_id;
uint32_t fec_source_symbol_num_offset = fec_symbol_id_offset + 1;
buffer_[12 + fec_source_symbol_num_offset] = fec_source_symbol_num;
uint32_t payload_offset = fec_source_symbol_num_offset + 1;
buffer_[12 + payload_offset] = fu_indicator_.forbidden_bit << 7 |
fu_indicator_.nal_reference_idc << 6 |
@@ -438,7 +508,7 @@ size_t RtpPacket::DecodeH264Fua(uint8_t *payload) {
return payload_size_;
}
size_t RtpPacket::DecodeH264Fec(uint8_t *payload) {
size_t RtpPacket::DecodeH264FecSource(uint8_t *payload) {
version_ = (buffer_[0] >> 6) & 0x03;
has_padding_ = (buffer_[0] >> 5) & 0x01;
has_extension_ = (buffer_[0] >> 4) & 0x01;
@@ -467,10 +537,69 @@ size_t RtpPacket::DecodeH264Fec(uint8_t *payload) {
extension_data_ = buffer_ + 16 + extension_offset;
}
uint32_t fec_symbol_id_offset = extension_offset + (has_extension_ ? 4 : 0);
uint32_t fec_symbol_id_offset =
extension_offset + (has_extension_ ? extension_len_ : 0);
fec_symbol_id_ = buffer_[12 + fec_symbol_id_offset];
uint32_t payload_offset = fec_symbol_id_offset + 1;
uint32_t fec_source_symbol_num_offset = fec_symbol_id_offset + 1;
fec_source_symbol_num_ = buffer_[12 + fec_source_symbol_num_offset];
uint32_t payload_offset = fec_source_symbol_num_offset + 1;
fu_indicator_.forbidden_bit = (buffer_[12 + payload_offset] >> 7) & 0x01;
fu_indicator_.nal_reference_idc = (buffer_[12 + payload_offset] >> 5) & 0x03;
fu_indicator_.nal_unit_type = buffer_[12 + payload_offset] & 0x1F;
fu_header_.start = (buffer_[13 + payload_offset] >> 7) & 0x01;
fu_header_.end = (buffer_[13 + payload_offset] >> 6) & 0x01;
fu_header_.remain_bit = (buffer_[13 + payload_offset] >> 5) & 0x01;
fu_header_.nal_unit_type = buffer_[13 + payload_offset] & 0x1F;
payload_size_ = size_ - (14 + payload_offset);
payload_ = buffer_ + 14 + payload_offset;
if (payload) {
memcpy(payload, payload_, payload_size_);
}
return payload_size_;
}
size_t RtpPacket::DecodeH264FecRepair(uint8_t *payload) {
version_ = (buffer_[0] >> 6) & 0x03;
has_padding_ = (buffer_[0] >> 5) & 0x01;
has_extension_ = (buffer_[0] >> 4) & 0x01;
total_csrc_number_ = buffer_[0] & 0x0f;
marker_ = (buffer_[1] >> 7) & 0x01;
payload_type_ = buffer_[1] & 0x7f;
sequence_number_ = (buffer_[2] << 8) | buffer_[3];
timestamp_ =
(buffer_[4] << 24) | (buffer_[5] << 16) | (buffer_[6] << 8) | buffer_[7];
ssrc_ = (buffer_[8] << 24) | (buffer_[9] << 16) | (buffer_[10] << 8) |
buffer_[11];
for (uint32_t index = 0; index < total_csrc_number_; index++) {
uint32_t csrc = (buffer_[12 + index] << 24) | (buffer_[13 + index] << 16) |
(buffer_[14 + index] << 8) | buffer_[15 + index];
csrcs_.push_back(csrc);
}
uint32_t extension_offset = total_csrc_number_ * 4;
if (has_extension_) {
extension_profile_ =
(buffer_[12 + extension_offset] << 8) | buffer_[13 + extension_offset];
extension_len_ =
(buffer_[14 + extension_offset] << 8) | buffer_[15 + extension_offset];
extension_data_ = buffer_ + 16 + extension_offset;
}
uint32_t fec_symbol_id_offset =
extension_offset + (has_extension_ ? extension_len_ : 0);
fec_symbol_id_ = buffer_[12 + fec_symbol_id_offset];
uint32_t fec_source_symbol_num_offset = fec_symbol_id_offset + 1;
fec_source_symbol_num_ = buffer_[12 + fec_source_symbol_num_offset];
uint32_t payload_offset = fec_source_symbol_num_offset + 1;
payload_size_ = size_ - (14 + payload_offset);
payload_ = buffer_ + 14 + payload_offset;