@@ -29,6 +29,86 @@ HtoNS(uint16_t v)
29
29
((v >> 8 ) & 0xff );
30
30
}
31
31
32
+ static float
33
+ Saturate01 (const float v)
34
+ {
35
+ if (v < 0 ) {
36
+ return 0 ;
37
+ } else if (1 .0f < v) {
38
+ return 1 .0f ;
39
+ } else {
40
+ return v;
41
+ }
42
+ }
43
+
44
+ // / <summary>
45
+ // / 0~1の範囲のfloat値のYUVを0~1の範囲のfloat値のRGBにする。
46
+ // / </summary>
47
+ static void
48
+ YuvToRgb (
49
+ const float y, const float u, const float v,
50
+ float * r_return, float *g_return, float *b_return)
51
+ {
52
+ *r_return = Saturate01 (1 .1644f * y + 0 .0000f * u + 1 .5960f * v - 0 .8742f );
53
+ *g_return = Saturate01 (1 .1644f * y - 0 .3918f * u - 0 .8130f * v + 0 .5317f );
54
+ *b_return = Saturate01 (1 .1644f * y + 2 .0172f * u + 0 .0000f * v - 1 .0856f );
55
+ }
56
+
57
+ // / <summary>
58
+ // / 8bit YUV → 8bit RGB
59
+ // / </summary>
60
+ static void
61
+ Yuv8ToRgb8 (
62
+ const uint8_t y8, const uint8_t u8 , const uint8_t v8,
63
+ uint8_t * r8_return, uint8_t * g8_return, uint8_t * b8_return)
64
+ {
65
+ const float y = y8 / 255 .0f ;
66
+ const float u = u8 / 255 .0f ;
67
+ const float v = v8 / 255 .0f ;
68
+
69
+ const float r = Saturate01 (1 .1644f * y + 0 .0000f * u + 1 .5960f * v - 0 .8742f );
70
+ const float g = Saturate01 (1 .1644f * y - 0 .3918f * u - 0 .8130f * v + 0 .5317f );
71
+ const float b = Saturate01 (1 .1644f * y + 2 .0172f * u + 0 .0000f * v - 1 .0856f );
72
+
73
+ *r8_return = (uint8_t )(r * 255 .0f );
74
+ *g8_return = (uint8_t )(g * 255 .0f );
75
+ *b8_return = (uint8_t )(b * 255 .0f );
76
+ }
77
+
78
+ // / <summary>
79
+ // / 10bit YUV → 10bit RGB
80
+ // / </summary>
81
+ static void
82
+ Yuv10ToRgb10 (
83
+ const uint16_t y10, const uint16_t u10, const uint16_t v10,
84
+ uint16_t * r10_return, uint16_t * g10_return, uint16_t * b10_return)
85
+ {
86
+ const float y = y10 / 1023 .0f ;
87
+ const float u = u10 / 1023 .0f ;
88
+ const float v = v10 / 1023 .0f ;
89
+
90
+ const float r = Saturate01 (1 .1644f * y + 0 .0000f * u + 1 .5960f * v - 0 .8742f );
91
+ const float g = Saturate01 (1 .1644f * y - 0 .3918f * u - 0 .8130f * v + 0 .5317f );
92
+ const float b = Saturate01 (1 .1644f * y + 2 .0172f * u + 0 .0000f * v - 1 .0856f );
93
+
94
+ *r10_return = (uint16_t )(r * 1023 .0f );
95
+ *g10_return = (uint16_t )(g * 1023 .0f );
96
+ *b10_return = (uint16_t )(b * 1023 .0f );
97
+ }
98
+
99
+ // / <summary>
100
+ // / 0~1の範囲のfloat値のRGBを0~1の範囲のfloat値のYUVにする。
101
+ // / </summary>
102
+ static void
103
+ RgbToYuv (
104
+ const float r, const float g, const float b,
105
+ float * y_return, float * u_return, float * v_return)
106
+ {
107
+ *y_return = Saturate01 ( 0 .2568f * r + 0 .5041f * g + 0 .0979f * b + 0 .0627f );
108
+ *u_return = Saturate01 (-0 .1482f * r - 0 .2910f * g + 0 .4392f * b + 0 .5020f );
109
+ *v_return = Saturate01 ( 0 .4392f * r - 0 .3678f * g - 0 .0714f * b + 0 .5020f );
110
+ }
111
+
32
112
static const float pq_m1 = 0 .1593017578125f ; // ( 2610.0 / 4096.0 ) / 4.0;
33
113
static const float pq_m2 = 78 .84375f ; // ( 2523.0 / 4096.0 ) * 128.0;
34
114
static const float pq_c1 = 0 .8359375f ; // 3424.0 / 4096.0 or pq_c3 - pq_c2 + 1.0;
@@ -68,6 +148,134 @@ MLConverter::MLConverter(void)
68
148
}
69
149
}
70
150
151
+ void
152
+ MLConverter::Uyvy8bitToR8G8B8A8 (const uint32_t * pFrom, uint32_t * pTo, const int width, const int height)
153
+ {
154
+ // widthは2で割り切れる。
155
+ assert ((width & 1 ) == 0 );
156
+
157
+ const uint32_t a = 0xff ;
158
+
159
+ #pragma omp parallel for
160
+ for (int y = 0 ; y < height; ++y) {
161
+ for (int x2 = 0 ; x2 < width/2 ; ++x2) {
162
+ // 2ピクセルずつ処理。
163
+
164
+ // 入力のUYVY: 2ピクセルが1個のuint32に入る。
165
+ const int readP = x2 + y * (width/2 );
166
+ // 出力: 1ピクセルが1個のuint32に入る。
167
+ const int writeP = (x2 * 2 ) + y * width;
168
+
169
+ // bmdFormat8BitYUV: UYVY
170
+ // ビッグエンディアンのUYVU
171
+ // w LSB
172
+ // YYYYYYYY VVVVVVVV YYYYYYYY UUUUUUUU
173
+ // 76543210 76543210 76543210 76543210
174
+ const uint32_t w = pFrom[readP];
175
+
176
+ const uint32_t y0 = (w >> 8 ) & 0xff ;
177
+ const uint32_t y1 = (w >> 24 ) & 0xff ;
178
+
179
+ const uint32_t u = (w >> 0 ) & 0xff ;
180
+ const uint32_t v = (w >> 16 ) & 0xff ;
181
+
182
+ // yuv → RGB
183
+ uint8_t r, g, b;
184
+
185
+ Yuv8ToRgb8 (y0, u, v, &r, &g, &b);
186
+ pTo[writeP + 0 ] = (a << 24 ) + (b << 16 ) + (g << 8 ) + r;
187
+
188
+ Yuv8ToRgb8 (y1, u, v, &r, &g, &b);
189
+ pTo[writeP + 1 ] = (a << 24 ) + (b << 16 ) + (g << 8 ) + r;
190
+ }
191
+ }
192
+ }
193
+ // / <summary>
194
+ // / bmdFormat10BitYUV v210 → DXGI_FORMAT_R10G10B10A2_UNORM
195
+ // / </summary>
196
+ void
197
+ MLConverter::Yuv422_10bitToR10G10B10A2 (const uint32_t * pFrom, uint32_t * pTo, const int width, const int height)
198
+ {
199
+ const uint32_t a = 0x3 ;
200
+
201
+ assert ((width % 48 ) == 0 );
202
+
203
+ #pragma omp parallel for
204
+ for (int y = 0 ; y < height; ++y) {
205
+ for (int x6 = 0 ; x6 < width/6 ; ++x6) {
206
+ // 6ピクセルずつ処理。
207
+
208
+ // 入力のv210: 6ピクセルが4個のuint32に入る。
209
+ const int readP = x6*4 + y * (width *4 / 6 );
210
+
211
+ // 出力:1ピクセルが1個のuint32に入る。
212
+ const int writeP = (x6 * 6 ) + y * width;
213
+
214
+ // bmdFormat10BitYUV v210
215
+ const uint32_t w0 = pFrom[readP + 0 ];
216
+ const uint32_t w1 = pFrom[readP + 1 ];
217
+ const uint32_t w2 = pFrom[readP + 2 ];
218
+ const uint32_t w3 = pFrom[readP + 3 ];
219
+
220
+ // w0 LSB
221
+ // --vvvvvv vvvvyyyy yyyyyyuu uuuuuuuu
222
+ // --000000 00000000 00000000 00000000 pixelIdx
223
+ // --987654 32109876 54321098 76543210
224
+
225
+ // w1 LSB
226
+ // --yyyyyy yyyyuuuu uuuuuuyy yyyyyyyy
227
+ // --222222 22222222 22222211 11111111 pixelIdx
228
+ // --987654 32109876 54321098 76543210
229
+
230
+ // w0 LSB
231
+ // --uuuuuu uuuuyyyy yyyyyyvv vvvvvvvv
232
+ // --444444 44443333 33333322 22222222 pixelIdx
233
+ // --987654 32109876 54321098 76543210
234
+ // w0 LSB
235
+ // --yyyyyy yyyyvvvv vvvvvvyy yyyyyyyy
236
+ // --555555 55554444 44444444 44444444 pixelIdx
237
+ // --987654 32109876 54321098 76543210
238
+
239
+ const uint32_t u0 = (w0 >> 0 ) & 0x3ff ;
240
+ const uint32_t y0 = (w0 >> 10 ) & 0x3ff ;
241
+ const uint32_t v0 = (w0 >> 20 ) & 0x3ff ;
242
+
243
+ const uint32_t y1 = (w1 >> 0 ) & 0x3ff ;
244
+ const uint32_t u2 = (w1 >> 10 ) & 0x3ff ;
245
+ const uint32_t y2 = (w1 >> 20 ) & 0x3ff ;
246
+
247
+ const uint32_t v2 = (w2 >> 0 ) & 0x3ff ;
248
+ const uint32_t y3 = (w2 >> 10 ) & 0x3ff ;
249
+ const uint32_t u4 = (w2 >> 20 ) & 0x3ff ;
250
+
251
+ const uint32_t y4 = (w3 >> 0 ) & 0x3ff ;
252
+ const uint32_t v4 = (w3 >> 10 ) & 0x3ff ;
253
+ const uint32_t y5 = (w3 >> 20 ) & 0x3ff ;
254
+
255
+ // yuv → RGB
256
+ uint16_t r, g, b;
257
+
258
+ Yuv10ToRgb10 (y0, u0, v0, &r, &g, &b);
259
+ pTo[writeP + 0 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
260
+
261
+ Yuv10ToRgb10 (y1, u0, v0, &r, &g, &b);
262
+ pTo[writeP + 1 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
263
+
264
+ Yuv10ToRgb10 (y2, u2, v2, &r, &g, &b);
265
+ pTo[writeP + 2 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
266
+
267
+ Yuv10ToRgb10 (y3, u2, v2, &r, &g, &b);
268
+ pTo[writeP + 3 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
269
+
270
+ Yuv10ToRgb10 (y4, u4, v4, &r, &g, &b);
271
+ pTo[writeP + 4 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
272
+
273
+ Yuv10ToRgb10 (y5, u4, v4, &r, &g, &b);
274
+ pTo[writeP + 5 ] = (a << 30 ) + (b << 20 ) + (g << 10 ) + r;
275
+ }
276
+ }
277
+ }
278
+
71
279
void
72
280
MLConverter::Argb8bitToR8G8B8A8 (const uint32_t * pFrom, uint32_t * pTo, const int width, const int height)
73
281
{
@@ -78,16 +286,16 @@ MLConverter::Argb8bitToR8G8B8A8(const uint32_t* pFrom, uint32_t* pTo, const int
78
286
79
287
// bmdFormat8BitARGB
80
288
// ビッグエンディアンのA8R8G8B8 → リトルエンディアンのR8G8B8A8
81
- const uint32_t v = NtoHL ( pFrom[pos]) ;
289
+ const uint32_t w = pFrom[pos];
82
290
83
- // v LSB
84
- // AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB
291
+ // w LSB
292
+ // BBBBBBBB GGGGGGGG RRRRRRRR AAAAAAAA
85
293
// 76543210 76543210 76543210 76543210
86
294
87
- const uint32_t a = (v >> 24 ) & 0xff ;
88
- const uint32_t r = (v >> 16 ) & 0xff ;
89
- const uint32_t g = (v >> 8 ) & 0xff ;
90
- const uint32_t b = (v >> 0 ) & 0xff ;
295
+ const uint8_t a = (w >> 0 ) & 0xff ;
296
+ const uint8_t r = (w >> 8 ) & 0xff ;
297
+ const uint8_t g = (w >> 16 ) & 0xff ;
298
+ const uint8_t b = (w >> 24 ) & 0xff ;
91
299
pTo[pos] = (a << 24 ) + (b << 16 ) + (g << 8 ) + r;
92
300
}
93
301
}
0 commit comments