Index: webrtc/modules/audio_coding/neteq/payload_splitter.cc |
diff --git a/webrtc/modules/audio_coding/neteq/payload_splitter.cc b/webrtc/modules/audio_coding/neteq/payload_splitter.cc |
index 530e9d064dc703a655c7dd00aa0392f4140ea0a2..87d2ce588e97732923a13990be8e513723bacc59 100644 |
--- a/webrtc/modules/audio_coding/neteq/payload_splitter.cc |
+++ b/webrtc/modules/audio_coding/neteq/payload_splitter.cc |
@@ -11,6 +11,7 @@ |
#include "webrtc/modules/audio_coding/neteq/payload_splitter.h" |
#include <assert.h> |
+#include <iostream> |
#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
@@ -29,10 +30,9 @@ int PayloadSplitter::SplitRed(PacketList* packet_list) { |
int ret = kOK; |
PacketList::iterator it = packet_list->begin(); |
while (it != packet_list->end()) { |
- PacketList new_packets; // An empty list to store the split packets in. |
- Packet* red_packet = (*it); |
- assert(red_packet->payload); |
- uint8_t* payload_ptr = red_packet->payload; |
+ const Packet* red_packet = (*it); |
+ assert(!red_packet->payload.empty()); |
+ const uint8_t* payload_ptr = red_packet->payload.data(); |
// Read RED headers (according to RFC 2198): |
// |
@@ -47,72 +47,74 @@ int PayloadSplitter::SplitRed(PacketList* packet_list) { |
// |0| Block PT | |
// +-+-+-+-+-+-+-+-+ |
+ struct RedHeader { |
+ uint8_t payload_type; |
+ uint32_t timestamp; |
+ size_t payload_length; |
+ bool primary; |
+ }; |
+ |
+ std::vector<RedHeader> new_headers; |
bool last_block = false; |
size_t sum_length = 0; |
while (!last_block) { |
- Packet* new_packet = new Packet; |
- new_packet->header = red_packet->header; |
+ RedHeader new_header; |
// Check the F bit. If F == 0, this was the last block. |
last_block = ((*payload_ptr & 0x80) == 0); |
// Bits 1 through 7 are payload type. |
- new_packet->header.payloadType = payload_ptr[0] & 0x7F; |
+ new_header.payload_type = payload_ptr[0] & 0x7F; |
if (last_block) { |
// No more header data to read. |
++sum_length; // Account for RED header size of 1 byte. |
- new_packet->payload_length = red_packet->payload_length - sum_length; |
- new_packet->primary = true; // Last block is always primary. |
+ new_header.timestamp = red_packet->header.timestamp; |
+ new_header.payload_length = red_packet->payload.size() - sum_length; |
+ new_header.primary = true; // Last block is always primary. |
payload_ptr += 1; // Advance to first payload byte. |
} else { |
// Bits 8 through 21 are timestamp offset. |
int timestamp_offset = (payload_ptr[1] << 6) + |
((payload_ptr[2] & 0xFC) >> 2); |
- new_packet->header.timestamp = red_packet->header.timestamp - |
- timestamp_offset; |
+ new_header.timestamp = red_packet->header.timestamp - timestamp_offset; |
// Bits 22 through 31 are payload length. |
- new_packet->payload_length = ((payload_ptr[2] & 0x03) << 8) + |
- payload_ptr[3]; |
- new_packet->primary = false; |
+ new_header.payload_length = |
+ ((payload_ptr[2] & 0x03) << 8) + payload_ptr[3]; |
+ new_header.primary = false; |
payload_ptr += 4; // Advance to next RED header. |
} |
- sum_length += new_packet->payload_length; |
+ sum_length += new_header.payload_length; |
sum_length += 4; // Account for RED header size of 4 bytes. |
// Store in new list of packets. |
- new_packets.push_back(new_packet); |
+ new_headers.push_back(new_header); |
} |
// Populate the new packets with payload data. |
// |payload_ptr| now points at the first payload byte. |
- PacketList::iterator new_it; |
- for (new_it = new_packets.begin(); new_it != new_packets.end(); ++new_it) { |
- size_t payload_length = (*new_it)->payload_length; |
+ PacketList new_packets; // An empty list to store the split packets in. |
+ for (const auto& new_header : new_headers) { |
+ size_t payload_length = new_header.payload_length; |
if (payload_ptr + payload_length > |
- red_packet->payload + red_packet->payload_length) { |
+ red_packet->payload.data() + red_packet->payload.size()) { |
// The block lengths in the RED headers do not match the overall packet |
// length. Something is corrupt. Discard this and the remaining |
// payloads from this packet. |
LOG(LS_WARNING) << "SplitRed length mismatch"; |
- while (new_it != new_packets.end()) { |
- // Payload should not have been allocated yet. |
- assert(!(*new_it)->payload); |
- delete (*new_it); |
- new_it = new_packets.erase(new_it); |
- } |
ret = kRedLengthMismatch; |
break; |
} |
- (*new_it)->payload = new uint8_t[payload_length]; |
- memcpy((*new_it)->payload, payload_ptr, payload_length); |
+ Packet* new_packet = new Packet; |
+ new_packet->header = red_packet->header; |
+ new_packet->header.timestamp = new_header.timestamp; |
+ new_packet->header.payloadType = new_header.payload_type; |
+ new_packet->primary = new_header.primary; |
+ new_packet->payload.SetData(payload_ptr, payload_length); |
+ new_packets.push_front(new_packet); |
payload_ptr += payload_length; |
} |
- // Reverse the order of the new packets, so that the primary payload is |
- // always first. |
- new_packets.reverse(); |
// Insert new packets into original list, before the element pointed to by |
// iterator |it|. |
packet_list->splice(it, new_packets, new_packets.begin(), |
new_packets.end()); |
// Delete old packet payload. |
- delete [] (*it)->payload; |
delete (*it); |
// Remove |it| from the packet list. This operation effectively moves the |
// iterator |it| to the next packet in the list. Thus, we do not have to |
@@ -148,7 +150,8 @@ int PayloadSplitter::SplitFec(PacketList* packet_list, |
// are handled separately. |
assert(decoder != NULL || decoder_database->IsComfortNoise(payload_type)); |
if (!decoder || |
- !decoder->PacketHasFec(packet->payload, packet->payload_length)) { |
+ !decoder->PacketHasFec(packet->payload.data(), |
+ packet->payload.size())) { |
++it; |
continue; |
} |
@@ -162,12 +165,10 @@ int PayloadSplitter::SplitFec(PacketList* packet_list, |
Packet* new_packet = new Packet; |
new_packet->header = packet->header; |
- int duration = decoder-> |
- PacketDurationRedundant(packet->payload, packet->payload_length); |
+ int duration = decoder->PacketDurationRedundant(packet->payload.data(), |
+ packet->payload.size()); |
new_packet->header.timestamp -= duration; |
- new_packet->payload = new uint8_t[packet->payload_length]; |
- memcpy(new_packet->payload, packet->payload, packet->payload_length); |
- new_packet->payload_length = packet->payload_length; |
+ new_packet->payload.SetData(packet->payload); |
new_packet->primary = false; |
new_packet->sync_packet = packet->sync_packet; |
// Waiting time should not be set here. |
@@ -203,7 +204,6 @@ int PayloadSplitter::CheckRedPayloads(PacketList* packet_list, |
if (this_payload_type != main_payload_type) { |
// We do not allow redundant payloads of a different type. |
// Discard this payload. |
- delete [] (*it)->payload; |
delete (*it); |
// Remove |it| from the packet list. This operation effectively |
// moves the iterator |it| to the next packet in the list. Thus, we |
@@ -304,15 +304,15 @@ int PayloadSplitter::SplitAudio(PacketList* packet_list, |
case NetEqDecoder::kDecoderILBC: { |
size_t bytes_per_frame; |
int timestamps_per_frame; |
- if (packet->payload_length >= 950) { |
+ if (packet->payload.size() >= 950) { |
LOG(LS_WARNING) << "SplitAudio too large iLBC payload"; |
return kTooLargePayload; |
} |
- if (packet->payload_length % 38 == 0) { |
+ if (packet->payload.size() % 38 == 0) { |
// 20 ms frames. |
bytes_per_frame = 38; |
timestamps_per_frame = 160; |
- } else if (packet->payload_length % 50 == 0) { |
+ } else if (packet->payload.size() % 50 == 0) { |
// 30 ms frames. |
bytes_per_frame = 50; |
timestamps_per_frame = 240; |
@@ -348,7 +348,6 @@ int PayloadSplitter::SplitAudio(PacketList* packet_list, |
packet_list->splice(it, new_packets, new_packets.begin(), |
new_packets.end()); |
// Delete old packet payload. |
- delete [] (*it)->payload; |
delete (*it); |
// Remove |it| from the packet list. This operation effectively moves the |
// iterator |it| to the next packet in the list. Thus, we do not have to |
@@ -365,7 +364,7 @@ void PayloadSplitter::SplitBySamples(const Packet* packet, |
assert(packet); |
assert(new_packets); |
- size_t split_size_bytes = packet->payload_length; |
+ size_t split_size_bytes = packet->payload.size(); |
// Find a "chunk size" >= 20 ms and < 40 ms. |
size_t min_chunk_size = bytes_per_ms * 20; |
@@ -379,17 +378,15 @@ void PayloadSplitter::SplitBySamples(const Packet* packet, |
split_size_bytes * timestamps_per_ms / bytes_per_ms); |
uint32_t timestamp = packet->header.timestamp; |
- uint8_t* payload_ptr = packet->payload; |
- size_t len = packet->payload_length; |
+ const uint8_t* payload_ptr = packet->payload.data(); |
+ size_t len = packet->payload.size(); |
while (len >= (2 * split_size_bytes)) { |
Packet* new_packet = new Packet; |
- new_packet->payload_length = split_size_bytes; |
new_packet->header = packet->header; |
new_packet->header.timestamp = timestamp; |
timestamp += timestamps_per_chunk; |
new_packet->primary = packet->primary; |
- new_packet->payload = new uint8_t[split_size_bytes]; |
- memcpy(new_packet->payload, payload_ptr, split_size_bytes); |
+ new_packet->payload.SetData(payload_ptr, split_size_bytes); |
payload_ptr += split_size_bytes; |
new_packets->push_back(new_packet); |
len -= split_size_bytes; |
@@ -397,12 +394,10 @@ void PayloadSplitter::SplitBySamples(const Packet* packet, |
if (len > 0) { |
Packet* new_packet = new Packet; |
- new_packet->payload_length = len; |
new_packet->header = packet->header; |
new_packet->header.timestamp = timestamp; |
new_packet->primary = packet->primary; |
- new_packet->payload = new uint8_t[len]; |
- memcpy(new_packet->payload, payload_ptr, len); |
+ new_packet->payload.SetData(payload_ptr, len); |
new_packets->push_back(new_packet); |
} |
} |
@@ -411,29 +406,27 @@ int PayloadSplitter::SplitByFrames(const Packet* packet, |
size_t bytes_per_frame, |
uint32_t timestamps_per_frame, |
PacketList* new_packets) { |
- if (packet->payload_length % bytes_per_frame != 0) { |
+ if (packet->payload.size() % bytes_per_frame != 0) { |
LOG(LS_WARNING) << "SplitByFrames length mismatch"; |
return kFrameSplitError; |
} |
- if (packet->payload_length == bytes_per_frame) { |
+ if (packet->payload.size() == bytes_per_frame) { |
// Special case. Do not split the payload. |
return kNoSplit; |
} |
uint32_t timestamp = packet->header.timestamp; |
- uint8_t* payload_ptr = packet->payload; |
- size_t len = packet->payload_length; |
+ const uint8_t* payload_ptr = packet->payload.data(); |
+ size_t len = packet->payload.size(); |
while (len > 0) { |
assert(len >= bytes_per_frame); |
Packet* new_packet = new Packet; |
- new_packet->payload_length = bytes_per_frame; |
new_packet->header = packet->header; |
new_packet->header.timestamp = timestamp; |
timestamp += timestamps_per_frame; |
new_packet->primary = packet->primary; |
- new_packet->payload = new uint8_t[bytes_per_frame]; |
- memcpy(new_packet->payload, payload_ptr, bytes_per_frame); |
+ new_packet->payload.SetData(payload_ptr, bytes_per_frame); |
payload_ptr += bytes_per_frame; |
new_packets->push_back(new_packet); |
len -= bytes_per_frame; |