vo: remove qimage member in qpainter renderer

This commit is contained in:
wang-bin
2016-02-06 12:41:40 +08:00
parent 52a356f72d
commit b24cb56dd4
4 changed files with 23 additions and 31 deletions
+1 -1
View File
@@ -35,7 +35,7 @@ public:
QPainterRenderer();
bool isSupported(VideoFormat::PixelFormat pixfmt) const Q_DECL_OVERRIDE;
protected:
bool prepareFrame(const VideoFrame& frame);
bool preparePixmap(const VideoFrame& frame);
void drawBackground() Q_DECL_OVERRIDE;
//draw the current frame using the current paint engine. called by paintEvent()
void drawFrame() Q_DECL_OVERRIDE;
+1 -1
View File
@@ -124,7 +124,7 @@ bool GraphicsItemRenderer::receiveFrame(const VideoFrame& frame)
} else
#endif
{
prepareFrame(frame);
preparePixmap(frame);
}
scene()->update(sceneBoundingRect()); //TODO: thread?
//update(); //does not cause an immediate paint. my not redraw.
+20 -28
View File
@@ -43,34 +43,30 @@ bool QPainterRenderer::isSupported(VideoFormat::PixelFormat pixfmt) const
return VideoFormat::imageFormatFromPixelFormat(pixfmt) != QImage::Format_Invalid;
}
bool QPainterRenderer::prepareFrame(const VideoFrame &frame)
bool QPainterRenderer::preparePixmap(const VideoFrame &frame)
{
DPTR_D(QPainterRenderer);
/*
* QImage constructed from memory do not deep copy the data, data should be available throughout
* image's lifetime and not be modified. painting image happens in main thread, we must ensure the
* image data is not changed if not use the original frame size, so we need the lock.
* In addition, the data passed by ref, so even if we lock, the original data may changed in decoder
* (ImageConverter), so we need a copy of this data(not deep copy) to ensure the image's data not changes before it
* is painted.
* But if we use the fixed original frame size, the data address and size always the same, so we can
* avoid the lock and use the ref data directly and safely
*/
// already locked in a larger scope of receive()
//If use d.data.data() it will eat more cpu, deep copy?
if (frame.constBits(0))
QImage::Format imgfmt = frame.imageFormat();
if (frame.constBits(0)) {
d.video_frame = frame;
else
d.video_frame = frame.to(frame.pixelFormat()); // assume frame format is supported
// DO NOT use frameData().data() because it's temp ptr while QImage does not deep copy the data
QImage::Format imgfmt = d.video_frame.imageFormat();
} 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);
}
d.image = QImage((uchar*)d.video_frame.constBits(), d.video_frame.width(), d.video_frame.height(), d.video_frame.bytesPerLine(), 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)
d.image = d.image.rgbSwapped();
image = image.rgbSwapped();
d.pixmap = QPixmap::fromImage(image);
//Format_RGB32 is fast. see document
return true;
}
@@ -101,20 +97,17 @@ void QPainterRenderer::drawFrame()
DPTR_D(QPainterRenderer);
if (!d.painter)
return;
if (d.image.isNull())
if (d.pixmap.isNull())
return;
QRect roi = realROI();
if (orientation() == 0) {
//assume that the image data is already scaled to out_size(NOT renderer size!)
if (roi.size() == d.out_rect.size()) {
d.painter->drawPixmap(d.out_rect.topLeft(), QPixmap::fromImage(d.image), roi);
//d.painter->drawImage(d.out_rect.topLeft(), d.image, roi);
d.painter->drawPixmap(d.out_rect.topLeft(), d.pixmap, roi);
} else {
// drawPixmap() is faster for on screen painting
d.painter->drawPixmap(d.out_rect, QPixmap::fromImage(d.image), roi);
//d.painter->drawImage(d.out_rect, d.image, roi);
d.painter->drawPixmap(d.out_rect, d.pixmap, roi);
//what's the difference?
//d.painter->drawImage(QPoint(), image.scaled(d.renderer_width, d.renderer_height));
//d.painter->drawPixmap(QPoint(), d.pixmap.scaled(d.renderer_width, d.renderer_height));
}
return;
}
@@ -129,8 +122,7 @@ void QPainterRenderer::drawFrame()
d.painter->scale((qreal)d.out_rect.width()/(qreal)rendererWidth(), (qreal)d.out_rect.height()/(qreal)rendererHeight());
d.painter->rotate(orientation());
d.painter->translate(-rendererWidth()/2, -rendererHeight()/2);
d.painter->drawPixmap(QRect(0, 0, rendererWidth(), rendererHeight()), QPixmap::fromImage(d.image), roi);
//d.painter->drawImage(QRect(0, 0, rendererWidth(), rendererHeight()), d.image, roi);
d.painter->drawPixmap(QRect(0, 0, rendererWidth(), rendererHeight()), d.pixmap, roi);
d.painter->restore();
}
+1 -1
View File
@@ -78,7 +78,7 @@ WidgetRenderer::WidgetRenderer(WidgetRendererPrivate &d, QWidget *parent, Qt::Wi
bool WidgetRenderer::receiveFrame(const VideoFrame &frame)
{
prepareFrame(frame);
preparePixmap(frame);
updateUi();
/*
* workaround for the widget not updated if has parent. don't know why it works and why update() can't