예제 #1
0
void ItemListItem::setHighlight(const QColor &color) {
	if (_Change(d->highlight, color)) {
		if (d->pressed.attached && d->pressed.attached->canInteract())
			d->pressed.attached->setColor(d->highlight);
		emit highlightChanged();
	}
}
예제 #2
0
void VideoRendererItem::reset() {
	if (_Change(d->dropped, 0))
		emit droppedFramesChanged(d->dropped);
	d->drawnFrames = 0;
	d->lastCheckedFrames = 0;
	d->lastCheckedTime = 0;
}
예제 #3
0
void VideoRendererItem::setChromaUpscaler(InterpolatorType type) {
	if (_Change(d->chromaUpscaler, type)) {
		if (d->shader)
			d->shader->setChromaInterpolator(d->chromaUpscaler);
		rerender();
	}
}
예제 #4
0
void SoftwareDeinterlacer::setOption(const DeintOption &deint) {
	if (!_Change(d->deint, deint))
		return;
	d->option.clear();
	if (d->deint.method == DeintMethod::None) {
		d->type = Pass;
	} else if (deint.device == DeintDevice::OpenGL || d->deint.device == DeintDevice::GPU) {
		d->type = Mark;
	} else {
		d->type = PP;
		switch (d->deint.method) {
		case DeintMethod::LinearBob:
			d->option = "li";
			break;
		case DeintMethod::LinearBlend:
			d->option = "lb";
			break;
		case DeintMethod::CubicBob:
			d->option = "ci";
			break;
		case DeintMethod::Median:
			d->option = "md";
			break;
		case DeintMethod::Yadif:
			d->option = _L("yadif") + (d->deint.doubler ? "=mode=1" : "");
			d->type = Graph;
			break;
		default:
			d->type = Pass;
			break;
		}
	}
}
예제 #5
0
void AScrollBar::DoMouseMove(AEvent* pEvent)
{
	AMouseEvent* evt = dynamic_cast<AMouseEvent*>(pEvent);
	if( evt == NULL ) return;

	int iElem = ButtonElemOnPos(evt->m_X,evt->m_Y);
	if( evt->m_KeyStates.Has(ksLeftButton) ) iElem = m_MouseOnElem;
	if(iElem == SCROLLBAR_ELEM_NONE ) return;


	if( !(evt->m_KeyStates.Has(ksLeftButton) || evt->m_KeyStates.Has(ksRightButton) || evt->m_KeyStates.Has(ksMiddleButton)) )
		m_ElemStatus = SCROLLBAR_STATUS_OVER;
	if( evt->m_KeyStates.Has(ksLeftButton))
	{
		if( iElem == SCROLLBAR_ELEM_SLIDE )
		{
			int iSize= 0;
			if( m_Kind == sbVert ) iSize = evt->m_Y - m_ptMouse.y;
			else iSize = evt->m_X - m_ptMouse.x;

			if( GetRate() != 0.0 )
				iSize = (int)( (double)iSize / GetRate() );
			if( iSize != 0 )
			{
				m_iPosition = m_iDownPosition;
				_Change(iSize);
			}
		}
	}
	base_class::DoMouseMove(pEvent);
	Refresh();
}
예제 #6
0
void VideoRendererItem::prepare(QSGGeometryNode *node) {
	Q_ASSERT(d->shader);
	if (d->take) {
		auto image = renderTarget().toImage();
		if (!image.isNull())
			d->mposd->drawOn(image);
		emit frameImageObtained(image);
		d->take = false;
	}
	if (!d->queue.isEmpty()) {
		auto &frame = d->queue.front();
		if (!frame.format().isEmpty()) {
			d->ptsOut = frame.pts();
			d->render = true;
			d->frameSize = frame.format().size();
			if (_Change(d->displaySize, frame.format().displaySize()))
				d->updateGeometry(true);
			d->shader->upload(frame);
			d->direct = d->shader->directRendering();
			++d->drawnFrames;
		}
		d->queue.pop_front();
		if (!d->queue.isEmpty()) {
			if (d->queue.size() > 3) {
				emit droppedFramesChanged(d->dropped += d->queue.size());
				d->queue.clear();
			} else {
				if (d->queue.size() > 1) {
					d->queue.pop_front();
					emit droppedFramesChanged(++d->dropped);
				}
				update();
			}
		}
	}

	if (d->render && !d->frameSize.isEmpty()) {
		if (d->rerender)
			d->shader->reupload();
		if (d->direct) {
			setRenderTarget(d->shader->renderTarget());
		} else {
			if (!d->fbo || d->fbo->size() != d->frameSize) {
				_Renew(d->fbo, d->frameSize, OpenGLCompat::framebufferObjectTextureFormat());
				Q_ASSERT(d->fbo->isValid());
			}
			setRenderTarget(d->fbo->texture());
			d->fbo->bind();
			d->shader->render(d->kernel);
			d->fbo->release();
		}
		node->markDirty(QSGNode::DirtyMaterial);
	}
	d->rerender = d->render = false;
	LOG_GL_ERROR_Q
}
예제 #7
0
void VideoRendererItem::setEffects(Effects effects) {
	if ((effects^d->effects) & (FlipHorizontally | FlipVertically))
		setGeometryDirty();
	if (_Change(d->effects, effects)) {
		if (d->shader)
			d->shader->setEffects(d->effects);
		d->fillKernel();
		d->repaint();
	}
}
예제 #8
0
SimpleFboItem::SimpleFboItem(QQuickItem *parent)
: SimpleTextureItem(parent) {
    connect(&m_sizeChecker, &QTimer::timeout, [this] () {
        if (!_Change(m_prevSize, QSizeF(width(), height()).toSize())) {
            m_sizeChecker.stop();
            emit targetSizeChanged(m_targetSize = m_prevSize);
        }
    });
    m_sizeChecker.setInterval(300);
}
예제 #9
0
SimpleFboItem::SimpleFboItem(QQuickItem *parent)
: SimpleTextureItem(parent) {
    connect(&m_sizeChecker, &QTimer::timeout, [this] () {
        if (!_Change(m_prevSize, size().toSize())) {
            m_sizeChecker.stop();
            reserve(UpdateMaterial);
            m_targetSize = m_prevSize;
        }
    });
    m_sizeChecker.setInterval(300);
}
예제 #10
0
VideoRenderer::VideoRenderer(QQuickItem *parent)
    : Super(parent), d(new Data)
{
    d->p = this;
    d->letterbox = new LetterboxItem(this);
    const QQmlProperty property(d->letterbox, u"anchors.centerIn"_q);
    property.write(QVariant::fromValue(this));
    setZ(-1);
    setAcceptHoverEvents(true);
    setAcceptedMouseButtons(Qt::AllButtons);
    setFlag(ItemAcceptsDrops, true);
    connect(&d->sizeChecker, &QTimer::timeout, [this] () {
        if (_Change(d->frame.size, d->fboSizeHint()) |
                _Change(d->osd.size, d->osdSizeHint())) {
            d->redraw = true;
            reserve(UpdateAll);
        }
    });
    d->sizeChecker.setInterval(300);
    d->sizeChecker.setSingleShot(true);
}
예제 #11
0
	void layout() {
		rectCount = 0;
		minimum = 0;
		if (list.isEmpty())
			return;
		_Expand(rects, list.size()+4, 2.1);

		int fills = 0;
		qreal filled = 0;
		auto calculate = [&filled, &fills, this] (const ItemListAttached *attached) {
			filled += 2*O::padding(p, attached);
			if (attached->thickness() < 0) {
				if (length < 0)
					++fills;
				else
					filled += length;
			} else
				filled += attached->thickness();
		};
		runLayoutLoop(calculate);
		const auto fill = qMax((O::length(p) - filled)/fills, 0.0);
		auto it = rects.begin();
		qreal pos = 0;
		auto append = [&it, &pos, fill, this] (ItemListAttached *attached) {
			qreal total = 2*O::padding(p, attached);
			if (attached->thickness() < 0) {
				if (length < 0)
					total += fill;
				else
					total += length;
			} else
				total += attached->thickness();
			attached->fill(total);
			if (attached->isQmlItem()) {
				const auto vpad = pick(attached->verticalPadding(), this->vpad);
				const auto hpad = pick(attached->horizontalPadding(), this->hpad);
				const auto rect = O::itemRect(p, attached, pos, {hpad, vpad});
				auto qml = static_cast<QQuickItem*>(attached->attachee());
				qml->setPosition(rect.topLeft());
				qml->setSize(rect.size());
			}
			it->attached = attached;
			it->pos = pos;
			++it;
			pos += total;
		};
		runLayoutLoop(append);
		rectCount = std::distance(rects.begin(), it);
		if (_Change(minimum, filled))
			emit p->minimumLengthChanged();
		p->setGeometryDirty();
	}
예제 #12
0
bool VdaMixer::upload(const VideoFrame &frame, bool /*deint*/) {
	Q_ASSERT(frame.format().imgfmt() == IMGFMT_VDA);
	CGLError error = kCGLNoError;
	for (auto &texture : m_textures) {
		const auto cgl = CGLGetCurrentContext();
		const auto surface = CVPixelBufferGetIOSurface((CVPixelBufferRef)frame.data(3));
		texture.bind();
		const auto w = IOSurfaceGetWidthOfPlane(surface, texture.plane());
		const auto h = IOSurfaceGetHeightOfPlane(surface, texture.plane());
		if (_Change(error, CGLTexImageIOSurface2D(cgl, texture.target(), texture.format(), w, h, texture.transfer().format, texture.transfer().type, surface, texture.plane()))) {
			_Error("CGLError: %%(0x%%)", CGLErrorString(error), _N(error, 16));
			return false;
		}
	}
	return true;
}
예제 #13
0
	void updateGeometry(bool forceUpdateOsd) {
		QRectF letter;
		if (_Change(vtx, frameRect(p->geometry(), offset, &letter))) {
			if (vtx.size() != QSizeF(mposd->width(), mposd->height())) {
				if (forceUpdateOsd)
					mposd->forceUpdateTargetSize();
			}
			mposd->setGeometry(vtx);
			emit p->frameRectChanged(vtx);
		}
		if (letterbox->set(p->rect(), letter))
			emit p->screenRectChanged(letterbox->screen());
		if (overlay)
			overlay->setGeometry(overlayInLetterbox ? p->rect() : letterbox->screen());
		p->setGeometryDirty();
	}
예제 #14
0
void AScrollBar::DoMouseWheel(AEvent* pEvent)
{
	AMouseEvent* evt = dynamic_cast<AMouseEvent *>(pEvent);
	if( evt == NULL ) return;

	if( evt->m_Delta == 0 ) return;


	int delta = 7864320;//for 上下滚动
	if( evt->m_KeyStates.Has(ksShift) ) delta = 7864316;//for 左右滚动 fix me later 为什么会有差异?
	int iSize = -(evt->m_Delta / delta * m_iMiniStep);//7864320 ? fix me later
	if( GetRate() != 0.0 ) iSize = (int)( (double)iSize/GetRate() );

	_Change(iSize);

	Refresh();
}
예제 #15
0
VideoRenderer::VideoRenderer(QQuickItem *parent)
    : HighQualityTextureItem(parent)
    , d(new Data(this))
{
    d->letterbox = new LetterboxItem(this);
    const QQmlProperty property(d->letterbox, u"anchors.centerIn"_q);
    property.write(QVariant::fromValue(this));
    setZ(-1);
    setAcceptHoverEvents(true);
    setAcceptedMouseButtons(Qt::AllButtons);
    setFlag(ItemAcceptsDrops, true);
    connect(&d->sizeChecker, &QTimer::timeout, [=] () { d->updateOsdSize(); });
    d->sizeChecker.setInterval(300);

    d->measure.setTimer([=]() {
        if (_Change(d->fps, d->measure.get()))
            emit fpsChanged(d->fps);
    }, 100000);
}
예제 #16
0
void AScrollBar::DoMouseDown(AEvent* pEvent)
{
	AMouseEvent* evt = dynamic_cast<AMouseEvent*>(pEvent);
	if( evt == NULL ) return;

	m_MouseOnElem = ButtonElemOnPos(evt->m_X,evt->m_Y);

	m_ptMouse = APoint(evt->m_X,evt->m_Y);
	m_ElemStatus = SCROLLBAR_STATUS_DOWN;
	m_iDownPosition = (int)m_iPosition;

	if( OnMouseDown.IsValid() )
		OnMouseDown.Call(this,pEvent);
	else
	{
	
		int delta = 0;
		if( m_MouseOnElem == SCROLLBAR_ELEM_BUTTON1 ) delta = -m_iMiniStep;
		else  if( m_MouseOnElem == SCROLLBAR_ELEM_BUTTON2 ) delta = m_iMiniStep;
		else  if( m_MouseOnElem == SCROLLBAR_ELEM_RAIL_1 ) delta = -m_iBigStep;
		else  if( m_MouseOnElem == SCROLLBAR_ELEM_RAIL_2 ) delta = m_iBigStep;

		if( m_MouseOnElem == SCROLLBAR_ELEM_TOP1 )
		{
			delta = -GetPosition();
		}
		else if( m_MouseOnElem == SCROLLBAR_ELEM_TOP2 )
		{
			delta = GetRange() - GetPosition();
		}

		if( delta != 0 )
		{
			_Change(delta);
		}
		
		Refresh();
	}
}
예제 #17
0
void VideoRendererItem::customEvent(QEvent *event) {
	switch ((int)event->type()) {
	case NewFrame:
		if (d->queue.size() < 3)
			d->queue.push_back(_GetData<VideoFrame>(event));
		update();
		break;
	case NextFrame:
		update();
		break;
	case Rerender:
		d->repaint();
		break;
	case UpdateDeint: {
		if (_Change(d->deint, _GetData<DeintMethod>(event)) && d->shader) {
			d->shader->setDeintMethod(d->deint);
			d->repaint();
		}
		break;
	} default:
		break;
	}
}
예제 #18
0
	void setSelected(bool s) { if (_Change(m_selected, s)) emit selectedChanged(); }
예제 #19
0
	bool changeAndPolish(T &t, const T &new_) {
		if (!_Change(t, new_))
			return false;
		p->polishAndUpdate();
		return true;
	}
예제 #20
0
void ItemListItem::setVerticalPadding(qreal pad) {
	if (_Change(d->vpad, pad))
		emit verticalPaddingChanged();
}
예제 #21
0
void ItemListItem::setHorizontalPadding(qreal pad) {
	if (_Change(d->hpad, pad))
		emit horizontalPaddingChanged();
}
예제 #22
0
void VideoRendererItem::setRange(ColorRange range) {
	if (_Change(d->range, range) && d->shader) {
		d->shader->setRange(d->range);
		d->repaint();
	}
}
예제 #23
0
void TextureItem::setTextureRect(const QRectF &rect) {
	if (_Change(d->txtRect, rect)) {
		d->dirtyGeometry = true;
		update();
	}
}
예제 #24
0
void ItemListItem::setFixedItemLength(qreal width) {
	if (_Change(d->length, width)) {
		polishAndUpdate();
		emit fixedItemLengthChanged();
	}
}
예제 #25
0
void VideoRendererItem::setOverlayOnLetterbox(bool letterbox) {
	if (_Change(d->overlayInLetterbox, letterbox))
		d->updateGeometry(false);
}
예제 #26
0
PlayEngine::PlayEngine()
: d(new Data(this)) {
    Q_ASSERT(d->confDir.isValid());

    _Debug("Create audio/video plugins");
    d->audio = new AudioController(this);
    d->video = new VideoOutput(this);
    d->filter = new VideoFilter;

    d->chapterInfo = new ChapterInfoObject(this, this);
    d->updateMediaName();

    _Debug("Make registrations and connections");

    connect(d->video, &VideoOutput::formatChanged,
            this, &PlayEngine::updateVideoFormat);
    connect(d->video, &VideoOutput::droppedFramesChanged,
            this, &PlayEngine::droppedFramesChanged);

    d->handle = mpv_create();
    auto verbose = qgetenv("CMPLAYER_MPV_VERBOSE").toLower().trimmed();
    const QVector<QByteArray> lvs = {"no", "fatal", "error", "warn", "info",
                                     "status", "v", "debug", "trace"};
    if (lvs.indexOf(verbose) < lvs.indexOf("info"))
        verbose = "info";
    mpv_request_log_messages(d->handle, verbose.constData());

    d->observe();
    connect(this, &PlayEngine::beginChanged, this, &PlayEngine::endChanged);
    connect(this, &PlayEngine::durationChanged, this, &PlayEngine::endChanged);
    connect(this, &PlayEngine::videoStreamsChanged, this, [=] () {
        if (_Change(d->hasVideo, !d->streams[StreamVideo].tracks.isEmpty()))
            emit hasVideoChanged();
        d->videoInfo.setTracks(d->streams[StreamVideo].tracks);
    });
    connect(this, &PlayEngine::audioStreamsChanged, this, [=] ()
        { d->audioInfo.setTracks(d->streams[StreamAudio].tracks); });
    connect(this, &PlayEngine::subtitleStreamsChanged, this, [=] ()
        { d->subInfo.setTracks(d->streams[StreamSubtitle].tracks); });
    connect(this, &PlayEngine::currentVideoStreamChanged, this, [=] (int id)
        { d->videoInfo.setTrack(d->streams[StreamVideo].tracks.value(id)); });
    connect(this, &PlayEngine::currentAudioStreamChanged, this, [=] (int id)
        { d->audioInfo.setTrack(d->streams[StreamAudio].tracks.value(id)); });
    connect(this, &PlayEngine::currentSubtitleStreamChanged, this, [=] ()
        { d->subInfo.setTracks(d->streams[StreamSubtitle].tracks); });
    auto checkDeint = [=] () {
        auto act = Unavailable;
        if (d->filter->isInputInterlaced())
            act = d->filter->isOutputInterlaced() ? Deactivated : Activated;
        d->videoInfo.setDeinterlacer(act);
    };
    connect(d->filter, &VideoFilter::inputInterlacedChanged,
            this, checkDeint, Qt::QueuedConnection);
    connect(d->filter, &VideoFilter::outputInterlacedChanged,
            this, checkDeint, Qt::QueuedConnection);
    connect(d->audio, &AudioController::inputFormatChanged, this, [=] () {
        d->audioInfo.output()->setFormat(d->audio->inputFormat());
    }, Qt::QueuedConnection);
    connect(d->audio, &AudioController::outputFormatChanged, this, [=] () {
        d->audioInfo.renderer()->setFormat(d->audio->outputFormat());
    }, Qt::QueuedConnection);
    connect(d->audio, &AudioController::samplerateChanged, this, [=] (int sr) {
        d->audioInfo.renderer()->setSampleRate(sr, true);
    }, Qt::QueuedConnection);
    connect(d->audio, &AudioController::gainChanged,
            &d->audioInfo, &AudioInfoObject::setNormalizer);
    auto setOption = [this] (const char *name, const char *data) {
        const auto err = mpv_set_option_string(d->handle, name, data);
        d->fatal(err, "Couldn't set option %%=%%.", name, data);
    };
    setOption("fs", "no");
    setOption("input-cursor", "yes");
    setOption("softvol", "yes");
    setOption("softvol-max", "1000.0");
    setOption("sub-auto", "no");
    setOption("osd-level", "0");
    setOption("quiet", "yes");
    setOption("input-terminal", "no");
    setOption("ad-lavc-downmix", "no");
    setOption("title", "\"\"");
    setOption("vo", d->vo().constData());
    setOption("fixed-vo", "yes");

    auto overrides = qgetenv("CMPLAYER_MPV_OPTIONS").trimmed();
    if (!overrides.isEmpty()) {
        const auto opts = QString::fromLocal8Bit(overrides);
        const auto args = opts.split(QRegEx(uR"([\s\t]+)"_q),
                                     QString::SkipEmptyParts);
        for (int i=0; i<args.size(); ++i) {
            if (!args[i].startsWith("--"_a)) {
                _Error("Cannot parse option %%.", args[i]);
                continue;
            }
            const auto arg = args[i].midRef(2);
            const int index = arg.indexOf('='_q);
            if (index < 0) {
                if (arg.startsWith("no-"_a))
                    setOption(arg.mid(3).toLatin1(), "no");
                else
                    setOption(arg.toLatin1(), "yes");
            } else {
                const auto key = arg.left(index).toLatin1();
                const auto value = arg.mid(index+1).toLatin1();
                setOption(key, value);
            }
        }
    }
    d->fatal(mpv_initialize(d->handle), "Couldn't initialize mpv.");
    _Debug("Initialized");
    d->initialized = true;
}
예제 #27
0
void ItemListItem::setInteractive(bool interactive) {
	if (_Change(d->interactive, interactive))
		emit interactiveChanged();
}
예제 #28
0
 void setFillChar(QChar c) {
     if (_Change(m_fill, c)) emit fillCharChanged();
 }
예제 #29
0
void VideoRendererItem::setColor(const VideoColor &prop) {
	if (_Change(d->color, prop) && d->shader) {
		d->shader->setColor(d->color);
		d->repaint();
	}
}
예제 #30
0
void ItemListItem::setSelectionMode(SelectionMode mode) {
	if (_Change(d->selectionMode, mode)) {
		clearSelections();
		emit selectionModeChanged();
	}
}