Ring Daemon 16.0.0
Loading...
Searching...
No Matches
system_codec_container.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2004-2025 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
36
41
46
47void
49{
50#ifdef ENABLE_VIDEO
51 auto minH264 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
52 auto maxH264 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
53 auto minH265 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
54 auto maxH265 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
55 auto minVP8 = SystemCodecInfo::DEFAULT_VP8_MIN_QUALITY;
56 auto maxVP8 = SystemCodecInfo::DEFAULT_VP8_MAX_QUALITY;
58#endif
59 availableCodecList_ = {
60#ifdef ENABLE_VIDEO
61 /* Define supported video codec*/
62 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_HEVC,
64 "H.265/HEVC",
65 "H265",
66 "",
69 minH265,
70 maxH265),
71
72 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H264,
74 "H.264/AVC",
75 "H264",
76 "libx264",
79 minH264,
80 maxH264),
81
82 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_VP8,
84 "VP8",
85 "VP8",
86 "libvpx",
89 minVP8,
90 maxVP8),
91#if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS)
92 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_MPEG4,
94 "MP4V-ES",
95 "MP4V-ES",
96 "mpeg4",
99
100 std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H263,
102 "H.263",
103 "H263-1998",
104 "h263",
107#endif
108
109#endif
110 /* Define supported audio codec*/
111
112 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_OPUS,
114 "Opus",
115 "opus",
116 "libopus",
118 0,
119 48000,
120 2,
121 104,
123
124 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G722,
126 "G.722",
127 "G722",
128 "g722",
130 0,
131 16000,
132 1,
133 9),
134
135 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G726,
137 "G.726",
138 "G726-32",
139 "g726",
141 0,
142 8000,
143 1,
144 2),
145
146 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x20000000,
148 "Speex",
149 "speex",
150 "libspeex",
152 0,
153 32000,
154 1,
155 112),
156
157 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x10000000,
159 "Speex",
160 "speex",
161 "libspeex",
163 0,
164 16000,
165 1,
166 111),
167
168 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX,
170 "Speex",
171 "speex",
172 "libspeex",
174 0,
175 8000,
176 1,
177 110),
178
179 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_ALAW,
181 "G.711a",
182 "PCMA",
183 "pcm_alaw",
185 64,
186 8000,
187 1,
188 8),
189
190 std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_MULAW,
192 "G.711u",
193 "PCMU",
194 "pcm_mulaw",
196 64,
197 8000,
198 1,
199 0),
200 };
201 setActiveH265();
202 checkInstalledCodecs();
203}
204
205bool
206SystemCodecContainer::setActiveH265()
207{
208#if (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
209 removeCodecByName("H265");
210 return false;
211#endif
212
214 if (apiName != "") {
215 JAMI_WARN("Found a usable accelerated H265/HEVC codec: %s, enabling.", apiName.c_str());
216 return true;
217 } else {
218 JAMI_ERR("Unable to find a usable accelerated H265/HEVC codec, disabling.");
219 removeCodecByName("H265");
220 }
221 return false;
222}
223
224void
225SystemCodecContainer::checkInstalledCodecs()
226{
227 std::ostringstream enc_ss;
228 std::ostringstream dec_ss;
229
230 for (const auto& codecIt : availableCodecList_) {
231 AVCodecID codecId = (AVCodecID) codecIt->avcodecId;
232 CodecType codecType = codecIt->codecType;
233
234 if (codecType & CODEC_ENCODER) {
235 if (avcodec_find_encoder(codecId) != nullptr)
236 enc_ss << codecIt->name << ' ';
237 else
238 codecIt->codecType = (CodecType)((unsigned) codecType & ~CODEC_ENCODER);
239 }
240
241 if (codecType & CODEC_DECODER) {
242 if (avcodec_find_decoder(codecId) != nullptr)
243 dec_ss << codecIt->name << ' ';
244 else
245 codecIt->codecType = (CodecType)((unsigned) codecType & ~CODEC_DECODER);
246 }
247 }
248 JAMI_INFO("Encoder(s) found: %s", enc_ss.str().c_str());
249 JAMI_INFO("Decoder(s) found: %s", dec_ss.str().c_str());
250}
251
252std::vector<std::shared_ptr<SystemCodecInfo>>
254{
255 if (mediaType & MEDIA_ALL)
256 return availableCodecList_;
257
258 // otherwise we have to instantiate a new list containing filtered objects
259 // must be destroyed by the caller…
260 std::vector<std::shared_ptr<SystemCodecInfo>> systemCodecList;
261 for (const auto& codecIt : availableCodecList_) {
262 if (codecIt->mediaType & mediaType)
263 systemCodecList.push_back(codecIt);
264 }
265 return systemCodecList;
266}
267
268std::vector<unsigned>
270{
271 std::vector<unsigned> idList;
272 for (const auto& codecIt : availableCodecList_) {
273 if (codecIt->mediaType & mediaType)
274 idList.push_back(codecIt->id);
275 }
276 return idList;
277}
278
279std::shared_ptr<SystemCodecInfo>
281{
282 for (const auto& codecIt : availableCodecList_) {
283 if ((codecIt->id == codecId) && (codecIt->mediaType & mediaType))
284 return codecIt;
285 }
286 return {};
287}
288std::shared_ptr<SystemCodecInfo>
289SystemCodecContainer::searchCodecByName(const std::string& name, MediaType mediaType)
290{
291 for (const auto& codecIt : availableCodecList_) {
292 if (codecIt->name == name && (codecIt->mediaType & mediaType))
293 return codecIt;
294 }
295 return {};
296}
297std::shared_ptr<SystemCodecInfo>
299{
300 for (const auto& codecIt : availableCodecList_) {
301 if ((codecIt->payloadType == payload) && (codecIt->mediaType & mediaType))
302 return codecIt;
303 }
304 return {};
305}
306void
307SystemCodecContainer::removeCodecByName(const std::string& name, MediaType mediaType)
308{
309 for (auto codecIt = availableCodecList_.begin(); codecIt != availableCodecList_.end();
310 ++codecIt) {
311 if ((*codecIt)->mediaType & mediaType and (*codecIt)->name == name) {
312 availableCodecList_.erase(codecIt);
313 break;
314 }
315 }
316}
317
318} // 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_ERR(...)
Definition logger.h:218
#define JAMI_WARN(...)
Definition logger.h:217
#define JAMI_INFO(...)
Definition logger.h:215
decltype(getGlobalInstance< SystemCodecContainer >) & getSystemCodecContainer
void emitSignal(Args... args)
Definition ring_signal.h:64
@ CODEC_ENCODER
Definition media_codec.h:40
@ CODEC_ENCODER_DECODER
Definition media_codec.h:42
@ CODEC_DECODER
Definition media_codec.h:41
@ MEDIA_ALL
Definition media_codec.h:49
static constexpr unsigned DEFAULT_VIDEO_BITRATE
Definition media_codec.h:74