6.1.4
This commit is contained in:
parent
a2b22cb733
commit
6159104671
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
|
||||
|
@ -1,105 +0,0 @@
|
||||
From 0c3f8b4f9de7d4dcd24d952184dabdbda74b4c35 Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||
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<Encoder> 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<H264VAAPIEncoder>(profile, this);
|
||||
hardwareEncoder->setQuality(m_quality);
|
||||
hardwareEncoder->setEncodingPreference(m_encodingPreference);
|
||||
@@ -314,7 +287,7 @@ std::unique_ptr<Encoder> PipeWireProduce::makeEncoder()
|
||||
}
|
||||
}
|
||||
|
||||
- if (!forceHardware) {
|
||||
+ if (forcedEncoder.isNull() || forcedEncoder == u"libx264") {
|
||||
auto softwareEncoder = std::make_unique<LibX264Encoder>(profile, this);
|
||||
softwareEncoder->setQuality(m_quality);
|
||||
softwareEncoder->setEncodingPreference(m_encodingPreference);
|
||||
@@ -325,7 +298,7 @@ std::unique_ptr<Encoder> PipeWireProduce::makeEncoder()
|
||||
break;
|
||||
}
|
||||
case PipeWireBaseEncodedStream::VP8: {
|
||||
- if (!forceHardware) {
|
||||
+ if (forcedEncoder.isNull() || forcedEncoder == u"libvpx") {
|
||||
auto encoder = std::make_unique<LibVpxEncoder>(this);
|
||||
encoder->setQuality(m_quality);
|
||||
if (encoder->initialize(size)) {
|
||||
@@ -335,7 +308,7 @@ std::unique_ptr<Encoder> PipeWireProduce::makeEncoder()
|
||||
break;
|
||||
}
|
||||
case PipeWireBaseEncodedStream::VP9: {
|
||||
- if (!forceHardware) {
|
||||
+ if (forcedEncoder.isNull() || forcedEncoder == u"libvpx-vp9") {
|
||||
auto encoder = std::make_unique<LibVpxVp9Encoder>(this);
|
||||
encoder->setQuality(m_quality);
|
||||
if (encoder->initialize(size)) {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,222 +0,0 @@
|
||||
From e17793a3b023f26411001093bb2d5934adf715c7 Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||
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 <aleixpol@kde.org>
|
||||
+ SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
|
||||
+ SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
|
||||
+ SPDX-FileCopyrightText: 2024 Fabian Vogt <fabian@ritter-vogt.de>
|
||||
+
|
||||
+ SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
+*/
|
||||
+
|
||||
+#include "libopenh264encoder_p.h"
|
||||
+
|
||||
+#include <QSize>
|
||||
+#include <QThread>
|
||||
+
|
||||
+extern "C" {
|
||||
+#include <libavcodec/avcodec.h>
|
||||
+#include <libavfilter/buffersink.h>
|
||||
+#include <libavfilter/buffersrc.h>
|
||||
+#include <libavutil/pixfmt.h>
|
||||
+}
|
||||
+
|
||||
+#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<quint8> &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 <aleixpol@kde.org>
|
||||
+ SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
|
||||
+ SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
|
||||
+ SPDX-FileCopyrightText: 2024 Fabian Vogt <fabian@ritter-vogt.de>
|
||||
+
|
||||
+ 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<quint8> &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::Encoder> 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 <qstringliteral.h>
|
||||
|
||||
#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<Encoder> 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<LibOpenH264Encoder>(profile, this);
|
||||
+ softwareEncoder->setQuality(m_quality);
|
||||
+ softwareEncoder->setEncodingPreference(m_encodingPreference);
|
||||
+ if (softwareEncoder->initialize(size)) {
|
||||
+ return softwareEncoder;
|
||||
+ }
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
case PipeWireBaseEncodedStream::VP8: {
|
||||
--
|
||||
2.45.2
|
||||
|
@ -1,54 +0,0 @@
|
||||
From c7d88d028ea1e5aa4ed1729fd987c7e1c0517faa Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fabian@ritter-vogt.de>
|
||||
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<quint8> &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<quint8> &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
|
||||
|
@ -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 <farchord@gmail.com> - 6.1.4-1
|
||||
- 6.1.4
|
||||
|
||||
* Wed Jul 24 2024 Marc Deop i Argemí <marcdeop@fedoraproject.org> - 6.1.3-3
|
||||
- rebuilt
|
||||
|
||||
|
2
sources
2
sources
@ -1 +1 @@
|
||||
SHA512 (kpipewire-6.1.3.tar.xz) = d2b1971ca7970a61da700b7f5004e045dfc0535a28ce6bb9be590a2122e0af8b82ec44513f78190e2e6ca9424d389ce11332e7b9031d74c113525e14d1c0bdcb
|
||||
SHA512 (kpipewire-6.1.4.tar.xz) = e247709e2f89ac3bc55ca3cda78024d39b608c0be09453dcbabe441b247e7b8a54ad8c9ef0ba52a5d9e01b3361e569d14041188e317384c7baa835ec6d943ff4
|
||||
|
Loading…
Reference in New Issue
Block a user