fec description in webrtc

 The theoretical analysis of the webrtcfec mechanism has been well analyzed by the great gods [1]. I'll give an example here to be more figurative.
 Assume that the number of media data packets is now 5, and the number of redundant packets is also 5. Suppose the mask table used is kPacketMaskBurstyTbl.
 Then packet_masks_=kPacketMaskBurstyTbl[4][4]=kMaskBursty5_5 in the function ForwardErrorCorrection::GenerateFecPayloads;

const uint8_t kMaskBursty5_5[10] = {
  0x80, 0x00,
  0xc0, 0x00,
  0x60, 0x00,
  0x30, 0x00,
  0x18, 0x00
};

 This array can be regarded as a matrix, and (i,j)=c represents this matrix, which means that the i-th fec packet is composed of the exclusive OR of the media data packets indicated by the position of 1 in the number c.
 The first fec packet is formed by the XOR of the first (0x80) media packet, the second redundant packet is formed by the XOR of the first, 3, and 4 (0xc0) media packets, and the third redundant packet is formed by the first 2, 3 (0x60) media packets are XORed…. Assuming that the first media packet is lost, take the first fec packet on top.
 This XOR process is completed in the function GenerateFecPayloads.

void ForwardErrorCorrection::GenerateFecPayloads(
    const PacketList& media_packets,
    size_t num_fec_packets) {
  RTC_DCHECK(!media_packets.empty());
  for (size_t i = 0; i < num_fec_packets; ++i) {
    Packet* const fec_packet = &generated_fec_packets_[i];
    size_t pkt_mask_idx = i * packet_mask_size_;
    const size_t min_packet_mask_size = fec_header_writer_->MinPacketMaskSize(
        &packet_masks_[pkt_mask_idx], packet_mask_size_);
    const size_t fec_header_size =
        fec_header_writer_->FecHeaderSize(min_packet_mask_size);

    size_t media_pkt_idx = 0;
    auto media_packets_it = media_packets.cbegin();
    uint16_t prev_seq_num = ParseSequenceNumber((*media_packets_it)->data);
    while (media_packets_it != media_packets.end()) {
      Packet* const media_packet = media_packets_it->get();
      // Should |media_packet| be protected by |fec_packet|?
      if (packet_masks_[pkt_mask_idx] & (1 << (7 - media_pkt_idx))) {
        size_t media_payload_length = media_packet->length - kRtpHeaderSize;

        bool first_protected_packet = (fec_packet->length == 0);
        size_t fec_packet_length = fec_header_size + media_payload_length;
        if (fec_packet_length > fec_packet->length) {
          // Recall that XORing with zero (which the FEC packets are prefilled
          // with) is the identity operator, thus all prior XORs are
          // still correct even though we expand the packet length here.
          fec_packet->length = fec_packet_length;
        }
        if (first_protected_packet) {
          // Write P, X, CC, M, and PT recovery fields.
          // Note that bits 0, 1, and 16 are overwritten in FinalizeFecHeaders.
          memcpy(&fec_packet->data[0], &media_packet->data[0], 2);
          // Write length recovery field. (This is a temporary location for
          // ULPFEC.)
          ByteWriter<uint16_t>::WriteBigEndian(&fec_packet->data[2],
                                               media_payload_length);
          // Write timestamp recovery field.
          memcpy(&fec_packet->data[4], &media_packet->data[4], 4);
          // Write payload.
          memcpy(&fec_packet->data[fec_header_size],
                 &media_packet->data[kRtpHeaderSize], media_payload_length);
        } else {
          XorHeaders(*media_packet, fec_packet);
          XorPayloads(*media_packet, media_payload_length, fec_header_size,
                      fec_packet);
        }
      }
      media_packets_it++;
      if (media_packets_it != media_packets.end()) {
        uint16_t seq_num = ParseSequenceNumber((*media_packets_it)->data);
        media_pkt_idx += static_cast<uint16_t>(seq_num - prev_seq_num);
        prev_seq_num = seq_num;
      }
      pkt_mask_idx += media_pkt_idx / 8;
      media_pkt_idx %= 8;
    }
    RTC_DCHECK_GT(fec_packet->length, 0)
        << "Packet mask is wrong or poorly designed.";
  }
}

[1] Implementation of ULPFEC in WebRTC

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325448355&siteId=291194637