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(); } }
void VideoRendererItem::reset() { if (_Change(d->dropped, 0)) emit droppedFramesChanged(d->dropped); d->drawnFrames = 0; d->lastCheckedFrames = 0; d->lastCheckedTime = 0; }
void VideoRendererItem::setChromaUpscaler(InterpolatorType type) { if (_Change(d->chromaUpscaler, type)) { if (d->shader) d->shader->setChromaInterpolator(d->chromaUpscaler); rerender(); } }
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; } } }
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(); }
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 }
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(); } }
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); }
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); }
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); }
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(); }
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; }
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(); }
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(); }
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); }
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(); } }
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; } }
void setSelected(bool s) { if (_Change(m_selected, s)) emit selectedChanged(); }
bool changeAndPolish(T &t, const T &new_) { if (!_Change(t, new_)) return false; p->polishAndUpdate(); return true; }
void ItemListItem::setVerticalPadding(qreal pad) { if (_Change(d->vpad, pad)) emit verticalPaddingChanged(); }
void ItemListItem::setHorizontalPadding(qreal pad) { if (_Change(d->hpad, pad)) emit horizontalPaddingChanged(); }
void VideoRendererItem::setRange(ColorRange range) { if (_Change(d->range, range) && d->shader) { d->shader->setRange(d->range); d->repaint(); } }
void TextureItem::setTextureRect(const QRectF &rect) { if (_Change(d->txtRect, rect)) { d->dirtyGeometry = true; update(); } }
void ItemListItem::setFixedItemLength(qreal width) { if (_Change(d->length, width)) { polishAndUpdate(); emit fixedItemLengthChanged(); } }
void VideoRendererItem::setOverlayOnLetterbox(bool letterbox) { if (_Change(d->overlayInLetterbox, letterbox)) d->updateGeometry(false); }
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; }
void ItemListItem::setInteractive(bool interactive) { if (_Change(d->interactive, interactive)) emit interactiveChanged(); }
void setFillChar(QChar c) { if (_Change(m_fill, c)) emit fillCharChanged(); }
void VideoRendererItem::setColor(const VideoColor &prop) { if (_Change(d->color, prop) && d->shader) { d->shader->setColor(d->color); d->repaint(); } }
void ItemListItem::setSelectionMode(SelectionMode mode) { if (_Change(d->selectionMode, mode)) { clearSelections(); emit selectionModeChanged(); } }