bool QPainterRenderer::preparePixmap(const VideoFrame &frame) { DPTR_D(QPainterRenderer); // already locked in a larger scope of receive() QImage::Format imgfmt = frame.imageFormat(); if (frame.constBits(0)) { d.video_frame = frame; } else { if (imgfmt == QImage::Format_Invalid) { d.video_frame = frame.to(VideoFormat::Format_RGB32); imgfmt = d.video_frame.imageFormat(); } else { d.video_frame = frame.to(frame.pixelFormat()); } } const bool swapRGB = (int)imgfmt < 0; if (swapRGB) { imgfmt = (QImage::Format)(-imgfmt); } // DO NOT use frameData().data() because it's temp ptr while d.image does not deep copy the data QImage image = QImage((uchar*)d.video_frame.constBits(), d.video_frame.width(), d.video_frame.height(), d.video_frame.bytesPerLine(), imgfmt); if (swapRGB) image = image.rgbSwapped(); d.pixmap = QPixmap::fromImage(image); //Format_RGB32 is fast. see document return true; }
bool QQuickItemRenderer::receiveFrame(const VideoFrame &frame) { DPTR_D(QQuickItemRenderer); d.video_frame = frame; if (!isOpenGL()) { d.image = QImage((uchar*)frame.constBits(), frame.width(), frame.height(), frame.bytesPerLine(), frame.imageFormat()); QRect r = realROI(); if (r != QRect(0, 0, frame.width(), frame.height())) d.image = d.image.copy(r); } d.frame_changed = true; // update(); // why update slow? because of calling in a different thread? //QMetaObject::invokeMethod(this, "update"); // slower than directly postEvent QCoreApplication::postEvent(this, new QEvent(QEvent::User)); return true; }