KPipewire

gifencoder.cpp
1/*
2 SPDX-FileCopyrightText: 2023 Aleix Pol Gonzalez <aleixpol@kde.org>
3 SPDX-FileCopyrightText: 2023 Marco Martin <mart@kde.org>
4 SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
5 SPDX-FileCopyrightText: 2024 Noah Davis <noahadvs@gmail.com>
6
7 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8*/
9
10#include "gifencoder_p.h"
11
12#include "pipewireproduce_p.h"
13
14#include <QSize>
15#include <QThread>
16
17extern "C" {
18#include <libavcodec/avcodec.h>
19#include <libavfilter/buffersink.h>
20#include <libavfilter/buffersrc.h>
21#include <libavutil/pixfmt.h>
22}
23
24#include "logging_record.h"
25
26using namespace Qt::StringLiterals;
27
28GifEncoder::GifEncoder(PipeWireProduce *produce)
29 : SoftwareEncoder(produce)
30{
31}
32
33bool GifEncoder::initialize(const QSize &size)
34{
35 m_filterGraphToParse = u"split[v1][v2];[v1]palettegen=stats_mode=single[palette];[v2][palette]paletteuse=new=1:dither=sierra2_4a"_s;
36 createFilterGraph(size);
37
38 auto codec = avcodec_find_encoder_by_name("gif");
39 if (!codec) {
40 qCWarning(PIPEWIRERECORD_LOGGING) << "gif codec not found";
41 return false;
42 }
43
44 m_avCodecContext = avcodec_alloc_context3(codec);
45 if (!m_avCodecContext) {
46 qCWarning(PIPEWIRERECORD_LOGGING) << "Could not allocate video codec context";
47 return false;
48 }
49
50 Q_ASSERT(!size.isEmpty());
51 m_avCodecContext->width = size.width();
52 m_avCodecContext->height = size.height();
53 m_avCodecContext->pix_fmt = AV_PIX_FMT_PAL8;
54 m_avCodecContext->time_base = AVRational{1, 1000};
55
56 AVDictionary *options = nullptr;
57
58 applyEncodingPreference(options);
59
60 if (int result = avcodec_open2(m_avCodecContext, codec, &options); result < 0) {
61 qCWarning(PIPEWIRERECORD_LOGGING) << "Could not open codec" << av_err2str(result);
62 return false;
63 }
64
65 return true;
66}
67
68std::pair<int, int> GifEncoder::encodeFrame(int maximumFrames)
69{
70 auto level = av_log_get_level();
71 // Gif encoder spams the console when generating palettes unless you do this.
72 av_log_set_level(AV_LOG_ERROR);
73 auto ret = SoftwareEncoder::encodeFrame(maximumFrames);
74 av_log_set_level(level);
75 return ret;
76}
77
78int GifEncoder::percentageToAbsoluteQuality([[maybe_unused]] const std::optional<quint8> &quality)
79{
80 return -1; // Not possible to set quality
81}
82
83void GifEncoder::applyEncodingPreference([[maybe_unused]] AVDictionary *options)
84{
85}
QStringView level(QStringView ifopt)
int height() const const
bool isEmpty() const const
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:05:20 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.