生命在于折腾
给数据增加冗余 前向纠错编码
在不可靠的链路传送数据 比如udp
如果需要增加数据传输的可靠性
我们可以在传输原始数据的时候 增加冗余数据
这样 只要我们收到了一定数量的数据包(不需要所有的)
就可以还原出原始的数据包
比如原始数据是“10”
分成两个包,分别为“1”和“0”
通过异或计算出一个冗余包“0”
我们收到任意两个就能组装出原始的包(知道次序的情况下)
这有些类似磁盘冗余阵列的原理
这些纠错编码的理论不少
实际上可以直接拿来用的代码很少见
好不容易找到了这个 zfec
C代码 GPL 提供了Python接口
作者看起来是个水果迷
在他的Mac中测试效率不错
FEC是Forward Error Correction的简称,意为前向纠错
虽然给了代码 实际要用起来还是很麻烦的
所以这里记录一下方法
1 fec_t* fec_new(unsigned k, unsigned m);
k 把原始数据包分成k块
m 编码后生成m块数据块
块的大小都是一致的,所以很显然m>k,其中编码后的m块中,前k块就是原始的数据
2 void fec_encode(const fec_t* code, const gf*restrict const*restrict const src, gf*restrict const*restrict const fecs, const unsigned*restrict const block_nums, size_t num_block_nums, size_t sz);
编码,参数比较难看,src是包含原始数据指针的一个数组(原始数据分成k块),fecs 是返回的包含冗余数据指针的数组,block_nums为冗余数组的序号,由我们设置传入的,k<=序号
3 void fec_decode(const fec_t* code, const gf*restrict const*restrict const inpkts, gf*restrict const*restrict const outpkts, const unsigned*restrict const index, size_t sz);
基本同上,我们只需要任意k个包就可以还原。inpkts是将收到的数据包按序传入,如果丢包则拿一个冗余包补入。outpkts是返回我们缺失的数据包,index是我们传入的数据包的序号,sz是每个包的大小
4 void fec_free(fec_t* p);
不过 即使这样,还是有内存泄露,自己改改吧
//
说不清楚 看代码吧
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 | fec_t* p = fec_new( 4,6); char buf[1024] = {0}; for ( int i = 0; i < 1024; i++) buf[i]= i % 255; char* src[] = {buf, buf + 256, buf + 512, buf + 768}; char dest[512] = {0}; char* const fecs[] = { dest, dest + 256}; UINT block_nums[] = {4,5};//原始数据编号是0,1,2,3 UINT num_block_nums = 2; //block_nums的大小 UINT sz = 1024 / 4; fec_encode(p, (const gf*const*)src, (gf*const*const)fecs, block_nums, num_block_nums, sz); // 解码,假设我们丢失了原始的数据包 0,3 char* inpkts[] = {fecs[0], buf + 256, buf + 512, fecs[1]};//必须按顺序,丢失的包由冗余包补齐 char output[512] = {0}; char* const outpkts[] = { output, output + 256}; UINT index[] = {4, 1, 2, 5}; //对应inpkts的顺序 fec_decode(p, (const gf* const*const)inpkts, (gf* const* const)outpkts, (const unsigned* const)index, sz); if ( 0 == memcmp( src[0], outpkts[0], 256)) TRACE(L"ok"); if ( 0 == memcmp( src[3], outpkts[1], 256)) TRACE(L"ok"); fec_free(p); |
随便看看
| 打印文章 | 这篇文章由bborn于2008-08-11 22:35发表在code。你可以订阅RSS 2.0 也可以发表评论或引用到你的网站。 |


大约1年前
作者: lixin
评论:
原文中:// 解码,假设我们丢失了原始的数据包 0,3,我不明白。
可是在解码前无法判断丢失的数据包。解码后的数据放在什么地方?
作者: lixin
评论:
文中,// 解码,假设我们丢失了原始的数据包 0,3
char* inpkts[] = {fecs[0], buf + 256, buf + 512, fecs[1]};//
那么接收方如何得知fecs.
作者: lixin
评论:
收到的数据包个数大于等于K,才能还原数据对吗?
如果原始数据是216bit,如何修改程序?谢谢!
作者: lixin
评论:
for ( int i = 0; i < 1024; i++)
buf[i]= i % 255;
char* src[] = {buf, buf + 256, buf + 512, buf + 768};
上述代码的作用是不是对源数据将进行分块处理。
作者: lixin
评论:
文中,// 解码,假设我们丢失了原始的数据包 0,3
char* inpkts[] = {fecs[0], buf + 256, buf + 512, fecs[1]};//
那么接收方如何得知fecs.
大约1年前
看了很长时间zfec,还是没搞懂如何在我的c程序中使用,能否告诉我在c程序中使用,需要哪几个文件?
谢谢!
大约1年前
好像就一个h一个c吧
可能你直接看zfec的文档更好
大约7月前
在搞RTP流的冗余,想用到这个,能否给个联系方式,请教一下。