OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 size_t sum_length = 0; | 62 size_t sum_length = 0; |
63 while (!last_block) { | 63 while (!last_block) { |
64 RedHeader new_header; | 64 RedHeader new_header; |
65 // Check the F bit. If F == 0, this was the last block. | 65 // Check the F bit. If F == 0, this was the last block. |
66 last_block = ((*payload_ptr & 0x80) == 0); | 66 last_block = ((*payload_ptr & 0x80) == 0); |
67 // Bits 1 through 7 are payload type. | 67 // Bits 1 through 7 are payload type. |
68 new_header.payload_type = payload_ptr[0] & 0x7F; | 68 new_header.payload_type = payload_ptr[0] & 0x7F; |
69 if (last_block) { | 69 if (last_block) { |
70 // No more header data to read. | 70 // No more header data to read. |
71 ++sum_length; // Account for RED header size of 1 byte. | 71 ++sum_length; // Account for RED header size of 1 byte. |
72 new_header.timestamp = red_packet->header.timestamp; | 72 new_header.timestamp = red_packet->timestamp; |
73 new_header.payload_length = red_packet->payload.size() - sum_length; | 73 new_header.payload_length = red_packet->payload.size() - sum_length; |
74 payload_ptr += 1; // Advance to first payload byte. | 74 payload_ptr += 1; // Advance to first payload byte. |
75 } else { | 75 } else { |
76 // Bits 8 through 21 are timestamp offset. | 76 // Bits 8 through 21 are timestamp offset. |
77 int timestamp_offset = | 77 int timestamp_offset = |
78 (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2); | 78 (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2); |
79 new_header.timestamp = red_packet->header.timestamp - timestamp_offset; | 79 new_header.timestamp = red_packet->timestamp - timestamp_offset; |
80 // Bits 22 through 31 are payload length. | 80 // Bits 22 through 31 are payload length. |
81 new_header.payload_length = | 81 new_header.payload_length = |
82 ((payload_ptr[2] & 0x03) << 8) + payload_ptr[3]; | 82 ((payload_ptr[2] & 0x03) << 8) + payload_ptr[3]; |
83 payload_ptr += 4; // Advance to next RED header. | 83 payload_ptr += 4; // Advance to next RED header. |
84 } | 84 } |
85 sum_length += new_header.payload_length; | 85 sum_length += new_header.payload_length; |
86 sum_length += 4; // Account for RED header size of 4 bytes. | 86 sum_length += 4; // Account for RED header size of 4 bytes. |
87 // Store in new list of packets. | 87 // Store in new list of packets. |
88 new_headers.push_back(new_header); | 88 new_headers.push_back(new_header); |
89 } | 89 } |
90 | 90 |
91 if (new_headers.size() <= kMaxRedBlocks) { | 91 if (new_headers.size() <= kMaxRedBlocks) { |
92 // Populate the new packets with payload data. | 92 // Populate the new packets with payload data. |
93 // |payload_ptr| now points at the first payload byte. | 93 // |payload_ptr| now points at the first payload byte. |
94 PacketList new_packets; // An empty list to store the split packets in. | 94 PacketList new_packets; // An empty list to store the split packets in. |
95 for (size_t i = 0; i != new_headers.size(); ++i) { | 95 for (size_t i = 0; i != new_headers.size(); ++i) { |
96 const auto& new_header = new_headers[i]; | 96 const auto& new_header = new_headers[i]; |
97 size_t payload_length = new_header.payload_length; | 97 size_t payload_length = new_header.payload_length; |
98 if (payload_ptr + payload_length > | 98 if (payload_ptr + payload_length > |
99 red_packet->payload.data() + red_packet->payload.size()) { | 99 red_packet->payload.data() + red_packet->payload.size()) { |
100 // The block lengths in the RED headers do not match the overall | 100 // The block lengths in the RED headers do not match the overall |
101 // packet length. Something is corrupt. Discard this and the remaining | 101 // packet length. Something is corrupt. Discard this and the remaining |
102 // payloads from this packet. | 102 // payloads from this packet. |
103 LOG(LS_WARNING) << "SplitRed length mismatch"; | 103 LOG(LS_WARNING) << "SplitRed length mismatch"; |
104 ret = false; | 104 ret = false; |
105 break; | 105 break; |
106 } | 106 } |
107 | 107 |
108 Packet* new_packet = new Packet; | 108 Packet* new_packet = new Packet; |
109 new_packet->header = red_packet->header; | 109 new_packet->timestamp = new_header.timestamp; |
110 new_packet->header.timestamp = new_header.timestamp; | 110 new_packet->payload_type = new_header.payload_type; |
111 new_packet->header.payloadType = new_header.payload_type; | 111 new_packet->sequence_number = red_packet->sequence_number; |
112 new_packet->priority.red_level = | 112 new_packet->priority.red_level = |
113 rtc::checked_cast<int>((new_headers.size() - 1) - i); | 113 rtc::checked_cast<int>((new_headers.size() - 1) - i); |
114 new_packet->payload.SetData(payload_ptr, payload_length); | 114 new_packet->payload.SetData(payload_ptr, payload_length); |
115 new_packets.push_front(new_packet); | 115 new_packets.push_front(new_packet); |
116 payload_ptr += payload_length; | 116 payload_ptr += payload_length; |
117 } | 117 } |
118 // Insert new packets into original list, before the element pointed to by | 118 // Insert new packets into original list, before the element pointed to by |
119 // iterator |it|. | 119 // iterator |it|. |
120 packet_list->splice(it, new_packets, new_packets.begin(), | 120 packet_list->splice(it, new_packets, new_packets.begin(), |
121 new_packets.end()); | 121 new_packets.end()); |
(...skipping 11 matching lines...) Expand all Loading... |
133 return ret; | 133 return ret; |
134 } | 134 } |
135 | 135 |
136 int RedPayloadSplitter::CheckRedPayloads( | 136 int RedPayloadSplitter::CheckRedPayloads( |
137 PacketList* packet_list, | 137 PacketList* packet_list, |
138 const DecoderDatabase& decoder_database) { | 138 const DecoderDatabase& decoder_database) { |
139 PacketList::iterator it = packet_list->begin(); | 139 PacketList::iterator it = packet_list->begin(); |
140 int main_payload_type = -1; | 140 int main_payload_type = -1; |
141 int num_deleted_packets = 0; | 141 int num_deleted_packets = 0; |
142 while (it != packet_list->end()) { | 142 while (it != packet_list->end()) { |
143 uint8_t this_payload_type = (*it)->header.payloadType; | 143 uint8_t this_payload_type = (*it)->payload_type; |
144 if (!decoder_database.IsDtmf(this_payload_type) && | 144 if (!decoder_database.IsDtmf(this_payload_type) && |
145 !decoder_database.IsComfortNoise(this_payload_type)) { | 145 !decoder_database.IsComfortNoise(this_payload_type)) { |
146 if (main_payload_type == -1) { | 146 if (main_payload_type == -1) { |
147 // This is the first packet in the list which is non-DTMF non-CNG. | 147 // This is the first packet in the list which is non-DTMF non-CNG. |
148 main_payload_type = this_payload_type; | 148 main_payload_type = this_payload_type; |
149 } else { | 149 } else { |
150 if (this_payload_type != main_payload_type) { | 150 if (this_payload_type != main_payload_type) { |
151 // We do not allow redundant payloads of a different type. | 151 // We do not allow redundant payloads of a different type. |
152 // Discard this payload. | 152 // Discard this payload. |
153 delete (*it); | 153 delete (*it); |
154 // Remove |it| from the packet list. This operation effectively | 154 // Remove |it| from the packet list. This operation effectively |
155 // moves the iterator |it| to the next packet in the list. Thus, we | 155 // moves the iterator |it| to the next packet in the list. Thus, we |
156 // do not have to increment it manually. | 156 // do not have to increment it manually. |
157 it = packet_list->erase(it); | 157 it = packet_list->erase(it); |
158 ++num_deleted_packets; | 158 ++num_deleted_packets; |
159 continue; | 159 continue; |
160 } | 160 } |
161 } | 161 } |
162 } | 162 } |
163 ++it; | 163 ++it; |
164 } | 164 } |
165 return num_deleted_packets; | 165 return num_deleted_packets; |
166 } | 166 } |
167 | 167 |
168 } // namespace webrtc | 168 } // namespace webrtc |
OLD | NEW |