我使用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--;
}
答案 0 :(得分:3)
byteswap的最快方法是使用为其设计的机器指令,即x86处理器上的bswap
和pshufb
(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。