144 {
145 constexpr float kKr = 0.2627f;
146 constexpr float kKg = 0.6780f;
147 constexpr float kKb = 0.0593f;
148 constexpr float kPbDiv = 1.0f / 1.8814f;
149 constexpr float kPrDiv = 1.0f / 1.4746f;
150 constexpr float kInv65535 = 1.0f / 65535.0f;
151
152 for (int y = 0; y < height; y += 2) {
153 const int y1 = std::min(y + 1, height - 1);
154 const uint16_t *row0 = rgba + y * src_stride_shorts;
155 const uint16_t *row1 = rgba + y1 * src_stride_shorts;
156 uint16_t *yr0 = y_plane + y * y_stride_shorts;
157 uint16_t *yr1 = y_plane + y1 * y_stride_shorts;
158 uint16_t *ur = u_plane + (y / 2) * u_stride_shorts;
159 uint16_t *vr = v_plane + (y / 2) * v_stride_shorts;
160
161 for (int x = 0; x < width; x += 2) {
162 const int x1 = std::min(x + 1, width - 1);
163
164 auto load = [&](const uint16_t *px, float &Y, float &U, float &V) {
165 const float rp = px[0] * kInv65535;
166 const float gp = px[1] * kInv65535;
167 const float bp = px[2] * kInv65535;
168 Y = kKr * rp + kKg * gp + kKb * bp;
169 U = (bp - Y) * kPbDiv;
170 V = (rp - Y) * kPrDiv;
171 };
172
173 float Y00, U00, V00;
174 float Y01, U01, V01;
175 float Y10, U10, V10;
176 float Y11, U11, V11;
177 load(row0 + x * 4, Y00, U00, V00);
178 load(row0 + x1 * 4, Y01, U01, V01);
179 load(row1 + x * 4, Y10, U10, V10);
180 load(row1 + x1 * 4, Y11, U11, V11);
181
182 yr0[x] =
clamp10(Y00 * 876.0f + 64.0f);
183 yr0[x1] =
clamp10(Y01 * 876.0f + 64.0f);
184 yr1[x] =
clamp10(Y10 * 876.0f + 64.0f);
185 yr1[x1] =
clamp10(Y11 * 876.0f + 64.0f);
186
187 const float Uavg = 0.25f * (U00 + U01 + U10 + U11);
188 const float Vavg = 0.25f * (V00 + V01 + V10 + V11);
189 ur[x / 2] =
clamp10(Uavg * 896.0f + 512.0f);
190 vr[x / 2] =
clamp10(Vavg * 896.0f + 512.0f);
191 }
192 }
193}
uint16_t clamp10(float v)