mirror of
https://github.com/wang-bin/QtAV.git
synced 2026-10-28 11:07:07 +08:00
filterContextType, filter opacity. FilterContext in AVThread can be null
TODO: do not check FilterContext in public api
This commit is contained in:
+16
-6
@@ -40,12 +40,6 @@ void Filter::process(FilterContext *context, Statistics *statistics)
|
||||
Q_UNUSED(statistics);
|
||||
}
|
||||
|
||||
void Filter::process(QByteArray &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
}
|
||||
|
||||
|
||||
void Filter::setEnabled(bool enabled)
|
||||
{
|
||||
DPTR_D(Filter);
|
||||
@@ -58,4 +52,20 @@ 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;
|
||||
}
|
||||
|
||||
} //namespace QtAV
|
||||
|
||||
@@ -46,6 +46,12 @@ VideoFilterContext::VideoFilterContext():
|
||||
{
|
||||
}
|
||||
|
||||
QPainterFilterContext::QPainterFilterContext():
|
||||
painter(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FilterContext::Type QPainterFilterContext::type() const
|
||||
{
|
||||
return FilterContext::QtPainter;
|
||||
|
||||
+27
-3
@@ -43,13 +43,31 @@ OSDFilterImpl<QPainterFilterContext>::OSDFilterImpl():
|
||||
}
|
||||
|
||||
template<>
|
||||
void OSFilterQPainter::process(FilterContext *context, Statistics *statistics)
|
||||
void OSDFilterQPainter::process(FilterContext *context, Statistics *statistics)
|
||||
{
|
||||
if (mShowType == ShowNone)
|
||||
return;
|
||||
if (!context || context->type() != contextType()) {
|
||||
if (context && context->type() != contextType()) {
|
||||
qDebug("incompatible context type");
|
||||
delete context;
|
||||
context = 0;
|
||||
} else {
|
||||
qDebug("null context");
|
||||
}
|
||||
context = FilterContext::create(FilterContext::QtPainter);
|
||||
QPainterFilterContext* ctx = static_cast<QPainterFilterContext*>(context);
|
||||
ctx->painter = new QPainter();
|
||||
}
|
||||
QPainterFilterContext* ctx = static_cast<QPainterFilterContext*>(context);
|
||||
if (!ctx->painter)
|
||||
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);
|
||||
@@ -57,5 +75,11 @@ void OSFilterQPainter::process(FilterContext *context, Statistics *statistics)
|
||||
p->drawText(ctx->rect.topLeft(), text(statistics));
|
||||
p->restore(); //TODO: move outside?
|
||||
}
|
||||
|
||||
/*
|
||||
template<>
|
||||
FilterContext::Type OSDFilterQPainter::contextType() const
|
||||
{
|
||||
return FilterContext::QtPainter;
|
||||
}
|
||||
*/
|
||||
} //namespace QtAV
|
||||
|
||||
@@ -31,7 +31,7 @@ QPainterRenderer::QPainterRenderer()
|
||||
{
|
||||
DPTR_D(QPainterRenderer);
|
||||
d.filter_context = FilterContext::create(FilterContext::QtPainter);
|
||||
d.osd_filter = new OSFilterQPainter();
|
||||
d.osd_filter = new OSDFilterQPainter();
|
||||
d.filters.append(d.osd_filter);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ QPainterRenderer::QPainterRenderer(QPainterRendererPrivate &d)
|
||||
:VideoRenderer(d)
|
||||
{
|
||||
d.filter_context = FilterContext::create(FilterContext::QtPainter);
|
||||
d.osd_filter = new OSFilterQPainter();
|
||||
d.osd_filter = new OSDFilterQPainter();
|
||||
d.filters.append(d.osd_filter);
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -42,18 +42,23 @@ class Q_EXPORT Filter
|
||||
public:
|
||||
virtual ~Filter() = 0;
|
||||
//isEnabled() then setContext
|
||||
virtual void process(FilterContext* context, Statistics* statistics);
|
||||
/*!
|
||||
* if context is null, or contextType() != context->type(), then create a right one and assign it to context.
|
||||
*/
|
||||
virtual void process(FilterContext *context, Statistics* statistics);
|
||||
//TODO: parameter FrameContext
|
||||
void setEnabled(bool enabled); //AVComponent.enabled
|
||||
bool isEnabled() const;
|
||||
|
||||
FilterContext::Type contextType() const;
|
||||
qreal opacity() const;
|
||||
void setOpacity(qreal o);
|
||||
|
||||
virtual FilterContext::Type contextType() const;
|
||||
|
||||
protected:
|
||||
/*
|
||||
* If the filter is in AVThread, it's safe to operate on ref.
|
||||
*/
|
||||
virtual void process(QByteArray& data);
|
||||
Filter(FilterPrivate& d);
|
||||
|
||||
friend class AVThread;
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
static FilterContext* create(Type t);
|
||||
virtual ~FilterContext();
|
||||
virtual Type type() const = 0;
|
||||
QByteArray data;
|
||||
QByteArray data; //TODO: initialize() on data
|
||||
//QPainter, paintdevice, surface etc. contains all of them here?
|
||||
};
|
||||
|
||||
@@ -59,14 +59,23 @@ public:
|
||||
QRect rect;
|
||||
};
|
||||
|
||||
//TODO: font, pen, brush etc?
|
||||
class Q_EXPORT QPainterFilterContext : public VideoFilterContext
|
||||
{
|
||||
public:
|
||||
QPainterFilterContext();
|
||||
QPainter *painter;
|
||||
virtual Type type() const; //QtPainter
|
||||
};
|
||||
|
||||
|
||||
template<class T> struct TypeTrait {};
|
||||
template<> struct TypeTrait<QPainterFilterContext> {
|
||||
enum {
|
||||
type = FilterContext::QtPainter
|
||||
};
|
||||
};
|
||||
|
||||
} //namespace QtAV
|
||||
|
||||
#endif // QTAV_FILTERCONTEXT_H
|
||||
|
||||
@@ -42,10 +42,13 @@ class OSDFilterImpl : public OSDFilter
|
||||
public:
|
||||
OSDFilterImpl();
|
||||
~OSDFilterImpl() {}
|
||||
virtual void process(FilterContext* context, Statistics* statistics);
|
||||
virtual void process(FilterContext *context, Statistics* statistics);
|
||||
FilterContext::Type contextType() const {
|
||||
return (FilterContext::Type)TypeTrait<Context>::type;
|
||||
}
|
||||
};
|
||||
|
||||
typedef OSDFilterImpl<QPainterFilterContext> OSFilterQPainter;
|
||||
typedef OSDFilterImpl<QPainterFilterContext> OSDFilterQPainter;
|
||||
|
||||
} //namespace QtAV
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <QtCore/QMutex>
|
||||
#include <QtCore/QMutexLocker>
|
||||
#include <QtCore/QWaitCondition>
|
||||
|
||||
#include <QtAV/Packet.h>
|
||||
#include <QtAV/QtAV_Global.h>
|
||||
|
||||
@@ -67,7 +68,7 @@ public:
|
||||
QMutex mutex;
|
||||
QWaitCondition cond; //pause
|
||||
qreal delay;
|
||||
FilterContext *filter_context;
|
||||
FilterContext *filter_context;//TODO: use own smart ptr. QSharedPointer "=" is ugly
|
||||
QList<Filter*> filters;
|
||||
Statistics *statistics; //not obj. Statistics is unique for the player, which is in AVPlayer
|
||||
};
|
||||
|
||||
@@ -34,11 +34,13 @@ public:
|
||||
FilterPrivate():
|
||||
enabled(true)
|
||||
, context(0)
|
||||
, opacity(1)
|
||||
{}
|
||||
virtual ~FilterPrivate() {}
|
||||
|
||||
bool enabled;
|
||||
FilterContext *context; //used only when is necessary
|
||||
qreal opacity;
|
||||
};
|
||||
|
||||
} //namespace QtAV
|
||||
|
||||
+1
-3
@@ -91,8 +91,6 @@ void VideoThread::run()
|
||||
Q_ASSERT(d.clock != 0);
|
||||
VideoDecoder *dec = static_cast<VideoDecoder*>(d.dec);
|
||||
VideoRenderer* vo = static_cast<VideoRenderer*>(d.writer);
|
||||
//TODO: do not init filter_context
|
||||
d.filter_context = FilterContext::create(FilterContext::QtPainter); //vo->filterContextType()
|
||||
while (!d.stop) {
|
||||
//TODO: why put it at the end of loop then playNextFrame() not work?
|
||||
if (tryPause()) { //DO NOT continue, or playNextFrame() will fail
|
||||
@@ -162,7 +160,7 @@ void VideoThread::run()
|
||||
if (!d.conv->convert(d.decoded_data.constData(), d.image.bits())) {
|
||||
}*/
|
||||
QByteArray data = dec->data();
|
||||
if (d.statistics && d.filter_context) {
|
||||
if (d.statistics) {
|
||||
d.statistics->video.current_time = QTime().addMSecs(int(pkt.pts * 1000.0)); //TODO: is it expensive?
|
||||
foreach (Filter *filter, d.filters) {
|
||||
filter->process(d.filter_context, d.statistics);
|
||||
|
||||
Reference in New Issue
Block a user