10#include "libopenh264encoder_p.h"
16#include <libavcodec/avcodec.h>
17#include <libavfilter/buffersink.h>
18#include <libavfilter/buffersrc.h>
19#include <libavutil/pixfmt.h>
22#include "logging_record.h"
24LibOpenH264Encoder::LibOpenH264Encoder(H264Profile profile, PipeWireProduce *produce)
25 : SoftwareEncoder(produce)
30bool LibOpenH264Encoder::initialize(
const QSize &size)
32 createFilterGraph(size);
34 auto codec = avcodec_find_encoder_by_name(
"libopenh264");
36 qCWarning(PIPEWIRERECORD_LOGGING) <<
"libopenh264 codec not found";
40 m_avCodecContext = avcodec_alloc_context3(codec);
41 if (!m_avCodecContext) {
42 qCWarning(PIPEWIRERECORD_LOGGING) <<
"Could not allocate video codec context";
47 m_avCodecContext->width = size.
width();
48 m_avCodecContext->height = size.
height();
49 m_avCodecContext->max_b_frames = 0;
50 m_avCodecContext->gop_size = 100;
51 m_avCodecContext->pix_fmt = AV_PIX_FMT_YUV420P;
52 m_avCodecContext->time_base = AVRational{1, 1000};
56 m_avCodecContext->qmin = m_avCodecContext->qmax = percentageToAbsoluteQuality(m_quality);
60 case H264Profile::Baseline:
67 m_avCodecContext->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;
69 case H264Profile::Main:
70 m_avCodecContext->profile = FF_PROFILE_H264_MAIN;
72 case H264Profile::High:
73 m_avCodecContext->profile = FF_PROFILE_H264_HIGH;
77 AVDictionary *options =
nullptr;
79 applyEncodingPreference(options);
81 if (
int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
82 qCWarning(PIPEWIRERECORD_LOGGING) <<
"Could not open codec" << av_err2str(result);
89int LibOpenH264Encoder::percentageToAbsoluteQuality(
const std::optional<quint8> &quality)
96 return 51 - (m_quality.value() / 100.0) * 50;
99void LibOpenH264Encoder::applyEncodingPreference(AVDictionary *options)
101 SoftwareEncoder::applyEncodingPreference(options);
103 av_dict_set(&options,
"flags",
"+mv4", 0);
105 av_dict_set_int(&options,
"loopfilter", 0, 0);
bool isEmpty() const const