Home | History | Annotate | Download | only in source
      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 <assert.h>
     12 
     13 #include "webrtc/common_types.h"
     14 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
     15 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
     16 
     17 namespace webrtc {
     18 
     19 RtpHeaderExtensionMap::RtpHeaderExtensionMap() {
     20 }
     21 
     22 RtpHeaderExtensionMap::~RtpHeaderExtensionMap() {
     23   Erase();
     24 }
     25 
     26 void RtpHeaderExtensionMap::Erase() {
     27   while (!extensionMap_.empty()) {
     28     std::map<uint8_t, HeaderExtension*>::iterator it =
     29         extensionMap_.begin();
     30     delete it->second;
     31     extensionMap_.erase(it);
     32   }
     33 }
     34 
     35 int32_t RtpHeaderExtensionMap::Register(const RTPExtensionType type,
     36                                         const uint8_t id) {
     37   return Register(type, id, true);
     38 }
     39 
     40 int32_t RtpHeaderExtensionMap::RegisterInactive(const RTPExtensionType type,
     41                                                 const uint8_t id) {
     42   return Register(type, id, false);
     43 }
     44 
     45 int32_t RtpHeaderExtensionMap::Register(const RTPExtensionType type,
     46                                         const uint8_t id,
     47                                         bool active) {
     48   if (id < 1 || id > 14) {
     49     return -1;
     50   }
     51   std::map<uint8_t, HeaderExtension*>::iterator it =
     52       extensionMap_.find(id);
     53   if (it != extensionMap_.end()) {
     54     if (it->second->type != type) {
     55       // An extension is already registered with the same id
     56       // but a different type, so return failure.
     57       return -1;
     58     }
     59     // This extension type is already registered with this id,
     60     // so return success.
     61     it->second->active = active;
     62     return 0;
     63   }
     64   extensionMap_[id] = new HeaderExtension(type, active);
     65   return 0;
     66 }
     67 
     68 bool RtpHeaderExtensionMap::SetActive(const RTPExtensionType type,
     69                                       bool active) {
     70   for (auto& kv : extensionMap_) {
     71     if (kv.second->type == type) {
     72       kv.second->active = active;
     73       return true;
     74     }
     75   }
     76   return false;
     77 }
     78 
     79 int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) {
     80   uint8_t id;
     81   if (GetId(type, &id) != 0) {
     82     return 0;
     83   }
     84   std::map<uint8_t, HeaderExtension*>::iterator it =
     85       extensionMap_.find(id);
     86   assert(it != extensionMap_.end());
     87   delete it->second;
     88   extensionMap_.erase(it);
     89   return 0;
     90 }
     91 
     92 bool RtpHeaderExtensionMap::IsRegistered(RTPExtensionType type) const {
     93   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     94     extensionMap_.begin();
     95   for (; it != extensionMap_.end(); ++it) {
     96     if (it->second->type == type)
     97       return true;
     98   }
     99   return false;
    100 }
    101 
    102 int32_t RtpHeaderExtensionMap::GetType(const uint8_t id,
    103                                        RTPExtensionType* type) const {
    104   assert(type);
    105   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    106       extensionMap_.find(id);
    107   if (it == extensionMap_.end()) {
    108     return -1;
    109   }
    110   HeaderExtension* extension = it->second;
    111   *type = extension->type;
    112   return 0;
    113 }
    114 
    115 int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type,
    116                                      uint8_t* id) const {
    117   assert(id);
    118   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    119       extensionMap_.begin();
    120 
    121   while (it != extensionMap_.end()) {
    122     HeaderExtension* extension = it->second;
    123     if (extension->type == type) {
    124       *id = it->first;
    125       return 0;
    126     }
    127     it++;
    128   }
    129   return -1;
    130 }
    131 
    132 size_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
    133   // Get length for each extension block.
    134   size_t length = 0;
    135   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    136       extensionMap_.begin();
    137   while (it != extensionMap_.end()) {
    138     HeaderExtension* extension = it->second;
    139     if (extension->active) {
    140       length += extension->length;
    141     }
    142     it++;
    143   }
    144   // Add RTP extension header length.
    145   if (length > 0) {
    146     length += kRtpOneByteHeaderLength;
    147   }
    148   // Pad up to nearest 32bit word.
    149   length = RtpUtility::Word32Align(length);
    150   return length;
    151 }
    152 
    153 int32_t RtpHeaderExtensionMap::GetLengthUntilBlockStartInBytes(
    154     const RTPExtensionType type) const {
    155   uint8_t id;
    156   if (GetId(type, &id) != 0) {
    157     // Not registered.
    158     return -1;
    159   }
    160   // Get length until start of extension block type.
    161   uint16_t length = kRtpOneByteHeaderLength;
    162 
    163   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    164       extensionMap_.begin();
    165   while (it != extensionMap_.end()) {
    166     HeaderExtension* extension = it->second;
    167     if (extension->type == type) {
    168       if (!extension->active) {
    169         return -1;
    170       }
    171       break;
    172     } else if (extension->active) {
    173       length += extension->length;
    174     }
    175     it++;
    176   }
    177   return length;
    178 }
    179 
    180 int32_t RtpHeaderExtensionMap::Size() const {
    181   int32_t count = 0;
    182   for (auto& kv : extensionMap_) {
    183     if (kv.second->active) {
    184       count++;
    185     }
    186   }
    187   return count;
    188 }
    189 
    190 RTPExtensionType RtpHeaderExtensionMap::First() const {
    191   for (auto& kv : extensionMap_) {
    192     if (kv.second->active) {
    193       return kv.second->type;
    194     }
    195   }
    196 
    197   return kRtpExtensionNone;
    198 }
    199 
    200 RTPExtensionType RtpHeaderExtensionMap::Next(RTPExtensionType type) const {
    201   uint8_t id;
    202   if (GetId(type, &id) != 0) {
    203     return kRtpExtensionNone;
    204   }
    205   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    206       extensionMap_.find(id);
    207   if (it == extensionMap_.end() || !it->second->active) {
    208     return kRtpExtensionNone;
    209   }
    210   while ((++it) != extensionMap_.end()) {
    211     if (it->second->active) {
    212       return it->second->type;
    213     }
    214   }
    215 
    216   return kRtpExtensionNone;
    217 }
    218 
    219 void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const {
    220   assert(map);
    221   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    222       extensionMap_.begin();
    223   while (it != extensionMap_.end()) {
    224     HeaderExtension* extension = it->second;
    225     map->Register(extension->type, it->first, extension->active);
    226     it++;
    227   }
    228 }
    229 }  // namespace webrtc
    230