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 |
11 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" | 11 #include "webrtc/modules/audio_coding/neteq/payload_splitter.h" |
12 | 12 |
13 #include <assert.h> | 13 #include <assert.h> |
14 #include <iostream> | |
14 | 15 |
15 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/logging.h" | 17 #include "webrtc/base/logging.h" |
17 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" | 18 #include "webrtc/modules/audio_coding/neteq/decoder_database.h" |
18 | 19 |
19 namespace webrtc { | 20 namespace webrtc { |
20 | 21 |
21 // The method loops through a list of packets {A, B, C, ...}. Each packet is | 22 // The method loops through a list of packets {A, B, C, ...}. Each packet is |
22 // split into its corresponding RED payloads, {A1, A2, ...}, which is | 23 // split into its corresponding RED payloads, {A1, A2, ...}, which is |
23 // temporarily held in the list |new_packets|. | 24 // temporarily held in the list |new_packets|. |
24 // When the first packet in |packet_list| has been processed, the orignal packet | 25 // When the first packet in |packet_list| has been processed, the orignal packet |
25 // is replaced by the new ones in |new_packets|, so that |packet_list| becomes: | 26 // is replaced by the new ones in |new_packets|, so that |packet_list| becomes: |
26 // {A1, A2, ..., B, C, ...}. The method then continues with B, and C, until all | 27 // {A1, A2, ..., B, C, ...}. The method then continues with B, and C, until all |
27 // the original packets have been replaced by their split payloads. | 28 // the original packets have been replaced by their split payloads. |
28 int PayloadSplitter::SplitRed(PacketList* packet_list) { | 29 int PayloadSplitter::SplitRed(PacketList* packet_list) { |
29 int ret = kOK; | 30 int ret = kOK; |
30 PacketList::iterator it = packet_list->begin(); | 31 PacketList::iterator it = packet_list->begin(); |
31 while (it != packet_list->end()) { | 32 while (it != packet_list->end()) { |
32 PacketList new_packets; // An empty list to store the split packets in. | 33 const Packet* red_packet = (*it); |
33 Packet* red_packet = (*it); | 34 assert(!red_packet->payload.empty()); |
34 assert(red_packet->payload); | 35 const uint8_t* payload_ptr = red_packet->payload.data(); |
35 uint8_t* payload_ptr = red_packet->payload; | |
36 | 36 |
37 // Read RED headers (according to RFC 2198): | 37 // Read RED headers (according to RFC 2198): |
38 // | 38 // |
39 // 0 1 2 3 | 39 // 0 1 2 3 |
40 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 40 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
41 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 41 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
42 // |F| block PT | timestamp offset | block length | | 42 // |F| block PT | timestamp offset | block length | |
43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 43 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
44 // Last RED header: | 44 // Last RED header: |
45 // 0 1 2 3 4 5 6 7 | 45 // 0 1 2 3 4 5 6 7 |
46 // +-+-+-+-+-+-+-+-+ | 46 // +-+-+-+-+-+-+-+-+ |
47 // |0| Block PT | | 47 // |0| Block PT | |
48 // +-+-+-+-+-+-+-+-+ | 48 // +-+-+-+-+-+-+-+-+ |
49 | 49 |
50 struct RedHeader { | |
51 uint8_t payload_type; | |
52 uint32_t timestamp; | |
53 size_t payload_length; | |
54 bool primary; | |
55 }; | |
56 | |
57 std::vector<RedHeader> new_headers; | |
50 bool last_block = false; | 58 bool last_block = false; |
51 size_t sum_length = 0; | 59 size_t sum_length = 0; |
52 while (!last_block) { | 60 while (!last_block) { |
53 Packet* new_packet = new Packet; | 61 RedHeader new_header; |
54 new_packet->header = red_packet->header; | |
55 // Check the F bit. If F == 0, this was the last block. | 62 // Check the F bit. If F == 0, this was the last block. |
56 last_block = ((*payload_ptr & 0x80) == 0); | 63 last_block = ((*payload_ptr & 0x80) == 0); |
57 // Bits 1 through 7 are payload type. | 64 // Bits 1 through 7 are payload type. |
58 new_packet->header.payloadType = payload_ptr[0] & 0x7F; | 65 new_header.payload_type = payload_ptr[0] & 0x7F; |
59 if (last_block) { | 66 if (last_block) { |
60 // No more header data to read. | 67 // No more header data to read. |
61 ++sum_length; // Account for RED header size of 1 byte. | 68 ++sum_length; // Account for RED header size of 1 byte. |
62 new_packet->payload_length = red_packet->payload_length - sum_length; | 69 new_header.timestamp = red_packet->header.timestamp; |
63 new_packet->primary = true; // Last block is always primary. | 70 new_header.payload_length = red_packet->payload.size() - sum_length; |
71 new_header.primary = true; // Last block is always primary. | |
64 payload_ptr += 1; // Advance to first payload byte. | 72 payload_ptr += 1; // Advance to first payload byte. |
65 } else { | 73 } else { |
66 // Bits 8 through 21 are timestamp offset. | 74 // Bits 8 through 21 are timestamp offset. |
67 int timestamp_offset = (payload_ptr[1] << 6) + | 75 int timestamp_offset = (payload_ptr[1] << 6) + |
68 ((payload_ptr[2] & 0xFC) >> 2); | 76 ((payload_ptr[2] & 0xFC) >> 2); |
69 new_packet->header.timestamp = red_packet->header.timestamp - | 77 new_header.timestamp = red_packet->header.timestamp - timestamp_offset; |
70 timestamp_offset; | |
71 // Bits 22 through 31 are payload length. | 78 // Bits 22 through 31 are payload length. |
72 new_packet->payload_length = ((payload_ptr[2] & 0x03) << 8) + | 79 new_header.payload_length = |
73 payload_ptr[3]; | 80 ((payload_ptr[2] & 0x03) << 8) + payload_ptr[3]; |
74 new_packet->primary = false; | 81 new_header.primary = false; |
75 payload_ptr += 4; // Advance to next RED header. | 82 payload_ptr += 4; // Advance to next RED header. |
76 } | 83 } |
77 sum_length += new_packet->payload_length; | 84 sum_length += new_header.payload_length; |
78 sum_length += 4; // Account for RED header size of 4 bytes. | 85 sum_length += 4; // Account for RED header size of 4 bytes. |
79 // Store in new list of packets. | 86 // Store in new list of packets. |
80 new_packets.push_back(new_packet); | 87 new_headers.push_back(new_header); |
81 } | 88 } |
82 | 89 |
83 // Populate the new packets with payload data. | 90 // Populate the new packets with payload data. |
84 // |payload_ptr| now points at the first payload byte. | 91 // |payload_ptr| now points at the first payload byte. |
85 PacketList::iterator new_it; | 92 PacketList new_packets; // An empty list to store the split packets in. |
86 for (new_it = new_packets.begin(); new_it != new_packets.end(); ++new_it) { | 93 for (const auto& new_header : new_headers) { |
87 size_t payload_length = (*new_it)->payload_length; | 94 size_t payload_length = new_header.payload_length; |
88 if (payload_ptr + payload_length > | 95 if (payload_ptr + payload_length > |
89 red_packet->payload + red_packet->payload_length) { | 96 red_packet->payload.data() + red_packet->payload.size()) { |
90 // The block lengths in the RED headers do not match the overall packet | 97 // The block lengths in the RED headers do not match the overall packet |
ossu
2016/08/30 15:22:16
Primarily a question to hlundin: I've kept this be
| |
91 // length. Something is corrupt. Discard this and the remaining | 98 // length. Something is corrupt. Discard this and the remaining |
92 // payloads from this packet. | 99 // payloads from this packet. |
93 LOG(LS_WARNING) << "SplitRed length mismatch"; | 100 LOG(LS_WARNING) << "SplitRed length mismatch"; |
94 while (new_it != new_packets.end()) { | |
95 // Payload should not have been allocated yet. | |
96 assert(!(*new_it)->payload); | |
97 delete (*new_it); | |
98 new_it = new_packets.erase(new_it); | |
99 } | |
100 ret = kRedLengthMismatch; | 101 ret = kRedLengthMismatch; |
101 break; | 102 break; |
102 } | 103 } |
103 (*new_it)->payload = new uint8_t[payload_length]; | 104 Packet* new_packet = new Packet; |
104 memcpy((*new_it)->payload, payload_ptr, payload_length); | 105 new_packet->header = red_packet->header; |
106 new_packet->header.timestamp = new_header.timestamp; | |
107 new_packet->header.payloadType = new_header.payload_type; | |
108 new_packet->primary = new_header.primary; | |
109 new_packet->payload = rtc::Buffer(payload_ptr, payload_length); | |
kwiberg-webrtc
2016/08/30 16:04:36
SetData
ossu
2016/08/30 16:27:14
Acknowledged.
| |
110 new_packets.push_front(new_packet); | |
105 payload_ptr += payload_length; | 111 payload_ptr += payload_length; |
106 } | 112 } |
107 // Reverse the order of the new packets, so that the primary payload is | |
108 // always first. | |
109 new_packets.reverse(); | |
110 // Insert new packets into original list, before the element pointed to by | 113 // Insert new packets into original list, before the element pointed to by |
111 // iterator |it|. | 114 // iterator |it|. |
112 packet_list->splice(it, new_packets, new_packets.begin(), | 115 packet_list->splice(it, new_packets, new_packets.begin(), |
113 new_packets.end()); | 116 new_packets.end()); |
114 // Delete old packet payload. | 117 // Delete old packet payload. |
115 delete [] (*it)->payload; | |
116 delete (*it); | 118 delete (*it); |
117 // Remove |it| from the packet list. This operation effectively moves the | 119 // Remove |it| from the packet list. This operation effectively moves the |
118 // iterator |it| to the next packet in the list. Thus, we do not have to | 120 // iterator |it| to the next packet in the list. Thus, we do not have to |
119 // increment it manually. | 121 // increment it manually. |
120 it = packet_list->erase(it); | 122 it = packet_list->erase(it); |
121 } | 123 } |
122 return ret; | 124 return ret; |
123 } | 125 } |
124 | 126 |
125 int PayloadSplitter::SplitFec(PacketList* packet_list, | 127 int PayloadSplitter::SplitFec(PacketList* packet_list, |
(...skipping 15 matching lines...) Expand all Loading... | |
141 ++it; | 143 ++it; |
142 continue; | 144 continue; |
143 } | 145 } |
144 | 146 |
145 // Not an FEC packet. | 147 // Not an FEC packet. |
146 AudioDecoder* decoder = decoder_database->GetDecoder(payload_type); | 148 AudioDecoder* decoder = decoder_database->GetDecoder(payload_type); |
147 // decoder should not return NULL, except for comfort noise payloads which | 149 // decoder should not return NULL, except for comfort noise payloads which |
148 // are handled separately. | 150 // are handled separately. |
149 assert(decoder != NULL || decoder_database->IsComfortNoise(payload_type)); | 151 assert(decoder != NULL || decoder_database->IsComfortNoise(payload_type)); |
150 if (!decoder || | 152 if (!decoder || |
151 !decoder->PacketHasFec(packet->payload, packet->payload_length)) { | 153 !decoder->PacketHasFec(packet->payload.data(), |
154 packet->payload.size())) { | |
152 ++it; | 155 ++it; |
153 continue; | 156 continue; |
154 } | 157 } |
155 | 158 |
156 switch (info->codec_type) { | 159 switch (info->codec_type) { |
157 case NetEqDecoder::kDecoderOpus: | 160 case NetEqDecoder::kDecoderOpus: |
158 case NetEqDecoder::kDecoderOpus_2ch: { | 161 case NetEqDecoder::kDecoderOpus_2ch: { |
159 // The main payload of this packet should be decoded as a primary | 162 // The main payload of this packet should be decoded as a primary |
160 // payload, even if it comes as a secondary payload in a RED packet. | 163 // payload, even if it comes as a secondary payload in a RED packet. |
161 packet->primary = true; | 164 packet->primary = true; |
162 | 165 |
163 Packet* new_packet = new Packet; | 166 Packet* new_packet = new Packet; |
164 new_packet->header = packet->header; | 167 new_packet->header = packet->header; |
165 int duration = decoder-> | 168 int duration = decoder->PacketDurationRedundant(packet->payload.data(), |
166 PacketDurationRedundant(packet->payload, packet->payload_length); | 169 packet->payload.size()); |
167 new_packet->header.timestamp -= duration; | 170 new_packet->header.timestamp -= duration; |
168 new_packet->payload = new uint8_t[packet->payload_length]; | 171 new_packet->payload = |
169 memcpy(new_packet->payload, packet->payload, packet->payload_length); | 172 rtc::Buffer(packet->payload.data(), packet->payload.size()); |
kwiberg-webrtc
2016/08/30 16:04:36
new_packet->payload.SetData(packet->payload);
usi
ossu
2016/08/30 16:27:14
Acknowledged.
| |
170 new_packet->payload_length = packet->payload_length; | |
171 new_packet->primary = false; | 173 new_packet->primary = false; |
172 new_packet->sync_packet = packet->sync_packet; | 174 new_packet->sync_packet = packet->sync_packet; |
173 // Waiting time should not be set here. | 175 // Waiting time should not be set here. |
174 RTC_DCHECK(!packet->waiting_time); | 176 RTC_DCHECK(!packet->waiting_time); |
175 | 177 |
176 packet_list->insert(it, new_packet); | 178 packet_list->insert(it, new_packet); |
177 break; | 179 break; |
178 } | 180 } |
179 default: { | 181 default: { |
180 LOG(LS_WARNING) << "SplitFec wrong payload type"; | 182 LOG(LS_WARNING) << "SplitFec wrong payload type"; |
(...skipping 15 matching lines...) Expand all Loading... | |
196 uint8_t this_payload_type = (*it)->header.payloadType; | 198 uint8_t this_payload_type = (*it)->header.payloadType; |
197 if (!decoder_database.IsDtmf(this_payload_type) && | 199 if (!decoder_database.IsDtmf(this_payload_type) && |
198 !decoder_database.IsComfortNoise(this_payload_type)) { | 200 !decoder_database.IsComfortNoise(this_payload_type)) { |
199 if (main_payload_type == -1) { | 201 if (main_payload_type == -1) { |
200 // This is the first packet in the list which is non-DTMF non-CNG. | 202 // This is the first packet in the list which is non-DTMF non-CNG. |
201 main_payload_type = this_payload_type; | 203 main_payload_type = this_payload_type; |
202 } else { | 204 } else { |
203 if (this_payload_type != main_payload_type) { | 205 if (this_payload_type != main_payload_type) { |
204 // We do not allow redundant payloads of a different type. | 206 // We do not allow redundant payloads of a different type. |
205 // Discard this payload. | 207 // Discard this payload. |
206 delete [] (*it)->payload; | |
207 delete (*it); | 208 delete (*it); |
208 // Remove |it| from the packet list. This operation effectively | 209 // Remove |it| from the packet list. This operation effectively |
209 // moves the iterator |it| to the next packet in the list. Thus, we | 210 // moves the iterator |it| to the next packet in the list. Thus, we |
210 // do not have to increment it manually. | 211 // do not have to increment it manually. |
211 it = packet_list->erase(it); | 212 it = packet_list->erase(it); |
212 ++num_deleted_packets; | 213 ++num_deleted_packets; |
213 continue; | 214 continue; |
214 } | 215 } |
215 } | 216 } |
216 } | 217 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 break; | 298 break; |
298 } | 299 } |
299 case NetEqDecoder::kDecoderPCM16B_5ch: { | 300 case NetEqDecoder::kDecoderPCM16B_5ch: { |
300 // 5 * 16 bytes per ms; 8 timestamps per ms. | 301 // 5 * 16 bytes per ms; 8 timestamps per ms. |
301 SplitBySamples(packet, 5 * 16, 8, &new_packets); | 302 SplitBySamples(packet, 5 * 16, 8, &new_packets); |
302 break; | 303 break; |
303 } | 304 } |
304 case NetEqDecoder::kDecoderILBC: { | 305 case NetEqDecoder::kDecoderILBC: { |
305 size_t bytes_per_frame; | 306 size_t bytes_per_frame; |
306 int timestamps_per_frame; | 307 int timestamps_per_frame; |
307 if (packet->payload_length >= 950) { | 308 if (packet->payload.size() >= 950) { |
308 LOG(LS_WARNING) << "SplitAudio too large iLBC payload"; | 309 LOG(LS_WARNING) << "SplitAudio too large iLBC payload"; |
309 return kTooLargePayload; | 310 return kTooLargePayload; |
310 } | 311 } |
311 if (packet->payload_length % 38 == 0) { | 312 if (packet->payload.size() % 38 == 0) { |
312 // 20 ms frames. | 313 // 20 ms frames. |
313 bytes_per_frame = 38; | 314 bytes_per_frame = 38; |
314 timestamps_per_frame = 160; | 315 timestamps_per_frame = 160; |
315 } else if (packet->payload_length % 50 == 0) { | 316 } else if (packet->payload.size() % 50 == 0) { |
316 // 30 ms frames. | 317 // 30 ms frames. |
317 bytes_per_frame = 50; | 318 bytes_per_frame = 50; |
318 timestamps_per_frame = 240; | 319 timestamps_per_frame = 240; |
319 } else { | 320 } else { |
320 LOG(LS_WARNING) << "SplitAudio invalid iLBC payload"; | 321 LOG(LS_WARNING) << "SplitAudio invalid iLBC payload"; |
321 return kFrameSplitError; | 322 return kFrameSplitError; |
322 } | 323 } |
323 int ret = SplitByFrames(packet, bytes_per_frame, timestamps_per_frame, | 324 int ret = SplitByFrames(packet, bytes_per_frame, timestamps_per_frame, |
324 &new_packets); | 325 &new_packets); |
325 if (ret < 0) { | 326 if (ret < 0) { |
(...skipping 15 matching lines...) Expand all Loading... | |
341 // old one. Skip the code after the switch case, and jump straight to | 342 // old one. Skip the code after the switch case, and jump straight to |
342 // the next packet in the while loop. | 343 // the next packet in the while loop. |
343 continue; | 344 continue; |
344 } | 345 } |
345 } | 346 } |
346 // Insert new packets into original list, before the element pointed to by | 347 // Insert new packets into original list, before the element pointed to by |
347 // iterator |it|. | 348 // iterator |it|. |
348 packet_list->splice(it, new_packets, new_packets.begin(), | 349 packet_list->splice(it, new_packets, new_packets.begin(), |
349 new_packets.end()); | 350 new_packets.end()); |
350 // Delete old packet payload. | 351 // Delete old packet payload. |
351 delete [] (*it)->payload; | |
352 delete (*it); | 352 delete (*it); |
353 // Remove |it| from the packet list. This operation effectively moves the | 353 // Remove |it| from the packet list. This operation effectively moves the |
354 // iterator |it| to the next packet in the list. Thus, we do not have to | 354 // iterator |it| to the next packet in the list. Thus, we do not have to |
355 // increment it manually. | 355 // increment it manually. |
356 it = packet_list->erase(it); | 356 it = packet_list->erase(it); |
357 } | 357 } |
358 return kOK; | 358 return kOK; |
359 } | 359 } |
360 | 360 |
361 void PayloadSplitter::SplitBySamples(const Packet* packet, | 361 void PayloadSplitter::SplitBySamples(const Packet* packet, |
362 size_t bytes_per_ms, | 362 size_t bytes_per_ms, |
363 uint32_t timestamps_per_ms, | 363 uint32_t timestamps_per_ms, |
364 PacketList* new_packets) { | 364 PacketList* new_packets) { |
365 assert(packet); | 365 assert(packet); |
366 assert(new_packets); | 366 assert(new_packets); |
367 | 367 |
368 size_t split_size_bytes = packet->payload_length; | 368 size_t split_size_bytes = packet->payload.size(); |
369 | 369 |
370 // Find a "chunk size" >= 20 ms and < 40 ms. | 370 // Find a "chunk size" >= 20 ms and < 40 ms. |
371 size_t min_chunk_size = bytes_per_ms * 20; | 371 size_t min_chunk_size = bytes_per_ms * 20; |
372 // Reduce the split size by half as long as |split_size_bytes| is at least | 372 // Reduce the split size by half as long as |split_size_bytes| is at least |
373 // twice the minimum chunk size (so that the resulting size is at least as | 373 // twice the minimum chunk size (so that the resulting size is at least as |
374 // large as the minimum chunk size). | 374 // large as the minimum chunk size). |
375 while (split_size_bytes >= 2 * min_chunk_size) { | 375 while (split_size_bytes >= 2 * min_chunk_size) { |
376 split_size_bytes >>= 1; | 376 split_size_bytes >>= 1; |
377 } | 377 } |
378 uint32_t timestamps_per_chunk = static_cast<uint32_t>( | 378 uint32_t timestamps_per_chunk = static_cast<uint32_t>( |
379 split_size_bytes * timestamps_per_ms / bytes_per_ms); | 379 split_size_bytes * timestamps_per_ms / bytes_per_ms); |
380 uint32_t timestamp = packet->header.timestamp; | 380 uint32_t timestamp = packet->header.timestamp; |
381 | 381 |
382 uint8_t* payload_ptr = packet->payload; | 382 const uint8_t* payload_ptr = packet->payload.data(); |
383 size_t len = packet->payload_length; | 383 size_t len = packet->payload.size(); |
384 while (len >= (2 * split_size_bytes)) { | 384 while (len >= (2 * split_size_bytes)) { |
385 Packet* new_packet = new Packet; | 385 Packet* new_packet = new Packet; |
386 new_packet->payload_length = split_size_bytes; | |
387 new_packet->header = packet->header; | 386 new_packet->header = packet->header; |
388 new_packet->header.timestamp = timestamp; | 387 new_packet->header.timestamp = timestamp; |
389 timestamp += timestamps_per_chunk; | 388 timestamp += timestamps_per_chunk; |
390 new_packet->primary = packet->primary; | 389 new_packet->primary = packet->primary; |
391 new_packet->payload = new uint8_t[split_size_bytes]; | 390 new_packet->payload = rtc::Buffer(payload_ptr, split_size_bytes); |
392 memcpy(new_packet->payload, payload_ptr, split_size_bytes); | |
393 payload_ptr += split_size_bytes; | 391 payload_ptr += split_size_bytes; |
394 new_packets->push_back(new_packet); | 392 new_packets->push_back(new_packet); |
395 len -= split_size_bytes; | 393 len -= split_size_bytes; |
396 } | 394 } |
397 | 395 |
398 if (len > 0) { | 396 if (len > 0) { |
399 Packet* new_packet = new Packet; | 397 Packet* new_packet = new Packet; |
400 new_packet->payload_length = len; | |
401 new_packet->header = packet->header; | 398 new_packet->header = packet->header; |
402 new_packet->header.timestamp = timestamp; | 399 new_packet->header.timestamp = timestamp; |
403 new_packet->primary = packet->primary; | 400 new_packet->primary = packet->primary; |
404 new_packet->payload = new uint8_t[len]; | 401 new_packet->payload = rtc::Buffer(payload_ptr, len); |
405 memcpy(new_packet->payload, payload_ptr, len); | |
406 new_packets->push_back(new_packet); | 402 new_packets->push_back(new_packet); |
407 } | 403 } |
408 } | 404 } |
409 | 405 |
410 int PayloadSplitter::SplitByFrames(const Packet* packet, | 406 int PayloadSplitter::SplitByFrames(const Packet* packet, |
411 size_t bytes_per_frame, | 407 size_t bytes_per_frame, |
412 uint32_t timestamps_per_frame, | 408 uint32_t timestamps_per_frame, |
413 PacketList* new_packets) { | 409 PacketList* new_packets) { |
414 if (packet->payload_length % bytes_per_frame != 0) { | 410 if (packet->payload.size() % bytes_per_frame != 0) { |
415 LOG(LS_WARNING) << "SplitByFrames length mismatch"; | 411 LOG(LS_WARNING) << "SplitByFrames length mismatch"; |
416 return kFrameSplitError; | 412 return kFrameSplitError; |
417 } | 413 } |
418 | 414 |
419 if (packet->payload_length == bytes_per_frame) { | 415 if (packet->payload.size() == bytes_per_frame) { |
420 // Special case. Do not split the payload. | 416 // Special case. Do not split the payload. |
421 return kNoSplit; | 417 return kNoSplit; |
422 } | 418 } |
423 | 419 |
424 uint32_t timestamp = packet->header.timestamp; | 420 uint32_t timestamp = packet->header.timestamp; |
425 uint8_t* payload_ptr = packet->payload; | 421 const uint8_t* payload_ptr = packet->payload.data(); |
426 size_t len = packet->payload_length; | 422 size_t len = packet->payload.size(); |
427 while (len > 0) { | 423 while (len > 0) { |
428 assert(len >= bytes_per_frame); | 424 assert(len >= bytes_per_frame); |
429 Packet* new_packet = new Packet; | 425 Packet* new_packet = new Packet; |
430 new_packet->payload_length = bytes_per_frame; | |
431 new_packet->header = packet->header; | 426 new_packet->header = packet->header; |
432 new_packet->header.timestamp = timestamp; | 427 new_packet->header.timestamp = timestamp; |
433 timestamp += timestamps_per_frame; | 428 timestamp += timestamps_per_frame; |
434 new_packet->primary = packet->primary; | 429 new_packet->primary = packet->primary; |
435 new_packet->payload = new uint8_t[bytes_per_frame]; | 430 new_packet->payload = rtc::Buffer(payload_ptr, bytes_per_frame); |
kwiberg-webrtc
2016/08/30 16:04:36
SetData
ossu
2016/08/30 16:27:14
Acknowledged.
| |
436 memcpy(new_packet->payload, payload_ptr, bytes_per_frame); | |
437 payload_ptr += bytes_per_frame; | 431 payload_ptr += bytes_per_frame; |
438 new_packets->push_back(new_packet); | 432 new_packets->push_back(new_packet); |
439 len -= bytes_per_frame; | 433 len -= bytes_per_frame; |
440 } | 434 } |
441 return kOK; | 435 return kOK; |
442 } | 436 } |
443 | 437 |
444 } // namespace webrtc | 438 } // namespace webrtc |
OLD | NEW |