X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=rsencoder.cpp;h=e4e9481f8b35c61715a3d2ba1966eaa8c414fa83;hb=7019fcdc8632b5740798e8345b48e23640e2de1b;hp=d98a13caf16cb9612965915a501f833a820cc96a;hpb=f873d7fa08ab2f48e5ca96a5b6d1b41724874b09;p=greproxy diff --git a/rsencoder.cpp b/rsencoder.cpp index d98a13c..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" @@ -18,12 +16,12 @@ extern "C" { using namespace std; RSEncoder::RSEncoder(Sender *sender) - : sender(sender) + : sender(sender), + rs(RS_PAYLOAD_SIZE, RS_GROUP_SIZE) { - rs = init_rs_char(RS_SYM_SIZE, RS_GF_POLY, 1, 1, RS_PARITY_SIZE, RS_PAD); } -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) { @@ -36,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(); @@ -51,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); @@ -61,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_char(rs, - reinterpret_cast(&data[0]), - reinterpret_cast(&parity[0])); - 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(); }