LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/audio_coding/acm2 - rent_a_codec.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 149 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 21 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/audio_coding/acm2/rent_a_codec.h"
      12             : 
      13             : #include <memory>
      14             : #include <utility>
      15             : 
      16             : #include "webrtc/base/logging.h"
      17             : #include "webrtc/modules/audio_coding/codecs/cng/audio_encoder_cng.h"
      18             : #include "webrtc/modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
      19             : #ifdef WEBRTC_CODEC_G722
      20             : #include "webrtc/modules/audio_coding/codecs/g722/audio_encoder_g722.h"
      21             : #endif
      22             : #ifdef WEBRTC_CODEC_ILBC
      23             : #include "webrtc/modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"
      24             : #endif
      25             : #ifdef WEBRTC_CODEC_ISACFX
      26             : #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"
      27             : #include "webrtc/modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"
      28             : #endif
      29             : #ifdef WEBRTC_CODEC_ISAC
      30             : #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"
      31             : #include "webrtc/modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"
      32             : #endif
      33             : #ifdef WEBRTC_CODEC_OPUS
      34             : #include "webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.h"
      35             : #endif
      36             : #include "webrtc/modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
      37             : #ifdef WEBRTC_CODEC_RED
      38             : #include "webrtc/modules/audio_coding/codecs/red/audio_encoder_copy_red.h"
      39             : #endif
      40             : #include "webrtc/modules/audio_coding/acm2/acm_codec_database.h"
      41             : #include "webrtc/modules/audio_coding/acm2/acm_common_defs.h"
      42             : 
      43             : #if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
      44             : #include "webrtc/modules/audio_coding/codecs/isac/locked_bandwidth_info.h"
      45             : #endif
      46             : 
      47             : namespace webrtc {
      48             : namespace acm2 {
      49             : 
      50           0 : rtc::Optional<SdpAudioFormat> RentACodec::NetEqDecoderToSdpAudioFormat(
      51             :     NetEqDecoder nd) {
      52           0 :   switch (nd) {
      53             :     case NetEqDecoder::kDecoderPCMu:
      54           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcmu", 8000, 1));
      55             :     case NetEqDecoder::kDecoderPCMa:
      56           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcma", 8000, 1));
      57             :     case NetEqDecoder::kDecoderPCMu_2ch:
      58           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcmu", 8000, 2));
      59             :     case NetEqDecoder::kDecoderPCMa_2ch:
      60           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("pcma", 8000, 2));
      61             :     case NetEqDecoder::kDecoderILBC:
      62           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("ilbc", 8000, 1));
      63             :     case NetEqDecoder::kDecoderISAC:
      64           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("isac", 16000, 1));
      65             :     case NetEqDecoder::kDecoderISACswb:
      66           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("isac", 32000, 1));
      67             :     case NetEqDecoder::kDecoderPCM16B:
      68           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 1));
      69             :     case NetEqDecoder::kDecoderPCM16Bwb:
      70           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 16000, 1));
      71             :     case NetEqDecoder::kDecoderPCM16Bswb32kHz:
      72           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 32000, 1));
      73             :     case NetEqDecoder::kDecoderPCM16Bswb48kHz:
      74           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 48000, 1));
      75             :     case NetEqDecoder::kDecoderPCM16B_2ch:
      76           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 2));
      77             :     case NetEqDecoder::kDecoderPCM16Bwb_2ch:
      78           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 16000, 2));
      79             :     case NetEqDecoder::kDecoderPCM16Bswb32kHz_2ch:
      80           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 32000, 2));
      81             :     case NetEqDecoder::kDecoderPCM16Bswb48kHz_2ch:
      82           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 48000, 2));
      83             :     case NetEqDecoder::kDecoderPCM16B_5ch:
      84           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("l16", 8000, 5));
      85             :     case NetEqDecoder::kDecoderG722:
      86           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("g722", 8000, 1));
      87             :     case NetEqDecoder::kDecoderG722_2ch:
      88           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("g722", 8000, 2));
      89             :     case NetEqDecoder::kDecoderOpus:
      90             :       return rtc::Optional<SdpAudioFormat>(
      91           0 :           SdpAudioFormat("opus", 48000, 2,
      92           0 :                          std::map<std::string, std::string>{{"stereo", "0"}}));
      93             :     case NetEqDecoder::kDecoderOpus_2ch:
      94             :       return rtc::Optional<SdpAudioFormat>(
      95           0 :           SdpAudioFormat("opus", 48000, 2,
      96           0 :                          std::map<std::string, std::string>{{"stereo", "1"}}));
      97             :     case NetEqDecoder::kDecoderRED:
      98           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("red", 8000, 1));
      99             :     case NetEqDecoder::kDecoderAVT:
     100             :       return rtc::Optional<SdpAudioFormat>(
     101           0 :           SdpAudioFormat("telephone-event", 8000, 1));
     102             :     case NetEqDecoder::kDecoderAVT16kHz:
     103             :       return rtc::Optional<SdpAudioFormat>(
     104           0 :           SdpAudioFormat("telephone-event", 16000, 1));
     105             :     case NetEqDecoder::kDecoderAVT32kHz:
     106             :       return rtc::Optional<SdpAudioFormat>(
     107           0 :           SdpAudioFormat("telephone-event", 32000, 1));
     108             :     case NetEqDecoder::kDecoderAVT48kHz:
     109             :       return rtc::Optional<SdpAudioFormat>(
     110           0 :           SdpAudioFormat("telephone-event", 48000, 1));
     111             :     case NetEqDecoder::kDecoderCNGnb:
     112           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("cn", 8000, 1));
     113             :     case NetEqDecoder::kDecoderCNGwb:
     114           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("cn", 16000, 1));
     115             :     case NetEqDecoder::kDecoderCNGswb32kHz:
     116           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("cn", 32000, 1));
     117             :     case NetEqDecoder::kDecoderCNGswb48kHz:
     118           0 :       return rtc::Optional<SdpAudioFormat>(SdpAudioFormat("cn", 48000, 1));
     119             :     default:
     120           0 :       return rtc::Optional<SdpAudioFormat>();
     121             :   }
     122             : }
     123             : 
     124           0 : rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByParams(
     125             :     const char* payload_name,
     126             :     int sampling_freq_hz,
     127             :     size_t channels) {
     128             :   return CodecIdFromIndex(
     129           0 :       ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels));
     130             : }
     131             : 
     132           0 : rtc::Optional<CodecInst> RentACodec::CodecInstById(CodecId codec_id) {
     133           0 :   rtc::Optional<int> mi = CodecIndexFromId(codec_id);
     134           0 :   return mi ? rtc::Optional<CodecInst>(Database()[*mi])
     135           0 :             : rtc::Optional<CodecInst>();
     136             : }
     137             : 
     138           0 : rtc::Optional<RentACodec::CodecId> RentACodec::CodecIdByInst(
     139             :     const CodecInst& codec_inst) {
     140           0 :   return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst));
     141             : }
     142             : 
     143           0 : rtc::Optional<CodecInst> RentACodec::CodecInstByParams(const char* payload_name,
     144             :                                                        int sampling_freq_hz,
     145             :                                                        size_t channels) {
     146             :   rtc::Optional<CodecId> codec_id =
     147           0 :       CodecIdByParams(payload_name, sampling_freq_hz, channels);
     148           0 :   if (!codec_id)
     149           0 :     return rtc::Optional<CodecInst>();
     150           0 :   rtc::Optional<CodecInst> ci = CodecInstById(*codec_id);
     151           0 :   RTC_DCHECK(ci);
     152             : 
     153             :   // Keep the number of channels from the function call. For most codecs it
     154             :   // will be the same value as in default codec settings, but not for all.
     155           0 :   ci->channels = channels;
     156             : 
     157           0 :   return ci;
     158             : }
     159             : 
     160           0 : bool RentACodec::IsCodecValid(const CodecInst& codec_inst) {
     161           0 :   return ACMCodecDB::CodecNumber(codec_inst) >= 0;
     162             : }
     163             : 
     164           0 : rtc::Optional<bool> RentACodec::IsSupportedNumChannels(CodecId codec_id,
     165             :                                                        size_t num_channels) {
     166           0 :   auto i = CodecIndexFromId(codec_id);
     167             :   return i ? rtc::Optional<bool>(
     168           0 :                  ACMCodecDB::codec_settings_[*i].channel_support >=
     169             :                  num_channels)
     170           0 :            : rtc::Optional<bool>();
     171             : }
     172             : 
     173           0 : rtc::ArrayView<const CodecInst> RentACodec::Database() {
     174           0 :   return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_,
     175           0 :                                          NumberOfCodecs());
     176             : }
     177             : 
     178           0 : rtc::Optional<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId(
     179             :     CodecId codec_id,
     180             :     size_t num_channels) {
     181           0 :   rtc::Optional<int> i = CodecIndexFromId(codec_id);
     182           0 :   if (!i)
     183           0 :     return rtc::Optional<NetEqDecoder>();
     184           0 :   const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i];
     185             :   return rtc::Optional<NetEqDecoder>(
     186           0 :       (ned == NetEqDecoder::kDecoderOpus && num_channels == 2)
     187           0 :           ? NetEqDecoder::kDecoderOpus_2ch
     188           0 :           : ned);
     189             : }
     190             : 
     191           0 : RentACodec::RegistrationResult RentACodec::RegisterCngPayloadType(
     192             :     std::map<int, int>* pt_map,
     193             :     const CodecInst& codec_inst) {
     194           0 :   if (STR_CASE_CMP(codec_inst.plname, "CN") != 0)
     195           0 :     return RegistrationResult::kSkip;
     196           0 :   switch (codec_inst.plfreq) {
     197             :     case 8000:
     198             :     case 16000:
     199             :     case 32000:
     200             :     case 48000:
     201           0 :       (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
     202           0 :       return RegistrationResult::kOk;
     203             :     default:
     204           0 :       return RegistrationResult::kBadFreq;
     205             :   }
     206             : }
     207             : 
     208           0 : RentACodec::RegistrationResult RentACodec::RegisterRedPayloadType(
     209             :     std::map<int, int>* pt_map,
     210             :     const CodecInst& codec_inst) {
     211           0 :   if (STR_CASE_CMP(codec_inst.plname, "RED") != 0)
     212           0 :     return RegistrationResult::kSkip;
     213           0 :   switch (codec_inst.plfreq) {
     214             :     case 8000:
     215           0 :       (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
     216           0 :       return RegistrationResult::kOk;
     217             :     default:
     218           0 :       return RegistrationResult::kBadFreq;
     219             :   }
     220             : }
     221             : 
     222             : namespace {
     223             : 
     224             : // Returns a new speech encoder, or null on error.
     225             : // TODO(kwiberg): Don't handle errors here (bug 5033)
     226           0 : std::unique_ptr<AudioEncoder> CreateEncoder(
     227             :     const CodecInst& speech_inst,
     228             :     const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo) {
     229             : #if defined(WEBRTC_CODEC_ISACFX)
     230             :   if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
     231             :     return std::unique_ptr<AudioEncoder>(
     232             :         new AudioEncoderIsacFix(speech_inst, bwinfo));
     233             : #endif
     234             : #if defined(WEBRTC_CODEC_ISAC)
     235             :   if (STR_CASE_CMP(speech_inst.plname, "isac") == 0)
     236             :     return std::unique_ptr<AudioEncoder>(
     237             :         new AudioEncoderIsac(speech_inst, bwinfo));
     238             : #endif
     239             : #ifdef WEBRTC_CODEC_OPUS
     240           0 :   if (STR_CASE_CMP(speech_inst.plname, "opus") == 0)
     241           0 :     return std::unique_ptr<AudioEncoder>(new AudioEncoderOpus(speech_inst));
     242             : #endif
     243           0 :   if (STR_CASE_CMP(speech_inst.plname, "pcmu") == 0)
     244           0 :     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmU(speech_inst));
     245           0 :   if (STR_CASE_CMP(speech_inst.plname, "pcma") == 0)
     246           0 :     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmA(speech_inst));
     247           0 :   if (STR_CASE_CMP(speech_inst.plname, "l16") == 0)
     248           0 :     return std::unique_ptr<AudioEncoder>(new AudioEncoderPcm16B(speech_inst));
     249             : #ifdef WEBRTC_CODEC_ILBC
     250             :   if (STR_CASE_CMP(speech_inst.plname, "ilbc") == 0)
     251             :     return std::unique_ptr<AudioEncoder>(new AudioEncoderIlbc(speech_inst));
     252             : #endif
     253             : #ifdef WEBRTC_CODEC_G722
     254             :   if (STR_CASE_CMP(speech_inst.plname, "g722") == 0)
     255             :     return std::unique_ptr<AudioEncoder>(new AudioEncoderG722(speech_inst));
     256             : #endif
     257           0 :   LOG_F(LS_ERROR) << "Could not create encoder of type " << speech_inst.plname;
     258           0 :   return std::unique_ptr<AudioEncoder>();
     259             : }
     260             : 
     261           0 : std::unique_ptr<AudioEncoder> CreateRedEncoder(
     262             :     std::unique_ptr<AudioEncoder> encoder,
     263             :     int red_payload_type) {
     264             : #ifdef WEBRTC_CODEC_RED
     265             :   AudioEncoderCopyRed::Config config;
     266             :   config.payload_type = red_payload_type;
     267             :   config.speech_encoder = std::move(encoder);
     268             :   return std::unique_ptr<AudioEncoder>(
     269             :       new AudioEncoderCopyRed(std::move(config)));
     270             : #else
     271           0 :   return std::unique_ptr<AudioEncoder>();
     272             : #endif
     273             : }
     274             : 
     275           0 : std::unique_ptr<AudioEncoder> CreateCngEncoder(
     276             :     std::unique_ptr<AudioEncoder> encoder,
     277             :     int payload_type,
     278             :     ACMVADMode vad_mode) {
     279           0 :   AudioEncoderCng::Config config;
     280           0 :   config.num_channels = encoder->NumChannels();
     281           0 :   config.payload_type = payload_type;
     282           0 :   config.speech_encoder = std::move(encoder);
     283           0 :   switch (vad_mode) {
     284             :     case VADNormal:
     285           0 :       config.vad_mode = Vad::kVadNormal;
     286           0 :       break;
     287             :     case VADLowBitrate:
     288           0 :       config.vad_mode = Vad::kVadLowBitrate;
     289           0 :       break;
     290             :     case VADAggr:
     291           0 :       config.vad_mode = Vad::kVadAggressive;
     292           0 :       break;
     293             :     case VADVeryAggr:
     294           0 :       config.vad_mode = Vad::kVadVeryAggressive;
     295           0 :       break;
     296             :     default:
     297           0 :       FATAL();
     298             :   }
     299           0 :   return std::unique_ptr<AudioEncoder>(new AudioEncoderCng(std::move(config)));
     300             : }
     301             : 
     302           0 : std::unique_ptr<AudioDecoder> CreateIsacDecoder(
     303             :     int sample_rate_hz,
     304             :     const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo) {
     305             : #if defined(WEBRTC_CODEC_ISACFX)
     306             :   return std::unique_ptr<AudioDecoder>(
     307             :       new AudioDecoderIsacFix(sample_rate_hz, bwinfo));
     308             : #elif defined(WEBRTC_CODEC_ISAC)
     309             :   return std::unique_ptr<AudioDecoder>(
     310             :       new AudioDecoderIsac(sample_rate_hz, bwinfo));
     311             : #else
     312           0 :   FATAL() << "iSAC is not supported.";
     313             :   return std::unique_ptr<AudioDecoder>();
     314             : #endif
     315             : }
     316             : 
     317             : }  // namespace
     318             : 
     319           0 : RentACodec::RentACodec() {
     320             : #if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
     321             :   isac_bandwidth_info_ = new LockedIsacBandwidthInfo;
     322             : #endif
     323           0 : }
     324             : RentACodec::~RentACodec() = default;
     325             : 
     326           0 : std::unique_ptr<AudioEncoder> RentACodec::RentEncoder(
     327             :     const CodecInst& codec_inst) {
     328           0 :   return CreateEncoder(codec_inst, isac_bandwidth_info_);
     329             : }
     330             : 
     331           0 : RentACodec::StackParameters::StackParameters() {
     332             :   // Register the default payload types for RED and CNG.
     333           0 :   for (const CodecInst& ci : RentACodec::Database()) {
     334           0 :     RentACodec::RegisterCngPayloadType(&cng_payload_types, ci);
     335           0 :     RentACodec::RegisterRedPayloadType(&red_payload_types, ci);
     336             :   }
     337           0 : }
     338             : 
     339             : RentACodec::StackParameters::~StackParameters() = default;
     340             : 
     341           0 : std::unique_ptr<AudioEncoder> RentACodec::RentEncoderStack(
     342             :     StackParameters* param) {
     343           0 :   if (!param->speech_encoder)
     344           0 :     return nullptr;
     345             : 
     346           0 :   if (param->use_codec_fec) {
     347             :     // Switch FEC on. On failure, remember that FEC is off.
     348           0 :     if (!param->speech_encoder->SetFec(true))
     349           0 :       param->use_codec_fec = false;
     350             :   } else {
     351             :     // Switch FEC off. This shouldn't fail.
     352           0 :     const bool success = param->speech_encoder->SetFec(false);
     353           0 :     RTC_DCHECK(success);
     354             :   }
     355             : 
     356           0 :   auto pt = [&param](const std::map<int, int>& m) {
     357           0 :     auto it = m.find(param->speech_encoder->SampleRateHz());
     358           0 :     return it == m.end() ? rtc::Optional<int>()
     359           0 :                          : rtc::Optional<int>(it->second);
     360           0 :   };
     361           0 :   auto cng_pt = pt(param->cng_payload_types);
     362           0 :   param->use_cng =
     363           0 :       param->use_cng && cng_pt && param->speech_encoder->NumChannels() == 1;
     364           0 :   auto red_pt = pt(param->red_payload_types);
     365           0 :   param->use_red = param->use_red && red_pt;
     366             : 
     367           0 :   if (param->use_cng || param->use_red) {
     368             :     // The RED and CNG encoders need to be in sync with the speech encoder, so
     369             :     // reset the latter to ensure its buffer is empty.
     370           0 :     param->speech_encoder->Reset();
     371             :   }
     372             :   std::unique_ptr<AudioEncoder> encoder_stack =
     373           0 :       std::move(param->speech_encoder);
     374           0 :   if (param->use_red) {
     375           0 :     encoder_stack = CreateRedEncoder(std::move(encoder_stack), *red_pt);
     376             :   }
     377           0 :   if (param->use_cng) {
     378             :     encoder_stack =
     379           0 :         CreateCngEncoder(std::move(encoder_stack), *cng_pt, param->vad_mode);
     380             :   }
     381           0 :   return encoder_stack;
     382             : }
     383             : 
     384           0 : std::unique_ptr<AudioDecoder> RentACodec::RentIsacDecoder(int sample_rate_hz) {
     385           0 :   return CreateIsacDecoder(sample_rate_hz, isac_bandwidth_info_);
     386             : }
     387             : 
     388             : }  // namespace acm2
     389             : }  // namespace webrtc

Generated by: LCOV version 1.13