From af0ccdfa67372ccd7ab63f43ab2fb03b04fc8aa7 Mon Sep 17 00:00:00 2001 From: wang-bin Date: Mon, 23 Sep 2013 22:34:51 +0800 Subject: [PATCH] use filter context drawing api TODO: implement QPaintEngine for different backend then remove context? --- src/Filter.cpp | 11 ----- src/FilterContext.cpp | 83 +++++++++++++++++++++++++++++++++++++ src/OSD.cpp | 12 ------ src/OSDFilter.cpp | 41 ++++-------------- src/QtAV/Filter.h | 5 +-- src/QtAV/FilterContext.h | 39 +++++++++++------ src/QtAV/OSD.h | 3 -- src/QtAV/OSDFilter.h | 23 ++++++---- src/QtAV/private/Filter_p.h | 2 - 9 files changed, 133 insertions(+), 86 deletions(-) diff --git a/src/Filter.cpp b/src/Filter.cpp index b26dfa6d..84f3ef7c 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -76,17 +76,6 @@ bool Filter::isEnabled() const return d.enabled; } -void Filter::setOpacity(qreal o) -{ - DPTR_D(Filter); - d.opacity = o; -} - -qreal Filter::opacity() const -{ - return d_func().opacity; -} - FilterContext::Type Filter::contextType() const { return FilterContext::None; diff --git a/src/FilterContext.cpp b/src/FilterContext.cpp index ae5cedfe..47ff2c9d 100644 --- a/src/FilterContext.cpp +++ b/src/FilterContext.cpp @@ -61,7 +61,11 @@ VideoFilterContext::VideoFilterContext() , painter(0) , paint_device(0) , own_paint_device(false) + , opacity(1) { + font.setBold(true); + font.setPixelSize(26); + pen.setColor(Qt::white); } VideoFilterContext::~VideoFilterContext() @@ -81,11 +85,78 @@ VideoFilterContext::~VideoFilterContext() } } +void VideoFilterContext::drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags) +{ + Q_UNUSED(target); + Q_UNUSED(image); + Q_UNUSED(source); + Q_UNUSED(flags); +} + +void VideoFilterContext::drawPlainText(const QRectF &rect, const QString &text) +{ + Q_UNUSED(rect); + Q_UNUSED(text); +} + +void VideoFilterContext::drawRichText(const QRectF &rect, const QString &text) +{ + Q_UNUSED(rect); + Q_UNUSED(text); +} + + + FilterContext::Type QPainterFilterContext::type() const { return FilterContext::QtPainter; } +void QPainterFilterContext::drawImage(const QRectF &target, const QImage &image, const QRectF &source, Qt::ImageConversionFlags flags) +{ + if (!prepare()) + return; + painter->drawImage(target, image, source, flags); + painter->restore(); +} + +void QPainterFilterContext::drawPlainText(const QRectF &rect, int flags, const QString &text) +{ + if (!prepare()) + return; + if (rect.isNull()) + painter->drawText(rect.topLeft(), text); + else + painter->drawText(rect, flags, text); + painter->restore(); +} + +void QPainterFilterContext::drawRichText(const QRectF &rect, int flags, const QString &text) +{ + if (!prepare()) + return; + //QTextDocument + painter->restore(); +} + +bool QPainterFilterContext::isReady() const +{ + return !!painter && painter->isActive(); +} + +bool QPainterFilterContext::prepare() +{ + if (!isReady()) + return false; + painter->save(); //is it necessary? + painter->setBrush(brush); + painter->setPen(pen); + painter->setFont(font); + painter->setOpacity(opacity); + painter->setTransform(transform); + return true; +} + void QPainterFilterContext::initializeOnData(QByteArray *data) { if (!data) { @@ -120,4 +191,16 @@ FilterContext::Type GLFilterContext::type() const return FilterContext::OpenGL; } +bool GLFilterContext::isReady() const +{ + return false; +} + +bool GLFilterContext::prepare() +{ + if (!isReady()) + return false; + return true; +} + } //namespace QtAV diff --git a/src/OSD.cpp b/src/OSD.cpp index 19e27e24..11ccbc4f 100644 --- a/src/OSD.cpp +++ b/src/OSD.cpp @@ -28,8 +28,6 @@ OSD::OSD(): mShowType(ShowCurrentAndTotalTime) , mSecsTotal(-1) { - mFont.setBold(true); - mFont.setPixelSize(26); } OSD::~OSD() @@ -64,16 +62,6 @@ bool OSD::hasShowType(ShowType t) const return (t&mShowType) == t; } -void OSD::setFont(const QFont &font) -{ - mFont = font; -} - -QFont OSD::font() const -{ - return mFont; -} - QString OSD::text(Statistics *statistics) { QString text; diff --git a/src/OSDFilter.cpp b/src/OSDFilter.cpp index 2a4977b4..df4a166b 100644 --- a/src/OSDFilter.cpp +++ b/src/OSDFilter.cpp @@ -38,19 +38,11 @@ OSDFilter::OSDFilter(OSDFilterPrivate &d): { } -template<> -OSDFilterImpl::OSDFilterImpl(): +OSDFilterQPainter::OSDFilterQPainter(): OSDFilter(*new OSDFilterPrivate()) { } -template<> -OSDFilterImpl::OSDFilterImpl(): - OSDFilter(*new OSDFilterPrivate()) -{ -} - -template<> void OSDFilterQPainter::process() { if (mShowType == ShowNone) @@ -58,31 +50,14 @@ void OSDFilterQPainter::process() DPTR_D(Filter); QPainterFilterContext* ctx = static_cast(d.context); //qDebug("ctx=%p tid=%p main tid=%p", ctx, QThread::currentThread(), qApp->thread()); - if (!ctx->painter) { - qWarning("null QPainter in OSDFilterQPainter!"); - return; - } - if (!ctx->painter->isActive()) { - qWarning("QPainter in OSDFilterQPainter is not active"); - return; - } - QPainter *p = ctx->painter; - p->save(); //TODO: move outside? - p->setFont(mFont); - p->setPen(Qt::white); - p->setOpacity(d.opacity); - p->drawText(ctx->rect.topLeft(), text(d.statistics)); - p->restore(); //TODO: move outside? + ctx->drawPlainText(ctx->rect, Qt::AlignCenter, text(d.statistics)); +} + +OSDFilterGL::OSDFilterGL(): + OSDFilter(*new OSDFilterPrivate()) +{ } -/* -template<> -FilterContext::Type OSDFilterQPainter::contextType() const -{ - return FilterContext::QtPainter; -} -*/ -template<> void OSDFilterGL::process() { if (mShowType == ShowNone) @@ -94,7 +69,7 @@ void OSDFilterGL::process() QGLWidget *glw = static_cast(ctx->paint_device); if (!glw) return; - glw->renderText(ctx->rect.x(), ctx->rect.y(), text(d.statistics), font()); + glw->renderText(ctx->rect.x(), ctx->rect.y(), text(d.statistics), ctx->font); #endif //QTAV_HAVE(GL) } } //namespace QtAV diff --git a/src/QtAV/Filter.h b/src/QtAV/Filter.h index ee33c925..981e8900 100644 --- a/src/QtAV/Filter.h +++ b/src/QtAV/Filter.h @@ -46,10 +46,7 @@ public: void setEnabled(bool enabled); //AVComponent.enabled bool isEnabled() const; - qreal opacity() const; - void setOpacity(qreal o); - - virtual FilterContext::Type contextType() const; + virtual FilterContext::Type contextType() const = 0; /*! * check context and apply the filter diff --git a/src/QtAV/FilterContext.h b/src/QtAV/FilterContext.h index 70ceb62e..5279d268 100644 --- a/src/QtAV/FilterContext.h +++ b/src/QtAV/FilterContext.h @@ -25,6 +25,7 @@ #include #include #include +#include /* * QPainterFilterContext, D2DFilterContext, ... */ @@ -59,21 +60,37 @@ protected: friend class Filter; }; + +//TODO: DrawTarget? New backend for QPaintEngine? class Q_EXPORT VideoFilterContext : public FilterContext { public: VideoFilterContext(); virtual ~VideoFilterContext(); - QRect rect; + // map to Qt types + //drawSurface? + virtual void drawImage(const QRectF& target, const QImage& image, const QRectF& source, Qt::ImageConversionFlags flags = Qt::AutoColor); + virtual void drawPlainText(const QRectF& rect, const QString& text); + virtual void drawRichText(const QRectF& rect, const QString& text); + + QRect rect; // Fallback to QPainter if no other paint engine implemented QPainter *painter; + qreal opacity; + QTransform transform; + QFont font; + QPen pen; + QBrush brush; /* * for the filters apply on decoded data, paint_device must be initialized once the data changes * can we allocate memory on stack? */ QPaintDevice *paint_device; bool own_paint_device; +protected: + virtual bool isReady() const = 0; + virtual bool prepare() = 0; }; //TODO: font, pen, brush etc? @@ -81,7 +98,13 @@ class Q_EXPORT QPainterFilterContext : public VideoFilterContext { public: virtual Type type() const; //QtPainter + virtual void drawImage(const QRectF& target, const QImage& image, const QRectF& source, Qt::ImageConversionFlags flags = Qt::AutoColor); + virtual void drawPlainText(const QRectF& rect, int flags, const QString& text); + virtual void drawRichText(const QRectF& rect, int flags, const QString& text); + protected: + virtual bool isReady() const; + virtual bool prepare(); virtual void initializeOnData(QByteArray* data); }; @@ -89,19 +112,11 @@ class Q_EXPORT GLFilterContext : public VideoFilterContext { public: virtual Type type() const; //OpenGL +protected: + virtual bool isReady() const; + virtual bool prepare(); }; -template struct TypeTrait {}; -template<> struct TypeTrait { - enum { - type = FilterContext::QtPainter - }; -}; -template<> struct TypeTrait { - enum { - type = FilterContext::OpenGL - }; -}; } //namespace QtAV diff --git a/src/QtAV/OSD.h b/src/QtAV/OSD.h index 4826ccf2..c85f892c 100644 --- a/src/QtAV/OSD.h +++ b/src/QtAV/OSD.h @@ -46,13 +46,10 @@ public: ShowType showType() const; void useNextShowType(); bool hasShowType(ShowType t) const; - void setFont(const QFont& font); - QFont font() const; QString text(Statistics* statistics); protected: ShowType mShowType; int mSecsTotal; - QFont mFont; }; }//namespace QtAV diff --git a/src/QtAV/OSDFilter.h b/src/QtAV/OSDFilter.h index f226c86f..1417f975 100644 --- a/src/QtAV/OSDFilter.h +++ b/src/QtAV/OSDFilter.h @@ -36,22 +36,27 @@ protected: OSDFilter(OSDFilterPrivate& d); }; -template -class OSDFilterImpl : public OSDFilter +class OSDFilterQPainter : public OSDFilter { - //DPTR_DECLARE_PRIVATE(OSDFilterImpl) public: - OSDFilterImpl(); - ~OSDFilterImpl() {} + OSDFilterQPainter(); FilterContext::Type contextType() const { - return (FilterContext::Type)TypeTrait::type; + return FilterContext::QtPainter; } protected: - virtual void process(); + void process(); }; -typedef OSDFilterImpl OSDFilterQPainter; -typedef OSDFilterImpl OSDFilterGL; +class OSDFilterGL : public OSDFilter +{ +public: + OSDFilterGL(); + FilterContext::Type contextType() const { + return FilterContext::OpenGL; + } +protected: + void process(); +}; } //namespace QtAV diff --git a/src/QtAV/private/Filter_p.h b/src/QtAV/private/Filter_p.h index f8b0ef40..755c5b6c 100644 --- a/src/QtAV/private/Filter_p.h +++ b/src/QtAV/private/Filter_p.h @@ -36,14 +36,12 @@ public: enabled(true) , context(0) , statistics(0) - , opacity(1) {} virtual ~FilterPrivate() {} bool enabled; FilterContext *context; //used only when is necessary Statistics *statistics; - qreal opacity; }; } //namespace QtAV