Home | History | Annotate | Download | only in neteq
      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 <assert.h>
     14 #include <utility>  // pair
     15 
     16 #include "webrtc/base/checks.h"
     17 #include "webrtc/base/logging.h"
     18 #include "webrtc/modules/audio_coding/codecs/audio_decoder.h"
     19 
     20 namespace webrtc {
     21 
     22 DecoderDatabase::DecoderDatabase()
     23     : active_decoder_(-1), active_cng_decoder_(-1) {}
     24 
     25 DecoderDatabase::~DecoderDatabase() {}
     26 
     27 DecoderDatabase::DecoderInfo::~DecoderInfo() {
     28   if (!external) delete decoder;
     29 }
     30 
     31 bool DecoderDatabase::Empty() const { return decoders_.empty(); }
     32 
     33 int DecoderDatabase::Size() const { return static_cast<int>(decoders_.size()); }
     34 
     35 void DecoderDatabase::Reset() {
     36   decoders_.clear();
     37   active_decoder_ = -1;
     38   active_cng_decoder_ = -1;
     39 }
     40 
     41 int DecoderDatabase::RegisterPayload(uint8_t rtp_payload_type,
     42                                      NetEqDecoder codec_type,
     43                                      const std::string& name) {
     44   if (rtp_payload_type > 0x7F) {
     45     return kInvalidRtpPayloadType;
     46   }
     47   if (!CodecSupported(codec_type)) {
     48     return kCodecNotSupported;
     49   }
     50   const int fs_hz = CodecSampleRateHz(codec_type);
     51   DecoderInfo info(codec_type, name, fs_hz, NULL, false);
     52   auto ret = decoders_.insert(std::make_pair(rtp_payload_type, info));
     53   if (ret.second == false) {
     54     // Database already contains a decoder with type |rtp_payload_type|.
     55     return kDecoderExists;
     56   }
     57   return kOK;
     58 }
     59 
     60 int DecoderDatabase::InsertExternal(uint8_t rtp_payload_type,
     61                                     NetEqDecoder codec_type,
     62                                     const std::string& codec_name,
     63                                     int fs_hz,
     64                                     AudioDecoder* decoder) {
     65   if (rtp_payload_type > 0x7F) {
     66     return kInvalidRtpPayloadType;
     67   }
     68   if (!CodecSupported(codec_type)) {
     69     return kCodecNotSupported;
     70   }
     71   if (fs_hz != 8000 && fs_hz != 16000 && fs_hz != 32000 && fs_hz != 48000) {
     72     return kInvalidSampleRate;
     73   }
     74   if (!decoder) {
     75     return kInvalidPointer;
     76   }
     77   std::pair<DecoderMap::iterator, bool> ret;
     78   DecoderInfo info(codec_type, codec_name, fs_hz, decoder, true);
     79   ret = decoders_.insert(std::make_pair(rtp_payload_type, info));
     80   if (ret.second == false) {
     81     // Database already contains a decoder with type |rtp_payload_type|.
     82     return kDecoderExists;
     83   }
     84   return kOK;
     85 }
     86 
     87 int DecoderDatabase::Remove(uint8_t rtp_payload_type) {
     88   if (decoders_.erase(rtp_payload_type) == 0) {
     89     // No decoder with that |rtp_payload_type|.
     90     return kDecoderNotFound;
     91   }
     92   if (active_decoder_ == rtp_payload_type) {
     93     active_decoder_ = -1;  // No active decoder.
     94   }
     95   if (active_cng_decoder_ == rtp_payload_type) {
     96     active_cng_decoder_ = -1;  // No active CNG decoder.
     97   }
     98   return kOK;
     99 }
    100 
    101 const DecoderDatabase::DecoderInfo* DecoderDatabase::GetDecoderInfo(
    102     uint8_t rtp_payload_type) const {
    103   DecoderMap::const_iterator it = decoders_.find(rtp_payload_type);
    104   if (it == decoders_.end()) {
    105     // Decoder not found.
    106     return NULL;
    107   }
    108   return &(*it).second;
    109 }
    110 
    111 uint8_t DecoderDatabase::GetRtpPayloadType(
    112     NetEqDecoder codec_type) const {
    113   DecoderMap::const_iterator it;
    114   for (it = decoders_.begin(); it != decoders_.end(); ++it) {
    115     if ((*it).second.codec_type == codec_type) {
    116       // Match found.
    117       return (*it).first;
    118     }
    119   }
    120   // No match.
    121   return kRtpPayloadTypeError;
    122 }
    123 
    124 AudioDecoder* DecoderDatabase::GetDecoder(uint8_t rtp_payload_type) {
    125   if (IsDtmf(rtp_payload_type) || IsRed(rtp_payload_type)) {
    126     // These are not real decoders.
    127     return NULL;
    128   }
    129   DecoderMap::iterator it = decoders_.find(rtp_payload_type);
    130   if (it == decoders_.end()) {
    131     // Decoder not found.
    132     return NULL;
    133   }
    134   DecoderInfo* info = &(*it).second;
    135   if (!info->decoder) {
    136     // Create the decoder object.
    137     AudioDecoder* decoder = CreateAudioDecoder(info->codec_type);
    138     assert(decoder);  // Should not be able to have an unsupported codec here.
    139     info->decoder = decoder;
    140   }
    141   return info->decoder;
    142 }
    143 
    144 bool DecoderDatabase::IsType(uint8_t rtp_payload_type,
    145                              NetEqDecoder codec_type) const {
    146   DecoderMap::const_iterator it = decoders_.find(rtp_payload_type);
    147   if (it == decoders_.end()) {
    148     // Decoder not found.
    149     return false;
    150   }
    151   return ((*it).second.codec_type == codec_type);
    152 }
    153 
    154 bool DecoderDatabase::IsComfortNoise(uint8_t rtp_payload_type) const {
    155   if (IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGnb) ||
    156       IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGwb) ||
    157       IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGswb32kHz) ||
    158       IsType(rtp_payload_type, NetEqDecoder::kDecoderCNGswb48kHz)) {
    159     return true;
    160   } else {
    161     return false;
    162   }
    163 }
    164 
    165 bool DecoderDatabase::IsDtmf(uint8_t rtp_payload_type) const {
    166   return IsType(rtp_payload_type, NetEqDecoder::kDecoderAVT);
    167 }
    168 
    169 bool DecoderDatabase::IsRed(uint8_t rtp_payload_type) const {
    170   return IsType(rtp_payload_type, NetEqDecoder::kDecoderRED);
    171 }
    172 
    173 int DecoderDatabase::SetActiveDecoder(uint8_t rtp_payload_type,
    174                                       bool* new_decoder) {
    175   // Check that |rtp_payload_type| exists in the database.
    176   DecoderMap::const_iterator it = decoders_.find(rtp_payload_type);
    177   if (it == decoders_.end()) {
    178     // Decoder not found.
    179     return kDecoderNotFound;
    180   }
    181   assert(new_decoder);
    182   *new_decoder = false;
    183   if (active_decoder_ < 0) {
    184     // This is the first active decoder.
    185     *new_decoder = true;
    186   } else if (active_decoder_ != rtp_payload_type) {
    187     // Moving from one active decoder to another. Delete the first one.
    188     DecoderMap::iterator it = decoders_.find(active_decoder_);
    189     if (it == decoders_.end()) {
    190       // Decoder not found. This should not be possible.
    191       assert(false);
    192       return kDecoderNotFound;
    193     }
    194     if (!(*it).second.external) {
    195       // Delete the AudioDecoder object, unless it is an externally created
    196       // decoder.
    197       delete (*it).second.decoder;
    198       (*it).second.decoder = NULL;
    199     }
    200     *new_decoder = true;
    201   }
    202   active_decoder_ = rtp_payload_type;
    203   return kOK;
    204 }
    205 
    206 AudioDecoder* DecoderDatabase::GetActiveDecoder() {
    207   if (active_decoder_ < 0) {
    208     // No active decoder.
    209     return NULL;
    210   }
    211   return GetDecoder(active_decoder_);
    212 }
    213 
    214 int DecoderDatabase::SetActiveCngDecoder(uint8_t rtp_payload_type) {
    215   // Check that |rtp_payload_type| exists in the database.
    216   DecoderMap::const_iterator it = decoders_.find(rtp_payload_type);
    217   if (it == decoders_.end()) {
    218     // Decoder not found.
    219     return kDecoderNotFound;
    220   }
    221   if (active_cng_decoder_ >= 0 && active_cng_decoder_ != rtp_payload_type) {
    222     // Moving from one active CNG decoder to another. Delete the first one.
    223     DecoderMap::iterator it = decoders_.find(active_cng_decoder_);
    224     if (it == decoders_.end()) {
    225       // Decoder not found. This should not be possible.
    226       assert(false);
    227       return kDecoderNotFound;
    228     }
    229     if (!(*it).second.external) {
    230       // Delete the AudioDecoder object, unless it is an externally created
    231       // decoder.
    232       delete (*it).second.decoder;
    233       (*it).second.decoder = NULL;
    234     }
    235   }
    236   active_cng_decoder_ = rtp_payload_type;
    237   return kOK;
    238 }
    239 
    240 AudioDecoder* DecoderDatabase::GetActiveCngDecoder() {
    241   if (active_cng_decoder_ < 0) {
    242     // No active CNG decoder.
    243     return NULL;
    244   }
    245   return GetDecoder(active_cng_decoder_);
    246 }
    247 
    248 int DecoderDatabase::CheckPayloadTypes(const PacketList& packet_list) const {
    249   PacketList::const_iterator it;
    250   for (it = packet_list.begin(); it != packet_list.end(); ++it) {
    251     if (decoders_.find((*it)->header.payloadType) == decoders_.end()) {
    252       // Payload type is not found.
    253       LOG(LS_WARNING) << "CheckPayloadTypes: unknown RTP payload type "
    254                       << static_cast<int>((*it)->header.payloadType);
    255       return kDecoderNotFound;
    256     }
    257   }
    258   return kOK;
    259 }
    260 
    261 
    262 }  // namespace webrtc
    263