X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=rsencoder.cpp;h=e4e9481f8b35c61715a3d2ba1966eaa8c414fa83;hb=HEAD;hp=3026dd4d2373fdc552fbe1660ab88dbf37ce818e;hpb=02120e9414a6e613b17d6284891593271659b5d9;p=greproxy diff --git a/rsencoder.cpp b/rsencoder.cpp index 3026dd4..e4e9481 100644 --- a/rsencoder.cpp +++ b/rsencoder.cpp @@ -5,9 +5,7 @@ #include #include #include -extern "C" { -#include -} +#include #include "reorderer.h" #include "rsencoder.h" @@ -16,8 +14,14 @@ extern "C" { #include using namespace std; + +RSEncoder::RSEncoder(Sender *sender) + : sender(sender), + rs(RS_PAYLOAD_SIZE, RS_GROUP_SIZE) +{ +} -void RSEncoder::send_packet(uint16_t proto, const std::string &data, int incoming_seq) +void RSEncoder::send_packet(uint16_t proto, const std::string &data, uint32_t incoming_seq) { if (!packet_history.empty() && incoming_seq <= packet_history.back().seq) { @@ -30,7 +34,17 @@ void RSEncoder::send_packet(uint16_t proto, const std::string &data, int incomin // Received an unfinished group. packet_history.clear(); } - sender->send_packet(proto, data, incoming_seq); + bool debug_drop_packet = false; // For testing only. + if (incoming_seq % RS_PAYLOAD_SIZE == 3) { + //debug_drop_packet = true; + } + if (debug_drop_packet) { + const unsigned char *ptr = reinterpret_cast(data.data()); + printf("DEBUG: Dropping packet seq=%u proto=0x%04x len=%d data=%02x %02x %02x %02x %02x %02x %02x %02x ...\n", + incoming_seq, proto, data.size(), ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); + } else { + sender->send_packet(proto, data, incoming_seq); + } packet_history.emplace_back(GREPacket{incoming_seq, proto, data}); if (packet_history.size() == RS_PAYLOAD_SIZE) { finish_group(); @@ -45,7 +59,9 @@ void RSEncoder::finish_group() max_length = max(max_length, packet_history[i].data.size()); } - vector padded_packets; + string padded_packets; + padded_packets.reserve((max_length + 4) * packet_history.size()); + // TODO: RS_PAD for (int i = 0; i < packet_history.size(); ++i) { string p; p.resize(max_length + 4); @@ -55,37 +71,22 @@ void RSEncoder::finish_group() uint16_t len_be = htons(packet_history[i].data.size()); memcpy(&p[2], &len_be, sizeof(uint16_t)); memcpy(&p[4], packet_history[i].data.data(), packet_history[i].data.size()); - padded_packets.push_back(p); + padded_packets += p; } - // Now construct RS packets. - vector rs_packets; - for (int i = 0; i < RS_PARITY_SIZE; ++i) { - string p; - p.resize(max_length + 4); - memset(&p[0], 0, max_length + 4); - rs_packets.push_back(p); - } - string data, parity; - data.resize(RS_PAYLOAD_SIZE); - parity.resize(RS_PARITY_SIZE); - for (int i = 0; i < max_length + 4; ++i) { - for (int j = 0; j < packet_history.size(); ++j) { - data[j] = packet_history[j].data[i]; - } - encode_rs_8(reinterpret_cast(&data[0]), - reinterpret_cast(&parity[0]), - RS_PAD); - for (int j = 0; j < RS_PARITY_SIZE; ++j) { - rs_packets[j][i] = parity[j]; - } - } + // Now construct and send RS packets. + rs.encode(reinterpret_cast(padded_packets.data()), + padded_packets.size(), + [&](size_t packet_num, size_t num_packets, const fecpp::byte data[], size_t size) { + // The first N packets are just the original ones; ignore them. + if (packet_num < RS_PAYLOAD_SIZE) { + return; + } - // Actually send the RS packets. - int start_seq = packet_history[0].seq - 1; - for (int i = 0; i < RS_PARITY_SIZE; ++i) { - sender->send_packet(0xffff, rs_packets[i], start_seq - i); - } + const char *sdata = reinterpret_cast(data); + uint32_t start_seq = packet_history[0].seq - 1; + sender->send_packet(0xffff, string(sdata, size), start_seq - (packet_num - RS_PAYLOAD_SIZE)); + }); packet_history.clear(); }