LCOV - code coverage report
Current view: top level - foo/src/media - system_codec_container.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 67 146 45.9 %
Date: 2025-12-18 10:07:43 Functions: 10 15 66.7 %

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

Generated by: LCOV version 1.14