rs_fec.c

Go to the documentation of this file.
00001 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <memory.h>
00037 #include <assert.h>
00038 
00039 #include "rs_fec.h"
00040 #include "fec.h"
00041 
00042 trans_block_t* rs_fec_encode_src_block(char *data, unsigned long long len, unsigned int sbn,
00043                                                                            unsigned short es_len, int rs, unsigned int max_sb_len) {
00044 
00045     trans_block_t *tr_block;                /* transport block struct */
00046     trans_unit_t *tr_unit;                  /* transport unit struct */
00047     unsigned int i;                         /* loop variables */
00048     char *ptr;                              /* pointer to left data */
00049     void *code;
00050     char *src[GF_SIZE];
00051     unsigned int k;                         /* number of source symbols */
00052     unsigned int n;                         /* number of encoding symbols */
00053     unsigned int max_k;
00054     unsigned int max_n;
00055     unsigned long long data_left;
00056     div_t div_k;
00057     div_t div_max_n;
00058     div_t div_n;
00059 
00060         data_left = len;
00061     max_k = max_sb_len;
00062 
00063     div_k = div((unsigned int)len, es_len);
00064 
00065     if(div_k.rem == 0) {
00066             k = (unsigned int)div_k.quot;
00067     }
00068     else {
00069             k = (unsigned int)div_k.quot + 1;
00070     }
00071 
00072     div_max_n = div((max_k * (100 + rs)), 100);
00073     max_n = (unsigned int)div_max_n.quot;
00074 
00075     div_n = div((k * max_n), (max_k));
00076     n = (unsigned int)div_n.quot;
00077 
00078     code =  fec_new(k, n);
00079         tr_block = create_block();
00080 
00081     if(tr_block == NULL) {
00082             return tr_block;
00083     }
00084 
00085     tr_unit = create_units(n);
00086 
00087     if(tr_unit == NULL) {
00088             free(tr_block);
00089             return NULL;
00090     }
00091 
00092     ptr = data;
00093 
00094     tr_block->unit_list = tr_unit;
00095     tr_block->sbn = sbn;
00096     tr_block->n = n;
00097 
00098     tr_block->k = k;
00099     tr_block->max_k = max_k;
00100     tr_block->max_n = max_n;
00101 
00102     for(i = 0; i < k; i++) {
00103            tr_unit->esi = i;
00104             tr_unit->len = data_left < es_len ? (unsigned short)data_left : es_len;
00105 
00106             /* Alloc memory for TU data */
00107             if(!(tr_unit->data = (char*)calloc(es_len, sizeof(char)))) {
00108                     printf("Could not alloc memory for transport unit's data!\n");
00109 
00110                     tr_unit = tr_block->unit_list;
00111 
00112                     while(tr_unit != NULL) {
00113                             free(tr_unit->data);
00114                             tr_unit++;
00115                     }
00116 
00117                     free(tr_block->unit_list);
00118                     free(tr_block);
00119                     return NULL;
00120             }
00121 
00122             memcpy(tr_unit->data, ptr, tr_unit->len);
00123 
00124             src[i] = tr_unit->data;
00125 
00126             ptr += tr_unit->len;
00127             data_left -= tr_unit->len;
00128             tr_unit++;
00129     }
00130   /* let's create FEC units */
00131 
00132     for (i = 0; i < (n - k); i++) {
00133 
00134             tr_unit->esi = k+i;
00135             tr_unit->len = es_len;
00136 
00137             /* Alloc memory for TU data */
00138             if(!(tr_unit->data = (char*)calloc(es_len, sizeof(char)))) {
00139                     printf("Could not alloc memory for transport unit's data!\n");
00140 
00141                     tr_unit = tr_block->unit_list;
00142 
00143                     while(tr_unit != NULL) {
00144                             free(tr_unit->data);
00145                             tr_unit++;
00146                     }
00147 
00148                     free(tr_block->unit_list);
00149                     free(tr_block);
00150                     return NULL;
00151             }
00152 
00153             fec_encode(code, (void**)src, tr_unit->data, k+i, es_len);
00154 
00155             tr_unit++;
00156     }
00157     fec_free(code);
00158 
00159     return tr_block;
00160 }
00161 
00162 char *rs_fec_decode_src_block(trans_block_t *tr_block, unsigned long long *block_len,
00163                                                           unsigned short es_len) {
00164 
00165     char *buf = NULL; /* buffer where to construct the source block from data units */
00166     trans_unit_t *next_tu;
00167     trans_unit_t *tu;
00168 
00169     unsigned long long len;
00170     void    *code;
00171     char    *dst[GF_SIZE];
00172     int             index[GF_SIZE];
00173     unsigned int i = 0;
00174     unsigned int k;
00175     unsigned int n;
00176     div_t div_n;
00177 
00178     k = tr_block->k;
00179 
00180     div_n = div((k * tr_block->max_n), tr_block->max_k);
00181     n = (unsigned int)div_n.quot;
00182 
00183     len = es_len*tr_block->k;
00184 
00185     code =  fec_new(k, n);
00186 
00187     /* Allocate memory for buf */
00188     if(!(buf = (char*)calloc((unsigned int)(len + 1), sizeof(char)))) {
00189             printf("Could not alloc memory for buf!\n");
00190             *block_len = 0;
00191             return NULL;
00192     }
00193 
00194     next_tu = tr_block->unit_list;
00195 
00196     while(next_tu != NULL) {
00197 
00198             tu = next_tu;
00199             dst[i] = tu->data;
00200             index[i] = tu->esi;
00201 
00202             next_tu = tu->next;
00203             i++;
00204     }
00205 
00206     /* Let's decode source block using Reed-Solomon FEC */
00207 
00208     fec_decode(code, (void**)dst, index, es_len);
00209 
00210     fec_free(code);
00211 
00212     /* Copy decoded encoding symbols to buffer */
00213 
00214     for(i = 0; i < k; i++) {
00215             memcpy(buf + i*es_len, dst[i], es_len);
00216     }
00217 
00218     next_tu = tr_block->unit_list;
00219 
00220 #ifndef USE_RETRIEVE_UNIT
00221     while(next_tu != NULL) {
00222                 tu = next_tu;
00223                 free(tu->data);
00224                 tu->data = NULL;
00225         next_tu = tu->next;
00226     }
00227 #endif
00228 
00229    *block_len = len;
00230 
00231     return buf;
00232 }
00233 
00234 
00235 
00236 char *rs_fec_decode_object(trans_obj_t *to, unsigned long long *data_len, alc_session_t *s) {
00237 
00238     char *object = NULL; /* buffer where to construct the object */
00239     char *block = NULL; /* buffer where to contruct the object */
00240 
00241     trans_block_t *tb;
00242 
00243     unsigned long long len;
00244     unsigned long long position;
00245     unsigned long long to_data_left;
00246     unsigned long long block_len;
00247     unsigned int i;
00248 
00249     /* Allocate memory for object */
00250     if(!(object = (char*)calloc((unsigned int)(to->len + 1), sizeof(char)))) {
00251             printf("Could not alloc memory for object!\n");
00252             *data_len = 0;
00253             return NULL;
00254     }
00255 
00256     position = 0;
00257     to_data_left = to->len;
00258 
00259     tb = to->block_list;
00260 
00261     /*while(tb != NULL) {*/
00262     for(i = 0; i < to->bs->N; i++) {
00263             block = rs_fec_decode_src_block(tb, &block_len, (unsigned short)to->es_len);
00264 
00265             /* the last packet of the last source block might be padded with zeros */
00266             len = to_data_left < block_len ? to_data_left : block_len;
00267 
00268                         assert(0 <= position);
00269                         assert(position < to->len+1);
00270                         assert(len <= (to->len-position));
00271 
00272             memcpy(object+(unsigned int)position, block, (unsigned int)len);
00273             position += len;
00274             to_data_left -= len;
00275 
00276             free(block);
00277             block = NULL;
00278 
00279             /*tb = tb->next;*/
00280             tb = to->block_list+(i+1);
00281     }
00282 
00283     *data_len = to->len;
00284     return object;
00285 }

Generated on Fri Mar 9 20:08:51 2007 for MAD-FCL by  doxygen 1.5.0