⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs_fec.c

📁 这个程序实现了FLUTE协议
💻 C
字号:
/* $Author: peltotal $ $Date: 2006/02/17 09:14:37 $ $Revision: 1.18 $ *//* *   MAD-ALCLIB: Implementation of ALC/LCT protocols, Compact No-Code FEC, *   Simple XOR FEC, Reed-Solomon FEC, and RLC Congestion Control protocol. *   Copyright (c) 2003-2006 TUT - Tampere University of Technology *   main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "inc.h"/* * This function encodes source block data to transport block using Reed-Solomon FEC. * * Params:	char *data: Pointer to data string to be segmented, *			ULONGLONG/unsigned long long len: Length of data string, *			unsigned int sbn: Source Block Number, *			unsigned short eslen: Encoding Symbol Length, *			int rs: FEC ratio percent, *			unsigned int max_sblen: Maximum Source Block Length. * * Return:	trans_block_t *t: Pointer to transport block, *			NULL: In error cases * */trans_block_t* rs_fec_encode_src_block(char *data, #ifdef WIN32								ULONGLONG len#else								unsigned long long len#endif	   								, unsigned int sbn,								unsigned short es_len, int rs, unsigned int max_sb_len) {		trans_block_t *tr_block;		/* transport block struct */	trans_unit_t *tr_unit;			/* transport unit struct */	unsigned int i;					/* loop variables */	char *ptr;						/* pointer to left data */	void *code;	char *src[GF_SIZE];	unsigned int k;					/* number of data units */	unsigned int n;					/* total number of units */	unsigned int max_k;	unsigned int max_n;#ifdef WIN32	ULONGLONG data_left = len;#else	unsigned long long data_left = len;#endif	div_t div_k;	div_t div_max_n;	div_t div_n;	max_k = max_sb_len;		div_k = div((unsigned int)len, es_len);		if(div_k.rem == 0) {		k = (unsigned int)div_k.quot;	}	else {		k = (unsigned int)div_k.quot + 1;	}	div_max_n = div((max_k * (100 + rs)), 100);	max_n = (unsigned int)div_max_n.quot;	div_n = div((k * max_n), (max_k));	n = (unsigned int)div_n.quot;	code = 	fec_new(k, n);	tr_block = create_block();	if(tr_block == NULL) {		return tr_block;	}	tr_unit = create_units(n);	if(tr_unit == NULL) {		free(tr_block);		return NULL;	}	ptr = data;	tr_block->unit_list = tr_unit;	tr_block->sbn = sbn;	tr_block->n = n;	tr_block->k = k;	tr_block->max_k = max_k;	tr_block->max_n = max_n;		for(i = 0; i < k; i++) {				tr_unit->esi = i;		tr_unit->len = data_left < es_len ? (unsigned short)data_left : es_len;		/* Alloc memory for TU data */		if(!(tr_unit->data = (char*)calloc(es_len, sizeof(char)))) {			printf("Could not alloc memory for transport unit's data!\n");						tr_unit = tr_block->unit_list;				while(tr_unit != NULL) {				free(tr_unit->data);				tr_unit++;			}				free(tr_block->unit_list);			free(tr_block);			return NULL;		}		memcpy(tr_unit->data, ptr, tr_unit->len);		src[i] = tr_unit->data;				ptr += tr_unit->len;		data_left -= tr_unit->len;		tr_unit++;	}	/* let's create FEC units */	for (i = 0; i < (n - k); i++) {		tr_unit->esi = k+i;		tr_unit->len = es_len;		/* Alloc memory for TU data */		if(!(tr_unit->data = (char*)calloc(es_len, sizeof(char)))) {			printf("Could not alloc memory for transport unit's data!\n");						tr_unit = tr_block->unit_list;				while(tr_unit != NULL) {				free(tr_unit->data);				tr_unit++;			}				free(tr_block->unit_list);			free(tr_block);			return NULL;		}		fec_encode(code, (void**)src, tr_unit->data, k+i, es_len);		tr_unit++;	}	fec_free(code);	return tr_block;}/* * This function decodes source block data to buffer using Reed-Solomon FEC. * * Params:      trans_block_t *tr_block: Pointer to source block, *              ULONGLONG/unsigned long long *block_len: Pointer to length of block, *				unsigned short eslen: Encoding Symbol Length for this block, * * Return:      char*: Pointer to buffer which contains block's data, *              NULL: when memory could not be allocated * */char *rs_fec_decode_src_block(trans_block_t *tr_block, #ifdef WIN32							ULONGLONG *block_len#else							unsigned long long *block_len#endif							, unsigned short es_len) {	char *buf = NULL; /* buffer where to construct the source block from data units */	trans_unit_t *next_tu;	trans_unit_t *tu;	#ifdef WIN32	ULONGLONG len;#else	unsigned long long len;#endif		void	*code;	char	*dst[GF_SIZE];	int		index[GF_SIZE];	unsigned int i = 0;	unsigned int k;						/* number of data units */	unsigned int n;						/* total number of units */	div_t div_n;	k = tr_block->k;	div_n = div((k * tr_block->max_n), tr_block->max_k);	n= (unsigned int)div_n.quot;	len = es_len*tr_block->k;	code = 	fec_new(k, n);	/* Allocate memory for buf */	if(!(buf = (char*)calloc((unsigned int)(len + 1), sizeof(char)))) {		printf("Could not alloc memory for buf!\n");		*block_len = -1;		return NULL;	}		next_tu = tr_block->unit_list;       			while(next_tu != NULL) {                        		tu = next_tu;								dst[i] = tu->data;		index[i] = tu->esi; 		next_tu = tu->next;		i++;	}	/* Let's decode source block using Reed-Solomon FEC */	fec_decode(code, (void**)dst, index, es_len);	fec_free(code);	/* Copy decoded encoding symbols to buffer */	for(i = 0; i < k; i++) {		memcpy(buf + i*es_len, dst[i], es_len);	}	next_tu = tr_block->unit_list;       			while(next_tu != NULL) {           		tu = next_tu;		        free(tu->data);		tu->data = NULL;              		next_tu = tu->next;	}	*block_len = len;	return buf;}/* * This function decodes object to buffer using Reed-Solomon FEC. * * Params:	trans_obj_t *tr_obj: Pointer to object, *			ULONGLONG/unsigned long long *datalen: Pointer to length of object, *			alc_session_t *s: Pointer to session. * * Return:	char*: Pointer to buffer which contains object's data, *			NULL: when memory could not be allocated. * */char *rs_fec_decode_object(trans_obj_t *to,#ifdef WIN32							ULONGLONG *data_len#else							unsigned long long *data_len#endif							, alc_session_t *s) {	char *object = NULL; /* buffer where to construct the object */	char *block = NULL; /* buffer where to contruct the object */		trans_block_t *tb;#ifdef WIN32	ULONGLONG len;	ULONGLONG position;	ULONGLONG to_data_left;	ULONGLONG block_len;#else	unsigned long long len;	unsigned long long position;	unsigned long long to_data_left;	unsigned long long block_len;#endif	unsigned int i;		/* Allocate memory for object */	if(!(object = (char*)calloc((unsigned int)(to->len + 1), sizeof(char)))) {		printf("Could not alloc memory for object!\n");		*data_len = -1;		return NULL;	}	position = 0;	to_data_left = to->len;		tb = to->block_list;		/*while(tb != NULL) {*/        for(i = 0; i < to->bs->N; i++) {		block = rs_fec_decode_src_block(tb, &block_len, (unsigned short)to->es_len);		/* the last packet of the last source block might be padded with zeros */		len = to_data_left < block_len ? to_data_left : block_len;		memcpy(object+(unsigned int)position, block, (unsigned int)len);		position += len;		to_data_left -= len;		free(block);		block = NULL;		/*tb = tb->next;*/		tb = to->block_list+(i+1);	}	*data_len = to->len;		return object;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -