diff --git a/src/Direct2DRenderer.cpp b/src/Direct2DRenderer.cpp index 671b8a80..458a21e9 100644 --- a/src/Direct2DRenderer.cpp +++ b/src/Direct2DRenderer.cpp @@ -156,7 +156,7 @@ void Direct2DRenderer::convertData(const QByteArray &data) //TODO: if CopyFromMemory() is deep copy, mutex can be avoided if (!d.scale_in_renderer) { /*if lock is required, do not use locker in if() scope, it will unlock outside the scope*/ - d.img_mutex.lock(); + d.img_mutex.lock();//TODO: d2d often crash, should we always lock? How about other renderer? hr = d.bitmap->CopyFromMemory(NULL //&D2D1::RectU(0, 0, image.width(), image.height()) /*&dstRect, NULL?*/, , data.constData() , d.src_width*4*sizeof(char)); @@ -200,14 +200,21 @@ void Direct2DRenderer::paintEvent(QPaintEvent *) d.render_target->BeginDraw(); d.render_target->SetTransform(D2D1::Matrix3x2F::Identity()); if (!d.bitmap) { + //TODO: It seems that the target's background keeps the color d.render_target->Clear(D2D1::ColorF(D2D1::ColorF::Black)); if (!d.scale_in_renderer) { d.img_mutex.unlock(); } return; } + D2D1_RECT_F out_rect = { + d.out_rect.left(), + d.out_rect.top(), + d.out_rect.right(), + d.out_rect.bottom() + }; d.render_target->DrawBitmap(d.bitmap - , &D2D1::RectF(0, 0, width(), height()) + , &out_rect , 1 //opacity , D2D1_BITMAP_INTERPOLATION_MODE_LINEAR , &D2D1::RectF(0, 0, d.src_width, d.src_height)); diff --git a/src/GDIRenderer.cpp b/src/GDIRenderer.cpp index 9a6a54f3..8fa14772 100644 --- a/src/GDIRenderer.cpp +++ b/src/GDIRenderer.cpp @@ -159,12 +159,29 @@ void GDIRenderer::paintEvent(QPaintEvent *) qWarning("Failed GetHBITMAP"); return; } + + //fill background color only when the displayed frame rect not equas to renderer's + if (d.out_rect != rect()) { + + } HBITMAP hbmp_old = (HBITMAP)SelectObject(d.off_dc, d.off_bitmap); // && image.size() != size() - if (d.scale_in_renderer || d.src_width != d.renderer_width || d.src_height != d.renderer_height) { //TODO:rename scale_on_paint - StretchBlt(hdc, 0, 0, width(), height(), d.off_dc, 0, 0, d.src_width, d.src_height, SRCCOPY); + //assume that the image data is already scaled to out_size(NOT renderer size!) + if (!d.scale_in_renderer || (d.src_width == d.out_rect.width() && d.src_height == d.out_rect.height())) { + BitBlt(hdc + , d.out_rect.left(), d.out_rect.top() + , d.out_rect.width(), d.out_rect.height() + , d.off_dc + , 0, 0 + , SRCCOPY); } else { - BitBlt(hdc, 0, 0, d.src_width, d.src_height, d.off_dc, 0, 0, SRCCOPY); + StretchBlt(hdc + , d.out_rect.left(), d.out_rect.top() + , d.out_rect.width(), d.out_rect.height() + , d.off_dc + , 0, 0 + , d.src_width, d.src_height + , SRCCOPY); } SelectObject(d.off_dc, hbmp_old); DeleteObject(d.off_bitmap); //avoid mem leak diff --git a/src/GraphicsItemRenderer.cpp b/src/GraphicsItemRenderer.cpp index 25b16eea..957bba52 100644 --- a/src/GraphicsItemRenderer.cpp +++ b/src/GraphicsItemRenderer.cpp @@ -70,20 +70,25 @@ void GraphicsItemRenderer::paint(QPainter *painter, const QStyleOptionGraphicsIt Q_UNUSED(option); Q_UNUSED(widget); DPTR_D(GraphicsItemRenderer); - if (!d.scale_in_qt) { + if (!d.scale_in_renderer) { d.img_mutex.lock(); } - painter->fillRect(boundingRect(), QColor(0, 0, 0)); + //fill background color only when the displayed frame rect not equas to renderer's + if (d.out_rect != boundingRect()) { + painter->fillRect(boundingRect(), QColor(0, 0, 0)); + } if (d.image.isNull()) { //TODO: when setInSize()? d.image = QImage(rendererSize(), QImage::Format_RGB32); d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint) } - if (d.image.size() == QSize(d.renderer_width, d.renderer_height)) + //assume that the image data is already scaled to out_size(NOT renderer size!) + if (!d.scale_in_renderer || d.image.size() == d.out_rect.size()) { painter->drawImage(d.out_rect.topLeft(), d.image); - else + } else { painter->drawImage(d.out_rect, d.image); - if (!d.scale_in_qt) { + } + if (!d.scale_in_renderer) { d.img_mutex.unlock(); } } diff --git a/src/ImageRenderer.cpp b/src/ImageRenderer.cpp index 49ceb0cc..cc7d3b4a 100644 --- a/src/ImageRenderer.cpp +++ b/src/ImageRenderer.cpp @@ -62,7 +62,7 @@ void ImageRenderer::convertData(const QByteArray &data) * 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 */ - if (!d.scale_in_qt) { + if (!d.scale_in_renderer) { /*if lock is required, do not use locker in if() scope, it will unlock outside the scope*/ d.img_mutex.lock(); d.data = data; diff --git a/src/VideoRenderer.cpp b/src/VideoRenderer.cpp index 54dbc600..d8bf6bd5 100644 --- a/src/VideoRenderer.cpp +++ b/src/VideoRenderer.cpp @@ -43,12 +43,12 @@ VideoRenderer::~VideoRenderer() void VideoRenderer::scaleInRenderer(bool q) { - d_func().scale_in_qt = q; + d_func().scale_in_renderer = q; } bool VideoRenderer::scaleInRenderer() const { - return d_func().scale_in_qt; + return d_func().scale_in_renderer; } void VideoRenderer::setOutAspectRatioMode(OutAspectRatioMode mode) diff --git a/src/WidgetRenderer.cpp b/src/WidgetRenderer.cpp index f916da7a..e3738762 100644 --- a/src/WidgetRenderer.cpp +++ b/src/WidgetRenderer.cpp @@ -118,17 +118,21 @@ void WidgetRenderer::mouseDoubleClickEvent(QMouseEvent *) void WidgetRenderer::paintEvent(QPaintEvent *) { DPTR_D(WidgetRenderer); - if (!d.scale_in_qt) { + if (!d.scale_in_renderer) { d.img_mutex.lock(); } QPainter p(this); - p.fillRect(rect(), QColor(0, 0, 0)); + //fill background color only when the displayed frame rect not equas to renderer's + if (d.out_rect != rect()) { + p.fillRect(rect(), QColor(0, 0, 0)); + } if (d.image.isNull()) { //TODO: when setInSize()? d.image = QImage(rendererSize(), QImage::Format_RGB32); d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint) } - if (d.image.size() == d.out_rect.size()) { + //assume that the image data is already scaled to out_size(NOT renderer size!) + if (!d.scale_in_renderer || d.image.size() == d.out_rect.size()) { //d.preview = d.image; p.drawImage(d.out_rect.topLeft(), d.image); } else { @@ -138,7 +142,7 @@ void WidgetRenderer::paintEvent(QPaintEvent *) //what's the difference? //p.drawImage(QPoint(), image.scaled(d.renderer_width, d.renderer_height)); } - if (!d.scale_in_qt) { + if (!d.scale_in_renderer) { d.img_mutex.unlock(); } } diff --git a/templates/vo.cpp b/templates/vo.cpp index 4285dd1a..2867733e 100644 --- a/templates/vo.cpp +++ b/templates/vo.cpp @@ -71,6 +71,18 @@ void %CLASS%::paintEvent(QPaintEvent *) } //begin paint. how about QPainter::beginNativePainting()? + //fill background color only when the displayed frame rect not equas to renderer's + if (d.out_rect != rect()) { + //fill background color + } + + //assume that the image data is already scaled to out_size(NOT renderer size!) + if (!d.scale_in_renderer || (d.src_width == d.out_rect.width() && d.src_height == d.out_rect.height())) { + //you may copy data to video buffer directly + } else { + //paint with scale + } + //end paint. how about QPainter::endNativePainting()? if (!d.scale_in_renderer) { d.img_mutex.unlock();