Git commit 73307da9a81bebbfae745e715c097104914963fc by Mauro Carvalho Chehab. Committed on 20/02/2018 at 17:58. Pushed by mauroc into branch 'master'.
mediawidget: allow better control of deinterlacing mode Instead of just on/off, allow setting the de-interlacing mode to the types supported by libVLC. Also changes default to not do deinterlacing, as most TV programs nowadays are in progressive mode, and doing de-interlacing on 4K programs can be a very CPU intensive task. BUG: 389783 Signed-off-by: Mauro Carvalho Chehab <mche...@s-opensource.com> M +1 -1 doc/index.docbook M +2 -2 src/abstractmediawidget.h M +3 -6 src/backend-mplayer/mplayermediawidget.cpp M +2 -2 src/backend-mplayer/mplayermediawidget.h M +36 -5 src/backend-vlc/vlcmediawidget.cpp M +1 -1 src/backend-vlc/vlcmediawidget.h M +135 -28 src/mediawidget.cpp M +17 -2 src/mediawidget.h https://commits.kde.org/kaffeine/73307da9a81bebbfae745e715c097104914963fc diff --git a/doc/index.docbook b/doc/index.docbook index 1e25f45..233c130 100644 --- a/doc/index.docbook +++ b/doc/index.docbook @@ -995,7 +995,7 @@ Offers a drop-down list with <action>options related to the video stream(s)</act <guimenuitem>Deinterlace</guimenuitem> </menuchoice></term> <listitem><para> - <inlinemediaobject><imageobject><imagedata fileref="format-justify-center.png" format="PNG"/></imageobject></inlinemediaobject> With a check box to verify your selection. <action>Is the process of converting interlaced video</action>, such as common analog television signals and more. See <ulink url="https://en.wikipedia.org/wiki/Deinterlacing">Wikipedia</ulink> article for more details. + <inlinemediaobject><imageobject><imagedata fileref="format-justify-center.png" format="PNG"/></imageobject></inlinemediaobject> Offers a drop-down list with available de-interlacing algorithms. <action>Is the process of converting interlaced video</action>, such as common analog television signals and more. See <ulink url="https://en.wikipedia.org/wiki/Deinterlacing">Wikipedia</ulink> article for more details. </para></listitem> </varlistentry> diff --git a/src/abstractmediawidget.h b/src/abstractmediawidget.h index cb4cd54..4b803e7 100644 --- a/src/abstractmediawidget.h +++ b/src/abstractmediawidget.h @@ -58,7 +58,7 @@ public: virtual void setVolume(int volume) = 0; // [0 - 200] virtual void setAspectRatio(MediaWidget::AspectRatio aspectRatio) = 0; virtual void resizeToVideo(float scale) = 0; - virtual void setDeinterlacing(bool deinterlacing) = 0; + virtual void setDeinterlacing(MediaWidget::DeinterlaceMode) = 0; virtual void play(const MediaSource &source) = 0; virtual void stop() = 0; virtual void setPaused(bool paused) = 0; @@ -145,7 +145,7 @@ public: void setVolume(int) {}; // [0 - 200] void setAspectRatio(MediaWidget::AspectRatio) {}; void resizeToVideo(float) {}; - void setDeinterlacing(bool) {}; + void setDeinterlacing(MediaWidget::DeinterlaceMode) {}; void play(const MediaSource &) {}; void stop() {}; void setPaused(bool) {}; diff --git a/src/backend-mplayer/mplayermediawidget.cpp b/src/backend-mplayer/mplayermediawidget.cpp index b4af9d2..3c26780 100644 --- a/src/backend-mplayer/mplayermediawidget.cpp +++ b/src/backend-mplayer/mplayermediawidget.cpp @@ -67,7 +67,8 @@ void MPlayerMediaWidget::setAspectRatio(MediaWidget::AspectRatio aspectRatio_) updateVideoWidgetGeometry(); } -void MPlayerMediaWidget::setDeinterlacing(bool deinterlacing_) +void MPlayerMediaWidget::setDeinterlacing(MediaWidget::DeinterlaceMode deinterlacing); + { deinterlacing = deinterlacing_; sendCommand(SetDeinterlacing); @@ -528,11 +529,7 @@ void MPlayerMediaWidget::sendCommand(Command command) break; } - if (deinterlacing) { - process.write("pausing_keep_force set_property deinterlace 1\n"); - } else { - process.write("pausing_keep_force set_property deinterlace 0\n"); - } + process.write("pausing_keep_force set_property deinterlace %1\n", deinterlacing); break; case SetVolume: { diff --git a/src/backend-mplayer/mplayermediawidget.h b/src/backend-mplayer/mplayermediawidget.h index fc27c8a..f397b81 100644 --- a/src/backend-mplayer/mplayermediawidget.h +++ b/src/backend-mplayer/mplayermediawidget.h @@ -40,7 +40,7 @@ public: void setMuted(bool muted); void setVolume(int volume); // [0 - 200] void setAspectRatio(MediaWidget::AspectRatio aspectRatio); - void setDeinterlacing(bool deinterlacing); + void setDeinterlacing(MediaWidget::DeinterlaceMode deinterlacing); void play(const MediaSource &source); void stop(); void setPaused(bool paused); @@ -86,7 +86,7 @@ private: bool muted; int volume; MediaWidget::AspectRatio aspectRatio; - bool deinterlacing; + MediaWidget::DeinterlaceMode deinterlacing; int timerId; QList<int> audioIds; int videoWidth; diff --git a/src/backend-vlc/vlcmediawidget.cpp b/src/backend-vlc/vlcmediawidget.cpp index 12dcebe..ee04e8a 100644 --- a/src/backend-vlc/vlcmediawidget.cpp +++ b/src/backend-vlc/vlcmediawidget.cpp @@ -229,16 +229,47 @@ void VlcMediaWidget::resizeToVideo(float resizeFactor) libvlc_video_set_scale(vlcMediaPlayer, resizeFactor); } -void VlcMediaWidget::setDeinterlacing(bool deinterlacing) +void VlcMediaWidget::setDeinterlacing(MediaWidget::DeinterlaceMode deinterlacing) { - // "", "blend", "bob", "discard", "ivtc", "linear", - // "mean", "phosphor", "x", "yadif", "yadif2x" - const char *vlcDeinterlaceMode = ""; + const char *vlcDeinterlaceMode; - if (deinterlacing) { + switch (deinterlacing) { + case MediaWidget::DeinterlaceDiscard: + vlcDeinterlaceMode = "discard"; + break; + case MediaWidget::DeinterlaceBob: + vlcDeinterlaceMode = "bob"; + break; + case MediaWidget::DeinterlaceLinear: + vlcDeinterlaceMode = "linear"; + break; + case MediaWidget::DeinterlaceYadif: vlcDeinterlaceMode = "yadif"; + break; + case MediaWidget::DeinterlaceYadif2x: + vlcDeinterlaceMode = "yadif2x"; + break; + case MediaWidget::DeinterlacePhosphor: + vlcDeinterlaceMode = "phosphor"; + break; + case MediaWidget::DeinterlaceX: + vlcDeinterlaceMode = "x"; + break; + case MediaWidget::DeinterlaceMean: + vlcDeinterlaceMode = "mean"; + break; + case MediaWidget::DeinterlaceBlend: + vlcDeinterlaceMode = "blend"; + break; + case MediaWidget::DeinterlaceIvtc: + vlcDeinterlaceMode = "ivtc"; + break; + case MediaWidget::DeinterlaceDisabled: + default: + vlcDeinterlaceMode = NULL; } + libvlc_video_set_deinterlace(vlcMediaPlayer, vlcDeinterlaceMode); } diff --git a/src/backend-vlc/vlcmediawidget.h b/src/backend-vlc/vlcmediawidget.h index 243df93..03c4e03 100644 --- a/src/backend-vlc/vlcmediawidget.h +++ b/src/backend-vlc/vlcmediawidget.h @@ -53,7 +53,7 @@ public: void setVolume(int volume); // [0 - 200] void setAspectRatio(MediaWidget::AspectRatio aspectRatio); void resizeToVideo(float resizeFactor); - void setDeinterlacing(bool deinterlacing); + void setDeinterlacing(MediaWidget::DeinterlaceMode deinterlacing); void play(const MediaSource &source); void stop(); void setPaused(bool paused); diff --git a/src/mediawidget.cpp b/src/mediawidget.cpp index f963a9e..9819857 100644 --- a/src/mediawidget.cpp +++ b/src/mediawidget.cpp @@ -193,26 +193,105 @@ MediaWidget::MediaWidget(QMenu *menu_, QToolBar *toolBar, KActionCollection *col menu->addMenu(videoMenu); menu->addSeparator(); - deinterlaceAction = new QWidgetAction(this); - deinterlaceAction->setIcon(QIcon::fromTheme(QLatin1String("format-justify-center"), QIcon(":format-justify-center"))); - deinterlaceAction->setText(i18nc("'Video' menu", "Deinterlace")); - deinterlaceAction->setCheckable(true); - deinterlaceAction->setChecked( - KSharedConfig::openConfig()->group("MediaObject").readEntry("Deinterlace", true)); - deinterlaceAction->setShortcut(Qt::Key_I); - connect(deinterlaceAction, SIGNAL(toggled(bool)), this, SLOT(deinterlacingChanged(bool))); - backend->setDeinterlacing(deinterlaceAction->isChecked()); - videoMenu->addAction(collection->addAction(QLatin1String("controls_deinterlace"), deinterlaceAction)); + QMenu *deinterlaceMenu = new QMenu(i18nc("'Video' menu", "Deinterlace"), this); + deinterlaceMenu->setIcon(QIcon::fromTheme(QLatin1String("format-justify-center"), QIcon(":format-justify-center"))); + QActionGroup *deinterlaceGroup = new QActionGroup(this); + connect(deinterlaceMenu, SIGNAL(triggered(QAction*)), + this, SLOT(deinterlacingChanged(QAction*))); + videoMenu->addMenu(deinterlaceMenu); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "disabled")); + action->setCheckable(true); + action->setShortcut(Qt::Key_D); + action->setData(DeinterlaceDisabled); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_disabled"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "discard")); + action->setCheckable(true); + action->setData(DeinterlaceDiscard); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_discard"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "bob")); + action->setCheckable(true); + action->setData(DeinterlaceBob); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_bob"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "linear")); + action->setCheckable(true); + action->setData(DeinterlaceLinear); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_linear"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "yadif")); + action->setCheckable(true); + action->setData(DeinterlaceYadif); + action->setShortcut(Qt::Key_I); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_yadif"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "yadif2x")); + action->setCheckable(true); + action->setData(DeinterlaceYadif2x); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_yadif2x"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "phosphor")); + action->setCheckable(true); + action->setData(DeinterlacePhosphor); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_phosphor"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "x")); + action->setCheckable(true); + action->setData(DeinterlaceX); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_x"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "mean")); + action->setCheckable(true); + action->setData(DeinterlaceMean); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_mean"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "blend")); + action->setCheckable(true); + action->setData(DeinterlaceBlend); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_blend"), action)); + + action = new QWidgetAction(deinterlaceGroup); + action->setText(i18nc("'Deinterlace' menu", "Inverse telecine")); + action->setCheckable(true); + action->setData(DeinterlaceIvtc); + deinterlaceMenu->addAction(collection->addAction(QLatin1String("interlace_ivtc"), action)); + + deinterlaceMode = + KSharedConfig::openConfig()->group("MediaObject").readEntry("Deinterlace", 0); + + if (deinterlaceMode <= DeinterlaceIvtc) { + for (int i = 0; i < deinterlaceGroup->actions().size(); i++) { + if (deinterlaceGroup->actions().at(i)->data().toInt() == deinterlaceMode) { + deinterlaceGroup->actions().at(i)->setChecked(true); + break; + } + } + } else { + deinterlaceGroup->actions().at(0)->setChecked(true); + } + backend->setDeinterlacing(static_cast<DeinterlaceMode>(deinterlaceMode)); QMenu *aspectMenu = new QMenu(i18nc("'Video' menu", "Aspect Ratio"), this); QActionGroup *aspectGroup = new QActionGroup(this); connect(aspectGroup, SIGNAL(triggered(QAction*)), this, SLOT(aspectRatioChanged(QAction*))); + videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "Automatic")); action->setCheckable(true); - action->setChecked(true); action->setData(AspectRatioAuto); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_auto"), action)); @@ -221,56 +300,48 @@ MediaWidget::MediaWidget(QMenu *menu_, QToolBar *toolBar, KActionCollection *col action->setCheckable(true); action->setData(AspectRatio1_1); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_1_1"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "4:3")); action->setCheckable(true); action->setData(AspectRatio4_3); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_4_3"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "5:4")); action->setCheckable(true); action->setData(AspectRatio5_4); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_5_4"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "16:9")); action->setCheckable(true); action->setData(AspectRatio16_9); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_16_9"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "16:10")); action->setCheckable(true); action->setData(AspectRatio16_10); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_16_10"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "2.21:1")); action->setCheckable(true); action->setData(AspectRatio221_100); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_221_100"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "2.35:1")); action->setCheckable(true); action->setData(AspectRatio235_100); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_235_100"), action)); - videoMenu->addMenu(aspectMenu); action = new QWidgetAction(aspectGroup); action->setText(i18nc("'Aspect Ratio' menu", "2.39:1")); action->setCheckable(true); action->setData(AspectRatio239_100); aspectMenu->addAction(collection->addAction(QLatin1String("controls_aspect_239_100"), action)); - videoMenu->addMenu(aspectMenu); QMenu *autoResizeMenu = new QMenu(i18n("Video size"), this); QActionGroup *autoResizeGroup = new QActionGroup(this); @@ -475,8 +546,7 @@ MediaWidget::MediaWidget(QMenu *menu_, QToolBar *toolBar, KActionCollection *col MediaWidget::~MediaWidget() { KSharedConfig::openConfig()->group("MediaObject").writeEntry("Volume", volumeSlider->value()); - KSharedConfig::openConfig()->group("MediaObject").writeEntry("Deinterlace", - deinterlaceAction->isChecked()); + KSharedConfig::openConfig()->group("MediaObject").writeEntry("Deinterlace", deinterlaceMode); KSharedConfig::openConfig()->group("MediaObject").writeEntry("AutoResizeFactor", autoResizeFactor); } @@ -847,15 +917,52 @@ void MediaWidget::seek(int position) backend->seek(position); } -void MediaWidget::deinterlacingChanged(bool deinterlacing) +void MediaWidget::deinterlacingChanged(QAction *action) { - backend->setDeinterlacing(deinterlacing); + bool ok; + const char *mode; - if (deinterlacing) { - osdWidget->showText(i18nc("osd message", "Deinterlacing On"), 1500); - } else { - osdWidget->showText(i18nc("osd message", "Deinterlacing Off"), 1500); + deinterlaceMode = action->data().toInt(&ok); + + switch (deinterlaceMode) { + case DeinterlaceDiscard: + mode = "discard"; + break; + case DeinterlaceBob: + mode = "bob"; + break; + case DeinterlaceLinear: + mode = "linear"; + break; + case DeinterlaceYadif: + mode = "yadif"; + break; + case DeinterlaceYadif2x: + mode = "yadif2x"; + break; + case DeinterlacePhosphor: + mode = "phosphor"; + break; + case DeinterlaceX: + mode = "x"; + break; + case DeinterlaceMean: + mode = "mean"; + break; + case DeinterlaceBlend: + mode = "blend"; + break; + case DeinterlaceIvtc: + mode = "ivtc"; + break; + case DeinterlaceDisabled: + default: + mode = "disabled"; } + + backend->setDeinterlacing(static_cast<DeinterlaceMode>(deinterlaceMode)); + + osdWidget->showText(i18nc("osd message", "Deinterlace %1", mode), 1500); } void MediaWidget::aspectRatioChanged(QAction *action) @@ -863,7 +970,7 @@ void MediaWidget::aspectRatioChanged(QAction *action) bool ok; unsigned int aspectRatio_ = action->data().toInt(&ok); - if (ok && aspectRatio_ <= AspectRatio239_100) { + if (aspectRatio_ <= AspectRatio239_100) { backend->setAspectRatio(static_cast<AspectRatio>(aspectRatio_)); setVideoSize(); diff --git a/src/mediawidget.h b/src/mediawidget.h index 09002c5..a646ea7 100644 --- a/src/mediawidget.h +++ b/src/mediawidget.h @@ -66,6 +66,21 @@ public: AspectRatio239_100, }; + enum DeinterlaceMode + { + DeinterlaceDisabled, + DeinterlaceDiscard, + DeinterlaceBob, + DeinterlaceLinear, + DeinterlaceYadif, + DeinterlaceYadif2x, + DeinterlacePhosphor, + DeinterlaceX, + DeinterlaceMean, + DeinterlaceBlend, + DeinterlaceIvtc, + }; + enum DisplayMode { NormalMode, @@ -164,7 +179,7 @@ private slots: void mutedChanged(); void volumeChanged(int volume); void seek(int position); - void deinterlacingChanged(bool deinterlacing); + void deinterlacingChanged(QAction *action); void aspectRatioChanged(QAction *action); void setVideoSize(); void autoResizeTriggered(QAction *action); @@ -217,7 +232,6 @@ private: QWidgetAction *shortSkipBackwardAction; QWidgetAction *shortSkipForwardAction; QWidgetAction *longSkipForwardAction; - QWidgetAction *deinterlaceAction; QWidgetAction *menuAction; QMenu *audioDevMenu; QMenu *titleMenu; @@ -232,6 +246,7 @@ private: DisplayMode displayMode; int autoResizeFactor; + int deinterlaceMode; QScopedPointer<MediaSource> dummySource; MediaSource *source; bool blockBackendUpdates;