LCOV - code coverage report
Current view: top level - src/media - system_codec_container.cpp (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 42.3 % 149 63
Test Date: 2026-06-13 09:18:46 Functions: 65.0 % 20 13

            Line data    Source code
       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"
      23              : #include "system_codec_container.h"
      24              : #include "media_encoder.h"
      25              : 
      26              : #include <sstream>
      27              : 
      28              : #ifdef APPLE
      29              : #include <TargetConditionals.h>
      30              : #endif
      31              : 
      32              : namespace jami {
      33              : 
      34           36 : SystemCodecContainer::SystemCodecContainer() {}
      35              : 
      36           36 : SystemCodecContainer::~SystemCodecContainer() {}
      37              : 
      38              : void
      39           36 : SystemCodecContainer::initCodecConfig()
      40              : {
      41              : #ifdef ENABLE_VIDEO
      42           36 :     auto minH264 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
      43           36 :     auto maxH264 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
      44           36 :     auto minH265 = SystemCodecInfo::DEFAULT_H264_MIN_QUALITY;
      45           36 :     auto maxH265 = SystemCodecInfo::DEFAULT_H264_MAX_QUALITY;
      46           36 :     auto minVP8 = SystemCodecInfo::DEFAULT_VP8_MIN_QUALITY;
      47           36 :     auto maxVP8 = SystemCodecInfo::DEFAULT_VP8_MAX_QUALITY;
      48           36 :     auto defaultBitrate = SystemCodecInfo::DEFAULT_VIDEO_BITRATE;
      49              : #endif
      50          504 :     availableCodecList_ = {
      51              : #ifdef ENABLE_VIDEO
      52              :         /* Define supported video codec*/
      53            0 :         std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_HEVC,
      54            0 :                                                AV_CODEC_ID_HEVC,
      55              :                                                "H.265/HEVC",
      56              :                                                "H265",
      57              :                                                "",
      58            0 :                                                CODEC_ENCODER_DECODER,
      59              :                                                defaultBitrate,
      60              :                                                minH265,
      61              :                                                maxH265),
      62              : 
      63            0 :         std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_H264,
      64            0 :                                                AV_CODEC_ID_H264,
      65              :                                                "H.264/AVC",
      66              :                                                "H264",
      67              :                                                "libx264",
      68           36 :                                                CODEC_ENCODER_DECODER,
      69              :                                                defaultBitrate,
      70              :                                                minH264,
      71              :                                                maxH264),
      72              : 
      73            0 :         std::make_shared<SystemVideoCodecInfo>(AV_CODEC_ID_VP8,
      74            0 :                                                AV_CODEC_ID_VP8,
      75              :                                                "VP8",
      76              :                                                "VP8",
      77              :                                                "libvpx",
      78           36 :                                                CODEC_ENCODER_DECODER,
      79              :                                                defaultBitrate,
      80              :                                                minVP8,
      81              :                                                maxVP8),
      82              : #if !(defined(TARGET_OS_IOS) && TARGET_OS_IOS)
      83            0 :         std::make_shared<SystemVideoCodecInfo>(
      84           36 :             AV_CODEC_ID_MPEG4, AV_CODEC_ID_MPEG4, "MP4V-ES", "MP4V-ES", "mpeg4", CODEC_ENCODER_DECODER, defaultBitrate),
      85              : 
      86            0 :         std::make_shared<SystemVideoCodecInfo>(
      87           36 :             AV_CODEC_ID_H263, AV_CODEC_ID_H263, "H.263", "H263-1998", "h263", CODEC_ENCODER_DECODER, defaultBitrate),
      88              : #endif
      89              : 
      90              : #endif
      91              :         /* Define supported audio codec*/
      92              : 
      93            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_OPUS,
      94            0 :                                                AV_CODEC_ID_OPUS,
      95              :                                                "Opus",
      96              :                                                "opus",
      97              :                                                "libopus",
      98            0 :                                                CODEC_ENCODER_DECODER,
      99            0 :                                                0,
     100            0 :                                                48000,
     101            0 :                                                2,
     102            0 :                                                104,
     103           36 :                                                AV_SAMPLE_FMT_FLT),
     104              : 
     105            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G722,
     106            0 :                                                AV_CODEC_ID_ADPCM_G722,
     107              :                                                "G.722",
     108              :                                                "G722",
     109              :                                                "g722",
     110            0 :                                                CODEC_ENCODER_DECODER,
     111            0 :                                                0,
     112            0 :                                                16000,
     113            0 :                                                1,
     114           36 :                                                9),
     115              : 
     116            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_ADPCM_G726,
     117            0 :                                                AV_CODEC_ID_ADPCM_G726,
     118              :                                                "G.726",
     119              :                                                "G726-32",
     120              :                                                "g726",
     121            0 :                                                CODEC_ENCODER_DECODER,
     122            0 :                                                0,
     123            0 :                                                8000,
     124            0 :                                                1,
     125           36 :                                                2),
     126              : 
     127            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x20000000,
     128            0 :                                                AV_CODEC_ID_SPEEX,
     129              :                                                "Speex",
     130              :                                                "speex",
     131              :                                                "libspeex",
     132            0 :                                                CODEC_ENCODER_DECODER,
     133            0 :                                                0,
     134            0 :                                                32000,
     135            0 :                                                1,
     136           36 :                                                112),
     137              : 
     138            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_SPEEX | 0x10000000,
     139            0 :                                                AV_CODEC_ID_SPEEX,
     140              :                                                "Speex",
     141              :                                                "speex",
     142              :                                                "libspeex",
     143            0 :                                                CODEC_ENCODER_DECODER,
     144            0 :                                                0,
     145            0 :                                                16000,
     146            0 :                                                1,
     147           36 :                                                111),
     148              : 
     149            0 :         std::make_shared<SystemAudioCodecInfo>(
     150           36 :             AV_CODEC_ID_SPEEX, AV_CODEC_ID_SPEEX, "Speex", "speex", "libspeex", CODEC_ENCODER_DECODER, 0, 8000, 1, 110),
     151              : 
     152            0 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_ALAW,
     153            0 :                                                AV_CODEC_ID_PCM_ALAW,
     154              :                                                "G.711a",
     155              :                                                "PCMA",
     156              :                                                "pcm_alaw",
     157            0 :                                                CODEC_ENCODER_DECODER,
     158            0 :                                                64,
     159            0 :                                                8000,
     160            0 :                                                1,
     161           36 :                                                8),
     162              : 
     163           36 :         std::make_shared<SystemAudioCodecInfo>(AV_CODEC_ID_PCM_MULAW,
     164            0 :                                                AV_CODEC_ID_PCM_MULAW,
     165              :                                                "G.711u",
     166              :                                                "PCMU",
     167              :                                                "pcm_mulaw",
     168            0 :                                                CODEC_ENCODER_DECODER,
     169            0 :                                                64,
     170            0 :                                                8000,
     171            0 :                                                1,
     172           36 :                                                0),
     173          504 :     };
     174           72 : }
     175              : 
     176              : void
     177           36 : SystemCodecContainer::init(bool enableAcceleration)
     178              : {
     179           36 :     initCodecConfig();
     180           36 :     setActiveH265(enableAcceleration);
     181           36 :     checkInstalledCodecs();
     182           36 : }
     183              : 
     184              : bool
     185           36 : SystemCodecContainer::setActiveH265(bool enableAcceleration)
     186              : {
     187              : #if (defined(TARGET_OS_IOS) && TARGET_OS_IOS)
     188              :     removeCodecByName("H265");
     189              :     return false;
     190              : #endif
     191              : 
     192              : #if defined(ENABLE_VIDEO) && defined(ENABLE_HWACCEL)
     193           36 :     if (not enableAcceleration) {
     194           36 :         removeCodecByName("H265");
     195           36 :         return false;
     196              :     }
     197              : 
     198            0 :     auto apiName = MediaEncoder::testH265Accel();
     199            0 :     if (apiName != "") {
     200            0 :         JAMI_WARNING("Found a usable accelerated H265/HEVC codec: {}, enabling.", apiName);
     201            0 :         return true;
     202              :     } else {
     203            0 :         JAMI_WARNING("Unable to find a usable accelerated H265/HEVC codec, disabling.");
     204            0 :         removeCodecByName("H265");
     205              :     }
     206              : #else
     207              :     removeCodecByName("H265");
     208              : #endif
     209            0 :     return false;
     210            0 : }
     211              : 
     212              : void
     213           36 : SystemCodecContainer::checkInstalledCodecs()
     214              : {
     215           36 :     std::ostringstream enc_ss;
     216           36 :     std::ostringstream dec_ss;
     217              : 
     218          468 :     for (const auto& codecIt : availableCodecList_) {
     219          432 :         AVCodecID codecId = (AVCodecID) codecIt->avcodecId;
     220          432 :         CodecType codecType = codecIt->codecType;
     221              : 
     222          432 :         if (codecType & CODEC_ENCODER) {
     223          432 :             if (avcodec_find_encoder(codecId) != nullptr)
     224          432 :                 enc_ss << codecIt->name << ' ';
     225              :             else
     226            0 :                 codecIt->codecType = (CodecType) ((unsigned) codecType & ~CODEC_ENCODER);
     227              :         }
     228              : 
     229          432 :         if (codecType & CODEC_DECODER) {
     230          432 :             if (avcodec_find_decoder(codecId) != nullptr)
     231          432 :                 dec_ss << codecIt->name << ' ';
     232              :             else
     233            0 :                 codecIt->codecType = (CodecType) ((unsigned) codecType & ~CODEC_DECODER);
     234              :         }
     235              :     }
     236          144 :     JAMI_LOG("Encoders found: {}", enc_ss.str());
     237          144 :     JAMI_LOG("Decoders found: {}", dec_ss.str());
     238           36 : }
     239              : 
     240              : std::vector<std::shared_ptr<SystemCodecInfo>>
     241          802 : SystemCodecContainer::getSystemCodecInfoList(MediaType mediaType)
     242              : {
     243          802 :     if (mediaType & MEDIA_ALL)
     244          802 :         return availableCodecList_;
     245              : 
     246              :     // otherwise we have to instantiate a new list containing filtered objects
     247              :     // must be destroyed by the caller…
     248            0 :     std::vector<std::shared_ptr<SystemCodecInfo>> systemCodecList;
     249            0 :     for (const auto& codecIt : availableCodecList_) {
     250            0 :         if (codecIt->mediaType & mediaType)
     251            0 :             systemCodecList.push_back(codecIt);
     252              :     }
     253            0 :     return systemCodecList;
     254            0 : }
     255              : 
     256              : std::vector<unsigned>
     257            0 : SystemCodecContainer::getSystemCodecInfoIdList(MediaType mediaType)
     258              : {
     259            0 :     std::vector<unsigned> idList;
     260            0 :     for (const auto& codecIt : availableCodecList_) {
     261            0 :         if (codecIt->mediaType & mediaType)
     262            0 :             idList.push_back(codecIt->id);
     263              :     }
     264            0 :     return idList;
     265            0 : }
     266              : 
     267              : std::shared_ptr<SystemCodecInfo>
     268            0 : SystemCodecContainer::searchCodecById(unsigned codecId, MediaType mediaType)
     269              : {
     270            0 :     for (const auto& codecIt : availableCodecList_) {
     271            0 :         if ((codecIt->id == codecId) && (codecIt->mediaType & mediaType))
     272            0 :             return codecIt;
     273              :     }
     274            0 :     return {};
     275              : }
     276              : std::shared_ptr<SystemCodecInfo>
     277            6 : SystemCodecContainer::searchCodecByName(const std::string& name, MediaType mediaType)
     278              : {
     279           21 :     for (const auto& codecIt : availableCodecList_) {
     280           21 :         if (codecIt->name == name && (codecIt->mediaType & mediaType))
     281            6 :             return codecIt;
     282              :     }
     283            0 :     return {};
     284              : }
     285              : std::shared_ptr<SystemCodecInfo>
     286            0 : SystemCodecContainer::searchCodecByPayload(unsigned payload, MediaType mediaType)
     287              : {
     288            0 :     for (const auto& codecIt : availableCodecList_) {
     289            0 :         if ((codecIt->payloadType == payload) && (codecIt->mediaType & mediaType))
     290            0 :             return codecIt;
     291              :     }
     292            0 :     return {};
     293              : }
     294              : void
     295           36 : SystemCodecContainer::removeCodecByName(const std::string& name, MediaType mediaType)
     296              : {
     297           36 :     for (auto codecIt = availableCodecList_.begin(); codecIt != availableCodecList_.end(); ++codecIt) {
     298           36 :         if ((*codecIt)->mediaType & mediaType and (*codecIt)->name == name) {
     299           36 :             availableCodecList_.erase(codecIt);
     300           36 :             break;
     301              :         }
     302              :     }
     303           36 : }
     304              : 
     305              : } // namespace jami
        

Generated by: LCOV version 2.0-1