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 
     16 namespace webrtc {
     17 
     18 RtpHeaderExtensionMap::RtpHeaderExtensionMap() {
     19 }
     20 
     21 RtpHeaderExtensionMap::~RtpHeaderExtensionMap() {
     22   Erase();
     23 }
     24 
     25 void RtpHeaderExtensionMap::Erase() {
     26   while (!extensionMap_.empty()) {
     27     std::map<uint8_t, HeaderExtension*>::iterator it =
     28         extensionMap_.begin();
     29     delete it->second;
     30     extensionMap_.erase(it);
     31   }
     32 }
     33 
     34 int32_t RtpHeaderExtensionMap::Register(const RTPExtensionType type,
     35                                         const uint8_t id) {
     36   if (id < 1 || id > 14) {
     37     return -1;
     38   }
     39   std::map<uint8_t, HeaderExtension*>::iterator it =
     40       extensionMap_.find(id);
     41   if (it != extensionMap_.end()) {
     42     if (it->second->type != type) {
     43       // An extension is already registered with the same id
     44       // but a different type, so return failure.
     45       return -1;
     46     }
     47     // This extension type is already registered with this id,
     48     // so return success.
     49     return 0;
     50   }
     51   extensionMap_[id] = new HeaderExtension(type);
     52   return 0;
     53 }
     54 
     55 int32_t RtpHeaderExtensionMap::Deregister(const RTPExtensionType type) {
     56   uint8_t id;
     57   if (GetId(type, &id) != 0) {
     58     return 0;
     59   }
     60   std::map<uint8_t, HeaderExtension*>::iterator it =
     61       extensionMap_.find(id);
     62   assert(it != extensionMap_.end());
     63   delete it->second;
     64   extensionMap_.erase(it);
     65   return 0;
     66 }
     67 
     68 bool RtpHeaderExtensionMap::IsRegistered(RTPExtensionType type) const {
     69   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     70     extensionMap_.begin();
     71   for (; it != extensionMap_.end(); ++it) {
     72     if (it->second->type == type)
     73       return true;
     74   }
     75   return false;
     76 }
     77 
     78 int32_t RtpHeaderExtensionMap::GetType(const uint8_t id,
     79                                        RTPExtensionType* type) const {
     80   assert(type);
     81   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     82       extensionMap_.find(id);
     83   if (it == extensionMap_.end()) {
     84     return -1;
     85   }
     86   HeaderExtension* extension = it->second;
     87   *type = extension->type;
     88   return 0;
     89 }
     90 
     91 int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type,
     92                                      uint8_t* id) const {
     93   assert(id);
     94   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     95       extensionMap_.begin();
     96 
     97   while (it != extensionMap_.end()) {
     98     HeaderExtension* extension = it->second;
     99     if (extension->type == type) {
    100       *id = it->first;
    101       return 0;
    102     }
    103     it++;
    104   }
    105   return -1;
    106 }
    107 
    108 uint16_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
    109   // Get length for each extension block.
    110   uint16_t length = 0;
    111   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    112       extensionMap_.begin();
    113   while (it != extensionMap_.end()) {
    114     HeaderExtension* extension = it->second;
    115     length += extension->length;
    116     it++;
    117   }
    118   // Add RTP extension header length.
    119   if (length > 0) {
    120     length += kRtpOneByteHeaderLength;
    121   }
    122   return length;
    123 }
    124 
    125 int32_t RtpHeaderExtensionMap::GetLengthUntilBlockStartInBytes(
    126     const RTPExtensionType type) const {
    127   uint8_t id;
    128   if (GetId(type, &id) != 0) {
    129     // Not registered.
    130     return -1;
    131   }
    132   // Get length until start of extension block type.
    133   uint16_t length = kRtpOneByteHeaderLength;
    134 
    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->type == type) {
    140       break;
    141     } else {
    142       length += extension->length;
    143     }
    144     it++;
    145   }
    146   return length;
    147 }
    148 
    149 int32_t RtpHeaderExtensionMap::Size() const {
    150   return extensionMap_.size();
    151 }
    152 
    153 RTPExtensionType RtpHeaderExtensionMap::First() const {
    154   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    155       extensionMap_.begin();
    156   if (it == extensionMap_.end()) {
    157      return kRtpExtensionNone;
    158   }
    159   HeaderExtension* extension = it->second;
    160   return extension->type;
    161 }
    162 
    163 RTPExtensionType RtpHeaderExtensionMap::Next(RTPExtensionType type) const {
    164   uint8_t id;
    165   if (GetId(type, &id) != 0) {
    166     return kRtpExtensionNone;
    167   }
    168   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    169       extensionMap_.find(id);
    170   if (it == extensionMap_.end()) {
    171     return kRtpExtensionNone;
    172   }
    173   it++;
    174   if (it == extensionMap_.end()) {
    175     return kRtpExtensionNone;
    176   }
    177   HeaderExtension* extension = it->second;
    178   return extension->type;
    179 }
    180 
    181 void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const {
    182   assert(map);
    183   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    184       extensionMap_.begin();
    185   while (it != extensionMap_.end()) {
    186     HeaderExtension* extension = it->second;
    187     map->Register(extension->type, it->first);
    188     it++;
    189   }
    190 }
    191 }  // namespace webrtc
    192