Warning: This is a development version. The latest stable version is Version 6.0.0.

Code Example: Encode and Decode

In this example shows how to use the API of otacast to implement encoding and decoding.

The example will walk through the basic functionality of class encoder and class decoder, and discuss how to use them.

 1#include <algorithm>
 2#include <cstdlib>
 3#include <iostream>
 4#include <vector>
 5
 6#include <otacast/decoder.hpp>
 7#include <otacast/encoder.hpp>
 8#include <otacast/version.hpp>
 9
10int main()
11{
12    // Create the encoder/decoder objects with a specific finite field
13    otacast::encoder encoder;
14    otacast::decoder decoder;
15
16    std::size_t block_bytes = 1024 * 1000 * 500; // 500 MB
17    std::size_t symbol_bytes = 1500;             // 1.5 kB
18    auto width = otacast::codec_width::_32;
19
20    encoder.configure(width, block_bytes, symbol_bytes);
21    decoder.configure(width, block_bytes, symbol_bytes);
22
23    std::cout << "Preparing some random test data..." << std::endl;
24
25    // Allocate some data to decode
26    std::vector<uint8_t> data_in(encoder.block_bytes());
27
28    // For the example - fill data_in with random data
29    std::generate(data_in.begin(), data_in.end(), rand);
30
31    // Assign the data buffer to the encoder so that we may start
32    // to produce encoded symbols from it
33    encoder.set_symbols_storage(data_in.data());
34
35    // Define a data buffer where the symbols should be decoded
36    std::vector<uint8_t> data_out(decoder.block_bytes());
37    decoder.set_symbols_storage(data_out.data());
38
39    // Initiate a zero-vector for the offset
40    std::vector<uint8_t> symbol(encoder.symbol_bytes());
41
42    // The seed can be anything, here it's basically a packet sequence number.
43    // Will be used to count transmissions as well
44    std::size_t transmissions = 0;
45
46    // Count number of packets received
47    std::size_t received = 0;
48
49    // Set up some packet loss
50    auto loss_probability = 10;
51
52    std::cout << "Encoding/decoding..." << std::endl;
53
54    while (!decoder.is_complete())
55    {
56        // Generate an encoded packet using the number of transmissions as seed
57        auto offset = encoder.encode(symbol.data(), transmissions);
58
59        // We see if the packet is lost
60        if (rand() % 100 >= loss_probability)
61        {
62            // Decode the encoded packet using the number of transmissions as
63            // seed
64            decoder.decode(symbol.data(), transmissions, offset);
65            received++;
66        }
67        transmissions++;
68    }
69
70    // Calculate the overhead
71    auto data_received = received * decoder.symbol_bytes();
72    auto overhead = (data_received / (double)decoder.block_bytes()) - 1;
73
74    // Check if everything went as it should
75    if (data_in == data_out)
76    {
77        std::cout << "Decoding finished successfully!" << std::endl;
78        std::cout << "Overhead: " << overhead * 100 << "%" << std::endl;
79    }
80    else
81    {
82        std::cout << "Something went wrong!" << std::endl;
83    }
84
85    return 0;
86}