Error when using OpenFEC-library.-decoder (with LDPC)
<p>I am using the OpenFEC-library (openfec.org).
On the encoder-side I am using some of the code provided in 'test/encoder_instance_test.c' in the OpenFEC-library.
I have a UDP-socket sending packets with the size SYMBOL_SIZE; and another UDP-socket receiving these packets with the same size. I notice by the print-outs of the code that the packages are received.
However, when I try to decode the packets, I get the error message from one of the FEC-files - 'wrong parameters'.
The call of_decode_with_new_symbol (ses, receiverBufferAllSymbols[p], p) results in the error code 3 being returned for all packages.</p>

<p>Why is this the case; and what should I change in my code in order to get it work?</p>

<p>Code of the sender/encoder-side:</p>

<pre><code>#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include "fec_parameters.h"

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

//C-code
 extern "C" {


 }


#define MAX_CODEC_ID    10
#define MAX_K       1000
#define MAX_N       1500
#define SYMBOL_LEN  1024 //we will add header to this, spec. for FEC.
#define MAX_ITER    500     /* MAX_ITER iterations per code/codec */
#define FEC_SPECIFIC_HEADER 2

//from openfec..
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;



#define INBUF_SIZE 4096
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096


#include "sockets/PracticalSocket.h" // For UDPSocket and SocketException
#include &lt;iostream&gt;          // For cout and cerr
#include &lt;cstdlib&gt;           // For atoi()

//const int ECHOMAX = 255;     // Longest string to echo

 /*if (argc != 2) {                  // Test for correct number of parameters
     cerr &lt;&lt; "Usage: " &lt;&lt; argv[0] &lt;&lt; " &lt;Server Port&gt;" &lt;&lt; endl;
     exit(1);
   } */
 //before char *argv[]
//before unsigned short echoServPort = atoi(argv[1]);     // First arg:  local port

 /*Sending packet to server at serverAddress:serverPort
  *
  *
  */
//8037... receiverPort
bool sendPacketWithFECData (char** dataToSend, int sizeOfMessage, string serverAddress, int receiverPort)
   {

  try {
    UDPSocket sock;

//    char echoBuffer[ECHOMAX];         // Buffer for echo string
   // int recvMsgSize;                  // Size of received message
   // string sourceAddress;             // Address of datagram source
   // unsigned short sourcePort;        // Port of datagram source
    //for (;;) {  // Run forever
      // Block until receive message from a client
  //    recvMsgSize = sock.recvFrom(echoBuffer, ECHOMAX, sourceAddress,
      //                                sourcePort);

    cerr &lt;&lt; "\n\ntime to send data....";
    sock.sendTo(dataToSend, sizeOfMessage, serverAddress, receiverPort);
    cerr &lt;&lt; "Package sent to" &lt;&lt;receiverPort;

    //if ( dataToSend[0] != 0)
        //cerr &lt;&lt; dataToSend[0];

    return true;
  } catch (SocketException &amp;e) {
    cerr &lt;&lt; e.what() &lt;&lt; endl;
    exit(1);
    return false;
  }
  // NOT REACHED

  return true;
}


int main(int argc, char **argv)
{
    cerr &lt;&lt; "test nr of arguments are" &lt;&lt; argc;
      if ((argc &lt; 2) || (argc &gt; 4)) {   // Test for correct number of arguments
        cerr &lt;&lt; "Usage: " &lt;&lt; argv[0]
             &lt;&lt; " &lt;Server&gt; [&lt;Server Port&gt;]\n";
        exit(1);
      }


    string serverAddress = argv[1];             // First arg: server address
    int serverPort = atoi(argv[2]);

    symbolLength = SYMBOL_LEN;

    if (argc == 4) //changed if argument..
        symbolLength = atoi (argv[3] );

    /* must be called before using avcodec lib */

    cerr &lt;&lt; "server address is" &lt;&lt; serverAddress;
    /* register all the codecs */
    avcodec_register_all();
    doFecOperations(serverAddress, serverPort, symbolLength);
    printf("inside of videofec-encoder");

    return 0;
}


int doFecOperations(string serverAddress, int serverPort, int symbolLength)
{
    of_codec_id_t   codec_id;
    UINT32      i, j;
    UINT32      k, n;
    UINT32      iter;
    UINT32      esi;
    of_session_t    *ses;
    of_status_t ret;
    char        **orig_symb_tab;
    void        **encoding_symb_tab;
    of_parameters_t *params = NULL;


    int numberOfPayLoadBytesPerPacket = symbolLength;
    int numberOfUserAddedHeaderBytesPerPacket =FEC_SPECIFIC_HEADER;

    int numberOfTotalUserDataBytesPerPacket = numberOfPayLoadBytesPerPacket + numberOfUserAddedHeaderBytesPerPacket;

    printf("do fec-operations");
    codec_id = (of_codec_id_t) 3; //Forcing to us LDPC.

    orig_symb_tab = (char**) calloc (MAX_K, sizeof(char*)); //4 bytes for one char-pointer...=&gt;MAX_K*4
    encoding_symb_tab = (void**) calloc(MAX_N, sizeof(void*));


    if (orig_symb_tab == NULL || encoding_symb_tab == NULL)
    {
        printf("ERROR: no memory for codec %d \n", codec_id);
        goto error;
    }
    for (i = 0; i &lt; MAX_K; i++)
    {          //david:1 element 1024 byte long.....think of package length..
        orig_symb_tab[i] = (char*)calloc(1, symbolLength); //each symbol is 1024.. in this example..e.g. allocate 1024.. K:: 1000 symbols for the origial K.
        encoding_symb_tab[i] = (void*)orig_symb_tab[i]; //david...start with filling encding table with orignal symbols..
        for (j = 0; j &lt; symbolLength; j++)
        {
            orig_symb_tab[i][j] = rand(); //todo david..here instead fill it with the data....
        }
    }
    for (i = MAX_K; i &lt; MAX_N; i++) //max k..that is the number of original symbols..untl n..fill it with repiring symbols..
    {
        encoding_symb_tab[i] = (void*)calloc(1, symbolLength); //each symbol is 1024 in this example..i.e. allocate 1024..
    }
    /*
     * Interesting stuff begins here...
     */
    //codec_id.
    //forcing to use LDPC-coe
    //WE WILL USE: OF_CODEC_LDPC_STAIRCASE_STABLE;

    printf("(OF_CODEC_LDPC_S TAIRCASE_STABLE):\n\t");
   //changed code..one iteration.

            fflush(stdout);



            //if (ret = of_create_codec_instance(&amp;ses, codec_id, OF_ENCODER, 0) != OF_STATUS_OK)
            //error not possible to convert bool to of_status_t in assignment ..

            //if (ret = of_create_codec_instance(&amp;ses, codec_id, OF_ENCODER, 0) != OF_STATUS_OK)
            //if ( of_create_codec_instance(&amp;ses, codec_id, OF_ENCODER, 0)
            //{
                //printf("of_create_codec_instance: ERROR for codec %d\n", codec_id);
                //goto error;
            //}rec

            of_create_codec_instance(&amp;ses, codec_id, OF_ENCODER, 0);

            /* code/codec specific code follows (this is the only place) */

                of_ldpc_parameters_t    *my_params;

                k = MAX_K;
                n = MAX_N;
                my_params = (of_ldpc_parameters_t *)calloc(1, sizeof(* my_params));
                if (my_params == NULL)
                {
                    printf("calloc: ERROR, no memory for codec %d\n", codec_id);
                    goto error;
                }

                my_params-&gt;prng_seed    = 12;
                my_params-&gt;N1       = 5;
                params = (of_parameters_t *) my_params;

            params-&gt;nb_source_symbols   = k;
            params-&gt;nb_repair_symbols   = n - k;
            params-&gt;encoding_symbol_length  = symbolLength;

            if ((ret = of_set_fec_parameters(ses, params)) != OF_STATUS_OK)
            {
                printf("of_set_fec_parameters(): ERROR for codec %d \n", codec_id);
                goto error;
            }
            /*
             * Finally perform encoding...
             */
            for (esi = params-&gt;nb_source_symbols;
                 esi &lt; params-&gt;nb_source_symbols + params-&gt;nb_repair_symbols;
                 esi++)
            {
                memset(encoding_symb_tab[esi], 0, params-&gt;encoding_symbol_length);
                if (of_build_repair_symbol(ses, encoding_symb_tab, esi) != OF_STATUS_OK)
                {
                    printf("of_build_repair_symbol(): ERROR for codec=%d/esi=%d\n",
                        codec_id, esi);
                    goto error;
                }



            }
            /*

    }

    //for (int i = numberOfUserAddedHeaderBytesPerPacket; i &lt; numberOfTotalUserDataBytesPerPacket ; i++)
//  {

//Send encoding_symb_tab[0] --contains SYMBOL_LEN bytes.

    //} */

    for (int l=0; l &lt; n; l++)
    {
    //sendPacketWithFECData ((char**) encoding_symb_tab[l], numberOfTotalUserDataBytesPerPacket, serverAddress, serverPort);
        sendPacketWithFECData ((char**) encoding_symb_tab[l], numberOfPayLoadBytesPerPacket, serverAddress, serverPort);
        cerr &lt;&lt; "Sent packagenr with id.." &lt;&lt; l;
    }

    for (i = 0; i &lt; MAX_N; i++)
    {
        free(encoding_symb_tab[i]);
        /* no need to free source symbols since freeing the first MAX_K
         * entries will free them too. */
    }
    free(orig_symb_tab);

//   * ... and release everything to finish.
    // error without. */
    of_release_codec_instance(ses);

    printf("encoder_instance_test: OK\n");
    return 0;

error:
    printf("encoder_instance_test: ERROR\n");
    return -1;

    return 0;
}
</code></pre>

<p>Here is the code of the receiver/decoding-side:</p>

<pre><code>#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include "data_receiver_fec.h"

#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

//C-code
 extern "C" {

#include "libavutil/imgutils.h"
#include "libavutil/opt.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include "libavutil/samplefmt.h"
#include "/usr/local/include/x264.h"
#include "/usr/local/include/x264_config.h"

 }


#define MAX_CODEC_ID    10
#define MAX_K       1000
#define MAX_N       1500
#define SYMBOL_LEN  1024 //we will add header to this, spec. for FEC.
#define MAX_ITER    500     /* MAX_ITER iterations per code/codec */
#define FEC_SPECIFIC_HEADER 2

//from openfec..
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

#include "PracticalSocket.h" // For UDPSocket and SocketException
#include &lt;iostream&gt;          // For cout and cerr
#include &lt;cstdlib&gt;           // For atoi()

int main(int argc, char **argv)
{

    cerr &lt;&lt; "test nr of arguments are" &lt;&lt; argc;
      if ((argc &lt; 1) || (argc &gt; 3)) {   // Test for correct number of arguments
        cerr &lt;&lt; "Usage: " &lt;&lt; argv[0]
             &lt;&lt; " &lt;Server&gt; [&lt;Server Port&gt;]\n";
        exit(1);
      }

    int symbolLength = SYMBOL_LEN;
    maxK = MAX_K;
    maxN = MAX_N;

    int serverPort = atoi(argv[1]);

    if (argc == 3)
        symbolLength = atoi(argv[2]);

    receivePackageAndFECDecode (serverPort, symbolLength);

    return 0;
}

int receivePackageAndFECDecode(int receiverPort, int packetDataSize) {

    of_codec_id_t   codec_id;

    of_session_t    *ses;
    of_status_t ret;
    char        **orig_symb_tab;
    void        **encoding_symb_tab;
    of_parameters_t *params = NULL;
    maxK = MAX_K;
    maxN = MAX_N;


    codec_id = (of_codec_id_t) 3; //Forcing to us LDPC.

    orig_symb_tab = (char**) calloc (MAX_K, sizeof(char*)); //4 bytes for one char-pointer...=&gt;MAX_K*4
    encoding_symb_tab = (void**) calloc(MAX_N, sizeof(void*));
    symbolLength = packetDataSize;

    of_create_codec_instance(&amp;ses, codec_id, OF_ENCODER, 0);

    if (orig_symb_tab == NULL || encoding_symb_tab == NULL)
    {
        printf("ERROR: no memory for codec %d \n", codec_id);

    }

    fflush(stdout);

        of_ldpc_parameters_t    *my_params;

        k = maxK;
        n = maxN;



        my_params = (of_ldpc_parameters_t *)calloc(1, sizeof(* my_params));
        if (my_params == NULL)
        {
            printf("calloc: ERROR, no memory for codec %d\n", codec_id);
        }
        my_params-&gt;prng_seed    = 12; //old rand()
        my_params-&gt;N1       = 5;
        params = (of_parameters_t *) my_params;

        params-&gt;nb_source_symbols   = k;
        params-&gt;nb_repair_symbols   = n - k;
        params-&gt;encoding_symbol_length  = symbolLength;

        if ((ret = of_set_fec_parameters(ses, params)) != OF_STATUS_OK)
        {
            printf("of_set_fec_parameters(): ERROR for codec %d \n", codec_id);
            //goto error;
        }

  try {
    UDPSocket sock(receiverPort);

    //void* receiverBuffer[packetDataSize+FEC_SPECIFIC_HEADER ];        // Buffer for echo string
    char* receiverBuffer; //[packetDataSize];
    char** receiverBufferAllSymbols;
    int recvMsgSize;                  // Size of received message
    string sourceAddress;             // Address of datagram source
    unsigned short sourcePort;        // Port of datagram source
    cerr &lt;&lt; "Receiver listening on port" &lt;&lt; receiverPort &lt;&lt; "for packets. Vers 1.38";

    receiverBufferAllSymbols = (char**) calloc(MAX_N, sizeof(char*));
    receiverBuffer = (char*) calloc( 1, symbolLength);

     memset (receiverBuffer,0, symbolLength); //reset space.

    cerr &lt;&lt; "did memset etc..";
    if (receiverBufferAllSymbols == NULL)
    {
        printf("ERROR: no memory for codec %d \n", codec_id);
    }

    for (i = 0; i &lt; MAX_N; i++)
    {
        receiverBufferAllSymbols[i] = (char*)calloc(1, symbolLength); //each symbol is 1024.. in this example..e.g. allocate 1024.. K:: 1000 symbols for the origial K.
        memset (receiverBufferAllSymbols[i],0, symbolLength);
    }

    int p = 0;

    while (p &lt; MAX_N)
    {
        memset (receiverBuffer,0, symbolLength); //reset space.

          // Block until receive message from a client
        recvMsgSize = sock.recvFrom(receiverBuffer, symbolLength, sourceAddress, sourcePort);

        char currentSymbol;

        for (int q=0; q &lt; symbolLength; q++)
        {
        currentSymbol = (char) receiverBuffer[q];
        receiverBufferAllSymbols[p][q] = currentSymbol; // *(char) receiverBuffer[q];
        }

    //todo..wrote +2..above....when defining paraetrs.. change that..

      cerr &lt;&lt; "Error status decode symbol for package " &lt;&lt; p &lt;&lt; "  is: " &lt;&lt; of_decode_with_new_symbol (ses, receiverBufferAllSymbols[p], p);

      if (of_is_decoding_complete (ses) == true)
      {
          cerr &lt;&lt; "Received packet, nr: " &lt;&lt; p &lt;&lt; "and msg size" &lt;&lt; recvMsgSize &lt;&lt; "coding complete" &lt;&lt; endl;
      }
      else
      {
          cerr &lt;&lt; "Received packet, nr: " &lt;&lt; p &lt;&lt; "and msg size" &lt;&lt; recvMsgSize &lt;&lt; "coding NOT complete" &lt;&lt; endl;
      }
      p++;

    } //end of loop. while (p &lt; MAX_N)

  } //end of try..
  catch (SocketException &amp;e) {
    cerr &lt;&lt; e.what() &lt;&lt; endl;
    //exit(1);
  }
  // NOT REACHED

    of_release_codec_instance(ses); //finished..release session..


  return 0;
}
</code></pre>

<p>Does anyone have any code working, which decodes FEC-packages using OpenFEC?</p>

<p>Thanks in advance!</p>
