LCOV - code coverage report
Current view: top level - src/media - system_codec_container.cpp (source / functions) Hit Total Coverage
Test: jami-coverage-filtered.info Lines: 67 154 43.5 %
Date: 2024-12-21 08:56:24 Functions: 8 11 72.7 %

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

Generated by: LCOV version 1.14