From 3ea6115e4f3e485be93b7ecd4250cc60ad50009a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B5=AE=E7=94=9F=E8=8B=A5=E6=A2=A6?= <1070753498@qq.com> Date: Thu, 13 Jun 2024 16:58:16 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=9B=B4=E6=96=B0=E9=9F=B3=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=92=AD=E6=94=BE=E5=99=A8=E5=9D=87=E8=A1=A1=E5=99=A8=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=92=8C=E8=B5=84=E6=BA=90=E6=96=87=E4=BB=B6]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新了`action.yml`文件,将Qt版本从`6.7.0`更改为`6.7.1`,以适应新的Qt版本需求。 - 调整了`cmake/qt.cmake`文件,更新了Windows和Linux系统下Qt的路径,使其与新版本匹配。 - 新增了`equalizerdialog.cpp`和`equalizerdialog.h`文件,为播放器增加了图形界面均衡器设置功能。 - 删除了`colorspacedialog`相关的文件,因为它们已被新的均衡器设置所取代。 - 更新了`CMakeLists.txt`和`.pro`文件,添加了新的均衡器源文件,并移除了旧的色彩空间设置文件。 - 在`ffmpegplayer`和`mpvplayer`的源文件中,增加了对均衡器的支持,并更新了相关的函数和信号。 - 新增了`mediainfo`子模块,并创建了`equalizer.cpp`和`equalizer.h`文件,为均衡器设置提供了数据结构和操作接口。 - 更新了`videorender`模块,增加了对均衡器效果的处理。 - 调整了`mpvplayer`模块,增加了对mpv播放器均衡器设置的支持。 - 新增了`utils`模块中的`range.hpp`文件,为均衡器范围提供了数据结构支持。 --- .../actions/install-dependencies/action.yml | 2 +- cmake/qt.cmake | 4 +- common.pri | 4 + examples/common/equalizerdialog.cpp | 249 ++++++++++++++++++ examples/common/equalizerdialog.h | 46 ++++ examples/common/playlistview.cc | 13 + examples/common/playlistview.hpp | 2 + examples/ffmpegplayer/CMakeLists.txt | 5 +- examples/ffmpegplayer/colorspacedialog.cc | 195 -------------- examples/ffmpegplayer/colorspacedialog.hpp | 37 --- examples/ffmpegplayer/ffmpegplayer.pro | 5 +- examples/ffmpegplayer/mainwindow.cpp | 70 ++--- examples/ffmpegplayer/mainwindow.h | 2 +- examples/mpvplayer/CMakeLists.txt | 3 + examples/mpvplayer/mainwindow.cc | 37 ++- examples/mpvplayer/mainwindow.hpp | 1 + examples/mpvplayer/mpvplayer.pro | 10 +- src/CMakeLists.txt | 1 + src/ffmpeg/CMakeLists.txt | 4 +- src/ffmpeg/colorutils.cc | 95 ------- src/ffmpeg/colorutils.hpp | 40 --- src/ffmpeg/ffmpeg.pro | 4 +- src/ffmpeg/filter/filter.cc | 8 +- src/ffmpeg/filter/filter.hpp | 3 +- src/ffmpeg/videorender/openglrender.cc | 8 +- src/ffmpeg/videorender/videorender.hpp | 10 +- src/ffmpeg/videorender/widgetrender.cc | 14 +- src/mediainfo/CMakeLists.txt | 8 + src/mediainfo/equalizer.cpp | 160 +++++++++++ src/mediainfo/equalizer.h | 48 ++++ src/mediainfo/mediainfo.pro | 15 ++ src/mediainfo/mediainfo_global.h | 12 + src/mpv/mpvplayer.cc | 60 +++++ src/mpv/mpvplayer.hpp | 15 ++ src/src.pro | 1 + src/utils/CMakeLists.txt | 1 + src/utils/range.hpp | 43 +++ src/utils/utils.pro | 1 + tests/subtitle_unittest/CMakeLists.txt | 10 +- tests/subtitle_unittest/subtitle_unittest.pro | 2 +- 40 files changed, 801 insertions(+), 447 deletions(-) create mode 100644 examples/common/equalizerdialog.cpp create mode 100644 examples/common/equalizerdialog.h delete mode 100644 examples/ffmpegplayer/colorspacedialog.cc delete mode 100644 examples/ffmpegplayer/colorspacedialog.hpp create mode 100644 src/mediainfo/CMakeLists.txt create mode 100644 src/mediainfo/equalizer.cpp create mode 100644 src/mediainfo/equalizer.h create mode 100644 src/mediainfo/mediainfo.pro create mode 100644 src/mediainfo/mediainfo_global.h create mode 100644 src/utils/range.hpp diff --git a/.github/actions/install-dependencies/action.yml b/.github/actions/install-dependencies/action.yml index 32a7e5e..8495e9c 100644 --- a/.github/actions/install-dependencies/action.yml +++ b/.github/actions/install-dependencies/action.yml @@ -23,7 +23,7 @@ inputs: qt_ver: description: 'qt version' required: false - default: '6.7.0' + default: '6.7.1' type: string runs: diff --git a/cmake/qt.cmake b/cmake/qt.cmake index 5a7f536..588c766 100644 --- a/cmake/qt.cmake +++ b/cmake/qt.cmake @@ -1,7 +1,7 @@ if(CMAKE_HOST_WIN32) - list(APPEND CMAKE_PREFIX_PATH "C:\\Qt\\6.7.0\\msvc2019_64") + list(APPEND CMAKE_PREFIX_PATH "C:\\Qt\\6.7.1\\msvc2019_64") elseif(CMAKE_HOST_APPLE) elseif(CMAKE_HOST_LINUX) - list(APPEND CMAKE_PREFIX_PATH "/opt/Qt/6.7.0/gcc_64") + list(APPEND CMAKE_PREFIX_PATH "/opt/Qt/6.7.1/gcc_64") endif() diff --git a/common.pri b/common.pri index 58deca2..7fd2b3a 100644 --- a/common.pri +++ b/common.pri @@ -57,3 +57,7 @@ defineReplace(replaceLibName) { isEmpty(RET):RET = $$LIBRARY_NAME return($$RET) } + +HEADERS += + +SOURCES += diff --git a/examples/common/equalizerdialog.cpp b/examples/common/equalizerdialog.cpp new file mode 100644 index 0000000..e5dd3f2 --- /dev/null +++ b/examples/common/equalizerdialog.cpp @@ -0,0 +1,249 @@ +#include "equalizerdialog.h" + +#include + +#include + +void setBlockValue(QSpinBox *spinBox, int value) +{ + spinBox->blockSignals(true); + spinBox->setValue(value); + spinBox->blockSignals(false); +} + +void setBlockValue(QSlider *slider, int value) +{ + slider->blockSignals(true); + slider->setValue(value); + slider->blockSignals(false); +} + +void init(QSlider *slider, QSpinBox *spinBox, const Media::Equalizer::EqualizerRange &equalizerRange) +{ + slider->setRange(equalizerRange.min(), equalizerRange.max()); + slider->setValue(equalizerRange.value()); + + spinBox->setKeyboardTracking(false); + spinBox->setRange(slider->minimum(), slider->maximum()); + spinBox->setValue(slider->value()); +} + +class EqualizerDialog::EqualizerDialogPrivate +{ +public: + explicit EqualizerDialogPrivate(EqualizerDialog *q) + : q_ptr(q) + { + Media::Equalizer equalizer; + + contrastSlider = new Slider(q_ptr); + contrastSpinBox = new QSpinBox(q_ptr); + init(contrastSlider, contrastSpinBox, equalizer.contrastRange()); + + saturationSlider = new Slider(q_ptr); + saturationSpinBox = new QSpinBox(q_ptr); + init(saturationSlider, saturationSpinBox, equalizer.saturationRange()); + + brightnessSlider = new Slider(q_ptr); + brightnessSpinBox = new QSpinBox(q_ptr); + init(brightnessSlider, brightnessSpinBox, equalizer.brightnessRange()); + + gammaSlider = new Slider(q_ptr); + gammaSpinBox = new QSpinBox(q_ptr); + init(gammaSlider, gammaSpinBox, equalizer.gammaRange()); + + hueSlider = new Slider(q_ptr); + hueSpinBox = new QSpinBox(q_ptr); + init(hueSlider, hueSpinBox, equalizer.hueRange()); + + resetButton = new QToolButton(q_ptr); + resetButton->setText("Reset"); + } + + void setupUI() const + { + auto *layout = new QGridLayout(q_ptr); + layout->addWidget(new QLabel(QObject::tr("Contrast:"), q_ptr), 0, 0); + layout->addWidget(contrastSlider, 0, 1); + layout->addWidget(contrastSpinBox, 0, 2); + layout->addWidget(new QLabel(QObject::tr("Saturation:"), q_ptr), 1, 0); + layout->addWidget(saturationSlider, 1, 1); + layout->addWidget(saturationSpinBox, 1, 2); + layout->addWidget(new QLabel(QObject::tr("Brightness:"), q_ptr), 2, 0); + layout->addWidget(brightnessSlider, 2, 1); + layout->addWidget(brightnessSpinBox, 2, 2); + layout->addWidget(new QLabel(QObject::tr("Gamma:"), q_ptr), 3, 0); + layout->addWidget(gammaSlider, 3, 1); + layout->addWidget(gammaSpinBox, 3, 2); + layout->addWidget(new QLabel(QObject::tr("Hue:"), q_ptr), 4, 0); + layout->addWidget(hueSlider, 4, 1); + layout->addWidget(hueSpinBox, 4, 2); + layout->addWidget(resetButton, 5, 2, Qt::AlignRight); + } + + EqualizerDialog *q_ptr; + + Slider *contrastSlider; + QSpinBox *contrastSpinBox; + + Slider *saturationSlider; + QSpinBox *saturationSpinBox; + + Slider *brightnessSlider; + QSpinBox *brightnessSpinBox; + + Slider *gammaSlider; + QSpinBox *gammaSpinBox; + + Slider *hueSlider; + QSpinBox *hueSpinBox; + + QToolButton *resetButton; +}; + +EqualizerDialog::EqualizerDialog(QWidget *parent) + : QDialog(parent) + , d_ptr(new EqualizerDialogPrivate(this)) +{ + d_ptr->setupUI(); + buildConnect(); + resize(400, 250); +} + +EqualizerDialog::~EqualizerDialog() = default; + +void EqualizerDialog::setEqualizer(const Media::Equalizer &equalizer) +{ + setBlockValue(d_ptr->contrastSlider, equalizer.contrastRange().value()); + setBlockValue(d_ptr->contrastSpinBox, equalizer.contrastRange().value()); + + setBlockValue(d_ptr->saturationSlider, equalizer.saturationRange().value()); + setBlockValue(d_ptr->saturationSpinBox, equalizer.saturationRange().value()); + + setBlockValue(d_ptr->brightnessSlider, equalizer.brightnessRange().value()); + setBlockValue(d_ptr->brightnessSpinBox, equalizer.brightnessRange().value()); + + setBlockValue(d_ptr->gammaSlider, equalizer.gammaRange().value()); + setBlockValue(d_ptr->gammaSpinBox, equalizer.gammaRange().value()); + + setBlockValue(d_ptr->hueSlider, equalizer.hueRange().value()); + setBlockValue(d_ptr->hueSpinBox, equalizer.hueRange().value()); +} + +Media::Equalizer EqualizerDialog::equalizer() const +{ + Media::Equalizer equalizer; + equalizer.contrastRange().setValue(d_ptr->contrastSlider->value()); + equalizer.saturationRange().setValue(d_ptr->saturationSlider->value()); + equalizer.brightnessRange().setValue(d_ptr->brightnessSlider->value()); + equalizer.gammaRange().setValue(d_ptr->gammaSlider->value()); + equalizer.hueRange().setValue(d_ptr->hueSlider->value()); + return equalizer; +} + +void EqualizerDialog::onContrastSliderChanged(int value) +{ + setBlockValue(d_ptr->contrastSpinBox, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onSaturationSliderChanged(int value) +{ + setBlockValue(d_ptr->saturationSpinBox, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onBrightnessSliderChanged(int value) +{ + setBlockValue(d_ptr->brightnessSpinBox, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onContrastSpinBoxChanged(int value) +{ + setBlockValue(d_ptr->contrastSlider, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onSaturationSpinBoxChanged(int value) +{ + setBlockValue(d_ptr->saturationSlider, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onBrightnessSpinBoxChanged(int value) +{ + setBlockValue(d_ptr->brightnessSlider, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onGammaSliderChanged(int value) +{ + setBlockValue(d_ptr->gammaSpinBox, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onGammaSpinBoxChanged(int value) +{ + setBlockValue(d_ptr->gammaSlider, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onHueSliderChanged(int value) +{ + setBlockValue(d_ptr->hueSpinBox, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onHueSpinBoxChanged(int value) +{ + setBlockValue(d_ptr->hueSlider, value); + emit equalizerChanged(); +} + +void EqualizerDialog::onReset() +{ + setEqualizer({}); + emit equalizerChanged(); +} + +void EqualizerDialog::buildConnect() +{ + connect(d_ptr->contrastSlider, + &Slider::valueChanged, + this, + &EqualizerDialog::onContrastSliderChanged); + connect(d_ptr->contrastSpinBox, + &QSpinBox::valueChanged, + this, + &EqualizerDialog::onContrastSpinBoxChanged); + + connect(d_ptr->saturationSlider, + &Slider::valueChanged, + this, + &EqualizerDialog::onSaturationSliderChanged); + connect(d_ptr->saturationSpinBox, + &QSpinBox::valueChanged, + this, + &EqualizerDialog::onSaturationSpinBoxChanged); + + connect(d_ptr->brightnessSlider, + &Slider::valueChanged, + this, + &EqualizerDialog::onBrightnessSliderChanged); + connect(d_ptr->brightnessSpinBox, + &QSpinBox::valueChanged, + this, + &EqualizerDialog::onBrightnessSpinBoxChanged); + + connect(d_ptr->gammaSlider, &Slider::valueChanged, this, &EqualizerDialog::onGammaSliderChanged); + connect(d_ptr->gammaSpinBox, + &QSpinBox::valueChanged, + this, + &EqualizerDialog::onGammaSpinBoxChanged); + + connect(d_ptr->hueSlider, &Slider::valueChanged, this, &EqualizerDialog::onHueSliderChanged); + connect(d_ptr->hueSpinBox, &QSpinBox::valueChanged, this, &EqualizerDialog::onHueSpinBoxChanged); + + connect(d_ptr->resetButton, &QToolButton::clicked, this, &EqualizerDialog::onReset); +} diff --git a/examples/common/equalizerdialog.h b/examples/common/equalizerdialog.h new file mode 100644 index 0000000..18feda3 --- /dev/null +++ b/examples/common/equalizerdialog.h @@ -0,0 +1,46 @@ +#ifndef EQUALIZERDIALOG_H +#define EQUALIZERDIALOG_H + +#include + +#include + +class EqualizerDialog : public QDialog +{ + Q_OBJECT +public: + explicit EqualizerDialog(QWidget *parent = nullptr); + ~EqualizerDialog() override; + + void setEqualizer(const Media::Equalizer &equalizer); + [[nodiscard]] auto equalizer() const -> Media::Equalizer; + +signals: + void equalizerChanged(); + +private slots: + void onContrastSliderChanged(int value); + void onContrastSpinBoxChanged(int value); + + void onSaturationSliderChanged(int value); + void onSaturationSpinBoxChanged(int value); + + void onBrightnessSliderChanged(int value); + void onBrightnessSpinBoxChanged(int value); + + void onGammaSliderChanged(int value); + void onGammaSpinBoxChanged(int value); + + void onHueSliderChanged(int value); + void onHueSpinBoxChanged(int value); + + void onReset(); + +private: + void buildConnect(); + + class EqualizerDialogPrivate; + QScopedPointer d_ptr; +}; + +#endif // EQUALIZERDIALOG_H diff --git a/examples/common/playlistview.cc b/examples/common/playlistview.cc index b6ce2c7..960fcbb 100644 --- a/examples/common/playlistview.cc +++ b/examples/common/playlistview.cc @@ -1,5 +1,18 @@ #include "playlistview.hpp" +#include +#include + +auto isPlaylist(const QUrl &url) -> bool // Check for ".m3u" playlists. +{ + if (!url.isLocalFile()) { + return false; + } + const QFileInfo fileInfo(url.toLocalFile()); + return fileInfo.exists() + && (fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive) == 0); +} + PlayListView::PlayListView(QWidget *parent) : QListView(parent) { diff --git a/examples/common/playlistview.hpp b/examples/common/playlistview.hpp index a47f51e..44e78c2 100644 --- a/examples/common/playlistview.hpp +++ b/examples/common/playlistview.hpp @@ -3,6 +3,8 @@ #include +auto isPlaylist(const QUrl &url) -> bool; + class PlayListView : public QListView { public: diff --git a/examples/ffmpegplayer/CMakeLists.txt b/examples/ffmpegplayer/CMakeLists.txt index f28b119..fb2088b 100644 --- a/examples/ffmpegplayer/CMakeLists.txt +++ b/examples/ffmpegplayer/CMakeLists.txt @@ -1,6 +1,8 @@ set(PROJECT_SOURCES ../common/controlwidget.cc ../common/controlwidget.hpp + ../common/equalizerdialog.cpp + ../common/equalizerdialog.h ../common/openwebmediadialog.cc ../common/openwebmediadialog.hpp ../common/playlistmodel.cpp @@ -16,8 +18,6 @@ set(PROJECT_SOURCES ../common/slider.h ../common/titlewidget.cc ../common/titlewidget.hpp - colorspacedialog.cc - colorspacedialog.hpp main.cpp mainwindow.cpp mainwindow.h) @@ -26,6 +26,7 @@ qt_add_executable(FfmpegPlayer MANUAL_FINALIZATION ${PROJECT_SOURCES}) target_link_libraries( FfmpegPlayer PRIVATE ffmpeg + mediainfo thirdparty dump utils diff --git a/examples/ffmpegplayer/colorspacedialog.cc b/examples/ffmpegplayer/colorspacedialog.cc deleted file mode 100644 index 7840e92..0000000 --- a/examples/ffmpegplayer/colorspacedialog.cc +++ /dev/null @@ -1,195 +0,0 @@ -#include "colorspacedialog.hpp" - -#include - -#include - -void setBlockValue(QSpinBox *spinBox, int value) -{ - spinBox->blockSignals(true); - spinBox->setValue(value); - spinBox->blockSignals(false); -} - -void setBlockValue(QSlider *slider, int value) -{ - slider->blockSignals(true); - slider->setValue(value); - slider->blockSignals(false); -} - -class ColorSpaceDialog::ColorSpaceDialogPrivate -{ -public: - explicit ColorSpaceDialogPrivate(ColorSpaceDialog *q) - : q_ptr(q) - { - Ffmpeg::ColorUtils::ColorSpaceTrc colorTrc; - - contrastSlider = new Slider(q_ptr); - contrastSlider->setRange(colorTrc.contrast_min * multiple, colorTrc.contrast_max * multiple); - contrastSlider->setValue(colorTrc.contrast() * multiple); - saturationSlider = new Slider(q_ptr); - saturationSlider->setRange(colorTrc.saturation_min * multiple, - colorTrc.saturation_max * multiple); - saturationSlider->setValue(colorTrc.saturation() * multiple); - brightnessSlider = new Slider(q_ptr); - brightnessSlider->setRange(colorTrc.brightness_min * multiple, - colorTrc.brightness_max * multiple); - brightnessSlider->setValue(colorTrc.brightness() * multiple); - - contrastSpinBox = new QSpinBox(q_ptr); - contrastSpinBox->setKeyboardTracking(false); - contrastSpinBox->setRange(colorTrc.contrast_min * multiple, - colorTrc.contrast_max * multiple); - contrastSpinBox->setValue(colorTrc.contrast() * multiple); - saturationSpinBox = new QSpinBox(q_ptr); - saturationSpinBox->setKeyboardTracking(false); - saturationSpinBox->setRange(colorTrc.saturation_min * multiple, - colorTrc.saturation_max * multiple); - saturationSpinBox->setValue(colorTrc.saturation() * multiple); - brightnessSpinBox = new QSpinBox(q_ptr); - brightnessSpinBox->setKeyboardTracking(false); - brightnessSpinBox->setRange(colorTrc.brightness_min * multiple, - colorTrc.brightness_max * multiple); - brightnessSpinBox->setValue(colorTrc.brightness() * multiple); - - resetButton = new QToolButton(q_ptr); - resetButton->setText("Reset"); - } - - void setupUI() const - { - auto *layout = new QGridLayout(q_ptr); - layout->addWidget(new QLabel(QObject::tr("Contrast:"), q_ptr), 0, 0); - layout->addWidget(contrastSlider, 0, 1); - layout->addWidget(contrastSpinBox, 0, 2); - layout->addWidget(new QLabel(QObject::tr("Saturation:"), q_ptr), 1, 0); - layout->addWidget(saturationSlider, 1, 1); - layout->addWidget(saturationSpinBox, 1, 2); - layout->addWidget(new QLabel(QObject::tr("Brightness:"), q_ptr), 2, 0); - layout->addWidget(brightnessSlider, 2, 1); - layout->addWidget(brightnessSpinBox, 2, 2); - layout->addWidget(resetButton, 3, 2, Qt::AlignRight); - } - - ColorSpaceDialog *q_ptr; - - Slider *contrastSlider; - Slider *saturationSlider; - Slider *brightnessSlider; - QSpinBox *contrastSpinBox; - QSpinBox *saturationSpinBox; - QSpinBox *brightnessSpinBox; - QToolButton *resetButton; - - const float multiple = 100.0; -}; - -ColorSpaceDialog::ColorSpaceDialog(QWidget *parent) - : QDialog(parent) - , d_ptr(new ColorSpaceDialogPrivate(this)) -{ - d_ptr->setupUI(); - buildConnect(); - resize(400, 250); -} - -ColorSpaceDialog::~ColorSpaceDialog() = default; - -void ColorSpaceDialog::setColorSpace(const Ffmpeg::ColorUtils::ColorSpaceTrc &colorTrc) -{ - setBlockValue(d_ptr->contrastSpinBox, colorTrc.contrast() * d_ptr->multiple); - setBlockValue(d_ptr->saturationSpinBox, colorTrc.saturation() * d_ptr->multiple); - setBlockValue(d_ptr->brightnessSpinBox, colorTrc.brightness() * d_ptr->multiple); - setBlockValue(d_ptr->contrastSlider, colorTrc.contrast() * d_ptr->multiple); - setBlockValue(d_ptr->saturationSlider, colorTrc.saturation() * d_ptr->multiple); - setBlockValue(d_ptr->brightnessSlider, colorTrc.brightness() * d_ptr->multiple); -} - -Ffmpeg::ColorUtils::ColorSpaceTrc ColorSpaceDialog::colorSpace() const -{ - Ffmpeg::ColorUtils::ColorSpaceTrc colorTrc; - colorTrc.setContrast(d_ptr->contrastSlider->value() / d_ptr->multiple); - colorTrc.setSaturation(d_ptr->saturationSlider->value() / d_ptr->multiple); - colorTrc.setBrightness(d_ptr->brightnessSlider->value() / d_ptr->multiple); - return colorTrc; -} - -void ColorSpaceDialog::onContrastSliderChanged(int value) -{ - setBlockValue(d_ptr->contrastSpinBox, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onSaturationSliderChanged(int value) -{ - setBlockValue(d_ptr->saturationSpinBox, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onBrightnessSliderChanged(int value) -{ - setBlockValue(d_ptr->brightnessSpinBox, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onContrastSpinBoxChanged(int value) -{ - setBlockValue(d_ptr->contrastSlider, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onSaturationSpinBoxChanged(int value) -{ - setBlockValue(d_ptr->saturationSlider, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onBrightnessSpinBoxChanged(int value) -{ - setBlockValue(d_ptr->brightnessSlider, value); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::onReset() -{ - Ffmpeg::ColorUtils::ColorSpaceTrc colorTrc; - setBlockValue(d_ptr->contrastSlider, colorTrc.contrast_default * d_ptr->multiple); - setBlockValue(d_ptr->saturationSlider, colorTrc.saturation_default * d_ptr->multiple); - setBlockValue(d_ptr->brightnessSlider, colorTrc.brightness_default * d_ptr->multiple); - setBlockValue(d_ptr->contrastSpinBox, colorTrc.contrast_default * d_ptr->multiple); - setBlockValue(d_ptr->saturationSpinBox, colorTrc.saturation_default * d_ptr->multiple); - setBlockValue(d_ptr->brightnessSpinBox, colorTrc.brightness_default * d_ptr->multiple); - emit d_ptr->q_ptr->colorSpaceChanged(); -} - -void ColorSpaceDialog::buildConnect() -{ - connect(d_ptr->contrastSlider, - &Slider::valueChanged, - this, - &ColorSpaceDialog::onContrastSliderChanged); - connect(d_ptr->saturationSlider, - &Slider::valueChanged, - this, - &ColorSpaceDialog::onSaturationSliderChanged); - connect(d_ptr->brightnessSlider, - &Slider::valueChanged, - this, - &ColorSpaceDialog::onBrightnessSliderChanged); - connect(d_ptr->contrastSpinBox, - &QSpinBox::valueChanged, - this, - &ColorSpaceDialog::onContrastSpinBoxChanged); - connect(d_ptr->saturationSpinBox, - &QSpinBox::valueChanged, - this, - &ColorSpaceDialog::onSaturationSpinBoxChanged); - connect(d_ptr->brightnessSpinBox, - &QSpinBox::valueChanged, - this, - &ColorSpaceDialog::onBrightnessSpinBoxChanged); - - connect(d_ptr->resetButton, &QToolButton::clicked, this, &ColorSpaceDialog::onReset); -} diff --git a/examples/ffmpegplayer/colorspacedialog.hpp b/examples/ffmpegplayer/colorspacedialog.hpp deleted file mode 100644 index 2c923a9..0000000 --- a/examples/ffmpegplayer/colorspacedialog.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef COLORSPACEDIALOG_HPP -#define COLORSPACEDIALOG_HPP - -#include - -#include - -class ColorSpaceDialog : public QDialog -{ - Q_OBJECT -public: - explicit ColorSpaceDialog(QWidget *parent = nullptr); - ~ColorSpaceDialog() override; - - void setColorSpace(const Ffmpeg::ColorUtils::ColorSpaceTrc &colorTrc); - [[nodiscard]] auto colorSpace() const -> Ffmpeg::ColorUtils::ColorSpaceTrc; - -signals: - void colorSpaceChanged(); - -private slots: - void onContrastSliderChanged(int value); - void onSaturationSliderChanged(int value); - void onBrightnessSliderChanged(int value); - void onContrastSpinBoxChanged(int value); - void onSaturationSpinBoxChanged(int value); - void onBrightnessSpinBoxChanged(int value); - void onReset(); - -private: - void buildConnect(); - - class ColorSpaceDialogPrivate; - QScopedPointer d_ptr; -}; - -#endif // COLORSPACEDIALOG_HPP diff --git a/examples/ffmpegplayer/ffmpegplayer.pro b/examples/ffmpegplayer/ffmpegplayer.pro index 31b4dda..81ef895 100644 --- a/examples/ffmpegplayer/ffmpegplayer.pro +++ b/examples/ffmpegplayer/ffmpegplayer.pro @@ -8,6 +8,7 @@ TARGET = FfmpegPlayer LIBS += \ -l$$replaceLibName(ffmpeg) \ + -l$$replaceLibName(mediainfo) \ -l$$replaceLibName(thirdparty) \ -l$$replaceLibName(dump) \ -l$$replaceLibName(utils) @@ -16,6 +17,7 @@ include(../../src/3rdparty/3rdparty.pri) SOURCES += \ ../common/controlwidget.cc \ + ../common/equalizerdialog.cpp \ ../common/openwebmediadialog.cc \ ../common/playlistmodel.cpp \ ../common/playlistview.cc \ @@ -23,12 +25,12 @@ SOURCES += \ ../common/qplaylistfileparser.cpp \ ../common/slider.cpp \ ../common/titlewidget.cc \ - colorspacedialog.cc \ main.cpp \ mainwindow.cpp HEADERS += \ ../common/controlwidget.hpp \ + ../common/equalizerdialog.h \ ../common/openwebmediadialog.hpp \ ../common/playlistmodel.h \ ../common/playlistview.hpp \ @@ -37,7 +39,6 @@ HEADERS += \ ../common/qplaylistfileparser_p.h \ ../common/slider.h \ ../common/titlewidget.hpp \ - colorspacedialog.hpp \ mainwindow.h DESTDIR = $$APP_OUTPUT_PATH diff --git a/examples/ffmpegplayer/mainwindow.cpp b/examples/ffmpegplayer/mainwindow.cpp index c81d64a..1bec94b 100644 --- a/examples/ffmpegplayer/mainwindow.cpp +++ b/examples/ffmpegplayer/mainwindow.cpp @@ -1,6 +1,6 @@ #include "mainwindow.h" -#include "colorspacedialog.hpp" +#include #include #include #include @@ -20,16 +20,6 @@ #include -static auto isPlaylist(const QUrl &url) -> bool // Check for ".m3u" playlists. -{ - if (!url.isLocalFile()) { - return false; - } - const QFileInfo fileInfo(url.toLocalFile()); - return fileInfo.exists() - && (fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive) == 0); -} - class MainWindow::MainWindowPrivate { public: @@ -59,12 +49,18 @@ class MainWindow::MainWindowPrivate //playlistView->setMaximumWidth(250); menu = new QMenu(q_ptr); - audioTracksGroup = new QActionGroup(q_ptr); - audioTracksGroup->setExclusive(true); + + videoMenu = new QMenu(QCoreApplication::translate("MainWindowPrivate", "Video"), q_ptr); + audioMenu = new QMenu(QCoreApplication::translate("MainWindowPrivate", "Audio"), q_ptr); + subMenu = new QMenu(QCoreApplication::translate("MainWindowPrivate", "Subtitles"), q_ptr); + videoTracksGroup = new QActionGroup(q_ptr); videoTracksGroup->setExclusive(true); + audioTracksGroup = new QActionGroup(q_ptr); + audioTracksGroup->setExclusive(true); subTracksGroup = new QActionGroup(q_ptr); subTracksGroup->setExclusive(true); + mediaInfoAction = new QAction(QCoreApplication::translate("MainWindowPrivate", "Media Info"), q_ptr); @@ -116,9 +112,9 @@ class MainWindow::MainWindowPrivate subTracksMenuPtr = new QMenu(QCoreApplication::translate("MainWindowPrivate", "Select subtitle track"), q_ptr); - menu->addMenu(videoTracksMenuPtr.data()); - menu->addMenu(audioTracksMenuPtr.data()); - menu->addMenu(subTracksMenuPtr.data()); + videoMenu->addMenu(videoTracksMenuPtr.data()); + audioMenu->addMenu(audioTracksMenuPtr.data()); + subMenu->addMenu(subTracksMenuPtr.data()); menu->removeAction(mediaInfoAction); menu->addAction(mediaInfoAction); @@ -201,12 +197,19 @@ class MainWindow::MainWindowPrivate PlaylistModel *playlistModel; QMenu *menu; - QPointer audioTracksMenuPtr; + + QMenu *videoMenu; QPointer videoTracksMenuPtr; - QPointer subTracksMenuPtr; - QActionGroup *audioTracksGroup; QActionGroup *videoTracksGroup; + + QMenu *audioMenu; + QPointer audioTracksMenuPtr; + QActionGroup *audioTracksGroup; + + QMenu *subMenu; + QPointer subTracksMenuPtr; QActionGroup *subTracksGroup; + QAction *mediaInfoAction; QMenu *playListMenu; @@ -360,15 +363,15 @@ void MainWindow::jump(const QModelIndex &index) } } -void MainWindow::onShowColorSpace() +void MainWindow::onEqualizer() { if (d_ptr->videoRender.isNull()) { return; } - ColorSpaceDialog dialog(this); - dialog.setColorSpace(d_ptr->videoRender->colorSpaceTrc()); - connect(&dialog, &ColorSpaceDialog::colorSpaceChanged, this, [&] { - d_ptr->videoRender->setColorSpaceTrc(dialog.colorSpace()); + EqualizerDialog dialog(this); + dialog.setEqualizer(d_ptr->videoRender->equalizer()); + connect(&dialog, &EqualizerDialog::equalizerChanged, this, [&] { + d_ptr->videoRender->setEqualizer(dialog.equalizer()); }); dialog.exec(); } @@ -638,13 +641,18 @@ void MainWindow::initMenu() hwAction->setChecked(true); d_ptr->menu->addAction(hwAction); - auto *colorSpaceAction = new QAction(tr("Color Space"), this); - connect(colorSpaceAction, &QAction::triggered, this, &MainWindow::onShowColorSpace); - d_ptr->menu->addAction(colorSpaceAction); + renderMenu(); + + d_ptr->menu->addMenu(d_ptr->videoMenu); + d_ptr->menu->addMenu(d_ptr->audioMenu); + d_ptr->menu->addMenu(d_ptr->subMenu); + + auto *equalizerAction = new QAction(tr("Equalizer"), this); + connect(equalizerAction, &QAction::triggered, this, &MainWindow::onEqualizer); + d_ptr->videoMenu->addAction(equalizerAction); tonemapMenu(); destPrimarisMenu(); - renderMenu(); connect(d_ptr->audioTracksGroup, &QActionGroup::triggered, this, [this](QAction *action) { d_ptr->playerPtr->addEvent(Ffmpeg::EventPtr( @@ -682,7 +690,7 @@ void MainWindow::tonemapMenu() action->setChecked(true); } } - d_ptr->menu->addMenu(tonemapMenu); + d_ptr->videoMenu->addMenu(tonemapMenu); connect(tonemapGroup, &QActionGroup::triggered, this, [this](QAction *action) { d_ptr->tonemapType = static_cast(action->data().toInt()); if (d_ptr->videoRender.isNull()) { @@ -710,7 +718,7 @@ void MainWindow::destPrimarisMenu() action->setChecked(true); } } - d_ptr->menu->addMenu(destPrimarisMenu); + d_ptr->videoMenu->addMenu(destPrimarisMenu); connect(destPrimarisGroup, &QActionGroup::triggered, this, [this](QAction *action) { d_ptr->primarisType = static_cast( action->data().toInt()); @@ -742,7 +750,7 @@ void MainWindow::renderMenu() Qt::QueuedConnection); openglAction->trigger(); - auto *renderMenu = new QMenu(tr("Video Render"), this); + auto *renderMenu = new QMenu(tr("Render"), this); renderMenu->addAction(widgetAction); renderMenu->addAction(openglAction); d_ptr->menu->addMenu(renderMenu); diff --git a/examples/ffmpegplayer/mainwindow.h b/examples/ffmpegplayer/mainwindow.h index 5a316d5..22a9231 100644 --- a/examples/ffmpegplayer/mainwindow.h +++ b/examples/ffmpegplayer/mainwindow.h @@ -18,7 +18,7 @@ private slots: void onHoverSlider(int pos, int value); void onLeaveSlider(); void onShowCurrentFPS(); - void onShowColorSpace(); + void onEqualizer(); void onShowMediaInfo(); void onOpenLocalMedia(); diff --git a/examples/mpvplayer/CMakeLists.txt b/examples/mpvplayer/CMakeLists.txt index d8b91f0..804a4c1 100644 --- a/examples/mpvplayer/CMakeLists.txt +++ b/examples/mpvplayer/CMakeLists.txt @@ -1,6 +1,8 @@ set(PROJECT_SOURCES ../common/controlwidget.cc ../common/controlwidget.hpp + ../common/equalizerdialog.cpp + ../common/equalizerdialog.h ../common/openwebmediadialog.cc ../common/openwebmediadialog.hpp ../common/playlistmodel.cpp @@ -29,6 +31,7 @@ target_compile_definitions(MpvPlayer PRIVATE "MPV_ON") target_link_libraries( MpvPlayer PRIVATE qmpv + mediainfo thirdparty dump utils diff --git a/examples/mpvplayer/mainwindow.cc b/examples/mpvplayer/mainwindow.cc index 05131da..a642c05 100644 --- a/examples/mpvplayer/mainwindow.cc +++ b/examples/mpvplayer/mainwindow.cc @@ -3,6 +3,7 @@ #include "subtitledelaydialog.hpp" #include +#include #include #include #include @@ -15,16 +16,6 @@ #include -static auto isPlaylist(const QUrl &url) -> bool // Check for ".m3u" playlists. -{ - if (!url.isLocalFile()) { - return false; - } - const QFileInfo fileInfo(url.toLocalFile()); - return fileInfo.exists() - && (fileInfo.suffix().compare(QLatin1String("m3u"), Qt::CaseInsensitive) == 0); -} - class MainWindow::MainWindowPrivate { public: @@ -397,6 +388,28 @@ void MainWindow::onRenderChanged(QAction *action) } } +void MainWindow::onEqualizer() +{ + Media::Equalizer equalizer; + equalizer.contrastRange().setValue(d_ptr->mpvPlayer->contrast()); + equalizer.brightnessRange().setValue(d_ptr->mpvPlayer->brightness()); + equalizer.saturationRange().setValue(d_ptr->mpvPlayer->saturation()); + equalizer.gammaRange().setValue(d_ptr->mpvPlayer->gamma()); + equalizer.hueRange().setValue(d_ptr->mpvPlayer->hue()); + + EqualizerDialog dialog(this); + dialog.setEqualizer(equalizer); + connect(&dialog, &EqualizerDialog::equalizerChanged, this, [&] { + auto equalizer = dialog.equalizer(); + d_ptr->mpvPlayer->setContrast(equalizer.contrastRange().value()); + d_ptr->mpvPlayer->setBrightness(equalizer.brightnessRange().value()); + d_ptr->mpvPlayer->setSaturation(equalizer.saturationRange().value()); + d_ptr->mpvPlayer->setGamma(equalizer.gammaRange().value()); + d_ptr->mpvPlayer->setHue(equalizer.hueRange().value()); + }); + dialog.exec(); +} + void MainWindow::onPreview(int pos, int value) { auto url = d_ptr->mpvPlayer->filepath(); @@ -690,6 +703,10 @@ void MainWindow::initMenu() d_ptr->menu->addMenu(d_ptr->audioMenu); d_ptr->menu->addMenu(d_ptr->subMenu); + auto *equalizerAction = new QAction(tr("Equalizer"), this); + connect(equalizerAction, &QAction::triggered, this, &MainWindow::onEqualizer); + d_ptr->videoMenu->addAction(equalizerAction); + connect(d_ptr->videoTracksGroup, &QActionGroup::triggered, this, [this](QAction *action) { auto data = action->data().value(); d_ptr->mpvPlayer->setVideoTrack(data.id); diff --git a/examples/mpvplayer/mainwindow.hpp b/examples/mpvplayer/mainwindow.hpp index a11b7bb..1fd1492 100644 --- a/examples/mpvplayer/mainwindow.hpp +++ b/examples/mpvplayer/mainwindow.hpp @@ -19,6 +19,7 @@ private slots: void onTrackChanged(); void onChapterChanged(); void onRenderChanged(QAction *action); + void onEqualizer(); void onPreview(int pos, int value); void onPreviewFinish(); diff --git a/examples/mpvplayer/mpvplayer.pro b/examples/mpvplayer/mpvplayer.pro index 27a537d..d1ef4e3 100644 --- a/examples/mpvplayer/mpvplayer.pro +++ b/examples/mpvplayer/mpvplayer.pro @@ -10,6 +10,7 @@ DEFINES += MPV_ON LIBS += \ -l$$replaceLibName(qmpv) \ + -l$$replaceLibName(mediainfo) \ -l$$replaceLibName(thirdparty) \ -l$$replaceLibName(dump) \ -l$$replaceLibName(utils) @@ -19,6 +20,7 @@ include(../../src/mpv/mpv.pri) SOURCES += \ ../common/controlwidget.cc \ + ../common/equalizerdialog.cpp \ ../common/openwebmediadialog.cc \ ../common/playlistmodel.cpp \ ../common/playlistview.cc \ @@ -33,6 +35,7 @@ SOURCES += \ HEADERS += \ ../common/controlwidget.hpp \ + ../common/equalizerdialog.h \ ../common/openwebmediadialog.hpp \ ../common/playlistmodel.h \ ../common/playlistview.hpp \ @@ -48,5 +51,10 @@ HEADERS += \ DESTDIR = $$APP_OUTPUT_PATH win32{ - QMAKE_POST_LINK += $$QMAKE_COPY_FILE C:\\3rd\\x64\\mpv\\libmpv-2.dll $$replace(APP_OUTPUT_PATH, /, \\)\\libmpv-2.dll + contains(QT_ARCH, i386) { + MPVDLL_PATH = C:\\3rd\\x86\\mpv\\libmpv-2.dll + }else{ + MPVDLL_PATH = C:\\3rd\\x64\\mpv\\libmpv-2.dll + } + QMAKE_POST_LINK += $$QMAKE_COPY_FILE $$MPVDLL_PATH $$replace(APP_OUTPUT_PATH, /, \\)\\libmpv-2.dll } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d81447..4748853 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(utils) add_subdirectory(dump) add_subdirectory(3rdparty) +add_subdirectory(mediainfo) add_subdirectory(ffmpeg) if(BUILD_MPV) diff --git a/src/ffmpeg/CMakeLists.txt b/src/ffmpeg/CMakeLists.txt index 3f427f3..93076d2 100644 --- a/src/ffmpeg/CMakeLists.txt +++ b/src/ffmpeg/CMakeLists.txt @@ -109,8 +109,8 @@ set(PROJECT_SOURCES qt_add_resources(SOURCES videorender/shaders.qrc) add_custom_library(ffmpeg ${PROJECT_SOURCES} ${SOURCES}) -target_link_libraries(ffmpeg PRIVATE utils Qt6::Widgets Qt6::Multimedia - Qt6::OpenGLWidgets) +target_link_libraries(ffmpeg PRIVATE mediainfo utils Qt6::Widgets + Qt6::Multimedia Qt6::OpenGLWidgets) target_link_libraries(ffmpeg PRIVATE PkgConfig::ffmpeg PkgConfig::ass) if(CMAKE_HOST_SYSTEM_NAME MATCHES "Linux") target_link_libraries(ffmpeg PRIVATE PkgConfig::fontconfig expat::expat) diff --git a/src/ffmpeg/colorutils.cc b/src/ffmpeg/colorutils.cc index 6aba610..b1cc2e3 100644 --- a/src/ffmpeg/colorutils.cc +++ b/src/ffmpeg/colorutils.cc @@ -321,101 +321,6 @@ auto Primaries::getAVColorPrimaries(Type type) -> AVColorPrimaries return AVCOL_PRI_RESERVED0; } -const float ColorSpaceTrc::contrast_min = 0.0; -const float ColorSpaceTrc::contrast_max = 2.0; -const float ColorSpaceTrc::contrast_default = 1.0; -const float ColorSpaceTrc::saturation_min = 0.0; -const float ColorSpaceTrc::saturation_max = 2.0; -const float ColorSpaceTrc::saturation_default = 1.0; -const float ColorSpaceTrc::brightness_min = -1.0; -const float ColorSpaceTrc::brightness_max = 1.0; -const float ColorSpaceTrc::brightness_default = 0.0; - -ColorSpaceTrc::ColorSpaceTrc() - : m_contrast(contrast_default) - , m_saturation(saturation_default) - , m_brightness(brightness_default) -{} - -ColorSpaceTrc::ColorSpaceTrc(const ColorSpaceTrc &other) -{ - if (this != &other) { - m_contrast = other.m_contrast; - m_saturation = other.m_saturation; - m_brightness = other.m_brightness; - } -} - -auto ColorSpaceTrc::operator=(const ColorSpaceTrc &other) -> ColorSpaceTrc & -{ - if (this != &other) { - m_contrast = other.m_contrast; - m_saturation = other.m_saturation; - m_brightness = other.m_brightness; - } - return *this; -} - -auto ColorSpaceTrc::operator==(const ColorSpaceTrc &other) const -> bool -{ - return m_contrast == other.m_contrast && m_saturation == other.m_saturation - && m_brightness == other.m_brightness; -} - -auto ColorSpaceTrc::operator!=(const ColorSpaceTrc &other) const -> bool -{ - return !(*this == other); -} - -void ColorSpaceTrc::setContrast(float contrast) -{ - Q_ASSERT(contrast_min <= contrast && contrast <= contrast_max); - m_contrast = contrast; -} - -auto ColorSpaceTrc::eqContrast() const -> float -{ - return m_contrast; - // The value must be a float value in range -1000.0 to 1000.0. The default value is "1". - // if (m_contrast == contrast_default) { - // return m_contrast; - // } - // if (m_contrast > 1) { - // return Utils::rangeMap(m_contrast, contrast_default, contrast_max, 1.0, 1000.0); - // } - // return Utils::rangeMap(m_contrast, contrast_min, contrast_default, -1000.0, 1.0); -} - -void ColorSpaceTrc::setSaturation(float saturation) -{ - Q_ASSERT(saturation_min <= saturation && saturation <= saturation_max); - m_saturation = saturation; -} - -auto ColorSpaceTrc::eqSaturation() const -> float -{ - // The value must be a float in range 0.0 to 3.0. The default value is "1". - if (m_saturation == saturation_default) { - return m_saturation; - } - if (m_saturation > 1) { - return Utils::rangeMap(m_saturation, saturation_default, saturation_max, 1.0, 3.0); - } - return m_saturation; -} - -void ColorSpaceTrc::setBrightness(float brightness) -{ - Q_ASSERT(brightness_min <= brightness && brightness <= brightness_max); - m_brightness = brightness; -} - -auto ColorSpaceTrc::eqBrightness() const -> float -{ - // The value must be a float value in range -1.0 to 1.0. The default value is "0". - return m_brightness; -} - } // namespace ColorUtils } // namespace Ffmpeg diff --git a/src/ffmpeg/colorutils.hpp b/src/ffmpeg/colorutils.hpp index 1f798d1..aa490f7 100644 --- a/src/ffmpeg/colorutils.hpp +++ b/src/ffmpeg/colorutils.hpp @@ -56,46 +56,6 @@ class FFMPEG_EXPORT Primaries : public QObject static auto getAVColorPrimaries(Type type) -> AVColorPrimaries; }; -struct FFMPEG_EXPORT ColorSpaceTrc -{ - ColorSpaceTrc(); - ColorSpaceTrc(const ColorSpaceTrc &other); - auto operator=(const ColorSpaceTrc &other) -> ColorSpaceTrc &; - ~ColorSpaceTrc() = default; - - auto operator==(const ColorSpaceTrc &other) const -> bool; - auto operator!=(const ColorSpaceTrc &other) const -> bool; - - void setContrast(float contrast); - [[nodiscard]] auto contrast() const -> float { return m_contrast; } - [[nodiscard]] auto eqContrast() const -> float; - - void setSaturation(float saturation); - [[nodiscard]] auto saturation() const -> float { return m_saturation; } - [[nodiscard]] auto eqSaturation() const -> float; - - void setBrightness(float brightness); - [[nodiscard]] auto brightness() const -> float { return m_brightness; } - [[nodiscard]] auto eqBrightness() const -> float; - - static const float contrast_min; - static const float contrast_max; - static const float contrast_default; - - static const float saturation_min; - static const float saturation_max; - static const float saturation_default; - - static const float brightness_min; - static const float brightness_max; - static const float brightness_default; - -private: - float m_contrast; - float m_saturation; - float m_brightness; -}; - } // namespace ColorUtils } // namespace Ffmpeg diff --git a/src/ffmpeg/ffmpeg.pro b/src/ffmpeg/ffmpeg.pro index d058b35..87320f7 100644 --- a/src/ffmpeg/ffmpeg.pro +++ b/src/ffmpeg/ffmpeg.pro @@ -13,7 +13,9 @@ QT += widgets multimedia openglwidgets DEFINES += FFMPEG_LIBRARY TARGET = $$replaceLibName(ffmpeg) -LIBS += -l$$replaceLibName(utils) +LIBS += \ + -l$$replaceLibName(mediainfo) \ + -l$$replaceLibName(utils) SOURCES += \ audiodecoder.cpp \ diff --git a/src/ffmpeg/filter/filter.cc b/src/ffmpeg/filter/filter.cc index 81abaf8..360513f 100644 --- a/src/ffmpeg/filter/filter.cc +++ b/src/ffmpeg/filter/filter.cc @@ -159,12 +159,12 @@ auto Filter::scale(const QSize &size) -> QString return QString("scale=%1:%2").arg(QString::number(size.width()), QString::number(size.height())); } -auto Filter::ep(const ColorUtils::ColorSpaceTrc &trc) -> QString +auto Filter::ep(const Media::Equalizer &equalizer) -> QString { return QString("eq=contrast=%1:saturation=%2:brightness=%3") - .arg(QString::number(trc.eqContrast()), - QString::number(trc.eqSaturation()), - QString::number(trc.eqBrightness())); + .arg(QString::number(equalizer.eqContrast()), + QString::number(equalizer.eqSaturation()), + QString::number(equalizer.eqBrightness())); } // need z.lib libzimg support zscale diff --git a/src/ffmpeg/filter/filter.hpp b/src/ffmpeg/filter/filter.hpp index 4e1fd08..01a6ef5 100644 --- a/src/ffmpeg/filter/filter.hpp +++ b/src/ffmpeg/filter/filter.hpp @@ -2,6 +2,7 @@ #define FILTER_HPP #include +#include #include #include @@ -34,7 +35,7 @@ class Filter : public QObject auto buffersinkCtx() -> FilterContext *; static auto scale(const QSize &size) -> QString; - static auto ep(const ColorUtils::ColorSpaceTrc &trc) -> QString; + static auto ep(const Media::Equalizer &equalizer) -> QString; static auto zscale(ColorUtils::Primaries::Type destPrimaries, Tonemap::Type type) -> QString; private: diff --git a/src/ffmpeg/videorender/openglrender.cc b/src/ffmpeg/videorender/openglrender.cc index f13a96f..dda6bdb 100644 --- a/src/ffmpeg/videorender/openglrender.cc +++ b/src/ffmpeg/videorender/openglrender.cc @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include @@ -294,9 +296,9 @@ void OpenglRender::paintVideoFrame() } d_ptr->programPtr->bind(); // 绑定着色器 d_ptr->programPtr->setUniformValue("transform", fitToScreen({avFrame->width, avFrame->height})); - d_ptr->programPtr->setUniformValue("contrast", m_colorSpaceTrc.contrast()); - d_ptr->programPtr->setUniformValue("saturation", m_colorSpaceTrc.saturation()); - d_ptr->programPtr->setUniformValue("brightness", m_colorSpaceTrc.brightness()); + d_ptr->programPtr->setUniformValue("contrast", m_equalizer.ffContrast()); + d_ptr->programPtr->setUniformValue("saturation", m_equalizer.ffSaturation()); + d_ptr->programPtr->setUniformValue("brightness", m_equalizer.ffBrightness()); draw(); d_ptr->programPtr->release(); d_ptr->frameChanged = false; diff --git a/src/ffmpeg/videorender/videorender.hpp b/src/ffmpeg/videorender/videorender.hpp index e9f84de..8b8f317 100644 --- a/src/ffmpeg/videorender/videorender.hpp +++ b/src/ffmpeg/videorender/videorender.hpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -34,11 +35,8 @@ class FFMPEG_EXPORT VideoRender void setSubTitleFrame(const QSharedPointer &framePtr); virtual void resetAllFrame() = 0; - void setColorSpaceTrc(const ColorUtils::ColorSpaceTrc &colorTrc) { m_colorSpaceTrc = colorTrc; } - [[nodiscard]] auto colorSpaceTrc() const -> ColorUtils::ColorSpaceTrc - { - return m_colorSpaceTrc; - } + void setEqualizer(const Media::Equalizer &equalizer) { m_equalizer = equalizer; } + [[nodiscard]] auto equalizer() const -> Media::Equalizer { return m_equalizer; } virtual void setTonemapType(Tonemap::Type type) { m_tonemapType = type; } [[nodiscard]] auto tonemapType() const -> Tonemap::Type { return m_tonemapType; } @@ -62,7 +60,7 @@ class FFMPEG_EXPORT VideoRender virtual void updateFrame(const QSharedPointer &framePtr) = 0; virtual void updateSubTitleFrame(const QSharedPointer &framePtr) = 0; - ColorUtils::ColorSpaceTrc m_colorSpaceTrc; + Media::Equalizer m_equalizer; Tonemap::Type m_tonemapType = Tonemap::Type::AUTO; ColorUtils::Primaries::Type m_destPrimaries = ColorUtils::Primaries::AUTO; diff --git a/src/ffmpeg/videorender/widgetrender.cc b/src/ffmpeg/videorender/widgetrender.cc index 9b2bcb1..7af4cbc 100644 --- a/src/ffmpeg/videorender/widgetrender.cc +++ b/src/ffmpeg/videorender/widgetrender.cc @@ -72,9 +72,9 @@ class WidgetRender::WidgetRenderPrivate frameConverterPtr->flush(framePtr.data(), size, dst_pix_fmt); } frameConverterPtr->setColorspaceDetails(framePtr.data(), - q_ptr->m_colorSpaceTrc.brightness(), - q_ptr->m_colorSpaceTrc.contrast(), - q_ptr->m_colorSpaceTrc.saturation()); + q_ptr->m_equalizer.ffBrightness(), + q_ptr->m_equalizer.ffContrast(), + q_ptr->m_equalizer.ffSaturation()); QSharedPointer frameRgbPtr(new Frame); frameRgbPtr->imageAlloc(size, dst_pix_fmt); frameConverterPtr->scale(framePtr.data(), frameRgbPtr.data()); @@ -93,12 +93,12 @@ class WidgetRender::WidgetRenderPrivate size.scale(q_ptr->size() * q_ptr->devicePixelRatio(), Qt::KeepAspectRatio); if (framePtr.isNull() || filterPtr.isNull() || lastFrameParam != frameParam - || lastScaleSize != size || colorSpaceTrc != q_ptr->m_colorSpaceTrc + || lastScaleSize != size || equalizer != q_ptr->m_equalizer /*|| tonemapType != q_ptr->m_tonemapType || destPrimaries != q_ptr->m_destPrimaries*/) { filterPtr.reset(new Filter); lastFrameParam = frameParam; lastScaleSize = size; - colorSpaceTrc = q_ptr->m_colorSpaceTrc; + equalizer = q_ptr->m_equalizer; destPrimaries = q_ptr->m_destPrimaries; } if (!filterPtr->isInitialized()) { @@ -110,7 +110,7 @@ class WidgetRender::WidgetRenderPrivate reinterpret_cast(&pix_fmt), sizeof(pix_fmt), AV_OPT_SEARCH_CHILDREN); - auto filterSpec = QString("%1,%2").arg(Filter::scale(size), Filter::ep(colorSpaceTrc)); + auto filterSpec = QString("%1,%2").arg(Filter::scale(size), Filter::ep(equalizer)); filterPtr->config(filterSpec); } auto framePtrs = filterPtr->filterFrame(framePtr.data()); @@ -139,7 +139,7 @@ class WidgetRender::WidgetRenderPrivate QColor backgroundColor = Qt::black; QSize lastScaleSize; - ColorUtils::ColorSpaceTrc colorSpaceTrc; + Media::Equalizer equalizer; Tonemap::Type tonemapType; ColorUtils::Primaries::Type destPrimaries; }; diff --git a/src/mediainfo/CMakeLists.txt b/src/mediainfo/CMakeLists.txt new file mode 100644 index 0000000..d1de3a2 --- /dev/null +++ b/src/mediainfo/CMakeLists.txt @@ -0,0 +1,8 @@ +set(PROJECT_SOURCES equalizer.cpp equalizer.h mediainfo_global.h) + +add_custom_library(mediainfo ${PROJECT_SOURCES}) +target_link_libraries(mediainfo PRIVATE utils Qt6::Core) + +if(CMAKE_HOST_WIN32) + target_compile_definitions(mediainfo PRIVATE "MEDIAINFO_LIBRARY") +endif() diff --git a/src/mediainfo/equalizer.cpp b/src/mediainfo/equalizer.cpp new file mode 100644 index 0000000..a13818b --- /dev/null +++ b/src/mediainfo/equalizer.cpp @@ -0,0 +1,160 @@ +#include "equalizer.h" + +#include + +namespace Media { + +class Equalizer::EqualizerPrivate +{ +public: + EqualizerPrivate(Equalizer *q) + : q_ptr(q) + , contrastRange(-100, 100) + , saturationRange(-100, 100) + , brightnessRange(-100, 100) + , gammaRange(-100, 100) + , hueRange(-100, 100) + { + contrastRange.setValue(0); + saturationRange.setValue(0); + brightnessRange.setValue(0); + gammaRange.setValue(0); + hueRange.setValue(0); + } + + Equalizer *q_ptr; + + EqualizerRange contrastRange; + EqualizerRange saturationRange; + EqualizerRange brightnessRange; + EqualizerRange gammaRange; + EqualizerRange hueRange; +}; + +Equalizer::Equalizer() + : d_ptr(new EqualizerPrivate(this)) +{} + +Equalizer::Equalizer(const Equalizer &other) + : d_ptr(new EqualizerPrivate(this)) +{ + d_ptr->contrastRange = other.d_ptr->contrastRange; + d_ptr->saturationRange = other.d_ptr->saturationRange; + d_ptr->brightnessRange = other.d_ptr->brightnessRange; + d_ptr->gammaRange = other.d_ptr->gammaRange; + d_ptr->hueRange = other.d_ptr->hueRange; +} + +Equalizer &Equalizer::operator=(const Equalizer &other) +{ + d_ptr->contrastRange = other.d_ptr->contrastRange; + d_ptr->saturationRange = other.d_ptr->saturationRange; + d_ptr->brightnessRange = other.d_ptr->brightnessRange; + d_ptr->gammaRange = other.d_ptr->gammaRange; + d_ptr->hueRange = other.d_ptr->hueRange; + + return *this; +} + +Equalizer::~Equalizer() {} + +bool Equalizer::operator==(const Equalizer &other) const +{ + return d_ptr->contrastRange == other.d_ptr->contrastRange + && d_ptr->saturationRange == other.d_ptr->saturationRange + && d_ptr->brightnessRange == other.d_ptr->brightnessRange + && d_ptr->gammaRange == other.d_ptr->gammaRange + && d_ptr->hueRange == other.d_ptr->hueRange; +} + +bool Equalizer::operator!=(const Equalizer &other) const +{ + return !(*this == other); +} + +Equalizer::EqualizerRange &Equalizer::contrastRange() const +{ + return d_ptr->contrastRange; +} + +float Equalizer::ffContrast() const +{ + return Utils::rangeMap(d_ptr->contrastRange.value(), + d_ptr->contrastRange.min(), + d_ptr->contrastRange.max(), + 0.0, + 2.0); +} + +float Equalizer::eqContrast() const +{ + return Utils::rangeMap(d_ptr->contrastRange.value(), + d_ptr->contrastRange.min(), + d_ptr->contrastRange.max(), + 0.0, + 2.0); + // The value must be a float value in range -1000.0 to 1000.0. The default value is "1". +} + +Equalizer::EqualizerRange &Equalizer::saturationRange() const +{ + return d_ptr->saturationRange; +} + +float Equalizer::ffSaturation() const +{ + return Utils::rangeMap(d_ptr->saturationRange.value(), + d_ptr->saturationRange.min(), + d_ptr->saturationRange.max(), + 0.0, + 2.0); +} + +float Equalizer::eqSaturation() const +{ + // The value must be a float in range 0.0 to 3.0. The default value is "1". + auto value = d_ptr->saturationRange.value(); + if (value == 0) { + return 1.0; + } + if (value > 1) { + return Utils::rangeMap(value, 0, d_ptr->saturationRange.max(), 1.0, 3.0); + } + return Utils::rangeMap(value, d_ptr->saturationRange.min(), 0, 0, 1.0); +} + +Equalizer::EqualizerRange &Equalizer::brightnessRange() const +{ + return d_ptr->brightnessRange; +} + +float Equalizer::ffBrightness() const +{ + return Utils::rangeMap(d_ptr->brightnessRange.value(), + d_ptr->brightnessRange.min(), + d_ptr->brightnessRange.max(), + -1, + 1.0); +} + +float Equalizer::eqBrightness() const +{ + return Utils::rangeMap(d_ptr->brightnessRange.value(), + d_ptr->brightnessRange.min(), + d_ptr->brightnessRange.max(), + -1, + 1); + // The value must be a float value in range -1000.0 to 1000.0. The default value is "1". +} + +Equalizer::EqualizerRange &Equalizer::gammaRange() const +{ + return d_ptr->gammaRange; +} + +Equalizer::EqualizerRange &Equalizer::hueRange() const +{ + return d_ptr->hueRange; +} + +} // namespace MediaInfo diff --git a/src/mediainfo/equalizer.h b/src/mediainfo/equalizer.h new file mode 100644 index 0000000..3783ce2 --- /dev/null +++ b/src/mediainfo/equalizer.h @@ -0,0 +1,48 @@ +#ifndef EQUALIZER_H +#define EQUALIZER_H + +#include "mediainfo_global.h" + +#include + +#include + +namespace Media { + +class MEDIAINFO_EXPORT Equalizer +{ +public: + using EqualizerRange = Utils::Range; + + Equalizer(); + Equalizer(const Equalizer &other); + auto operator=(const Equalizer &other) -> Equalizer &; + ~Equalizer(); + + auto operator==(const Equalizer &other) const -> bool; + auto operator!=(const Equalizer &other) const -> bool; + + EqualizerRange &contrastRange() const; + [[nodiscard]] auto ffContrast() const -> float; + [[nodiscard]] auto eqContrast() const -> float; + + EqualizerRange &saturationRange() const; + [[nodiscard]] auto ffSaturation() const -> float; + [[nodiscard]] auto eqSaturation() const -> float; + + EqualizerRange &brightnessRange() const; + [[nodiscard]] auto ffBrightness() const -> float; + [[nodiscard]] auto eqBrightness() const -> float; + + EqualizerRange &gammaRange() const; + + EqualizerRange &hueRange() const; + +private: + class EqualizerPrivate; + QScopedPointer d_ptr; +}; + +} // namespace Media + +#endif // EQUALIZER_H diff --git a/src/mediainfo/mediainfo.pro b/src/mediainfo/mediainfo.pro new file mode 100644 index 0000000..aa2989e --- /dev/null +++ b/src/mediainfo/mediainfo.pro @@ -0,0 +1,15 @@ +include(../slib.pri) + +QT += core + +DEFINES += MEDIAINFO_LIBRARY +TARGET = $$replaceLibName(mediainfo) + +LIBS += -l$$replaceLibName(utils) + +HEADERS += \ + equalizer.h \ + mediainfo_global.h + +SOURCES += \ + equalizer.cpp diff --git a/src/mediainfo/mediainfo_global.h b/src/mediainfo/mediainfo_global.h new file mode 100644 index 0000000..5e49bc1 --- /dev/null +++ b/src/mediainfo/mediainfo_global.h @@ -0,0 +1,12 @@ +#ifndef MEDIAINFO_GLOBAL_H +#define MEDIAINFO_GLOBAL_H + +#include + +#if defined(MEDIAINFO_LIBRARY) +#define MEDIAINFO_EXPORT Q_DECL_EXPORT +#else +#define MEDIAINFO_EXPORT Q_DECL_IMPORT +#endif + +#endif // MEDIAINFO_GLOBAL_H diff --git a/src/mpv/mpvplayer.cc b/src/mpv/mpvplayer.cc index 4227a58..816d64c 100644 --- a/src/mpv/mpvplayer.cc +++ b/src/mpv/mpvplayer.cc @@ -380,6 +380,66 @@ auto MpvPlayer::subtitleDelay() const -> double return mpv::qt::get_property(d_ptr->mpv, "sub-delay").toDouble(); } +void MpvPlayer::setBrightness(int value) +{ + qInfo() << "brightness: " << value; + Q_ASSERT(value >= -100 && value <= 100); + mpv::qt::set_property_async(d_ptr->mpv, "brightness", value); +} + +int MpvPlayer::brightness() const +{ + return mpv::qt::get_property(d_ptr->mpv, "brightness").toInt(); +} + +void MpvPlayer::setContrast(int value) +{ + qInfo() << "contrast: " << value; + Q_ASSERT(value >= -100 && value <= 100); + mpv::qt::set_property_async(d_ptr->mpv, "contrast", value); +} + +int MpvPlayer::contrast() const +{ + return mpv::qt::get_property(d_ptr->mpv, "contrast").toInt(); +} + +void MpvPlayer::setSaturation(int value) +{ + qInfo() << "saturation: " << value; + Q_ASSERT(value >= -100 && value <= 100); + mpv::qt::set_property_async(d_ptr->mpv, "saturation", value); +} + +int MpvPlayer::saturation() const +{ + return mpv::qt::get_property(d_ptr->mpv, "saturation").toInt(); +} + +void MpvPlayer::setGamma(int value) +{ + qInfo() << "gamma: " << value; + Q_ASSERT(value >= -100 && value <= 100); + mpv::qt::set_property_async(d_ptr->mpv, "gamma", value); +} + +int MpvPlayer::gamma() const +{ + return mpv::qt::get_property(d_ptr->mpv, "gamma").toInt(); +} + +void MpvPlayer::setHue(int value) +{ + qInfo() << "hue: " << value; + Q_ASSERT(value >= -100 && value <= 100); + mpv::qt::set_property_async(d_ptr->mpv, "hue", value); +} + +int MpvPlayer::hue() const +{ + return mpv::qt::get_property(d_ptr->mpv, "hue").toInt(); +} + void MpvPlayer::pauseAsync() { auto state = !isPaused(); diff --git a/src/mpv/mpvplayer.hpp b/src/mpv/mpvplayer.hpp index d9cca1f..cc3f9d5 100644 --- a/src/mpv/mpvplayer.hpp +++ b/src/mpv/mpvplayer.hpp @@ -80,6 +80,21 @@ class MPV_LIB_EXPORT MpvPlayer : public QObject void setSubtitleDelay(double delay); // seconds auto subtitleDelay() const -> double; + void setBrightness(int value); + int brightness() const; + + void setContrast(int value); + int contrast() const; + + void setSaturation(int value); + int saturation() const; + + void setGamma(int value); + int gamma() const; + + void setHue(int value); + int hue() const; + void pauseAsync(); void pauseSync(bool state); auto isPaused() -> bool; diff --git a/src/src.pro b/src/src.pro index 3836ead..dd5365d 100644 --- a/src/src.pro +++ b/src/src.pro @@ -5,6 +5,7 @@ SUBDIRS += \ utils \ dump \ 3rdparty \ + mediainfo \ ffmpeg win32 { diff --git a/src/utils/CMakeLists.txt b/src/utils/CMakeLists.txt index e96978a..2703bd8 100644 --- a/src/utils/CMakeLists.txt +++ b/src/utils/CMakeLists.txt @@ -9,6 +9,7 @@ set(PROJECT_SOURCES logasync.cpp logasync.h osspecificaspects.h + range.hpp singleton.hpp speed.cc speed.hpp diff --git a/src/utils/range.hpp b/src/utils/range.hpp new file mode 100644 index 0000000..139f900 --- /dev/null +++ b/src/utils/range.hpp @@ -0,0 +1,43 @@ +#pragma once + +namespace Utils { + +template +class Range +{ +public: + Range(T min, T max) + : m_min(min) + , m_max(max) + {} + + auto operator==(const Range &other) const -> bool + { + return m_min == other.m_min && m_max == other.m_max && m_value == other.m_value; + } + auto operator!=(const Range &other) const -> bool { return !(*this == other); } + + T min() const { return m_min; } + T max() const { return m_max; } + + T clamp(T value) const + { + if (value < m_min) { + return m_min; + } + if (value > m_max) { + return m_max; + } + return value; + } + + T value() const { return m_value; } + void setValue(T value) { m_value = clamp(value); } + +private: + T m_min; + T m_max; + T m_value; +}; + +} // namespace Utils diff --git a/src/utils/utils.pro b/src/utils/utils.pro index 765cae1..5f5834e 100644 --- a/src/utils/utils.pro +++ b/src/utils/utils.pro @@ -20,6 +20,7 @@ HEADERS += \ hostosinfo.h \ logasync.h \ osspecificaspects.h \ + range.hpp \ singleton.hpp \ speed.hpp \ threadsafequeue.hpp \ diff --git a/tests/subtitle_unittest/CMakeLists.txt b/tests/subtitle_unittest/CMakeLists.txt index cf722f6..3b711fc 100644 --- a/tests/subtitle_unittest/CMakeLists.txt +++ b/tests/subtitle_unittest/CMakeLists.txt @@ -1,14 +1,14 @@ set(PROJECT_SOURCES main.cc mainwindow.cc mainwindow.hpp subtitlethread.cc subtitlethread.hpp) -qt_add_executable(Subtitle_unittest MANUAL_FINALIZATION ${PROJECT_SOURCES}) -target_link_libraries(Subtitle_unittest PRIVATE Qt6::Widgets Qt6::Multimedia +qt_add_executable(subtitle_unittest MANUAL_FINALIZATION ${PROJECT_SOURCES}) +target_link_libraries(subtitle_unittest PRIVATE Qt6::Widgets Qt6::Multimedia Qt6::OpenGLWidgets ffmpeg utils) -target_link_libraries(Subtitle_unittest PRIVATE PkgConfig::ffmpeg) +target_link_libraries(subtitle_unittest PRIVATE PkgConfig::ffmpeg) if(CMAKE_HOST_APPLE) target_link_libraries( - Subtitle_unittest + subtitle_unittest PRIVATE ${Foundation_LIBRARY} ${CoreAudio_LIBRARY} ${AVFoundation_LIBRARY} @@ -26,4 +26,4 @@ if(CMAKE_HOST_APPLE) ${CoreServices_LIBRARY}) endif() -qt_finalize_executable(Subtitle_unittest) +qt_finalize_executable(subtitle_unittest) diff --git a/tests/subtitle_unittest/subtitle_unittest.pro b/tests/subtitle_unittest/subtitle_unittest.pro index d3e66e5..b1e5e46 100644 --- a/tests/subtitle_unittest/subtitle_unittest.pro +++ b/tests/subtitle_unittest/subtitle_unittest.pro @@ -6,7 +6,7 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets TEMPLATE = app -TARGET = Subtitle_unittest +TARGET = subtitle_unittest LIBS += -L$$APP_OUTPUT_PATH/../libs \ -l$$replaceLibName(ffmpeg) \