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

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2012 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/neteq/decoder_database.h"
      12             : 
      13             : #include <utility>  // pair
      14             : 
      15             : #include "webrtc/base/checks.h"
      16             : #include "webrtc/base/logging.h"
      17             : #include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
      18             : 
      19             : namespace webrtc {
      20             : 
      21           0 : DecoderDatabase::DecoderDatabase(
      22           0 :     const rtc::scoped_refptr<AudioDecoderFactory>& decoder_factory)
      23             :     : active_decoder_type_(-1),
      24             :       active_cng_decoder_type_(-1),
      25           0 :       decoder_factory_(decoder_factory) {}
      26             : 
      27             : DecoderDatabase::~DecoderDatabase() = default;
      28             : 
      29           0 : DecoderDatabase::DecoderInfo::DecoderInfo(const SdpAudioFormat& audio_format,
      30             :                                           AudioDecoderFactory* factory,
      31           0 :                                           const std::string& codec_name)
      32             :     : name_(codec_name),
      33             :       audio_format_(audio_format),
      34             :       factory_(factory),
      35             :       external_decoder_(nullptr),
      36             :       cng_decoder_(CngDecoder::Create(audio_format)),
      37           0 :       subtype_(SubtypeFromFormat(audio_format)) {}
      38             : 
      39           0 : DecoderDatabase::DecoderInfo::DecoderInfo(const SdpAudioFormat& audio_format,
      40           0 :                                           AudioDecoderFactory* factory)
      41           0 :     : DecoderInfo(audio_format, factory, audio_format.name) {}
      42             : 
      43           0 : DecoderDatabase::DecoderInfo::DecoderInfo(NetEqDecoder ct,
      44           0 :                                           AudioDecoderFactory* factory)
      45           0 :     : DecoderInfo(*acm2::RentACodec::NetEqDecoderToSdpAudioFormat(ct),
      46           0 :                   factory) {}
      47             : 
      48           0 : DecoderDatabase::DecoderInfo::DecoderInfo(const SdpAudioFormat& audio_format,
      49             :                                           AudioDecoder* ext_dec,
      50           0 :                                           const std::string& codec_name)
      51             :     : name_(codec_name),
      52             :       audio_format_(audio_format),
      53             :       factory_(nullptr),
      54             :       external_decoder_(ext_dec),
      55           0 :       subtype_(Subtype::kNormal) {
      56           0 :   RTC_CHECK(ext_dec);
      57           0 : }
      58             : 
      59             : DecoderDatabase::DecoderInfo::DecoderInfo(DecoderInfo&&) = default;
      60             : DecoderDatabase::DecoderInfo::~DecoderInfo() = default;
      61             : 
      62           0 : AudioDecoder* DecoderDatabase::DecoderInfo::GetDecoder() const {
      63           0 :   if (subtype_ != Subtype::kNormal) {
      64             :     // These are handled internally, so they have no AudioDecoder objects.
      65           0 :     return nullptr;
      66             :   }
      67           0 :   if (external_decoder_) {
      68           0 :     RTC_DCHECK(!decoder_);
      69           0 :     RTC_DCHECK(!cng_decoder_);
      70           0 :     return external_decoder_;
      71             :   }
      72           0 :   if (!decoder_) {
      73             :     // TODO(ossu): Keep a check here for now, since a number of tests create
      74             :     // DecoderInfos without factories.
      75           0 :     RTC_DCHECK(factory_);
      76           0 :     decoder_ = factory_->MakeAudioDecoder(audio_format_);
      77             :   }
      78           0 :   RTC_DCHECK(decoder_) << "Failed to create: " << audio_format_;
      79           0 :   return decoder_.get();
      80             : }
      81             : 
      82           0 : bool DecoderDatabase::DecoderInfo::IsType(const char* name) const {
      83           0 :   return STR_CASE_CMP(audio_format_.name.c_str(), name) == 0;
      84             : }
      85             : 
      86           0 : bool DecoderDatabase::DecoderInfo::IsType(const std::string& name) const {
      87           0 :   return IsType(name.c_str());
      88             : }
      89             : 
      90             : rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder>
      91           0 : DecoderDatabase::DecoderInfo::CngDecoder::Create(const SdpAudioFormat& format) {
      92           0 :   if (STR_CASE_CMP(format.name.c_str(), "CN") == 0) {
      93             :     // CN has a 1:1 RTP clock rate to sample rate ratio.
      94           0 :     const int sample_rate_hz = format.clockrate_hz;
      95           0 :     RTC_DCHECK(sample_rate_hz == 8000 || sample_rate_hz == 16000 ||
      96           0 :                sample_rate_hz == 32000 || sample_rate_hz == 48000);
      97             :     return rtc::Optional<DecoderDatabase::DecoderInfo::CngDecoder>(
      98           0 :         {sample_rate_hz});
      99             :   } else {
     100           0 :     return rtc::Optional<CngDecoder>();
     101             :   }
     102             : }
     103             : 
     104             : DecoderDatabase::DecoderInfo::Subtype
     105           0 : DecoderDatabase::DecoderInfo::SubtypeFromFormat(const SdpAudioFormat& format) {
     106           0 :   if (STR_CASE_CMP(format.name.c_str(), "CN") == 0) {
     107           0 :     return Subtype::kComfortNoise;
     108           0 :   } else if (STR_CASE_CMP(format.name.c_str(), "telephone-event") == 0) {
     109           0 :     return Subtype::kDtmf;
     110           0 :   } else if (STR_CASE_CMP(format.name.c_str(), "red") == 0) {
     111           0 :     return Subtype::kRed;
     112             :   }
     113             : 
     114           0 :   return Subtype::kNormal;
     115             : }
     116             : 
     117           0 : bool DecoderDatabase::Empty() const { return decoders_.empty(); }
     118             : 
     119           0 : int DecoderDatabase::Size() const { return static_cast<int>(decoders_.size()); }
     120             : 
     121           0 : void DecoderDatabase::Reset() {
     122           0 :   decoders_.clear();
     123           0 :   active_decoder_type_ = -1;
     124           0 :   active_cng_decoder_type_ = -1;
     125           0 : }
     126             : 
     127           0 : int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type,
     128             :                                      NetEqDecoder codec_type,
     129             :                                      const std::string& name) {
     130           0 :   if (rtp_payload_type > 0x7F) {
     131           0 :     return kInvalidRtpPayloadType;
     132             :   }
     133             :   // kCodecArbitrary is only supported through InsertExternal.
     134           0 :   if (codec_type == NetEqDecoder::kDecoderArbitrary ||
     135           0 :       !CodecSupported(codec_type)) {
     136           0 :     return kCodecNotSupported;
     137             :   }
     138             :   const auto opt_format =
     139           0 :       acm2::RentACodec::NetEqDecoderToSdpAudioFormat(codec_type);
     140           0 :   if (!opt_format) {
     141           0 :     return kCodecNotSupported;
     142             :   }
     143           0 :   DecoderInfo info(*opt_format, decoder_factory_, name);
     144             :   auto ret =
     145           0 :       decoders_.insert(std::make_pair(rtp_payload_type, std::move(info)));
     146           0 :   if (ret.second == false) {
     147             :     // Database already contains a decoder with type |rtp_payload_type|.
     148           0 :     return kDecoderExists;
     149             :   }
     150           0 :   return kOK;
     151             : }
     152             : 
     153           0 : int DecoderDatabase::RegisterPayload(int rtp_payload_type,
     154             :                                      const SdpAudioFormat& audio_format) {
     155           0 :   if (rtp_payload_type < 0 || rtp_payload_type > 0x7f) {
     156           0 :     return kInvalidRtpPayloadType;
     157             :   }
     158           0 :   const auto ret = decoders_.insert(std::make_pair(
     159           0 :       rtp_payload_type, DecoderInfo(audio_format, decoder_factory_.get())));
     160           0 :   if (ret.second == false) {
     161             :     // Database already contains a decoder with type |rtp_payload_type|.
     162           0 :     return kDecoderExists;
     163             :   }
     164           0 :   return kOK;
     165             : }
     166             : 
     167           0 : int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type,
     168             :                                     NetEqDecoder codec_type,
     169             :                                     const std::string& codec_name,
     170             :                                     AudioDecoder* decoder) {
     171           0 :   if (rtp_payload_type > 0x7F) {
     172           0 :     return kInvalidRtpPayloadType;
     173             :   }
     174           0 :   if (!decoder) {
     175           0 :     return kInvalidPointer;
     176             :   }
     177             : 
     178             :   const auto opt_db_format =
     179           0 :       acm2::RentACodec::NetEqDecoderToSdpAudioFormat(codec_type);
     180           0 :   const SdpAudioFormat format = opt_db_format.value_or({"arbitrary", 0, 0});
     181             : 
     182           0 :   std::pair<DecoderMap::iterator, bool> ret;
     183           0 :   DecoderInfo info(format, decoder, codec_name);
     184           0 :   ret = decoders_.insert(std::make_pair(rtp_payload_type, std::move(info)));
     185           0 :   if (ret.second == false) {
     186             :     // Database already contains a decoder with type |rtp_payload_type|.
     187           0 :     return kDecoderExists;
     188             :   }
     189           0 :   return kOK;
     190             : }
     191             : 
     192           0 : int DecoderDatabase::Remove(uint8_t rtp_payload_type) {
     193           0 :   if (decoders_.erase(rtp_payload_type) == 0) {
     194             :     // No decoder with that |rtp_payload_type|.
     195           0 :     return kDecoderNotFound;
     196             :   }
     197           0 :   if (active_decoder_type_ == rtp_payload_type) {
     198           0 :     active_decoder_type_ = -1;  // No active decoder.
     199             :   }
     200           0 :   if (active_cng_decoder_type_ == rtp_payload_type) {
     201           0 :     active_cng_decoder_type_ = -1;  // No active CNG decoder.
     202             :   }
     203           0 :   return kOK;
     204             : }
     205             : 
     206           0 : void DecoderDatabase::RemoveAll() {
     207           0 :   decoders_.clear();
     208           0 :   active_decoder_type_ = -1;      // No active decoder.
     209           0 :   active_cng_decoder_type_ = -1;  // No active CNG decoder.
     210           0 : }
     211             : 
     212           0 : const DecoderDatabase::DecoderInfo* DecoderDatabase::GetDecoderInfo(
     213             :     uint8_t rtp_payload_type) const {
     214           0 :   DecoderMap::const_iterator it = decoders_.find(rtp_payload_type);
     215           0 :   if (it == decoders_.end()) {
     216             :     // Decoder not found.
     217           0 :     return NULL;
     218             :   }
     219           0 :   return &it->second;
     220             : }
     221             : 
     222           0 : int DecoderDatabase::SetActiveDecoder(uint8_t rtp_payload_type,
     223             :                                       bool* new_decoder) {
     224             :   // Check that |rtp_payload_type| exists in the database.
     225           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     226           0 :   if (!info) {
     227             :     // Decoder not found.
     228           0 :     return kDecoderNotFound;
     229             :   }
     230           0 :   RTC_CHECK(!info->IsComfortNoise());
     231           0 :   RTC_DCHECK(new_decoder);
     232           0 :   *new_decoder = false;
     233           0 :   if (active_decoder_type_ < 0) {
     234             :     // This is the first active decoder.
     235           0 :     *new_decoder = true;
     236           0 :   } else if (active_decoder_type_ != rtp_payload_type) {
     237             :     // Moving from one active decoder to another. Delete the first one.
     238           0 :     const DecoderInfo *old_info = GetDecoderInfo(active_decoder_type_);
     239           0 :     RTC_DCHECK(old_info);
     240           0 :     old_info->DropDecoder();
     241           0 :     *new_decoder = true;
     242             :   }
     243           0 :   active_decoder_type_ = rtp_payload_type;
     244           0 :   return kOK;
     245             : }
     246             : 
     247           0 : AudioDecoder* DecoderDatabase::GetActiveDecoder() const {
     248           0 :   if (active_decoder_type_ < 0) {
     249             :     // No active decoder.
     250           0 :     return NULL;
     251             :   }
     252           0 :   return GetDecoder(active_decoder_type_);
     253             : }
     254             : 
     255           0 : int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) {
     256             :   // Check that |rtp_payload_type| exists in the database.
     257           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     258           0 :   if (!info) {
     259             :     // Decoder not found.
     260           0 :     return kDecoderNotFound;
     261             :   }
     262           0 :   if (active_cng_decoder_type_ >= 0 &&
     263           0 :       active_cng_decoder_type_ != rtp_payload_type) {
     264             :     // Moving from one active CNG decoder to another. Delete the first one.
     265           0 :     RTC_DCHECK(active_cng_decoder_);
     266           0 :     active_cng_decoder_.reset();
     267             :   }
     268           0 :   active_cng_decoder_type_ = rtp_payload_type;
     269           0 :   return kOK;
     270             : }
     271             : 
     272           0 : ComfortNoiseDecoder* DecoderDatabase::GetActiveCngDecoder() const {
     273           0 :   if (active_cng_decoder_type_ < 0) {
     274             :     // No active CNG decoder.
     275           0 :     return NULL;
     276             :   }
     277           0 :   if (!active_cng_decoder_) {
     278           0 :     active_cng_decoder_.reset(new ComfortNoiseDecoder);
     279             :   }
     280           0 :   return active_cng_decoder_.get();
     281             : }
     282             : 
     283           0 : AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) const {
     284           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     285           0 :   return info ? info->GetDecoder() : nullptr;
     286             : }
     287             : 
     288           0 : bool DecoderDatabase::IsType(uint8_t rtp_payload_type, const char* name) const {
     289           0 :   const DecoderInfo* info = GetDecoderInfo(rtp_payload_type);
     290           0 :   return info && info->IsType(name);
     291             : }
     292             : 
     293           0 : bool DecoderDatabase::IsType(uint8_t rtp_payload_type,
     294             :                              const std::string& name) const {
     295           0 :   return IsType(rtp_payload_type, name.c_str());
     296             : }
     297             : 
     298           0 : bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const {
     299           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     300           0 :   return info && info->IsComfortNoise();
     301             : }
     302             : 
     303           0 : bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const {
     304           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     305           0 :   return info && info->IsDtmf();
     306             : }
     307             : 
     308           0 : bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const {
     309           0 :   const DecoderInfo *info = GetDecoderInfo(rtp_payload_type);
     310           0 :   return info && info->IsRed();
     311             : }
     312             : 
     313           0 : int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const {
     314           0 :   PacketList::const_iterator it;
     315           0 :   for (it = packet_list.begin(); it != packet_list.end(); ++it) {
     316           0 :     if (!GetDecoderInfo(it->payload_type)) {
     317             :       // Payload type is not found.
     318           0 :       LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type "
     319           0 :                       << static_cast<int>(it->payload_type);
     320           0 :       return kDecoderNotFound;
     321             :     }
     322             :   }
     323           0 :   return kOK;
     324             : }
     325             : 
     326             : }  // namespace webrtc

Generated by: LCOV version 1.13