Ring Daemon
Loading...
Searching...
No Matches
system_codec_container.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2026 Savoir-faire Linux Inc.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "libav_deps.h" // MUST BE INCLUDED FIRST
19#ifdef HAVE_CONFIG_H
20#include "config.h"
21#endif
22#include "logger.h"
24#include "media_encoder.h"
25
26#include <sstream>
27
28#ifdef APPLE
29#include <TargetConditionals.h>
30#endif
31
32namespace jami {
33
35
40
45
46void
48{
49#ifdef ENABLE_VIDEO
50 auto minH264 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
51 auto maxH264 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
52 auto minH265 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
53 auto maxH265 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
54 auto minVP8 = SystemCodecInfo::DEFAULT_VP8_MIN_QUALITY;
55 auto maxVP8 = SystemCodecInfo::DEFAULT_VP8_MAX_QUALITY;
57#endif
58 availableCodecList_ = {
59#ifdef ENABLE_VIDEO
60 /* Define supported video codec*/
61 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_HEVC,
63 "H.265/HEVC",
64 "H265",
65 "",
68 minH265,
69 maxH265),
70
71 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H264,
73 "H.264/AVC",
74 "H264",
75 "libx264",
78 minH264,
79 maxH264),
80
81 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_VP8,
83 "VP8",
84 "VP8",
85 "libvpx",
88 minVP8,
89 maxVP8),
90#if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS)
91 std::make_shared<SystemVideoCodecInfo>(
93
94 std::make_shared<SystemVideoCodecInfo>(
96#endif
97
98#endif
99 /* Define supported audio codec*/
100
101 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_OPUS,
103 "Opus",
104 "opus",
105 "libopus",
107 0,
108 48000,
109 2,
110 104,
112
113 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G722,
115 "G.722",
116 "G722",
117 "g722",
119 0,
120 16000,
121 1,
122 9),
123
124 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G726,
126 "G.726",
127 "G726-32",
128 "g726",
130 0,
131 8000,
132 1,
133 2),
134
135 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x20000000,
137 "Speex",
138 "speex",
139 "libspeex",
141 0,
142 32000,
143 1,
144 112),
145
146 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x10000000,
148 "Speex",
149 "speex",
150 "libspeex",
152 0,
153 16000,
154 1,
155 111),
156
157 std::make_shared<SystemAudioCodecInfo>(
158 AV_CODEC_ID_SPEEX, AV_CODEC_ID_SPEEX, "Speex", "speex", "libspeex", CODEC_ENCODER_DECODER, 0, 8000, 1, 110),
159
160 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_ALAW,
162 "G.711a",
163 "PCMA",
164 "pcm_alaw",
166 64,
167 8000,
168 1,
169 8),
170
171 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_MULAW,
173 "G.711u",
174 "PCMU",
175 "pcm_mulaw",
177 64,
178 8000,
179 1,
180 0),
181 };
182 setActiveH265();
183 checkInstalledCodecs();
184}
185
186bool
187SystemCodecContainer::setActiveH265()
188{
189#if (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
190 removeCodecByName("H265");
191 return false;
192#endif
193
195 if (apiName != "") {
196 JAMI_WARNING("Found a usable accelerated H265/HEVC codec: {}, enabling.", apiName);
197 return true;
198 } else {
199 JAMI_WARNING("Unable to find a usable accelerated H265/HEVC codec, disabling.");
200 removeCodecByName("H265");
201 }
202 return false;
203}
204
205void
206SystemCodecContainer::checkInstalledCodecs()
207{
208 std::ostringstream enc_ss;
209 std::ostringstream dec_ss;
210
211 for (const auto& codecIt : availableCodecList_) {
212 AVCodecID codecId = (AVCodecID) codecIt->avcodecId;
213 CodecType codecType = codecIt->codecType;
214
215 if (codecType & CODEC_ENCODER) {
216 if (avcodec_find_encoder(codecId) != nullptr)
217 enc_ss << codecIt->name << ' ';
218 else
219 codecIt->codecType = (CodecType) ((unsigned) codecType & ~CODEC_ENCODER);
220 }
221
222 if (codecType & CODEC_DECODER) {
223 if (avcodec_find_decoder(codecId) != nullptr)
224 dec_ss << codecIt->name << ' ';
225 else
226 codecIt->codecType = (CodecType) ((unsigned) codecType & ~CODEC_DECODER);
227 }
228 }
229 JAMI_INFO("Encoder(s) found: %s", enc_ss.str().c_str());
230 JAMI_INFO("Decoder(s) found: %s", dec_ss.str().c_str());
231}
232
233std::vector<std::shared_ptr<SystemCodecInfo>>
235{
236 if (mediaType & MEDIA_ALL)
237 return availableCodecList_;
238
239 // otherwise we have to instantiate a new list containing filtered objects
240 // must be destroyed by the caller…
241 std::vector<std::shared_ptr<SystemCodecInfo>> systemCodecList;
242 for (const auto& codecIt : availableCodecList_) {
243 if (codecIt->mediaType & mediaType)
244 systemCodecList.push_back(codecIt);
245 }
246 return systemCodecList;
247}
248
249std::vector<unsigned>
251{
252 std::vector<unsigned> idList;
253 for (const auto& codecIt : availableCodecList_) {
254 if (codecIt->mediaType & mediaType)
255 idList.push_back(codecIt->id);
256 }
257 return idList;
258}
259
260std::shared_ptr<SystemCodecInfo>
262{
263 for (const auto& codecIt : availableCodecList_) {
264 if ((codecIt->id == codecId) && (codecIt->mediaType & mediaType))
265 return codecIt;
266 }
267 return {};
268}
269std::shared_ptr<SystemCodecInfo>
270SystemCodecContainer::searchCodecByName(const std::string& name, MediaType mediaType)
271{
272 for (const auto& codecIt : availableCodecList_) {
273 if (codecIt->name == name && (codecIt->mediaType & mediaType))
274 return codecIt;
275 }
276 return {};
277}
278std::shared_ptr<SystemCodecInfo>
280{
281 for (const auto& codecIt : availableCodecList_) {
282 if ((codecIt->payloadType == payload) && (codecIt->mediaType & mediaType))
283 return codecIt;
284 }
285 return {};
286}
287void
288SystemCodecContainer::removeCodecByName(const std::string& name, MediaType mediaType)
289{
290 for (auto codecIt = availableCodecList_.begin(); codecIt != availableCodecList_.end(); ++codecIt) {
291 if ((*codecIt)->mediaType & mediaType and (*codecIt)->name == name) {
292 availableCodecList_.erase(codecIt);
293 break;
294 }
295 }
296}
297
298} // namespace jami
static std::string testH265Accel()
std::shared_ptr< SystemCodecInfo > searchCodecByPayload(unsigned payload, MediaType type=MEDIA_ALL)
void removeCodecByName(const std::string &name, MediaType type=MEDIA_ALL)
std::vector< std::shared_ptr< SystemCodecInfo > > getSystemCodecInfoList(MediaType mediaType=MEDIA_ALL)
std::vector< unsigned > getSystemCodecInfoIdList(MediaType type=MEDIA_ALL)
std::shared_ptr< SystemCodecInfo > searchCodecById(unsigned codecId, MediaType type=MEDIA_ALL)
std::shared_ptr< SystemCodecInfo > searchCodecByName(const std::string &name, MediaType type=MEDIA_ALL)
#define JAMI_WARNING(formatstr,...)
Definition logger.h:242
#define JAMI_INFO(...)
Definition logger.h:227
decltype(getGlobalInstance< SystemCodecContainer >) & getSystemCodecContainer
void emitSignal(Args... args)
Definition jami_signal.h:64
@ CODEC_ENCODER
Definition media_codec.h:39
@ CODEC_ENCODER_DECODER
Definition media_codec.h:41
@ CODEC_DECODER
Definition media_codec.h:40
@ MEDIA_ALL
Definition media_codec.h:48
static constexpr unsigned DEFAULT_VIDEO_BITRATE
Definition media_codec.h:73