aboutsummaryrefslogtreecommitdiff
path: root/webrtc/modules/audio_coding/neteq/tools/packet.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webrtc/modules/audio_coding/neteq/tools/packet.cc')
-rw-r--r--webrtc/modules/audio_coding/neteq/tools/packet.cc167
1 files changed, 167 insertions, 0 deletions
diff --git a/webrtc/modules/audio_coding/neteq/tools/packet.cc b/webrtc/modules/audio_coding/neteq/tools/packet.cc
new file mode 100644
index 0000000000..b8b27afdec
--- /dev/null
+++ b/webrtc/modules/audio_coding/neteq/tools/packet.cc
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/audio_coding/neteq/tools/packet.h"
+
+#include <string.h>
+
+#include "webrtc/modules/interface/module_common_types.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
+
+namespace webrtc {
+namespace test {
+
+Packet::Packet(uint8_t* packet_memory,
+ size_t allocated_bytes,
+ double time_ms,
+ const RtpHeaderParser& parser)
+ : payload_memory_(packet_memory),
+ payload_(NULL),
+ packet_length_bytes_(allocated_bytes),
+ payload_length_bytes_(0),
+ virtual_packet_length_bytes_(allocated_bytes),
+ virtual_payload_length_bytes_(0),
+ time_ms_(time_ms) {
+ valid_header_ = ParseHeader(parser);
+}
+
+Packet::Packet(uint8_t* packet_memory,
+ size_t allocated_bytes,
+ size_t virtual_packet_length_bytes,
+ double time_ms,
+ const RtpHeaderParser& parser)
+ : payload_memory_(packet_memory),
+ payload_(NULL),
+ packet_length_bytes_(allocated_bytes),
+ payload_length_bytes_(0),
+ virtual_packet_length_bytes_(virtual_packet_length_bytes),
+ virtual_payload_length_bytes_(0),
+ time_ms_(time_ms) {
+ valid_header_ = ParseHeader(parser);
+}
+
+Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
+ : payload_memory_(packet_memory),
+ payload_(NULL),
+ packet_length_bytes_(allocated_bytes),
+ payload_length_bytes_(0),
+ virtual_packet_length_bytes_(allocated_bytes),
+ virtual_payload_length_bytes_(0),
+ time_ms_(time_ms) {
+ rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+ valid_header_ = ParseHeader(*parser);
+}
+
+Packet::Packet(uint8_t* packet_memory,
+ size_t allocated_bytes,
+ size_t virtual_packet_length_bytes,
+ double time_ms)
+ : payload_memory_(packet_memory),
+ payload_(NULL),
+ packet_length_bytes_(allocated_bytes),
+ payload_length_bytes_(0),
+ virtual_packet_length_bytes_(virtual_packet_length_bytes),
+ virtual_payload_length_bytes_(0),
+ time_ms_(time_ms) {
+ rtc::scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
+ valid_header_ = ParseHeader(*parser);
+}
+
+bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
+ //
+ // 0 1 2 3
+ // 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
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |1| block PT | timestamp offset | block length |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |1| ... |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // |0| block PT |
+ // +-+-+-+-+-+-+-+-+
+ //
+
+ assert(payload_);
+ const uint8_t* payload_ptr = payload_;
+ const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
+
+ // Find all RED headers with the extension bit set to 1. That is, all headers
+ // but the last one.
+ while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
+ RTPHeader* header = new RTPHeader;
+ CopyToHeader(header);
+ header->payloadType = payload_ptr[0] & 0x7F;
+ uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
+ header->timestamp -= offset;
+ headers->push_front(header);
+ payload_ptr += 4;
+ }
+ // Last header.
+ assert(payload_ptr < payload_end_ptr);
+ if (payload_ptr >= payload_end_ptr) {
+ return false; // Payload too short.
+ }
+ RTPHeader* header = new RTPHeader;
+ CopyToHeader(header);
+ header->payloadType = payload_ptr[0] & 0x7F;
+ headers->push_front(header);
+ return true;
+}
+
+void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
+ while (!headers->empty()) {
+ delete headers->front();
+ headers->pop_front();
+ }
+}
+
+void Packet::ConvertHeader(WebRtcRTPHeader* copy_to) const {
+ memcpy(&copy_to->header, &header_, sizeof(header_));
+ copy_to->frameType = kAudioFrameSpeech;
+ copy_to->type.Audio.numEnergy = 0;
+ copy_to->type.Audio.channel = 1;
+ copy_to->type.Audio.isCNG = false;
+}
+
+bool Packet::ParseHeader(const RtpHeaderParser& parser) {
+ bool valid_header = parser.Parse(
+ payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_);
+ assert(valid_header);
+ if (!valid_header) {
+ return false;
+ }
+ assert(header_.headerLength <= packet_length_bytes_);
+ payload_ = &payload_memory_[header_.headerLength];
+ assert(packet_length_bytes_ >= header_.headerLength);
+ payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
+ assert(virtual_packet_length_bytes_ >= header_.headerLength);
+ virtual_payload_length_bytes_ =
+ virtual_packet_length_bytes_ - header_.headerLength;
+ return true;
+}
+
+void Packet::CopyToHeader(RTPHeader* destination) const {
+ destination->markerBit = header_.markerBit;
+ destination->payloadType = header_.payloadType;
+ destination->sequenceNumber = header_.sequenceNumber;
+ destination->timestamp = header_.timestamp;
+ destination->ssrc = header_.ssrc;
+ destination->numCSRCs = header_.numCSRCs;
+ destination->paddingLength = header_.paddingLength;
+ destination->headerLength = header_.headerLength;
+ destination->payload_type_frequency = header_.payload_type_frequency;
+ memcpy(&destination->arrOfCSRCs,
+ &header_.arrOfCSRCs,
+ sizeof(header_.arrOfCSRCs));
+ memcpy(
+ &destination->extension, &header_.extension, sizeof(header_.extension));
+}
+
+} // namespace test
+} // namespace webrtc