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 16namespace webrtc { 17 18RtpHeaderExtensionMap::RtpHeaderExtensionMap() { 19} 20 21RtpHeaderExtensionMap::~RtpHeaderExtensionMap() { 22 Erase(); 23} 24 25void 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 34int32_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 55int32_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 68bool 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 78int32_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 91int32_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 108uint16_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 125int32_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 149int32_t RtpHeaderExtensionMap::Size() const { 150 return extensionMap_.size(); 151} 152 153RTPExtensionType 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 163RTPExtensionType 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 181void 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