Im try conver rgb32 image to yuv420p for record video.
I have image
QImage image = QGuiApplication::primaryScreen()->grabWindow(0, rect_x, rect_y, rect_width, rect_height).toImage().convertToFormat(QImage::Format_RGB32);
AVFrame *frame;
and convert
for (y = 0; y < c->height; y++) {
QRgb *rowData = (QRgb*)image.scanLine(y);
for (x = 0; x < c->width; x++) {
QRgb pixelData = rowData[x];
int r = qRed(pixelData);
int g = qGreen(pixelData);
int b = qBlue(pixelData);
int y0 = (int)(0.2126 * (float)(r) + 0.7152 * (float)(g) + 0.0722 * (float)(b));
int u = 128 + (int)(-0.09991 * (float)(r) - 0.33609 * (float)(g) + 0.436 * (float)(b));
int v = 128 + (int)(0.615 * (float)(r) - 0.55861 * (float)(g) - 0.05639 * (float)(b));
frame->data[0][y * frame->linesize[0] + x] = y0;
frame->data[1][y / 2 * frame->linesize[1] + x / 2] = u;
frame->data[2][y / 2 * frame->linesize[2] + x / 2] = v;
}
}
but on result image im see artefact. Text look blended http://joxi.ru/eAORRX0u4d46a2
this bug in convert alogritm or something else?
UDP
for (y = 0; y < c->height; y++) {
QRgb *rowData = (QRgb*)image.scanLine(y);
for (x = 0; x < c->width; x++) {
QRgb pixelData = rowData[x];
int r = qRed(pixelData);
int g = qGreen(pixelData);
int b = qBlue(pixelData);
int y0 = (int)(0.2126 * (float)(r) + 0.7152 * (float)(g) + 0.0722 * (float)(b));
if (y0 < 0)
y0 = 0;
if (y0 > 255)
y0 = 255;
frame->data[0][y * frame->linesize[0] + x] = y0;
}
}
int x_pos = 0;
int y_pos = 0;
for (y = 1; y < c->height; y+=2) {
QRgb *pRow = (QRgb*)image.scanLine(y - 1);
QRgb *sRow = (QRgb*)image.scanLine(y);
for (x = 1; x < c->width; x+=2) {
QRgb pd1 = pRow[x - 1];
QRgb pd2 = pRow[x];
QRgb pd3 = sRow[x - 1];
QRgb pd4 = sRow[x];
int r = (qRed(pd1) + qRed(pd2) + qRed(pd3) + qRed(pd4)) / 4;
int g = (qGreen(pd1) + qGreen(pd2) + qGreen(pd3) + qGreen(pd4)) / 4;
int b = (qBlue(pd1) + qBlue(pd2) + qBlue(pd3) + qBlue(pd4)) / 4;
int u = 128 + (int)(-0.147 * (float)(r) - 0.289 * (float)(g) + 0.436 * (float)(b));
int v = 128 + (int)(0.615 * (float)(r) - 0.515 * (float)(g) - 0.1 * (float)(b));
if (u < 0)
u = 0;
if (v > 255)
v = 255;
frame->data[1][y_pos * frame->linesize[1] + x_pos] = u;
frame->data[2][y_pos * frame->linesize[2] + x_pos] = v;
x_pos++;
}
x_pos = 0;
y_pos++;
}
this work for me, but its wery slow, 60-70ms for one frame