Big/Little Endian issue, 今天又被这个问题浪费了二个多小时,在这重申一下,免得下次再忽略这一issue.
Big/Little Endian 概念:
所谓的大端模式,是指数据的低位(就是权值较小的后面那几位)保存在内存的高地 址中,而数据的高位,保存在内存的低地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;
如:0x789e5799, 但实际用时,是先用78,再 9e.
所谓的小端模式,是指数据的低位保存在内存的低地址中,而数 据的高位保存在内存的高地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
如:与big endian相反。
至于为什么引入这二种模式,大家可以Google一下。目前ARM 和 DSP默认都是小端模式,但现在有很多都能通过设定改变大小端模式。
目前很多complier 都是小端模型,但你写代码时应该同时支持这二种模式,通过MACRO来切换。应该在自己的test plan中加入这一项测试,这一点是有很必要的,下面将分析到。
如何测试Core 或complier的大小端模式。有一简单的方法,加入下面的代码(Google一下,有的更简捷)
short x = 0x1122;
char x0 = ((char *)&x)[0];
if x0 = 0x22, little endian.
原理很简单,但有时跟这个打交道,还是容易出错。我有二次经历。
第一次是 AC3 Decoder, AC3 Decoder reference code 有个MACRO控制little or big endian,但在应用时,为了能支持block input and more frame output, frame input and frame output 模式时,当得知送给decoder process 数据不够时,就要恢复数据的存储格式,然后跳到最外层要数据,并做相应的Buffer 拼接。这个过程很容易出错,希望有碰到这种情况时,要小心一点。
还有一点,过AC3 认证的bitstream 全部是大端存储的,但AC3格式的音乐全部是小端存储。
还有一次就是今天,最近在完善APE Codec, reference code 是C++ template 写的, 读起来有点费神,为了Porting 到Startphone上,我用C重写了。APE 格式的音乐和代码处理的模式不一致。如码流是大端,那代码处理就是小端。APE 对bit 处理是以Byte以单位,这个就简单一点,不要像AAC/AC3那要考虑用了多少个bits.
问题还是出在buffer拼接上,还是为了支持多种模式的输出,就是frame input and frame output, block input and more frame output.
我API层的buffer 是unsigned char 型的,而APE reference code 是以int 型来操作buffer.
当get one output frame data,用掉的buffer刚好是4 alignment,不会出现问题
如不是,就有问题了。如0x789E5799 0x9E999DB7, 如用了0x78后,就得到完整的output frame data, 我返回到API层,把数据放到相应的buffer, 然后做buffer拼接, 0xB7789E57
decoder next frame, 首先就得到B7数据,但这是错误的,正确的应该得到9E才对,而且操作时还把正确的数据 0x99给去掉。
最后修改方案:把APE bits 操作改成Byte,不再就int , 同时让code 支持little and big endian 二种模式。
提议Audio/Video Codec都应该支持big/little endian mode, 并且做好相关测试.