Optimized bgr to yuv420 code

This commit is contained in:
weil 2024-02-11 15:37:19 +01:00
parent 2060e18b75
commit 96cb1af807
1 changed files with 24 additions and 36 deletions

View File

@ -167,49 +167,37 @@ public:
void rgbToYuv(D3D11_MAPPED_SUBRESOURCE mappedResource, size_t width, size_t height)
{
auto srcPtr = static_cast<uint8_t*>(mappedResource.pData);
auto rgb = static_cast<uint8_t*>(mappedResource.pData);
// Lambda functions for YUV conversion
auto rgbToY = [](uint8_t r, uint8_t g, uint8_t b) -> uint8_t {
return static_cast<uint8_t>((0.299 * r) + (0.587 * g) + (0.114 * b));
};
size_t upos = width * height;
size_t vpos = upos + upos / 4;
size_t i = 0;
auto rgbToU = [](uint8_t r, uint8_t g, uint8_t b, int& sumU) -> uint8_t {
sumU += (128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b));
return 0; // Placeholder, real value computed in averaging step
};
for (size_t line = 0; line < height; ++line) {
if (!(line % 2)) {
for (size_t x = 0; x < width; x += 2) {
uint8_t b = rgb[4 * i];
uint8_t g = rgb[4 * i + 1];
uint8_t r = rgb[4 * i + 2];
auto rgbToV = [](uint8_t r, uint8_t g, uint8_t b, int& sumV) -> uint8_t {
sumV += (128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b));
return 0; // Placeholder, real value computed in averaging step
};
m_buffer[i++] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int srcIndex = (y * mappedResource.RowPitch) + (x * 4); // 4 bytes per pixel in source (BGRA)
uint8_t b = srcPtr[srcIndex];
uint8_t g = srcPtr[srcIndex + 1];
uint8_t r = srcPtr[srcIndex + 2];
m_buffer[upos++] = ((-38 * r + -74 * g + 112 * b) >> 8) + 128;
m_buffer[vpos++] = ((112 * r + -94 * g + -18 * b) >> 8) + 128;
// Set Y value
m_buffer[y * width + x] = rgbToY(r, g, b);
b = rgb[4 * i];
g = rgb[4 * i + 1];
r = rgb[4 * i + 2];
// Compute and average U and V values for 2x2 blocks
if (x % 2 == 0 && y % 2 == 0) {
int sumU = 0, sumV = 0;
for (int dy = 0; dy < 2; ++dy) {
for (int dx = 0; dx < 2; ++dx) {
if ((y + dy) < height && (x + dx) < width) {
int i = (y + dy) * width + (x + dx);
rgbToU(r, g, b, sumU);
rgbToV(r, g, b, sumV);
}
}
m_buffer[i++] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
}
} else {
for (size_t x = 0; x < width; x += 1) {
uint8_t b = rgb[4 * i];
uint8_t g = rgb[4 * i + 1];
uint8_t r = rgb[4 * i + 2];
int uvIndex = width * height + (y / 2) * (width / 2) + (x / 2);
m_buffer[uvIndex] = sumU / 4; // Average U
m_buffer[uvIndex + width * height / 4] = sumV / 4; // Average V
m_buffer[i++] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
}
}
}