9#include "libvpxencoder_p.h"
15#include <libavcodec/avcodec.h>
16#include <libavfilter/buffersink.h>
17#include <libavfilter/buffersrc.h>
18#include <libavutil/pixfmt.h>
21#include "logging_record.h"
23LibVpxEncoder::LibVpxEncoder(PipeWireProduce *produce)
24 : SoftwareEncoder(produce)
28bool LibVpxEncoder::initialize(
const QSize &size)
30 createFilterGraph(size);
32 auto codec = avcodec_find_encoder_by_name(
"libvpx");
34 qCWarning(PIPEWIRERECORD_LOGGING) <<
"libvpx codec not found";
38 m_avCodecContext = avcodec_alloc_context3(codec);
39 if (!m_avCodecContext) {
40 qCWarning(PIPEWIRERECORD_LOGGING) <<
"Could not allocate video codec context";
43 m_avCodecContext->bit_rate = size.
width() * size.
height() * 2;
46 m_avCodecContext->width = size.
width();
47 m_avCodecContext->height = size.
height();
48 m_avCodecContext->max_b_frames = 0;
49 m_avCodecContext->gop_size = 100;
50 m_avCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
51 m_avCodecContext->time_base = AVRational{1, 1000};
52 m_avCodecContext->global_quality = 35;
55 m_avCodecContext->global_quality = percentageToAbsoluteQuality(m_quality);
57 m_avCodecContext->global_quality = 35;
60 AVDictionary *options =
nullptr;
61 applyEncodingPreference(options);
63 if (
int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
64 qCWarning(PIPEWIRERECORD_LOGGING) <<
"Could not open codec" << av_err2str(result);
71int LibVpxEncoder::percentageToAbsoluteQuality(
const std::optional<quint8> &quality)
77 constexpr int MinQuality = 63;
78 return std::max(1,
int(MinQuality - (m_quality.value() / 100.0) * MinQuality));
81void LibVpxEncoder::applyEncodingPreference(AVDictionary *options)
84 av_dict_set(&options,
"preset",
"veryfast", 0);
85 av_dict_set(&options,
"tune-content",
"screen", 0);
86 av_dict_set(&options,
"deadline",
"realtime", 0);
90 av_dict_set(&options,
"flags",
"+mv4", 0);
92 av_dict_set(&options,
"-flags",
"+loop", 0);
93 av_dict_set(&options,
"crf",
"45", 0);
bool isEmpty() const const