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