如何修改YUV420转RGB24的Intrinsics代码以输出RGBA32
YUV420转r8g8b8a8的Intrinsics优化问题
我首次使用Intrinsics做图像转换优化,参考了一个YUV420转RGB24的实现代码,但我的目标输出格式是r8g8b8a8,原代码只输出r8g8b8。我对代码做了如下修改:
const __m128 rgb1_1 = _mm_shuffle_ps( _mm_shuffle_ps(b1, g1, _MM_SHUFFLE(0, 0, 0, 0)), _mm_shuffle_ps(r1, b1, _MM_SHUFFLE(1, 1, 0, 0)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb1_2 = _mm_shuffle_ps( _mm_shuffle_ps(g1, r1, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b1, g1, _MM_SHUFFLE(2, 2, 2, 2)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb1_3 = _mm_shuffle_ps( _mm_shuffle_ps(r1, b1, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_ps(g1, r1, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb2_1 = _mm_shuffle_ps( _mm_shuffle_ps(b2, g2, _MM_SHUFFLE(0, 0, 0, 0)), _mm_shuffle_ps(r2, b2, _MM_SHUFFLE(1, 1, 0, 0)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb2_2 = _mm_shuffle_ps( _mm_shuffle_ps(g2, r2, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b2, g2, _MM_SHUFFLE(2, 2, 2, 2)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb2_3 = _mm_shuffle_ps( _mm_shuffle_ps(r2, b2, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_ps(g2, r2, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb3_1 = _mm_shuffle_ps( _mm_shuffle_ps(b3, g3, _MM_SHUFFLE(0, 0, 0, 0)), _mm_shuffle_ps(r3, b3, _MM_SHUFFLE(1, 1, 0, 0)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb3_2 = _mm_shuffle_ps( _mm_shuffle_ps(g3, r3, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b3, g3, _MM_SHUFFLE(2, 2, 2, 2)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb3_3 = _mm_shuffle_ps( _mm_shuffle_ps(r3, b3, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_ps(g3, r3, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb4_1 = _mm_shuffle_ps( _mm_shuffle_ps(b4, g4, _MM_SHUFFLE(0, 0, 0, 0)), _mm_shuffle_ps(r4, b4, _MM_SHUFFLE(1, 1, 0, 0)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb4_2 = _mm_shuffle_ps( _mm_shuffle_ps(g4, r4, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b4, g4, _MM_SHUFFLE(2, 2, 2, 2)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128 rgb4_3 = _mm_shuffle_ps( _mm_shuffle_ps(r4, b4, _MM_SHUFFLE(3, 3, 2, 2)), _mm_shuffle_ps(g4, r4, _MM_SHUFFLE(3, 3, 3, 3)), _MM_SHUFFLE(2, 0, 2, 0)); const __m128i pack1l = _mm_packs_epi32(_mm_cvtps_epi32(rgb1_1), _mm_cvtps_epi32(rgb1_2)); const __m128i pack1h = _mm_packs_epi32(_mm_cvtps_epi32(rgb1_3), _mm_cvtps_epi32(rgb2_1)); const __m128i pack1 = _mm_packus_epi16(pack1l, pack1h); const __m128i pack2l = _mm_packs_epi32(_mm_cvtps_epi32(rgb2_2), _mm_cvtps_epi32(rgb2_3)); const __m128i pack2h = _mm_packs_epi32(_mm_cvtps_epi32(rgb3_1), _mm_cvtps_epi32(rgb3_2)); const __m128i pack2 = _mm_packus_epi16(pack2l, pack2h); const __m128i pack3l = _mm_packs_epi32(_mm_cvtps_epi32(rgb3_3), _mm_cvtps_epi32(rgb4_1)); const __m128i pack3h = _mm_packs_epi32(_mm_cvtps_epi32(rgb4_2), _mm_cvtps_epi32(rgb4_3)); const __m128i pack3 = _mm_packus_epi16(pack3l, pack3h); const __m128i packAlpha = { 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }; // and finally store in output _mm_storeu_si128((__m128i*)(pixels + ((wh - width) * 4) - h * width * 4 + w * 4 + 0 * 16), pack1); _mm_storeu_si128((__m128i*)(pixels + ((wh - width) * 4) - h * width * 4 + w * 4 + 1 * 16), pack2); _mm_storeu_si128((__m128i*)(pixels + ((wh - width) * 4) - h * width * 4 + w * 4 + 2 * 16), pack3); _mm_storeu_si128((__m128i*)(pixels + ((wh - width) * 4) - h * width * 4 + w * 4 + 3 * 16), packAlpha);
我新增了packAlpha相关代码,原本以为能正确对齐r8g8b8a8格式,但输出图像呈现灰度且带有垂直白线。另外,图像双轴翻转的问题在修改前就存在,后续可以通过旋转纹理解决,暂时不用关注这个问题。
内容的提问来源于stack exchange,提问作者Connor
相关产品推荐
相关产品推荐

