m_encodingPreference = preference;
}
-void Encoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *Encoder::buildEncodingOptions()
{
+ AVDictionary *options = NULL;
+
switch (m_encodingPreference) {
case PipeWireBaseEncodedStream::EncodingPreference::NoPreference:
av_dict_set(&options, "preset", "veryfast", 0);
av_dict_set(&options, "preset", "veryfast", 0);
break;
}
+
+ return options;
}
SoftwareEncoder::SoftwareEncoder(PipeWireProduce *produce)
protected:
virtual int percentageToAbsoluteQuality(const std::optional<quint8> &quality) = 0;
+ virtual AVDictionary *buildEncodingOptions();
PipeWireProduce *m_produce;
std::optional<quint8> m_quality;
PipeWireBaseEncodedStream::EncodingPreference m_encodingPreference;
- virtual void applyEncodingPreference(AVDictionary *options);
};
/**
m_avCodecContext->time_base = AVRational{1, 1000};
AVDictionary *options = nullptr;
-
- 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 -1; // Not possible to set quality
}
-
-void GifEncoder::applyEncodingPreference([[maybe_unused]] AVDictionary *options)
-{
-}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
};
break;
}
- AVDictionary *options = nullptr;
- // av_dict_set_int(&options, "threads", qMin(16, QThread::idealThreadCount()), 0);
- applyEncodingPreference(options);
+ AVDictionary *options = buildEncodingOptions();
// Assign the right hardware context for encoding frames.
// We rely on FFmpeg for creating the VAAPI hardware context as part of
return std::max(1, int(MinQuality - (m_quality.value() / 100.0) * MinQuality));
}
-void H264VAAPIEncoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *H264VAAPIEncoder::buildEncodingOptions()
{
- HardwareEncoder::applyEncodingPreference(options);
+ AVDictionary *options = HardwareEncoder::buildEncodingOptions();
// 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(&options, "-flags", "+loop", 0);
+
+ return options;
}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
+ AVDictionary *buildEncodingOptions() override;
private:
H264Profile m_profile = H264Profile::Main;
break;
}
- AVDictionary *options = nullptr;
- av_dict_set_int(&options, "threads", qMin(16, QThread::idealThreadCount()), 0);
- applyEncodingPreference(options);
+ AVDictionary *options = buildEncodingOptions();
if (int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
qCWarning(PIPEWIRERECORD_LOGGING) << "Could not open codec" << av_err2str(result);
return 51 - (m_quality.value() / 100.0) * 50;
}
-void LibOpenH264Encoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *LibOpenH264Encoder::buildEncodingOptions()
{
- SoftwareEncoder::applyEncodingPreference(options);
+ AVDictionary *options = SoftwareEncoder::buildEncodingOptions();
// 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);
+
+ return options;
}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
+ AVDictionary *buildEncodingOptions() override;
private:
H264Profile m_profile = H264Profile::Main;
m_avCodecContext->global_quality = 35;
}
- AVDictionary *options = nullptr;
- applyEncodingPreference(options);
+ AVDictionary *options = buildEncodingOptions();
if (int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
qCWarning(PIPEWIRERECORD_LOGGING) << "Could not open codec" << av_err2str(result);
return std::max(1, int(MinQuality - (m_quality.value() / 100.0) * MinQuality));
}
-void LibVpxEncoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *LibVpxEncoder::buildEncodingOptions()
{
- av_dict_set_int(&options, "threads", qMin(16, QThread::idealThreadCount()), 0);
+ AVDictionary *options = SoftwareEncoder::buildEncodingOptions();
+
av_dict_set(&options, "preset", "veryfast", 0);
av_dict_set(&options, "tune-content", "screen", 0);
av_dict_set(&options, "deadline", "realtime", 0);
// Disable in-loop filtering
av_dict_set(&options, "-flags", "+loop", 0);
av_dict_set(&options, "crf", "45", 0);
+
+ return options;
}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
+ AVDictionary *buildEncodingOptions() override;
};
m_avCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
m_avCodecContext->time_base = AVRational{1, 1000};
- AVDictionary *options = nullptr;
-
- applyEncodingPreference(options);
+ AVDictionary *options = buildEncodingOptions();
const auto area = size.width() * size.height();
// m_avCodecContext->framerate is not set, so we use m_produce->maxFramerate() instead.
return std::max(1, int(MinQuality - (m_quality.value() / 100.0) * MinQuality));
}
-void LibVpxVp9Encoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *LibVpxVp9Encoder::buildEncodingOptions()
{
+ AVDictionary *options = SoftwareEncoder::buildEncodingOptions();
+
// We're probably capturing a screen
av_dict_set(&options, "tune-content", "screen", 0);
// This should make things faster, but it only seems to consume 100MB more RAM.
// av_dict_set(&options, "row-mt", "1", 0);
av_dict_set(&options, "frame-parallel", "1", 0);
+
+ return options;
}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
+ AVDictionary *buildEncodingOptions() override;
};
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
};
break;
}
- AVDictionary *options = nullptr;
- av_dict_set_int(&options, "threads", qMin(16, QThread::idealThreadCount()), 0);
- applyEncodingPreference(options);
+ AVDictionary *options = buildEncodingOptions();
if (int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
qCWarning(PIPEWIRERECORD_LOGGING) << "Could not open codec" << av_err2str(result);
return std::max(1, int(MinQuality - (m_quality.value() / 100.0) * MinQuality));
}
-void LibX264Encoder::applyEncodingPreference(AVDictionary *options)
+AVDictionary *LibX264Encoder::buildEncodingOptions()
{
- SoftwareEncoder::applyEncodingPreference(options);
+ AVDictionary *options = SoftwareEncoder::buildEncodingOptions();
+
// 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(&options, "-flags", "+loop", 0);
+
+ return options;
}
protected:
int percentageToAbsoluteQuality(const std::optional<quint8> &quality) override;
- void applyEncodingPreference(AVDictionary *options) override;
+ AVDictionary *buildEncodingOptions() override;
private:
H264Profile m_profile = H264Profile::Main;