2014-07-22 59 views
0

我正在使用FlasCC允許我使用FFmpeg呈現來自AS3的視頻。在AS3中進行endian交換非常慢我在發送視頻字節(用於該幀)之前正在運行一些測試並刪除我的視頻ByteArray中的endian交換,從而使渲染時間縮短了大約一半。我想看看是否可以通過在C中執行endian swap來更快地完成endian swap,但是我之前從未在C或C++中做過endian swap,而且我發現的一些帖子有點複雜。將大端序列轉換爲AS3中的小端序列ByteArray in C

我正在將一個指針作爲uint8_t指向我的ByteArray,並且想要使用C將大寫字母從大到小交換。任何人都可以用正確的方向指向我,或者給我一些示例代碼來做到這一點?

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--; 
} 
+1

如果你已經有了'uint8_t'數組,那隻不過是顛倒了數組。 – mafso

+1

字節沒有字節序,只有多字節纔有字節序。什麼樣的數據你想改變排序? – ouah

+0

@ouah AS3 ByteArray的大小不一。當您在位圖數據上使用getPixels()時,您將以Big Endian格式獲取RGB32信息的ByteArray。我想將它換成小端格式,以傳遞到採用RGB32像素並處理它們的FFmpeg。所以我有一些字節抱歉,我想我不清楚。 –

回答

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; 
     } 
    } 
} 
+0

這種形式的byteswapping不是最佳的尺寸2,4和8,因爲編譯器很難將其檢測爲字節切換並將其替換爲專用優化的機器指令。使用掩碼來交換小尺寸通常在編譯器模式匹配器中扮演更好的角色。 – jtaylor

+0

@jtaylor:你必須確保數組本身與2,4或8字節地址對齊,以便安全地應用這種優化。上面的代碼假定情況並非如此。在x86上的 –

+0

bswap指令沒有對齊要求。在沒有未對齊的加載的平臺上,你可能不希望你的內存在第一時間沒有對齊,因爲它會很慢,但你是對的,必須小心。 – jtaylor

3

以最快的方式字節交換是使用bswappshufb(SSSE3)x86處理器上爲它設計的,即機器指令。 好的編譯器有模式匹配器來使用基於通用掩碼的實現的指令。從int8鑄造uint32平臺上,不允許非對齊負載時

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

務必小心,以確保您的數據一致。

可靠地使用它們的最簡單的方法是使用編譯器內在函數,與海灣合作委員會或鏗鏘:

__builtin_bswap32(var) 

使用PSHUFB可以更快,如果你你的機器有SSSE3:

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); 
+0

確保x和xswapped32變量都是unsigned int(uint32),否則byteswapping出錯 – Roalt

0

好了,所以我其實只是理解了它自己。到目前爲止,所有人都說技術上正確,但不是我一直在尋找的東西。希望這可以幫助別人。

當使用BitmapData.getPixels()在AS3你得到的數組,像這樣:

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

要交換需要的字節序基本上需要交換A和B值,而R和G的值。但保持該像素的ARGB分組在一起。這就是爲什麼陣列的反轉給了我正確的顏色,但是整個畫面被顛倒過來了,我改變了endian,但主要是作爲將右上像素移動到左下(等等)的雙重產物。

要正確切換RGB32端我需要上述表示更改爲:

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

這將給予FFmpeg的正確輸入在這種情況下。

然而,一個快速的方法是在我的FFmpeg API中使用像素格式,這意味着我沒有endian轉換。我使用AV_PIX_FMT_ARGB而不是使用PIX_FMT_RGB32。