从C中的AS3 ByteArray将big endian转换为little endian

时间:2014-07-22 14:47:54

标签: c

我使用FlasCC允许我使用FFmpeg从AS3渲染视频。在AS3中进行endian交换非常慢我在发送视频字节(对于该帧)之前运行了一些测试并在我的视频ByteArray上删除了我的endian交换,从而渲染了大约一半的渲染时间。我想知道我是否可以通过在C语言中更快地进行endian交换,但我在C或C ++之前从未进行过endian交换,而且我发现的一些帖子是有点复杂。

我将指针作为uint8_t接收到我的ByteArray并希望使用C将端点从大到小交换。任何人都可以指向正确的方向或给我一些示例代码吗?< / p>

ByteArray应该保存RGB32数据,但它是一个大端,我需要用大端进行处理,以便使用ffmpeg进行处理。

编辑:

目前正在使用:

int i = 0;
int j = bufferSize - 1;
int temp;
while (i < j)
{
  temp = buffer[i];
  buffer[i] = buffer[j];
  buffer[j] = temp;
  i++;
  j--;
}

3 个答案:

答案 0 :(得分:3)

byteswap的最快方法是使用为其设计的机器指令,即x86处理器上的bswappshufb(SSSE3)。 好的编译器有模式匹配器来使用基于掩码的常见实现的指令。

xswapped32 = ((x & 0xffu) << 24) | ((x & 0xff00u) << 8) |
             ((x & 0xff0000u) >> 8) | (x >> 24);

在不允许未对齐加载的平台上从int8投射到uint32时,请务必确保数据一致。

可靠地使用它们的最简单方法是使用编译器内在函数,例如与海湾合作委员会或铿锵声:

__builtin_bswap32(var)
如果你的机器有SSSE3,那么

使用pshufb会更快:

const __m128i cmask4 = _mm_set_epi8(12, 13, 14, 15, 
                                    8, 9, 10, 11, 
                                    4, 5, 6, 7,
                                    0, 1, 2 ,3);
_mm_shuffle_epi8(vectorvalue, cmask4);

答案 1 :(得分:1)

如果数据中每个逻辑元素的大小为1个字节,则无需执行任何操作。

否则,您可以使用以下功能:

void Reverse(uint8_t* arr,int arr_size,int elem_size)
{
    int i,j;
    uint8_t temp;
    for (i=0; i<arr_size; i+=elem_size)
    {
        for (j=0; j<elem_size/2; j++)
        {
            temp = arr[i+j];
            arr[i+j] = arr[i+j+elem_size-1];
            arr[i+j+elem_size-1] = temp;
        }
    }
}

答案 2 :(得分:0)

好的,所以我其实只是想出来了。到目前为止,每个人所说的在技术上都是正确的,但不是我一直在寻找的。希望这可以帮助别人。

在AS3中使用BitmapData.getPixels()时,会得到如下数组:

0 1 2 3 4 5 6...
A R G B A R G...

要交换所需的字节序,基本上需要交换A和B值以及R和G值。但是要将ARGB分组保存在一起。这就是为什么阵列的反转给了我正确的颜色,但是整个画面都被反转了,我改变了端部,但主要是将右上角像素移动到左下角(等等)的副产品。

要正确切换RGB32端,我需要将上面的表示更改为:

0 1 2 3 4 5 6...
B G R A B G R...

在这种情况下,这将为FFmpeg提供正确的输入。

然而,快速的方法是在我的FFmpeg API中使用像素格式,这意味着我没有端序转换。我没有使用PIX_FMT_RGB32,而是使用了AV_PIX_FMT_ARGB。