From d2046b49f6f98913bbe07711720bdf4388888bfb0d383232e31ac49c3accdd01 Mon Sep 17 00:00:00 2001 From: Christophe Marin Date: Tue, 16 Jul 2024 17:34:19 +0000 Subject: [PATCH] Plasma 6.1.3 OBS-URL: https://build.opensuse.org/package/show/KDE:Frameworks/kpipewire6?expand=0&rev=19 --- ...-useful-handling-of-KPIPEWIRE_FORCE_.patch | 107 +++++++++ 0002-Add-encoder-using-libopenh264.patch | 223 ++++++++++++++++++ kpipewire-6.1.2.tar.xz | 3 - kpipewire-6.1.2.tar.xz.sig | 16 -- kpipewire-6.1.3.tar.xz | 3 + kpipewire-6.1.3.tar.xz.sig | 16 ++ kpipewire6.changes | 19 ++ kpipewire6.spec | 5 +- 8 files changed, 372 insertions(+), 20 deletions(-) create mode 100644 0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch create mode 100644 0002-Add-encoder-using-libopenh264.patch delete mode 100644 kpipewire-6.1.2.tar.xz delete mode 100644 kpipewire-6.1.2.tar.xz.sig create mode 100644 kpipewire-6.1.3.tar.xz create mode 100644 kpipewire-6.1.3.tar.xz.sig diff --git a/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch b/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch new file mode 100644 index 0000000..5f15b08 --- /dev/null +++ b/0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch @@ -0,0 +1,107 @@ +From a50c28da704fbf8b9e71ec92054f325a33b9765f Mon Sep 17 00:00:00 2001 +From: Fabian Vogt +Date: Sat, 6 Jul 2024 16:27:28 +0200 +Subject: [PATCH 1/2] 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. + +(cherry picked from commit 0c3f8b4f9de7d4dcd24d952184dabdbda74b4c35) +--- + 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 new file mode 100644 index 0000000..f7ca058 --- /dev/null +++ b/0002-Add-encoder-using-libopenh264.patch @@ -0,0 +1,223 @@ +From 43ab595c28e031f38bc92bea4cf475de64021958 Mon Sep 17 00:00:00 2001 +From: Fabian Vogt +Date: Sat, 6 Jul 2024 16:40:42 +0200 +Subject: [PATCH 2/2] 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 +(cherry picked from commit e17793a3b023f26411001093bb2d5934adf715c7) +--- + 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/kpipewire-6.1.2.tar.xz b/kpipewire-6.1.2.tar.xz deleted file mode 100644 index d528a72..0000000 --- a/kpipewire-6.1.2.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:250f505d723fb71fdfb5af5f89e4f878f632c534fb2b01ba0bbb3ac19170d571 -size 148220 diff --git a/kpipewire-6.1.2.tar.xz.sig b/kpipewire-6.1.2.tar.xz.sig deleted file mode 100644 index eea2450..0000000 --- a/kpipewire-6.1.2.tar.xz.sig +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCgAdFiEE4KPrIC+OV1KOE+cv11dEg7tXsY0FAmaDxI8ACgkQ11dEg7tX -sY21PA/9HMpwLbpVc5d0ZvdfHnaHhbvnN4foiRYEa22CCarhP7BWRjUjGaRHeqAv -DVfspp/zg6hHcXTYg0RuLmcsmAeDp3W7tCK8fyU3+XnWwhsqG+NnmFdNR7LNZGgG -L9ZHCINl63a5ZL/D7/TRmGpL4YTtitsMzPwZ6dQmjOStpUaPoJTelhzAROFPU0Ac -jbGyaV4M4dmBzthtKEsmCsDSgphPcNP47EJpJtHoYqPNLO/g0OpEGIzg0JJxe/2/ -iobqFYU1WJvfSkAsFw3ubz/FF7r/8RycuzquVksoiNY1tLzP+oqUbw1xw2iJDHY2 -y5DBBRoEUQxwg/Be1vfH9H7LYaX561vU1Gik9GYJgPA1SEPhCBCjI3cmJW5AMLuk -EiP2TxM+BSuP5/Jcbt8JNGdfuDlezrDJKHinYt5Eh7IhV9zxLk3Ac7WVaXfHYFgO -b1dOE21C5FTb2VbLn+MbYValy0CR3k49jPM+c9lCX/WjqX3wEoGCISNTbPAtRuge -OyByv/KQx0onmOCrZsAKYxWy6dN8A0z5W+tt7PUm9n1eSMKZL7js4D1o2Xb/KfJn -W8DObXf2puLBY3sDR3kuMySEyhOn5h5OgLKTs6jOBRc6h/CuiCJuoMA9GroxmGto -a+lzcrnpoh2nrg/Dfi+PvJfUqUq8FLu4mWEGussJJC9jMrWF7kA= -=CGqa ------END PGP SIGNATURE----- diff --git a/kpipewire-6.1.3.tar.xz b/kpipewire-6.1.3.tar.xz new file mode 100644 index 0000000..aeaa567 --- /dev/null +++ b/kpipewire-6.1.3.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb2217024e3bf3a4777548b9a0bda88ca0b97912d20336b03f5942b28b1baef9 +size 148504 diff --git a/kpipewire-6.1.3.tar.xz.sig b/kpipewire-6.1.3.tar.xz.sig new file mode 100644 index 0000000..d49c963 --- /dev/null +++ b/kpipewire-6.1.3.tar.xz.sig @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEE4KPrIC+OV1KOE+cv11dEg7tXsY0FAmaWVKcACgkQ11dEg7tX +sY0bnA/9FAl4Ym/986mF3V5rW/z7SACdBUSd/PivMDigDVRedzYuAe2oR87e2paO +UO51vAEGjXZEeNk9X2jUd/nYXda/EtwjWHMxxHsnzgb5kpIvA7vZ+9tE5FCNUbRy +9EWMf2OId/INCsSh6RH6iLmiuoUa7jtdJ2cAvx5AxSGfYxjHj3YAoWk77zDAxhy4 +bZzY0+5fgYCcT8xbSUeGiRscXIw/G6Q8boOOqACyeJCD7mESOB4BtziF6RL4r05i +EBMeuutUDTK1//bu6Y4MaEKx1bPrawR6RQeFocW4Pgp2hKiPTRuWMy8e+7OjTvb1 +cfQlEqOEVtyWKAD5uSCCif+yCqdFkSXXpo9vNXpKjBnMlyXASFLM7jN8TIm7HcQo +FqPaHstaOaOOQ33om5PjLsSNEzV/MSv2SQ6aA0CbglJxBm5okfLuYb/Vuaid4iPD +LV5eySGagfmI+LS/SGUTbNC499+cFCnWB0XziYbbW0mxQWfBe25Yxk4LXMzSYFIH +WZE3MUgKbPRrRL4/VGdrD2eBGCt7p2xlLEdmTSVJ0AIHfKoaIC8hmDoy3N8L8S7Q +IS9Qf95EASBc0/aDbY7o1JQuKjR8VnDvE8ooBtBnW9sObnDSJhWYpi8fOr1ZhWvW +RKDnX/B6rWkIVqG7rZLUcpXwrnQjAdnO5B3NAwn7Eo7/vt0OFdY= +=9kTE +-----END PGP SIGNATURE----- diff --git a/kpipewire6.changes b/kpipewire6.changes index f1aec0b..db6b5e8 100644 --- a/kpipewire6.changes +++ b/kpipewire6.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Tue Jul 16 13:35:56 UTC 2024 - Fabian Vogt + +- Add patches to support libopenh264 for encoding + (boo#1227461, kde#476187): + * 0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch + * 0002-Add-encoder-using-libopenh264.patch + +------------------------------------------------------------------- +Tue Jul 16 13:23:41 UTC 2024 - Fabian Vogt + +- Update to 6.1.3: + * New bugfix release + * For more details see https://kde.org/announcements/plasma/6/6.1.3 +- Changes since 6.1.2: + * produce: Properly cleanup on deactivate in all cases (kde#488687) + * produce: Destroy PipeWireSourceStream on the right thread (kde#489434) + * update version for new release + ------------------------------------------------------------------- Tue Jul 2 17:34:03 UTC 2024 - Fabian Vogt diff --git a/kpipewire6.spec b/kpipewire6.spec index 7fac80f..99a121c 100644 --- a/kpipewire6.spec +++ b/kpipewire6.spec @@ -27,7 +27,7 @@ %{!?_plasma6_version: %define _plasma6_version %(echo %{_plasma6_bugfix} | awk -F. '{print $1"."$2}')} %bcond_without released Name: kpipewire6 -Version: 6.1.2 +Version: 6.1.3 Release: 0 Summary: PipeWire integration for KDE Plasma License: LGPL-2.0-only AND LGPL-3.0-only @@ -37,6 +37,9 @@ Source: https://download.kde.org/stable/plasma/%{version}/%{rname}-%{ver Source1: https://download.kde.org/stable/plasma/%{version}/%{rname}-%{version}.tar.xz.sig Source2: plasma.keyring %endif +# PATCH-FEATURE-UPSTREAM +Patch1: 0001-Simpler-yet-more-useful-handling-of-KPIPEWIRE_FORCE_.patch +Patch2: 0002-Add-encoder-using-libopenh264.patch BuildRequires: kf6-extra-cmake-modules BuildRequires: pkgconfig BuildRequires: qt6-gui-private-devel >= %{qt6_version}