Ulpfec_Generator_GetFecPackets
- tags
- webrtc
总结
- UlpfecGenerator::GetFecPackets
- GetFecPackets 负责将已生成的 FEC 包(generated_fec_packets_)全部封装成 RTP RED 包返回。RTP 头部全部复用最后一个媒体包(last_media_packet_)。如果没有 FEC 包,直接返回空。每次调用后内部状态会被重置,并更新 FEC 发送速率统计。
- RTP RED包的说明:https://tools.ietf.org/html/rfc2198
概况序列图
细节序列图
代码
std::vector<std::unique_ptr<RtpPacketToSend>> UlpfecGenerator::GetFecPackets() {
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
if (generated_fec_packets_.empty()) {
return std::vector<std::unique_ptr<RtpPacketToSend>>();
}
// Wrap FEC packet (including FEC headers) in a RED packet. Since the
// FEC packets in `generated_fec_packets_` don't have RTP headers, we
// reuse the header from the last media packet.
RTC_CHECK(last_media_packet_.has_value());
last_media_packet_->SetPayloadSize(0);
std::vector<std::unique_ptr<RtpPacketToSend>> fec_packets;
fec_packets.reserve(generated_fec_packets_.size());
size_t total_fec_size_bytes = 0;
for (const auto* fec_packet : generated_fec_packets_) {
std::unique_ptr<RtpPacketToSend> red_packet =
std::make_unique<RtpPacketToSend>(*last_media_packet_);
red_packet->SetPayloadType(red_payload_type_); //设置payload!
red_packet->SetMarker(false);
uint8_t* payload_buffer = red_packet->SetPayloadSize(
kRedForFecHeaderLength + fec_packet->data.size());
// Primary RED header with F bit unset.
// See https://tools.ietf.org/html/rfc2198#section-3
payload_buffer[0] = ulpfec_payload_type_; // RED header.
memcpy(&payload_buffer[1], fec_packet->data.data(),
fec_packet->data.size());
total_fec_size_bytes += red_packet->size();
red_packet->set_packet_type(RtpPacketMediaType::kForwardErrorCorrection);
red_packet->set_allow_retransmission(false);
red_packet->set_is_red(true);
red_packet->set_fec_protect_packet(false);
fec_packets.push_back(std::move(red_packet));
}
ResetState();
MutexLock lock(&mutex_);
fec_bitrate_.Update(total_fec_size_bytes, env_.clock().CurrentTime());
return fec_packets;
}
思考
- FEC包的序号这里没有设置,在哪里设置?
- ModuleRtpRtcpImpl2::AssignSequenceNumber
void ModuleRtpRtcpImpl2::AssignSequenceNumber(RtpPacketToSend& packet) {
RTC_DCHECK_RUN_ON(&rtp_sender_->sequencing_checker);
bool is_flexfec =
packet.packet_type() == RtpPacketMediaType::kForwardErrorCorrection &&
packet.Ssrc() == rtp_sender_->packet_generator.FlexfecSsrc();
if (!is_flexfec) {
rtp_sender_->sequencer.Sequence(packet);
}
}