From 4ebe753c762fc76422dadfa3cfca6dfea77f9386 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: Fri, 14 Jun 2024 10:56:42 +0800 Subject: [PATCH] =?UTF-8?q?[=E6=96=B0=E5=A2=9E=E4=B8=8E=E6=94=B9=E8=BF=9B]?= =?UTF-8?q?:=20=E5=BC=95=E5=85=A5=E8=89=B2=E7=9B=B8=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96Equalizer=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在filter.cc中将`ep`函数重命名为`eq`,以提供更清晰的命名,并添加了gamma和hue的调整支持。 - 添加了新的`hue`函数,允许用户通过FFmpeg滤镜直接调整色相。 - 在filter.hpp中声明了新的`eq`和`hue`函数,提供外部访问。 - 在openglrender.cc中更新了`paintVideoFrame`方法,增加了对gamma和hue uniform值的支持。 - video_color.frag着色器中新增了gamma和hue的调整代码段,允许更细致的颜色调整。 - shaderutils.cc更新,将gamma和hue调整逻辑加入到片段着色器代码生成过程中。 - widgetrender.cc中调整了构造滤镜字符串的逻辑,包括hue的调整。 - 在equalizer.cc中为Equalizer类新增了gamma和hue的调整逻辑,包括ffGamma、eqGamma、ffHue和eqHue方法。 - 为equalizer.hpp添加了gamma和hue相关的方法声明,以便支持新的颜色调整功能。 --- src/ffmpeg/filter/filter.cc | 12 ++- src/ffmpeg/filter/filter.hpp | 3 +- src/ffmpeg/videorender/openglrender.cc | 2 + .../videorender/shader/video_color.frag | 15 +++ src/ffmpeg/videorender/shaderutils.cc | 2 + src/ffmpeg/videorender/widgetrender.cc | 5 +- src/mediaconfig/equalizer.cc | 95 +++++++++++-------- src/mediaconfig/equalizer.hpp | 4 + src/utils/utils.cpp | 7 +- 9 files changed, 99 insertions(+), 46 deletions(-) diff --git a/src/ffmpeg/filter/filter.cc b/src/ffmpeg/filter/filter.cc index dc6dc72..096168e 100644 --- a/src/ffmpeg/filter/filter.cc +++ b/src/ffmpeg/filter/filter.cc @@ -159,12 +159,18 @@ 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 MediaConfig::Equalizer &equalizer) -> QString +auto Filter::eq(const MediaConfig::Equalizer &equalizer) -> QString { - return QString("eq=contrast=%1:saturation=%2:brightness=%3") + return QString("eq=contrast=%1:saturation=%2:brightness=%3:gamma=%4") .arg(QString::number(equalizer.eqContrast()), QString::number(equalizer.eqSaturation()), - QString::number(equalizer.eqBrightness())); + QString::number(equalizer.eqBrightness()), + QString::number(equalizer.eqGamma())); +} + +auto Filter::hue(int value) -> QString +{ + return QString("hue=%1").arg(QString::number(value)); } // need z.lib libzimg support zscale diff --git a/src/ffmpeg/filter/filter.hpp b/src/ffmpeg/filter/filter.hpp index 73bd128..81b58c6 100644 --- a/src/ffmpeg/filter/filter.hpp +++ b/src/ffmpeg/filter/filter.hpp @@ -35,7 +35,8 @@ class Filter : public QObject auto buffersinkCtx() -> FilterContext *; static auto scale(const QSize &size) -> QString; - static auto ep(const MediaConfig::Equalizer &equalizer) -> QString; + static auto eq(const MediaConfig::Equalizer &equalizer) -> QString; + static auto hue(int value) -> 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 5336ac2..7a57e2b 100644 --- a/src/ffmpeg/videorender/openglrender.cc +++ b/src/ffmpeg/videorender/openglrender.cc @@ -299,6 +299,8 @@ void OpenglRender::paintVideoFrame() d_ptr->programPtr->setUniformValue("contrast", m_equalizer.ffContrast()); d_ptr->programPtr->setUniformValue("saturation", m_equalizer.ffSaturation()); d_ptr->programPtr->setUniformValue("brightness", m_equalizer.ffBrightness()); + d_ptr->programPtr->setUniformValue("gamma", m_equalizer.ffGamma()); + d_ptr->programPtr->setUniformValue("hue", m_equalizer.ffHue()); draw(); d_ptr->programPtr->release(); d_ptr->frameChanged = false; diff --git a/src/ffmpeg/videorender/shader/video_color.frag b/src/ffmpeg/videorender/shader/video_color.frag index 6ad1c4d..1aaf460 100644 --- a/src/ffmpeg/videorender/shader/video_color.frag +++ b/src/ffmpeg/videorender/shader/video_color.frag @@ -1,6 +1,8 @@ uniform float contrast; uniform float saturation; uniform float brightness; +uniform float gamma; +uniform float hue; vec3 adjustBrightness(vec3 rgb, float brightness) // 调整亮度 { @@ -41,3 +43,16 @@ vec3 adjustSaturation(vec3 rgb, float saturation) // 调整饱和度 hsv.y = hsv.y * saturation; return hsv2Rgb(hsv); } + +vec3 adjustGamma(vec3 rgb, float gamma) // 调整gamma +{ + gamma = clamp(gamma, 0.1, 10.0); + return pow(rgb, vec3(1.0 / gamma)); +} + +vec3 adjustHue(vec3 color, float hue) +{ + vec3 hsv = rgb2Hsv(color); + hsv.x = hsv.x + hue / 360.0; + return hsv2Rgb(hsv); +} diff --git a/src/ffmpeg/videorender/shaderutils.cc b/src/ffmpeg/videorender/shaderutils.cc index 761999f..9b5c8e5 100644 --- a/src/ffmpeg/videorender/shaderutils.cc +++ b/src/ffmpeg/videorender/shaderutils.cc @@ -185,6 +185,8 @@ void finishFragment(QByteArray &frag) frag.append(GLSL(color.rgb = adjustContrast(color.rgb, contrast);\n)); frag.append(GLSL(color.rgb = adjustSaturation(color.rgb, saturation);\n)); frag.append(GLSL(color.rgb = adjustBrightness(color.rgb, brightness);\n)); + frag.append(GLSL(color.rgb = adjustGamma(color.rgb, gamma);\n)); + frag.append(GLSL(color.rgb = adjustHue(color.rgb, hue);\n)); frag.append(GLSL(FragColor = color;\n)); } diff --git a/src/ffmpeg/videorender/widgetrender.cc b/src/ffmpeg/videorender/widgetrender.cc index a4f23de..3e06413 100644 --- a/src/ffmpeg/videorender/widgetrender.cc +++ b/src/ffmpeg/videorender/widgetrender.cc @@ -110,7 +110,10 @@ 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(equalizer)); + auto filterSpec = QString("%1,%2,%3") + .arg(Filter::scale(size), + Filter::eq(equalizer), + Filter::hue(equalizer.eqHue())); filterPtr->config(filterSpec); } auto framePtrs = filterPtr->filterFrame(framePtr.data()); diff --git a/src/mediaconfig/equalizer.cc b/src/mediaconfig/equalizer.cc index bfa068a..856940d 100644 --- a/src/mediaconfig/equalizer.cc +++ b/src/mediaconfig/equalizer.cc @@ -7,7 +7,7 @@ namespace MediaConfig { class Equalizer::EqualizerPrivate { public: - EqualizerPrivate(Equalizer *q) + explicit EqualizerPrivate(Equalizer *q) : q_ptr(q) , contrastRange(-100, 100) , saturationRange(-100, 100) @@ -45,7 +45,7 @@ Equalizer::Equalizer(const Equalizer &other) d_ptr->hueRange = other.d_ptr->hueRange; } -Equalizer &Equalizer::operator=(const Equalizer &other) +auto Equalizer::operator=(const Equalizer &other) -> Equalizer & { d_ptr->contrastRange = other.d_ptr->contrastRange; d_ptr->saturationRange = other.d_ptr->saturationRange; @@ -56,9 +56,9 @@ Equalizer &Equalizer::operator=(const Equalizer &other) return *this; } -Equalizer::~Equalizer() {} +Equalizer::~Equalizer() = default; -bool Equalizer::operator==(const Equalizer &other) const +auto Equalizer::operator==(const Equalizer &other) const -> bool { return d_ptr->contrastRange == other.d_ptr->contrastRange && d_ptr->saturationRange == other.d_ptr->saturationRange @@ -67,94 +67,115 @@ bool Equalizer::operator==(const Equalizer &other) const && d_ptr->hueRange == other.d_ptr->hueRange; } -bool Equalizer::operator!=(const Equalizer &other) const +auto Equalizer::operator!=(const Equalizer &other) const -> bool { return !(*this == other); } -Equalizer::EqualizerRange &Equalizer::contrastRange() const +auto Equalizer::contrastRange() const -> Equalizer::EqualizerRange & { return d_ptr->contrastRange; } -float Equalizer::ffContrast() const +auto Equalizer::ffContrast() const -> float { - return Utils::rangeMap(d_ptr->contrastRange.value(), - d_ptr->contrastRange.min(), - d_ptr->contrastRange.max(), - 0.0, - 2.0); + return eqContrast(); } -float Equalizer::eqContrast() const +auto Equalizer::eqContrast() const -> float { + // The value must be a float value in range -1000.0 to 1000.0. The default value is "1". return Utils::rangeMap(d_ptr->contrastRange.value(), d_ptr->contrastRange.min(), d_ptr->contrastRange.max(), - 0.0, + -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 +auto Equalizer::saturationRange() const -> Equalizer::EqualizerRange & { return d_ptr->saturationRange; } -float Equalizer::ffSaturation() const +auto Equalizer::ffSaturation() const -> float { - return Utils::rangeMap(d_ptr->saturationRange.value(), - d_ptr->saturationRange.min(), - d_ptr->saturationRange.max(), - 0.0, - 2.0); + return eqSaturation(); } -float Equalizer::eqSaturation() const +auto Equalizer::eqSaturation() const -> float { // 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) { + if (value > 0) { 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 +auto Equalizer::brightnessRange() const -> Equalizer::EqualizerRange & { return d_ptr->brightnessRange; } -float Equalizer::ffBrightness() const +auto Equalizer::ffBrightness() const -> float { - return Utils::rangeMap(d_ptr->brightnessRange.value(), - d_ptr->brightnessRange.min(), - d_ptr->brightnessRange.max(), - -1, - 1.0); + return eqBrightness(); } -float Equalizer::eqBrightness() const +auto Equalizer::eqBrightness() const -> float { + // The value must be a float value in range -1.0 to 1.0. The default value is "0". 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". + -1.0, + 1.0); } -Equalizer::EqualizerRange &Equalizer::gammaRange() const +auto Equalizer::gammaRange() const -> Equalizer::EqualizerRange & { return d_ptr->gammaRange; } -Equalizer::EqualizerRange &Equalizer::hueRange() const +auto Equalizer::ffGamma() const -> float +{ + return eqGamma(); +} + +auto Equalizer::eqGamma() const -> float +{ + // The value must be a float in range 0.1 to 10.0. The default value is "1". + auto value = d_ptr->gammaRange.value(); + if (value == 0) { + return 1.0; + } + if (value > 0) { + return Utils::rangeMap(value, 0, d_ptr->gammaRange.max(), 1.0, 10.0); + } + return Utils::rangeMap(value, d_ptr->gammaRange.min(), 0, 0.1, 1.0); +} + +auto Equalizer::hueRange() const -> Equalizer::EqualizerRange & { return d_ptr->hueRange; } +auto Equalizer::ffHue() const -> float +{ + return eqHue(); +} + +auto Equalizer::eqHue() const -> float +{ + // Set the hue shift in degrees to apply. Default is 0. Allowed range is from -180 to 180. + return Utils::rangeMap(d_ptr->hueRange.value(), + d_ptr->hueRange.min(), + d_ptr->hueRange.max(), + -180.0, + 180.0); +} + } // namespace MediaConfig diff --git a/src/mediaconfig/equalizer.hpp b/src/mediaconfig/equalizer.hpp index 722feae..e86904d 100644 --- a/src/mediaconfig/equalizer.hpp +++ b/src/mediaconfig/equalizer.hpp @@ -35,8 +35,12 @@ class MEDIACONFIG_EXPORT Equalizer [[nodiscard]] auto eqBrightness() const -> float; [[nodiscard]] auto gammaRange() const -> EqualizerRange &; + [[nodiscard]] auto ffGamma() const -> float; + [[nodiscard]] auto eqGamma() const -> float; [[nodiscard]] auto hueRange() const -> EqualizerRange &; + [[nodiscard]] auto ffHue() const -> float; + [[nodiscard]] auto eqHue() const -> float; private: class EqualizerPrivate; diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index d6c3489..1176e2e 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -18,7 +18,7 @@ void Utils::setSurfaceFormatVersion(int major, int minor) QSurfaceFormat::setDefaultFormat(surfaceFormat); } -QByteArray Utils::readAllFile(const QString &filePath) +auto Utils::readAllFile(const QString &filePath) -> QByteArray { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { @@ -30,10 +30,9 @@ QByteArray Utils::readAllFile(const QString &filePath) return buf; } -float Utils::rangeMap(float value, float min, float max, float newMin, float newMax) +auto Utils::rangeMap(float value, float min, float max, float newMin, float newMax) -> float { - Q_ASSERT(min <= max); - Q_ASSERT(newMin <= newMax); + Q_ASSERT(min <= max && newMin <= newMax); Q_ASSERT(min <= value && value <= max); return (value - min) * (newMax - newMin) / (max - min) + newMin; }