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 int32_t RtpHeaderExtensionMap::GetType(const uint8_t id,
     69                                        RTPExtensionType* type) const {
     70   assert(type);
     71   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     72       extensionMap_.find(id);
     73   if (it == extensionMap_.end()) {
     74     return -1;
     75   }
     76   HeaderExtension* extension = it->second;
     77   *type = extension->type;
     78   return 0;
     79 }
     80 
     81 int32_t RtpHeaderExtensionMap::GetId(const RTPExtensionType type,
     82                                      uint8_t* id) const {
     83   assert(id);
     84   std::map<uint8_t, HeaderExtension*>::const_iterator it =
     85       extensionMap_.begin();
     86 
     87   while (it != extensionMap_.end()) {
     88     HeaderExtension* extension = it->second;
     89     if (extension->type == type) {
     90       *id = it->first;
     91       return 0;
     92     }
     93     it++;
     94   }
     95   return -1;
     96 }
     97 
     98 uint16_t RtpHeaderExtensionMap::GetTotalLengthInBytes() const {
     99   // Get length for each extension block.
    100   uint16_t length = 0;
    101   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    102       extensionMap_.begin();
    103   while (it != extensionMap_.end()) {
    104     HeaderExtension* extension = it->second;
    105     length += extension->length;
    106     it++;
    107   }
    108   // Add RTP extension header length.
    109   if (length > 0) {
    110     length += kRtpOneByteHeaderLength;
    111   }
    112   return length;
    113 }
    114 
    115 int32_t RtpHeaderExtensionMap::GetLengthUntilBlockStartInBytes(
    116     const RTPExtensionType type) const {
    117   uint8_t id;
    118   if (GetId(type, &id) != 0) {
    119     // Not registered.
    120     return -1;
    121   }
    122   // Get length until start of extension block type.
    123   uint16_t length = kRtpOneByteHeaderLength;
    124 
    125   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    126       extensionMap_.begin();
    127   while (it != extensionMap_.end()) {
    128     HeaderExtension* extension = it->second;
    129     if (extension->type == type) {
    130       break;
    131     } else {
    132       length += extension->length;
    133     }
    134     it++;
    135   }
    136   return length;
    137 }
    138 
    139 int32_t RtpHeaderExtensionMap::Size() const {
    140   return extensionMap_.size();
    141 }
    142 
    143 RTPExtensionType RtpHeaderExtensionMap::First() const {
    144   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    145       extensionMap_.begin();
    146   if (it == extensionMap_.end()) {
    147      return kRtpExtensionNone;
    148   }
    149   HeaderExtension* extension = it->second;
    150   return extension->type;
    151 }
    152 
    153 RTPExtensionType RtpHeaderExtensionMap::Next(RTPExtensionType type) const {
    154   uint8_t id;
    155   if (GetId(type, &id) != 0) {
    156     return kRtpExtensionNone;
    157   }
    158   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    159       extensionMap_.find(id);
    160   if (it == extensionMap_.end()) {
    161     return kRtpExtensionNone;
    162   }
    163   it++;
    164   if (it == extensionMap_.end()) {
    165     return kRtpExtensionNone;
    166   }
    167   HeaderExtension* extension = it->second;
    168   return extension->type;
    169 }
    170 
    171 void RtpHeaderExtensionMap::GetCopy(RtpHeaderExtensionMap* map) const {
    172   assert(map);
    173   std::map<uint8_t, HeaderExtension*>::const_iterator it =
    174       extensionMap_.begin();
    175   while (it != extensionMap_.end()) {
    176     HeaderExtension* extension = it->second;
    177     map->Register(extension->type, it->first);
    178     it++;
    179   }
    180 }
    181 }  // namespace webrtc
    182