Apollo 11.0
自动驾驶开放平台
util.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19#include <cstdarg>
20#include <cstdint>
21
22namespace apollo {
23namespace drivers {
24namespace camera {
25
26void print_m256(__m256i a) {
27 unsigned char snoop[32];
28 bool dst_align = Aligned(reinterpret_cast<void*>(snoop));
29 if (dst_align) {
30 Store<true>(reinterpret_cast<__m256i*>(snoop), a);
31 }
32 else {
33 Store<false>(reinterpret_cast<__m256i*>(snoop), a);
34 }
35 for (int i = 0; i < 32; ++i) {
36 printf("DEBUG8 %d %u \n", i, snoop[i]);
37 }
38}
39void print_m256_i32(const __m256i a) {
40 unsigned int snoop[8];
41 bool dst_align = Aligned(reinterpret_cast<void*>(snoop));
42 if (dst_align)
43 Store<true>(reinterpret_cast<__m256i*>(snoop), a);
44 else
45 Store<false>(reinterpret_cast<__m256i*>(snoop), a);
46 for (int i = 0; i < 8; ++i) {
47 printf("DEBUG32 %d %u \n", i, snoop[i]);
48 }
49}
50
51void print_m256_i16(const __m256i a) {
52 uint16_t snoop[16];
53 bool dst_align = Aligned(reinterpret_cast<void*>(snoop));
54 if (dst_align)
55 Store<true>(reinterpret_cast<__m256i*>(snoop), a);
56 else
57 Store<false>(reinterpret_cast<__m256i*>(snoop), a);
58 for (int i = 0; i < 16; ++i) {
59 printf("DEBUG16 %d %u \n", i, snoop[i]);
60 }
61}
62
63template <bool align>
64SIMD_INLINE void yuv_separate_avx2(uint8_t* y, __m256i* y0, __m256i* y1, __m256i* u0, __m256i* v0) {
65 __m256i yuv_m256[4];
66
67 if (align) {
68 yuv_m256[0] = Load<true>(reinterpret_cast<__m256i*>(y));
69 yuv_m256[1] = Load<true>(reinterpret_cast<__m256i*>(y) + 1);
70 yuv_m256[2] = Load<true>(reinterpret_cast<__m256i*>(y) + 2);
71 yuv_m256[3] = Load<true>(reinterpret_cast<__m256i*>(y) + 3);
72 } else {
73 yuv_m256[0] = Load<false>(reinterpret_cast<__m256i*>(y));
74 yuv_m256[1] = Load<false>(reinterpret_cast<__m256i*>(y) + 1);
75 yuv_m256[2] = Load<false>(reinterpret_cast<__m256i*>(y) + 2);
76 yuv_m256[3] = Load<false>(reinterpret_cast<__m256i*>(y) + 3);
77 }
78
79 *y0 = _mm256_or_si256(
80 _mm256_permute4x64_epi64(_mm256_shuffle_epi8(yuv_m256[0], Y_SHUFFLE0), 0xD8),
81 _mm256_permute4x64_epi64(_mm256_shuffle_epi8(yuv_m256[1], Y_SHUFFLE1), 0xD8));
82 *y1 = _mm256_or_si256(
83 _mm256_permute4x64_epi64(_mm256_shuffle_epi8(yuv_m256[2], Y_SHUFFLE0), 0xD8),
84 _mm256_permute4x64_epi64(_mm256_shuffle_epi8(yuv_m256[3], Y_SHUFFLE1), 0xD8));
85
86 *u0 = _mm256_permutevar8x32_epi32(
87 _mm256_or_si256(
88 _mm256_or_si256(
89 _mm256_shuffle_epi8(yuv_m256[0], U_SHUFFLE0), _mm256_shuffle_epi8(yuv_m256[1], U_SHUFFLE1)),
90 _mm256_or_si256(
91 _mm256_shuffle_epi8(yuv_m256[2], U_SHUFFLE2),
92 _mm256_shuffle_epi8(yuv_m256[3], U_SHUFFLE3))),
94 *v0 = _mm256_permutevar8x32_epi32(
95 _mm256_or_si256(
96 _mm256_or_si256(
97 _mm256_shuffle_epi8(yuv_m256[0], V_SHUFFLE0), _mm256_shuffle_epi8(yuv_m256[1], V_SHUFFLE1)),
98 _mm256_or_si256(
99 _mm256_shuffle_epi8(yuv_m256[2], V_SHUFFLE2),
100 _mm256_shuffle_epi8(yuv_m256[3], V_SHUFFLE3))),
101 U_SHUFFLE4);
102}
103
104template <bool align>
105void yuv2rgb_avx2(__m256i y0, __m256i u0, __m256i v0, uint8_t* rgb) {
106 __m256i r0 = YuvToRed(y0, v0);
107 __m256i g0 = YuvToGreen(y0, u0, v0);
108 __m256i b0 = YuvToBlue(y0, u0);
109
110 Store<align>(reinterpret_cast<__m256i*>(rgb) + 0, InterleaveBgr<0>(r0, g0, b0));
111 Store<align>(reinterpret_cast<__m256i*>(rgb) + 1, InterleaveBgr<1>(r0, g0, b0));
112 Store<align>(reinterpret_cast<__m256i*>(rgb) + 2, InterleaveBgr<2>(r0, g0, b0));
113}
114
115template <bool align>
116void yuv2rgb_avx2(uint8_t* yuv, uint8_t* rgb) {
117 __m256i y0, y1, u0, v0;
118
119 yuv_separate_avx2<align>(yuv, &y0, &y1, &u0, &v0);
120 __m256i u0_u0 = _mm256_permute4x64_epi64(u0, 0xD8);
121 __m256i v0_v0 = _mm256_permute4x64_epi64(v0, 0xD8);
122 yuv2rgb_avx2<align>(y0, _mm256_unpacklo_epi8(u0_u0, u0_u0), _mm256_unpacklo_epi8(v0_v0, v0_v0), rgb);
123 yuv2rgb_avx2<align>(
124 y1, _mm256_unpackhi_epi8(u0_u0, u0_u0), _mm256_unpackhi_epi8(v0_v0, v0_v0), rgb + 3 * sizeof(__m256i));
125}
126
127void yuyv2rgb_avx(unsigned char* YUV, unsigned char* RGB, int NumPixels) {
128 assert(NumPixels == (1920 * 1080));
129 bool align = Aligned(YUV) & Aligned(RGB);
130 uint8_t* yuv_offset = YUV;
131 uint8_t* rgb_offset = RGB;
132 if (align) {
133 for (int i = 0; i < NumPixels; i = i + static_cast<int>(2 * sizeof(__m256i)),
134 yuv_offset += 4 * static_cast<int>(sizeof(__m256i)),
135 rgb_offset += 6 * static_cast<int>(sizeof(__m256i))) {
136 yuv2rgb_avx2<true>(yuv_offset, rgb_offset);
137 }
138 } else {
139 for (int i = 0; i < NumPixels; i = i + static_cast<int>(2 * sizeof(__m256i)),
140 yuv_offset += 4 * static_cast<int>(sizeof(__m256i)),
141 rgb_offset += 6 * static_cast<int>(sizeof(__m256i))) {
142 yuv2rgb_avx2<false>(yuv_offset, rgb_offset);
143 }
144 }
145}
146
147} // namespace camera
148} // namespace drivers
149} // namespace apollo
#define SIMD_INLINE
Definition util.h:43
void print_m256(__m256i a)
Definition util.cc:26
const __m256i Y_SHUFFLE0
Definition util.h:322
const __m256i V_SHUFFLE3
Definition util.h:656
SIMD_INLINE __m256i YuvToRed(__m256i y, __m256i v)
Definition util.h:1296
SIMD_INLINE __m256i InterleaveBgr< 2 >(__m256i blue, __m256i green, __m256i red)
Definition util.h:1345
const __m256i U_SHUFFLE1
Definition util.h:422
void print_m256_i16(const __m256i a)
Definition util.cc:51
void yuv2rgb_avx2(__m256i y0, __m256i u0, __m256i v0, uint8_t *rgb)
Definition util.cc:105
SIMD_INLINE void Store< true >(__m256i *p, __m256i a)
Definition util.h:1237
SIMD_INLINE __m256i YuvToBlue(__m256i y, __m256i u)
Definition util.h:1317
SIMD_INLINE __m256i Load< false >(const __m256i *p)
Definition util.h:1211
const __m256i V_SHUFFLE1
Definition util.h:589
const __m256i U_SHUFFLE2
Definition util.h:455
const __m256i V_SHUFFLE2
Definition util.h:622
void print_m256_i32(const __m256i a)
Definition util.cc:39
SIMD_INLINE __m256i InterleaveBgr< 1 >(__m256i blue, __m256i green, __m256i red)
Definition util.h:1336
const __m256i Y_SHUFFLE1
Definition util.h:355
const __m256i V_SHUFFLE0
Definition util.h:556
const __m256i U_SHUFFLE4
Definition util.h:522
SIMD_INLINE void yuv_separate_avx2(uint8_t *y, __m256i *y0, __m256i *y1, __m256i *u0, __m256i *v0)
Definition util.cc:64
SIMD_INLINE __m256i YuvToGreen(__m256i y, __m256i u, __m256i v)
Definition util.h:1305
SIMD_INLINE __m256i InterleaveBgr< 0 >(__m256i blue, __m256i green, __m256i red)
Definition util.h:1327
const __m256i U_SHUFFLE3
Definition util.h:489
SIMD_INLINE void Store< false >(__m256i *p, __m256i a)
Definition util.h:1232
void yuyv2rgb_avx(unsigned char *YUV, unsigned char *RGB, int NumPixels)
Definition util.cc:127
SIMD_INLINE __m256i Load< true >(const __m256i *p)
Definition util.h:1216
const __m256i U_SHUFFLE0
Definition util.h:389
SIMD_INLINE bool Aligned(const void *ptr, size_t align=sizeof(__m256))
Definition util.h:1224
class register implement
Definition arena_queue.h:37