Skip to content

Commit

Permalink
vo: simplify background update
Browse files Browse the repository at this point in the history
Deprecate needDrawFrame() and needUpdateBackground(). Introduce
backgroundRegion() thus only draw each rect in the region is enough.
  • Loading branch information
wang-bin committed Jan 11, 2016
1 parent a3fde67 commit a611beb
Show file tree
Hide file tree
Showing 18 changed files with 81 additions and 182 deletions.
13 changes: 0 additions & 13 deletions qml/QQuickItemRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,17 +201,6 @@ void QQuickItemRenderer::setOpenGL(bool o)
emit openGLChanged();
}

bool QQuickItemRenderer::needUpdateBackground() const
{
DPTR_D(const QQuickItemRenderer);
return d.out_rect != boundingRect().toRect();
}

bool QQuickItemRenderer::needDrawFrame() const
{
return true; //always call updatePaintNode, node must be set
}

void QQuickItemRenderer::drawFrame()
{
DPTR_D(QQuickItemRenderer);
Expand All @@ -223,7 +212,6 @@ void QQuickItemRenderer::drawFrame()
if (d.frame_changed)
sgvn->setCurrentFrame(d.video_frame);
d.frame_changed = false;
d.video_frame = VideoFrame();
sgvn->setTexturedRectGeometry(d.out_rect, normalizedROI(), d.orientation);
return;
}
Expand All @@ -249,7 +237,6 @@ void QQuickItemRenderer::drawFrame()
static_cast<QSGSimpleTextureNode*>(d.node)->setTexture(d.texture);
d.node->markDirty(QSGNode::DirtyGeometry);
d.frame_changed = false;
d.video_frame = VideoFrame();
}

QSGNode *QQuickItemRenderer::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *data)
Expand Down
3 changes: 0 additions & 3 deletions qml/QmlAV/QQuickItemRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ class QQuickItemRenderer : public QQuickItem, public VideoRenderer
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;

bool receiveFrame(const VideoFrame &frame) Q_DECL_OVERRIDE;
bool needUpdateBackground() const Q_DECL_OVERRIDE;
bool needDrawFrame() const Q_DECL_OVERRIDE;
void drawFrame() Q_DECL_OVERRIDE;

// QQuickItem interface
QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *data) Q_DECL_OVERRIDE;
private slots:
Expand Down
2 changes: 0 additions & 2 deletions qml/QmlAV/QuickFBORenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,7 @@ class QuickFBORenderer : public QQuickFramebufferObject, public VideoRenderer
protected:
bool event(QEvent *e) Q_DECL_OVERRIDE;
bool receiveFrame(const VideoFrame &frame) Q_DECL_OVERRIDE;
bool needUpdateBackground() const Q_DECL_OVERRIDE;
void drawBackground() Q_DECL_OVERRIDE;
bool needDrawFrame() const Q_DECL_OVERRIDE;
void drawFrame() Q_DECL_OVERRIDE;
private:
bool onSetOrientation(int value) Q_DECL_OVERRIDE;
Expand Down
11 changes: 0 additions & 11 deletions qml/QuickFBORenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,22 +211,11 @@ void QuickFBORenderer::renderToFbo()
handlePaintEvent();
}

bool QuickFBORenderer::needUpdateBackground() const
{
DPTR_D(const QuickFBORenderer);
return d.out_rect != boundingRect().toRect();
}

void QuickFBORenderer::drawBackground()
{
d_func().glv.fill(QColor(Qt::black));
}

bool QuickFBORenderer::needDrawFrame() const
{
return true; //always call updatePaintNode, node must be set
}

void QuickFBORenderer::drawFrame()
{
DPTR_D(QuickFBORenderer);
Expand Down
3 changes: 1 addition & 2 deletions src/QtAV/OpenGLRendererBase.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
Copyright (C) 2014-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -49,7 +49,6 @@ class Q_AV_EXPORT OpenGLRendererBase : public VideoRenderer
virtual bool isSupported(VideoFormat::PixelFormat pixfmt) const;
protected:
virtual bool receiveFrame(const VideoFrame& frame);
virtual bool needUpdateBackground() const;
//called in paintEvent before drawFrame() when required
virtual void drawBackground();
//draw the current frame using the current paint engine. called by paintEvent()
Expand Down
8 changes: 4 additions & 4 deletions src/QtAV/QPainterRenderer.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2013 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -33,12 +33,12 @@ class Q_AV_EXPORT QPainterRenderer : public VideoRenderer
DPTR_DECLARE_PRIVATE(QPainterRenderer)
public:
QPainterRenderer();
virtual bool isSupported(VideoFormat::PixelFormat pixfmt) const;
//virtual QImage currentFrameImage() const;
bool isSupported(VideoFormat::PixelFormat pixfmt) const Q_DECL_OVERRIDE;
protected:
bool prepareFrame(const VideoFrame& frame);
void drawBackground() Q_DECL_OVERRIDE;
//draw the current frame using the current paint engine. called by paintEvent()
virtual void drawFrame();
void drawFrame() Q_DECL_OVERRIDE;

QPainterRenderer(QPainterRendererPrivate& d);
};
Expand Down
6 changes: 4 additions & 2 deletions src/QtAV/VideoRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,12 @@ class Q_AV_EXPORT VideoRenderer : public AVOutput

protected:
VideoRenderer(VideoRendererPrivate &d);
QRegion backgroundRegion() const;
//TODO: batch drawBackground(color, region)=>loop drawBackground(color,rect)
virtual bool receiveFrame(const VideoFrame& frame) = 0;
virtual bool needUpdateBackground() const;
QTAV_DEPRECATED virtual bool needUpdateBackground() const;
virtual void drawBackground();
virtual bool needDrawFrame() const; //TODO: no virtual func. it's a solution for temporary
QTAV_DEPRECATED virtual bool needDrawFrame() const; //TODO: no virtual func. it's a solution for temporary
//draw the current frame using the current paint engine. called by paintEvent()
// TODO: parameter VideoFrame
virtual void drawFrame() = 0; //You MUST reimplement this to display a frame. Other draw functions are not essential
Expand Down
19 changes: 2 additions & 17 deletions src/output/video/Direct2DRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -73,17 +73,13 @@ class Direct2DRenderer : public QWidget, public VideoRenderer
virtual QWidget* widget() { return this; }
protected:
virtual bool receiveFrame(const VideoFrame& frame);
virtual bool needUpdateBackground() const;
//called in paintEvent before drawFrame() when required
virtual void drawBackground();
virtual bool needDrawFrame() const;
//draw the current frame using the current paint engine. called by paintEvent()
virtual void drawFrame();
/*usually you don't need to reimplement paintEvent, just drawXXX() is ok. unless you want do all
*things yourself totally*/
virtual void paintEvent(QPaintEvent *);
virtual void resizeEvent(QResizeEvent *);
//stay on top will change parent, hide then show(windows). we need GetDC() again
//stay on top will change parent, hide then show(windows)
virtual void showEvent(QShowEvent *);
};
typedef Direct2DRenderer VideoRendererDirect2D;
Expand Down Expand Up @@ -335,12 +331,6 @@ QPaintEngine* Direct2DRenderer::paintEngine() const
return 0; //use native engine
}

bool Direct2DRenderer::needUpdateBackground() const
{
DPTR_D(const Direct2DRenderer);
return (d.update_background && d.out_rect != rect()) || !d.video_frame.isValid();
}

void Direct2DRenderer::drawBackground()
{
DPTR_D(Direct2DRenderer);
Expand All @@ -352,11 +342,6 @@ void Direct2DRenderer::drawBackground()
//d.render_target->FillRectangle(D2D1::RectF(0, 0, width(), height()), brush);
}

bool Direct2DRenderer::needDrawFrame() const
{
return true;
}

void Direct2DRenderer::drawFrame()
{
DPTR_D(Direct2DRenderer);
Expand Down
18 changes: 7 additions & 11 deletions src/output/video/GDIRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -57,10 +57,7 @@ class GDIRenderer : public QWidget, public VideoRenderer
virtual QWidget* widget() { return this; }
protected:
virtual bool receiveFrame(const VideoFrame& frame);
virtual bool needUpdateBackground() const;
//called in paintEvent before drawFrame() when required
virtual void drawBackground();
//draw the current frame using the current paint engine. called by paintEvent()
virtual void drawFrame();
/*usually you don't need to reimplement paintEvent, just drawXXX() is ok. unless you want do all
*things yourself totally*/
Expand Down Expand Up @@ -231,19 +228,18 @@ bool GDIRenderer::receiveFrame(const VideoFrame& frame)
return true;
}

bool GDIRenderer::needUpdateBackground() const
{
DPTR_D(const GDIRenderer);
return (d.update_background && d.out_rect != rect()) || !d.video_frame.isValid();
}

void GDIRenderer::drawBackground()
{
DPTR_D(GDIRenderer);
//HDC hdc = d.device_context;
Graphics g(d.device_context);
SolidBrush brush(Color(255, 0, 0, 0)); //argb
g.FillRectangle(&brush, 0, 0, width(), height());
const QVector<QRect> bg(backgroundRegion().rects());
if (!bg.isEmpty()) {
foreach (const QRect& r, bg) {
g.FillRectangle(&brush, r.x(), r.y(), r.width(), r.height());
}
}
}

void GDIRenderer::drawFrame()
Expand Down
18 changes: 9 additions & 9 deletions src/output/video/GraphicsItemRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -169,18 +169,18 @@ void GraphicsItemRenderer::paint(QPainter *painter, const QStyleOptionGraphicsIt
ctx->painter = 0;
}

bool GraphicsItemRenderer::needUpdateBackground() const
{
DPTR_D(const GraphicsItemRenderer);
return d.out_rect != boundingRect() || !d.video_frame.isValid();
}

void GraphicsItemRenderer::drawBackground()
{
DPTR_D(GraphicsItemRenderer);
if (!d.painter)
#if QTAV_HAVE(OPENGL)
if (d.checkGL()) {
// d.glv.fill(QColor(0, 0, 0)); //FIXME: fill boundingRect
return;
d.painter->fillRect(boundingRect(), QColor(0, 0, 0));
} else
#endif
{
QPainterRenderer::drawBackground();
}
}

void GraphicsItemRenderer::drawFrame()
Expand Down
7 changes: 1 addition & 6 deletions src/output/video/OpenGLRendererBase.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2014-2015 Wang Bin <[email protected]>
Copyright (C) 2014-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -79,11 +79,6 @@ bool OpenGLRendererBase::receiveFrame(const VideoFrame& frame)
return true;
}

bool OpenGLRendererBase::needUpdateBackground() const
{
return true;
}

void OpenGLRendererBase::drawBackground()
{
d_func().glv.fill(QColor(Qt::black));
Expand Down
28 changes: 23 additions & 5 deletions src/output/video/QPainterRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2012-2015 Wang Bin <[email protected]>
Copyright (C) 2012-2016 Wang Bin <[email protected]>
* This file is part of QtAV
Expand Down Expand Up @@ -75,15 +75,33 @@ bool QPainterRenderer::prepareFrame(const VideoFrame &frame)
return true;
}

void QPainterRenderer::drawFrame()
void QPainterRenderer::drawBackground()
{
DPTR_D(QPainterRenderer);
if (!d.painter)
return;
if (d.image.isNull()) {
d.image = QImage(rendererSize(), QImage::Format_RGB32);
d.image.fill(Qt::black); //maemo 4.7.0: QImage.fill(uint)
#if 0
d.painter->save();
d.painter->setClipRegion(backgroundRegion());
d.painter->fillRect(QRect(QPoint(), rendererSize()), QColor(0, 0, 0));
d.painter->restore();
#else
const QVector<QRect> bg(backgroundRegion().rects());
if (!bg.isEmpty()) {
foreach (const QRect& r, bg) {
d.painter->fillRect(r, QColor(0, 0, 0));
}
}
#endif
}

void QPainterRenderer::drawFrame()
{
DPTR_D(QPainterRenderer);
if (!d.painter)
return;
if (d.image.isNull())
return;
QRect roi = realROI();
if (orientation() == 0) {
//assume that the image data is already scaled to out_size(NOT renderer size!)
Expand Down
27 changes: 12 additions & 15 deletions src/output/video/VideoRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,9 +445,17 @@ QPointF VideoRenderer::onMapFromFrame(const QPointF &p) const
return QPointF(rendererWidth()/2, rendererHeight()/2) + delta / zoom;
}

QRegion VideoRenderer::backgroundRegion() const
{
return QRegion(0, 0, rendererWidth(), rendererHeight()) - QRegion(d_func().out_rect);
}

bool VideoRenderer::needUpdateBackground() const
{
return d_func().update_background;
DPTR_D(const VideoRenderer);
const QRect rendererRect(QPoint(), rendererSize());
return d.update_background || !d.video_frame.isValid()
|| d.out_rect.intersected(rendererRect) != rendererRect;
}

void VideoRenderer::drawBackground()
Expand Down Expand Up @@ -493,22 +501,11 @@ void VideoRenderer::handlePaintEvent()
* protected by mutex. otherwise, e.g. QPainterRenderer, it's not required if drawing
* on the shared data is safe
*/
if (needUpdateBackground()) {
/* xv: should always draw the background. so shall we only paint the border
* rectangles, but not the whole widget
*/
d.update_background = false;
//fill background color. DO NOT return, you must continue drawing
drawBackground();
}
/* DO NOT return if no data. we should draw other things
* NOTE: if data is not copyed in receiveFrame(), you should always call drawFrame()
*/
drawBackground();
/*
* why the background is white if return? the below code draw an empty bitmap?
* NOTE: if data is not copyed in receiveFrame(), you should always call drawFrame()
*/
//DO NOT return if no data. we should draw other things
if (needDrawFrame()) {
if (d.video_frame.isValid()) {
drawFrame();
if (d.statistics) {
d.statistics->video_only.frameDisplayed(d.video_frame.timestamp());
Expand Down
Loading

0 comments on commit a611beb

Please sign in to comment.