# Encode on-the-fly¶

This example shows how to to perform on-the-fly encoding. The encoder can start to generate encoded packets from a block before all symbols are specified. This can be useful when the symbols are produced on-the-fly.

The complete example code is shown below.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 // Copyright Steinwurf ApS 2011. // Distributed under the "STEINWURF EVALUATION LICENSE 1.0". // See accompanying file LICENSE.rst or // http://www.steinwurf.com/licensing #include #include #include #include #include #include #include #include /// @example encode_on_the_fly.cpp /// /// This example shows how to perform on-the-fly encoding. The encoder /// can start to generate encoded packets from a block before all symbols /// are specified. This can be useful when the symbols are produced on-the-fly. int main() { // Seed random number generator to produce different results every time srand(static_cast(time(0))); // Set the number of symbols (i.e. the generation size in RLNC // terminology) and the size of a symbol in bytes uint32_t symbols = 6; uint32_t symbol_size = 160; fifi::api::field field = fifi::api::field::binary8; // Typdefs for the encoder/decoder type we wish to use using rlnc_encoder = kodo_rlnc::encoder; using rlnc_decoder = kodo_rlnc::decoder; // In the following we will make an encoder/decoder factory. // The factories are used to build actual encoders/decoders rlnc_encoder::factory encoder_factory(field, symbols, symbol_size); auto encoder = encoder_factory.build(); rlnc_decoder::factory decoder_factory(field, symbols, symbol_size); auto decoder = decoder_factory.build(); // Allocate some storage for a "payload" the payload is what we would // eventually send over a network std::vector payload(encoder->payload_size()); // Allocate some data to encode. In this case we make a buffer // with the same size as the encoder's block size (the max. // amount a single encoder can encode) std::vector data_in(encoder->block_size()); // Just for fun - fill the data with random data std::generate(data_in.begin(), data_in.end(), rand); // Let's split the data into symbols and feed the encoder one symbol // at a time auto symbol_storage = storage::split(storage::storage(data_in), symbol_size); // Define a data buffer where the symbols should be decoded std::vector data_out(decoder->block_size()); decoder->set_mutable_symbols(storage::storage(data_out)); // Install a trace function for the decoder if tracing is enabled if (decoder->has_trace_support()) { auto callback = [](const std::string& zone, const std::string& data) { std::set filters = { "decoder_state", "input_symbol_coefficients" }; if (filters.count(zone)) { std::cout << zone << ":" << std::endl; std::cout << data << std::endl; } }; decoder->set_trace_callback(callback); } while (!decoder->is_complete()) { // Randomly choose to insert a symbol until the encoder is full if ((rand() % 2) && (encoder->rank() < symbols)) { // The rank of an encoder specifies the number of symbols // it has available for encoding uint32_t rank = encoder->rank(); encoder->set_const_symbol(rank, symbol_storage[rank]); std::cout << "Symbol " << rank << " added to the encoder" << std::endl; } if (encoder->rank() == 0) { continue; } // Write an encoded packet into the payload buffer encoder->write_payload(payload.data()); std::cout << "Encoded packet generated" << std::endl; // Send the data to the decoder, here we just for fun // simulate that we are losing 50% of the packets if (rand() % 2) { std::cout << "Packet dropped on channel" << std::endl << std::endl; continue; } std::cout << "Decoder received packet" << std::endl; // Packet got through - pass that packet to the decoder decoder->read_payload(payload.data()); std::cout << "Encoder rank = " << encoder->rank() << std::endl; std::cout << "Decoder rank = " << decoder->rank() << std::endl; std::cout << "Decoder uncoded = " << decoder->symbols_uncoded() << " / symbols: "; for (uint32_t i = 0; i < decoder->symbols(); ++i) { if (decoder->is_symbol_uncoded(i)) std::cout << i << " "; } std::cout << std::endl; std::cout << "Decoder partially decoded = " << decoder->symbols_partially_decoded() << std::endl << std::endl; } // Check we properly decoded the data if (std::equal(data_out.begin(), data_out.end(), data_in.begin())) { std::cout << "Data decoded correctly" << std::endl; } else { std::cout << "Unexpected failure to decode, " << "please file a bug report :)" << std::endl; } }