Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq4 / tools / packet.cc
1 /*
2  *  Copyright (c) 2014 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 "webrtc/modules/audio_coding/neteq4/tools/packet.h"
12 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
13
14 namespace webrtc {
15 namespace test {
16
17 Packet::Packet(uint8_t* packet_memory,
18                size_t allocated_bytes,
19                double time_ms,
20                const RtpHeaderParser& parser)
21     : payload_memory_(packet_memory),
22       payload_(NULL),
23       packet_length_bytes_(allocated_bytes),
24       payload_length_bytes_(0),
25       virtual_packet_length_bytes_(allocated_bytes),
26       virtual_payload_length_bytes_(0),
27       time_ms_(time_ms) {
28   valid_header_ = ParseHeader(parser);
29 }
30
31 Packet::Packet(uint8_t* packet_memory,
32                size_t allocated_bytes,
33                size_t virtual_packet_length_bytes,
34                double time_ms,
35                const RtpHeaderParser& parser)
36     : payload_memory_(packet_memory),
37       payload_(NULL),
38       packet_length_bytes_(allocated_bytes),
39       payload_length_bytes_(0),
40       virtual_packet_length_bytes_(virtual_packet_length_bytes),
41       virtual_payload_length_bytes_(0),
42       time_ms_(time_ms) {
43   valid_header_ = ParseHeader(parser);
44 }
45
46 Packet::Packet(uint8_t* packet_memory, size_t allocated_bytes, double time_ms)
47     : payload_memory_(packet_memory),
48       payload_(NULL),
49       packet_length_bytes_(allocated_bytes),
50       payload_length_bytes_(0),
51       virtual_packet_length_bytes_(allocated_bytes),
52       virtual_payload_length_bytes_(0),
53       time_ms_(time_ms) {
54   scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
55   valid_header_ = ParseHeader(*parser);
56 }
57
58 Packet::Packet(uint8_t* packet_memory,
59                size_t allocated_bytes,
60                size_t virtual_packet_length_bytes,
61                double time_ms)
62     : payload_memory_(packet_memory),
63       payload_(NULL),
64       packet_length_bytes_(allocated_bytes),
65       payload_length_bytes_(0),
66       virtual_packet_length_bytes_(virtual_packet_length_bytes),
67       virtual_payload_length_bytes_(0),
68       time_ms_(time_ms) {
69   scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
70   valid_header_ = ParseHeader(*parser);
71 }
72
73 bool Packet::ExtractRedHeaders(std::list<RTPHeader*>* headers) const {
74   //
75   //  0                   1                    2                   3
76   //  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
77   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78   // |1|   block PT  |  timestamp offset         |   block length    |
79   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80   // |1|    ...                                                      |
81   // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82   // |0|   block PT  |
83   // +-+-+-+-+-+-+-+-+
84   //
85
86   assert(payload_);
87   const uint8_t* payload_ptr = payload_;
88   const uint8_t* payload_end_ptr = payload_ptr + payload_length_bytes_;
89
90   // Find all RED headers with the extension bit set to 1. That is, all headers
91   // but the last one.
92   while ((payload_ptr < payload_end_ptr) && (*payload_ptr & 0x80)) {
93     RTPHeader* header = new RTPHeader;
94     CopyToHeader(header);
95     header->payloadType = payload_ptr[0] & 0x7F;
96     uint32_t offset = (payload_ptr[1] << 6) + ((payload_ptr[2] & 0xFC) >> 2);
97     header->timestamp -= offset;
98     headers->push_front(header);
99     payload_ptr += 4;
100   }
101   // Last header.
102   assert(payload_ptr < payload_end_ptr);
103   if (payload_ptr >= payload_end_ptr) {
104     return false;  // Payload too short.
105   }
106   RTPHeader* header = new RTPHeader;
107   CopyToHeader(header);
108   header->payloadType = payload_ptr[0] & 0x7F;
109   headers->push_front(header);
110   return true;
111 }
112
113 void Packet::DeleteRedHeaders(std::list<RTPHeader*>* headers) {
114   while (!headers->empty()) {
115     delete headers->front();
116     headers->pop_front();
117   }
118 }
119
120 bool Packet::ParseHeader(const RtpHeaderParser& parser) {
121   bool valid_header = parser.Parse(
122       payload_memory_.get(), static_cast<int>(packet_length_bytes_), &header_);
123   assert(valid_header);
124   if (!valid_header) {
125     return false;
126   }
127   assert(header_.headerLength <= packet_length_bytes_);
128   payload_ = &payload_memory_[header_.headerLength];
129   assert(packet_length_bytes_ >= header_.headerLength);
130   payload_length_bytes_ = packet_length_bytes_ - header_.headerLength;
131   assert(virtual_packet_length_bytes_ >= header_.headerLength);
132   virtual_payload_length_bytes_ =
133       virtual_packet_length_bytes_ - header_.headerLength;
134   return true;
135 }
136
137 void Packet::CopyToHeader(RTPHeader* destination) const {
138   destination->markerBit = header_.markerBit;
139   destination->payloadType = header_.payloadType;
140   destination->sequenceNumber = header_.sequenceNumber;
141   destination->timestamp = header_.timestamp;
142   destination->ssrc = header_.ssrc;
143   destination->numCSRCs = header_.numCSRCs;
144   destination->paddingLength = header_.paddingLength;
145   destination->headerLength = header_.headerLength;
146   destination->payload_type_frequency = header_.payload_type_frequency;
147   memcpy(&destination->arrOfCSRCs,
148          &header_.arrOfCSRCs,
149          sizeof(header_.arrOfCSRCs));
150   memcpy(
151       &destination->extension, &header_.extension, sizeof(header_.extension));
152 }
153
154 }  // namespace test
155 }  // namespace webrtc