diff --git a/.gitignore b/.gitignore index f7b830b..d10ba38 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ /kpipewire-6.1.1.tar.xz /kpipewire-6.1.2.tar.xz /kpipewire-6.1.3.tar.xz +/kpipewire-6.1.4.tar.xz diff --git a/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch b/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch deleted file mode 100644 index be75886..0000000 --- a/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 0c3f8b4f9de7d4dcd24d952184dabdbda74b4c35 Mon Sep 17 00:00:00 2001 -From: Fabian Vogt -Date: Sat, 6 Jul 2024 16:27:28 +0200 -Subject: [PATCH 1/3] Simpler yet more useful handling of - KPIPEWIRE_FORCE_ENCODER - -Previously, it always overrode the encoder type and profile. - -Now just force a specific encoder by inlining the encoder selection -in the switch cases. - -This means it's no longer possible to force a different encoder type -than the application requested, but it's arguably not that useful to -e.g. force VP9 if the application expects H.264 packets. ---- - src/pipewireproduce.cpp | 45 +++++++++-------------------------------- - 1 file changed, 9 insertions(+), 36 deletions(-) - -diff --git a/src/pipewireproduce.cpp b/src/pipewireproduce.cpp -index 3452ce9..416bcd3 100644 ---- a/src/pipewireproduce.cpp -+++ b/src/pipewireproduce.cpp -@@ -266,46 +266,19 @@ void PipeWireProduce::stateChanged(pw_stream_state state) - - std::unique_ptr PipeWireProduce::makeEncoder() - { -- auto encoderType = m_encoderType; -- bool forceSoftware = false; -- bool forceHardware = false; -- -- if (qEnvironmentVariableIsSet("KPIPEWIRE_FORCE_ENCODER")) { -- auto forcedEncoder = qEnvironmentVariable("KPIPEWIRE_FORCE_ENCODER"); -- if (forcedEncoder == u"libvpx") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing VP8 Software encoding"; -- encoderType = PipeWireBaseEncodedStream::VP8; -- forceSoftware = true; -- } else if (forcedEncoder == u"libvpx-vp9") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing VP9 Software encoding"; -- encoderType = PipeWireBaseEncodedStream::VP9; -- forceSoftware = true; -- } else if (forcedEncoder == u"libx264") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing H264 Software encoding, main profile"; -- encoderType = PipeWireBaseEncodedStream::H264Main; -- forceSoftware = true; -- } else if (forcedEncoder == u"h264_vaapi") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing H264 Hardware encoding, main profile"; -- encoderType = PipeWireBaseEncodedStream::H264Main; -- forceHardware = true; -- } else if (forcedEncoder == u"libx264_baseline") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing H264 Software encoding, baseline profile"; -- encoderType = PipeWireBaseEncodedStream::H264Baseline; -- forceSoftware = true; -- } else if (forcedEncoder == u"h264_vaapi_baseline") { -- qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing H264 Hardware encoding, baseline profile"; -- encoderType = PipeWireBaseEncodedStream::H264Baseline; -- forceHardware = true; -- } -+ auto forcedEncoder = qEnvironmentVariable("KPIPEWIRE_FORCE_ENCODER"); -+ if (!forcedEncoder.isNull()) { -+ qCWarning(PIPEWIRERECORD_LOGGING) << "Forcing encoder to" << forcedEncoder; - } - - auto size = m_stream->size(); - -- switch (encoderType) { -+ switch (m_encoderType) { - case PipeWireBaseEncodedStream::H264Baseline: - case PipeWireBaseEncodedStream::H264Main: { - auto profile = m_encoderType == PipeWireBaseEncodedStream::H264Baseline ? Encoder::H264Profile::Baseline : Encoder::H264Profile::Main; -- if (!forceSoftware) { -+ -+ if (forcedEncoder.isNull() || forcedEncoder == u"h264_vaapi") { - auto hardwareEncoder = std::make_unique(profile, this); - hardwareEncoder->setQuality(m_quality); - hardwareEncoder->setEncodingPreference(m_encodingPreference); -@@ -314,7 +287,7 @@ std::unique_ptr PipeWireProduce::makeEncoder() - } - } - -- if (!forceHardware) { -+ if (forcedEncoder.isNull() || forcedEncoder == u"libx264") { - auto softwareEncoder = std::make_unique(profile, this); - softwareEncoder->setQuality(m_quality); - softwareEncoder->setEncodingPreference(m_encodingPreference); -@@ -325,7 +298,7 @@ std::unique_ptr PipeWireProduce::makeEncoder() - break; - } - case PipeWireBaseEncodedStream::VP8: { -- if (!forceHardware) { -+ if (forcedEncoder.isNull() || forcedEncoder == u"libvpx") { - auto encoder = std::make_unique(this); - encoder->setQuality(m_quality); - if (encoder->initialize(size)) { -@@ -335,7 +308,7 @@ std::unique_ptr PipeWireProduce::makeEncoder() - break; - } - case PipeWireBaseEncodedStream::VP9: { -- if (!forceHardware) { -+ if (forcedEncoder.isNull() || forcedEncoder == u"libvpx-vp9") { - auto encoder = std::make_unique(this); - encoder->setQuality(m_quality); - if (encoder->initialize(size)) { --- -2.45.2 - diff --git a/0002-Add-encoder-using-libopenh264.patch b/0002-Add-encoder-using-libopenh264.patch deleted file mode 100644 index 5307a98..0000000 --- a/0002-Add-encoder-using-libopenh264.patch +++ /dev/null @@ -1,222 +0,0 @@ -From e17793a3b023f26411001093bb2d5934adf715c7 Mon Sep 17 00:00:00 2001 -From: Fabian Vogt -Date: Sat, 6 Jul 2024 16:40:42 +0200 -Subject: [PATCH 2/3] Add encoder using libopenh264 - -On some distributions, libopenh264 is the only encoder available OOTB. -Add support for it and use it as fallback. - -BUG: 476187 ---- - src/CMakeLists.txt | 1 + - src/libopenh264encoder.cpp | 106 ++++++++++++++++++++++++++++++ - src/libopenh264encoder_p.h | 28 ++++++++ - src/pipewirebaseencodedstream.cpp | 2 +- - src/pipewireproduce.cpp | 11 ++++ - 5 files changed, 147 insertions(+), 1 deletion(-) - create mode 100644 src/libopenh264encoder.cpp - create mode 100644 src/libopenh264encoder_p.h - -diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt -index e96f52b..3126528 100644 ---- a/src/CMakeLists.txt -+++ b/src/CMakeLists.txt -@@ -135,6 +135,7 @@ add_library(KPipeWireRecord ${kpipewirerecord_SRCS} - encoder.cpp - h264vaapiencoder.cpp - libx264encoder.cpp -+ libopenh264encoder.cpp - libvpxencoder.cpp - libvpxvp9encoder.cpp - ) -diff --git a/src/libopenh264encoder.cpp b/src/libopenh264encoder.cpp -new file mode 100644 -index 0000000..6d4c6a1 ---- /dev/null -+++ b/src/libopenh264encoder.cpp -@@ -0,0 +1,106 @@ -+/* -+ SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez -+ SPDX-FileCopyrightText: 2023 Marco Martin -+ SPDX-FileCopyrightText: 2023 Arjen Hiemstra -+ SPDX-FileCopyrightText: 2024 Fabian Vogt -+ -+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL -+*/ -+ -+#include "libopenh264encoder_p.h" -+ -+#include -+#include -+ -+extern "C" { -+#include -+#include -+#include -+#include -+} -+ -+#include "logging_record.h" -+ -+LibOpenH264Encoder::LibOpenH264Encoder(H264Profile profile, PipeWireProduce *produce) -+ : SoftwareEncoder(produce) -+ , m_profile(profile) -+{ -+} -+ -+bool LibOpenH264Encoder::initialize(const QSize &size) -+{ -+ createFilterGraph(size); -+ -+ auto codec = avcodec_find_encoder_by_name("libopenh264"); -+ if (!codec) { -+ qCWarning(PIPEWIRERECORD_LOGGING) << "libopenh264 codec not found"; -+ return false; -+ } -+ -+ m_avCodecContext = avcodec_alloc_context3(codec); -+ if (!m_avCodecContext) { -+ qCWarning(PIPEWIRERECORD_LOGGING) << "Could not allocate video codec context"; -+ return false; -+ } -+ -+ Q_ASSERT(!size.isEmpty()); -+ m_avCodecContext->width = size.width(); -+ m_avCodecContext->height = size.height(); -+ m_avCodecContext->max_b_frames = 0; -+ m_avCodecContext->gop_size = 100; -+ m_avCodecContext->pix_fmt = AV_PIX_FMT_YUV420P; -+ m_avCodecContext->time_base = AVRational{1, 1000}; -+ -+ if (m_quality) { -+ // "q" here stands for "quantization", but that effectively impacts quality. -+ m_avCodecContext->qmin = m_avCodecContext->qmax = percentageToAbsoluteQuality(m_quality); -+ } -+ -+ switch (m_profile) { -+ case H264Profile::Baseline: -+ // libopenh264 only does constrained baseline. -+ // There's a bug in the ffmpeg -> openh264 interface though: -+ // ffmpeg expects CONSTRAINED_BASELINE from the application and -+ // passes that through, but libopenh264 only allows BASELINE. -+ // Until that bug is fixed there'll always be a warning that the -+ // profile is not supported (https://github.com/cisco/openh264/issues/3613) -+ m_avCodecContext->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE; -+ break; -+ case H264Profile::Main: -+ m_avCodecContext->profile = FF_PROFILE_H264_MAIN; -+ break; -+ case H264Profile::High: -+ m_avCodecContext->profile = FF_PROFILE_H264_HIGH; -+ break; -+ } -+ -+ AVDictionary *options = nullptr; -+ av_dict_set_int(&options, "threads", qMin(16, QThread::idealThreadCount()), 0); -+ applyEncodingPreference(options); -+ -+ if (int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) { -+ qCWarning(PIPEWIRERECORD_LOGGING) << "Could not open codec" << av_err2str(result); -+ return false; -+ } -+ -+ return true; -+} -+ -+int LibOpenH264Encoder::percentageToAbsoluteQuality(const std::optional &quality) -+{ -+ if (!quality) { -+ return -1; -+ } -+ -+ // 1-51 (incl.), lower is better -+ return 51 - (m_quality.value() / 100.0) * 50; -+} -+ -+void LibOpenH264Encoder::applyEncodingPreference(AVDictionary *options) -+{ -+ SoftwareEncoder::applyEncodingPreference(options); -+ // Disable motion estimation, not great while dragging windows but speeds up encoding by an order of magnitude -+ av_dict_set(&options, "flags", "+mv4", 0); -+ // Disable in-loop filtering -+ av_dict_set_int(&options, "loopfilter", 0, 0); -+} -diff --git a/src/libopenh264encoder_p.h b/src/libopenh264encoder_p.h -new file mode 100644 -index 0000000..fdacf14 ---- /dev/null -+++ b/src/libopenh264encoder_p.h -@@ -0,0 +1,28 @@ -+/* -+ SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez -+ SPDX-FileCopyrightText: 2023 Marco Martin -+ SPDX-FileCopyrightText: 2023 Arjen Hiemstra -+ SPDX-FileCopyrightText: 2024 Fabian Vogt -+ -+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL -+*/ -+ -+#include "encoder_p.h" -+ -+/** -+ * A software encoder that uses ffmpeg + libopenh264 to encode to H.264. -+ */ -+class LibOpenH264Encoder : public SoftwareEncoder -+{ -+public: -+ LibOpenH264Encoder(H264Profile profile, PipeWireProduce *produce); -+ -+ bool initialize(const QSize &size) override; -+ -+protected: -+ int percentageToAbsoluteQuality(const std::optional &quality) override; -+ void applyEncodingPreference(AVDictionary *options) override; -+ -+private: -+ H264Profile m_profile = H264Profile::Main; -+}; -diff --git a/src/pipewirebaseencodedstream.cpp b/src/pipewirebaseencodedstream.cpp -index 553c334..814d8d9 100644 ---- a/src/pipewirebaseencodedstream.cpp -+++ b/src/pipewirebaseencodedstream.cpp -@@ -225,7 +225,7 @@ QList PipeWireBaseEncodedStream::suggestedEn - && avcodec_find_encoder_by_name("h264_vaapi")) { - return false; - } else { -- return !avcodec_find_encoder_by_name("libx264"); -+ return !(avcodec_find_encoder_by_name("libx264") || avcodec_find_encoder_by_name("libopenh264")); - } - default: - return true; -diff --git a/src/pipewireproduce.cpp b/src/pipewireproduce.cpp -index 416bcd3..52594e6 100644 ---- a/src/pipewireproduce.cpp -+++ b/src/pipewireproduce.cpp -@@ -16,6 +16,7 @@ - #include - - #include "h264vaapiencoder_p.h" -+#include "libopenh264encoder_p.h" - #include "libvpxencoder_p.h" - #include "libvpxvp9encoder_p.h" - #include "libx264encoder_p.h" -@@ -295,6 +296,16 @@ std::unique_ptr PipeWireProduce::makeEncoder() - return softwareEncoder; - } - } -+ -+ // Try libopenh264 last, it's slower and has less features. -+ if (forcedEncoder.isNull() || forcedEncoder == u"libopenh264") { -+ auto softwareEncoder = std::make_unique(profile, this); -+ softwareEncoder->setQuality(m_quality); -+ softwareEncoder->setEncodingPreference(m_encodingPreference); -+ if (softwareEncoder->initialize(size)) { -+ return softwareEncoder; -+ } -+ } - break; - } - case PipeWireBaseEncodedStream::VP8: { --- -2.45.2 - diff --git a/0003-Fix-some-copy-and-paste-issues-in-h264vaapi-and-libx.patch b/0003-Fix-some-copy-and-paste-issues-in-h264vaapi-and-libx.patch deleted file mode 100644 index 6edbbc9..0000000 --- a/0003-Fix-some-copy-and-paste-issues-in-h264vaapi-and-libx.patch +++ /dev/null @@ -1,54 +0,0 @@ -From c7d88d028ea1e5aa4ed1729fd987c7e1c0517faa Mon Sep 17 00:00:00 2001 -From: Fabian Vogt -Date: Sat, 6 Jul 2024 16:42:36 +0200 -Subject: [PATCH 3/3] Fix some copy-and-paste issues in h264vaapi and libx264 - encoders - -The code was copied from the libvpx encoder and apparently not adjusted. ---- - src/h264vaapiencoder.cpp | 4 ---- - src/libx264encoder.cpp | 6 +----- - 2 files changed, 1 insertion(+), 9 deletions(-) - -diff --git a/src/h264vaapiencoder.cpp b/src/h264vaapiencoder.cpp -index c4a607d..2d610de 100644 ---- a/src/h264vaapiencoder.cpp -+++ b/src/h264vaapiencoder.cpp -@@ -167,10 +167,6 @@ int H264VAAPIEncoder::percentageToAbsoluteQuality(const std::optional &q - void H264VAAPIEncoder::applyEncodingPreference(AVDictionary *options) - { - HardwareEncoder::applyEncodingPreference(options); -- av_dict_set(&options, "tune-content", "screen", 0); -- av_dict_set(&options, "deadline", "realtime", 0); -- // In theory a lower number should be faster, but the opposite seems to be true -- // av_dict_set(&options, "quality", "40", 0); - // Disable motion estimation, not great while dragging windows but speeds up encoding by an order of magnitude - av_dict_set(&options, "flags", "+mv4", 0); - // Disable in-loop filtering -diff --git a/src/libx264encoder.cpp b/src/libx264encoder.cpp -index 6f95b84..04eb5ec 100644 ---- a/src/libx264encoder.cpp -+++ b/src/libx264encoder.cpp -@@ -32,7 +32,7 @@ bool LibX264Encoder::initialize(const QSize &size) - - auto codec = avcodec_find_encoder_by_name("libx264"); - if (!codec) { -- qCWarning(PIPEWIRERECORD_LOGGING) << "h264_vaapi codec not found"; -+ qCWarning(PIPEWIRERECORD_LOGGING) << "libx264 codec not found"; - return false; - } - -@@ -93,10 +93,6 @@ int LibX264Encoder::percentageToAbsoluteQuality(const std::optional &qua - void LibX264Encoder::applyEncodingPreference(AVDictionary *options) - { - SoftwareEncoder::applyEncodingPreference(options); -- av_dict_set(&options, "tune-content", "screen", 0); -- av_dict_set(&options, "deadline", "realtime", 0); -- // In theory a lower number should be faster, but the opposite seems to be true -- // av_dict_set(&options, "quality", "40", 0); - // Disable motion estimation, not great while dragging windows but speeds up encoding by an order of magnitude - av_dict_set(&options, "flags", "+mv4", 0); - // Disable in-loop filtering --- -2.45.2 - diff --git a/kpipewire.spec b/kpipewire.spec index 2e2071c..a1dd710 100644 --- a/kpipewire.spec +++ b/kpipewire.spec @@ -1,17 +1,12 @@ Name: kpipewire Summary: Set of convenient classes to use PipeWire in Qt projects -Version: 6.1.3 -Release: 3%{?dist} +Version: 6.1.4 +Release: 1%{?dist} License: BSD-3-Clause AND CC0-1.0 AND LGPL-2.1-only AND LGPL-3.0-only URL: https://invent.kde.org/plasma/%{name} Source0: https://download.kde.org/%{stable_kf6}/plasma/%{version}/%{name}-%{version}.tar.xz -# Backports from upstream to support OpenH264 -Patch0001: 0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch -Patch0002: 0002-Add-encoder-using-libopenh264.patch -Patch0003: 0003-Fix-some-copy-and-paste-issues-in-h264vaapi-and-libx.patch - # Compile Tools BuildRequires: cmake BuildRequires: gcc-c++ @@ -107,6 +102,9 @@ developing applications that use %{name}. %{_libdir}/cmake/KPipeWire/*.cmake %changelog +* Fri Aug 09 2024 Steve Cossette - 6.1.4-1 +- 6.1.4 + * Wed Jul 24 2024 Marc Deop i Argemí - 6.1.3-3 - rebuilt diff --git a/sources b/sources index e00d895..335df52 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (kpipewire-6.1.3.tar.xz) = d2b1971ca7970a61da700b7f5004e045dfc0535a28ce6bb9be590a2122e0af8b82ec44513f78190e2e6ca9424d389ce11332e7b9031d74c113525e14d1c0bdcb +SHA512 (kpipewire-6.1.4.tar.xz) = e247709e2f89ac3bc55ca3cda78024d39b608c0be09453dcbabe441b247e7b8a54ad8c9ef0ba52a5d9e01b3361e569d14041188e317384c7baa835ec6d943ff4