Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / main / test / RTPFile.cc
1 /*
2  *  Copyright (c) 2012 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 "RTPFile.h"
12
13 #include <stdlib.h>
14
15 #ifdef WIN32
16 #   include <Winsock2.h>
17 #else
18 #   include <arpa/inet.h>
19 #endif
20
21 #include "audio_coding_module.h"
22 #include "engine_configurations.h"
23 #include "gtest/gtest.h" // TODO (tlegrand): Consider removing usage of gtest.
24 #include "rw_lock_wrapper.h"
25
26 namespace webrtc {
27
28 void RTPStream::ParseRTPHeader(WebRtcRTPHeader* rtpInfo,
29                                const uint8_t* rtpHeader) {
30   rtpInfo->header.payloadType = rtpHeader[1];
31   rtpInfo->header.sequenceNumber = (static_cast<uint16_t>(rtpHeader[2]) << 8) |
32       rtpHeader[3];
33   rtpInfo->header.timestamp = (static_cast<uint32_t>(rtpHeader[4]) << 24) |
34       (static_cast<uint32_t>(rtpHeader[5]) << 16) |
35       (static_cast<uint32_t>(rtpHeader[6]) << 8) | rtpHeader[7];
36   rtpInfo->header.ssrc = (static_cast<uint32_t>(rtpHeader[8]) << 24) |
37       (static_cast<uint32_t>(rtpHeader[9]) << 16) |
38       (static_cast<uint32_t>(rtpHeader[10]) << 8) | rtpHeader[11];
39 }
40
41 void RTPStream::MakeRTPheader(uint8_t* rtpHeader, uint8_t payloadType,
42                               int16_t seqNo, uint32_t timeStamp,
43                               uint32_t ssrc) {
44   rtpHeader[0] = (unsigned char) 0x80;
45   rtpHeader[1] = (unsigned char) (payloadType & 0xFF);
46   rtpHeader[2] = (unsigned char) ((seqNo >> 8) & 0xFF);
47   rtpHeader[3] = (unsigned char) ((seqNo) & 0xFF);
48   rtpHeader[4] = (unsigned char) ((timeStamp >> 24) & 0xFF);
49   rtpHeader[5] = (unsigned char) ((timeStamp >> 16) & 0xFF);
50
51   rtpHeader[6] = (unsigned char) ((timeStamp >> 8) & 0xFF);
52   rtpHeader[7] = (unsigned char) (timeStamp & 0xFF);
53
54   rtpHeader[8] = (unsigned char) ((ssrc >> 24) & 0xFF);
55   rtpHeader[9] = (unsigned char) ((ssrc >> 16) & 0xFF);
56
57   rtpHeader[10] = (unsigned char) ((ssrc >> 8) & 0xFF);
58   rtpHeader[11] = (unsigned char) (ssrc & 0xFF);
59 }
60
61 RTPPacket::RTPPacket(uint8_t payloadType, uint32_t timeStamp, int16_t seqNo,
62                      const uint8_t* payloadData, uint16_t payloadSize,
63                      uint32_t frequency)
64     : payloadType(payloadType),
65       timeStamp(timeStamp),
66       seqNo(seqNo),
67       payloadSize(payloadSize),
68       frequency(frequency) {
69   if (payloadSize > 0) {
70     this->payloadData = new uint8_t[payloadSize];
71     memcpy(this->payloadData, payloadData, payloadSize);
72   }
73 }
74
75 RTPPacket::~RTPPacket() {
76   delete[] payloadData;
77 }
78
79 RTPBuffer::RTPBuffer() {
80   _queueRWLock = RWLockWrapper::CreateRWLock();
81 }
82
83 RTPBuffer::~RTPBuffer() {
84   delete _queueRWLock;
85 }
86
87 void RTPBuffer::Write(const uint8_t payloadType, const uint32_t timeStamp,
88                       const int16_t seqNo, const uint8_t* payloadData,
89                       const uint16_t payloadSize, uint32_t frequency) {
90   RTPPacket *packet = new RTPPacket(payloadType, timeStamp, seqNo, payloadData,
91                                     payloadSize, frequency);
92   _queueRWLock->AcquireLockExclusive();
93   _rtpQueue.push(packet);
94   _queueRWLock->ReleaseLockExclusive();
95 }
96
97 uint16_t RTPBuffer::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData,
98                          uint16_t payloadSize, uint32_t* offset) {
99   _queueRWLock->AcquireLockShared();
100   RTPPacket *packet = _rtpQueue.front();
101   _rtpQueue.pop();
102   _queueRWLock->ReleaseLockShared();
103   rtpInfo->header.markerBit = 1;
104   rtpInfo->header.payloadType = packet->payloadType;
105   rtpInfo->header.sequenceNumber = packet->seqNo;
106   rtpInfo->header.ssrc = 0;
107   rtpInfo->header.timestamp = packet->timeStamp;
108   if (packet->payloadSize > 0 && payloadSize >= packet->payloadSize) {
109     memcpy(payloadData, packet->payloadData, packet->payloadSize);
110   } else {
111     return 0;
112   }
113   *offset = (packet->timeStamp / (packet->frequency / 1000));
114
115   return packet->payloadSize;
116 }
117
118 bool RTPBuffer::EndOfFile() const {
119   _queueRWLock->AcquireLockShared();
120   bool eof = _rtpQueue.empty();
121   _queueRWLock->ReleaseLockShared();
122   return eof;
123 }
124
125 void RTPFile::Open(const char *filename, const char *mode) {
126   if ((_rtpFile = fopen(filename, mode)) == NULL) {
127     printf("Cannot write file %s.\n", filename);
128     ADD_FAILURE() << "Unable to write file";
129     exit(1);
130   }
131 }
132
133 void RTPFile::Close() {
134   if (_rtpFile != NULL) {
135     fclose(_rtpFile);
136     _rtpFile = NULL;
137   }
138 }
139
140 void RTPFile::WriteHeader() {
141   // Write data in a format that NetEQ and RTP Play can parse
142   fprintf(_rtpFile, "#!RTPencode%s\n", "1.0");
143   uint32_t dummy_variable = 0;
144   // should be converted to network endian format, but does not matter when 0
145   if (fwrite(&dummy_variable, 4, 1, _rtpFile) != 1) {
146     return;
147   }
148   if (fwrite(&dummy_variable, 4, 1, _rtpFile) != 1) {
149     return;
150   }
151   if (fwrite(&dummy_variable, 4, 1, _rtpFile) != 1) {
152     return;
153   }
154   if (fwrite(&dummy_variable, 2, 1, _rtpFile) != 1) {
155     return;
156   }
157   if (fwrite(&dummy_variable, 2, 1, _rtpFile) != 1) {
158     return;
159   }
160   fflush(_rtpFile);
161 }
162
163 void RTPFile::ReadHeader() {
164   uint32_t start_sec, start_usec, source;
165   uint16_t port, padding;
166   char fileHeader[40];
167   EXPECT_TRUE(fgets(fileHeader, 40, _rtpFile) != 0);
168   EXPECT_EQ(1u, fread(&start_sec, 4, 1, _rtpFile));
169   start_sec = ntohl(start_sec);
170   EXPECT_EQ(1u, fread(&start_usec, 4, 1, _rtpFile));
171   start_usec = ntohl(start_usec);
172   EXPECT_EQ(1u, fread(&source, 4, 1, _rtpFile));
173   source = ntohl(source);
174   EXPECT_EQ(1u, fread(&port, 2, 1, _rtpFile));
175   port = ntohs(port);
176   EXPECT_EQ(1u, fread(&padding, 2, 1, _rtpFile));
177   padding = ntohs(padding);
178 }
179
180 void RTPFile::Write(const uint8_t payloadType, const uint32_t timeStamp,
181                     const int16_t seqNo, const uint8_t* payloadData,
182                     const uint16_t payloadSize, uint32_t frequency) {
183   /* write RTP packet to file */
184   uint8_t rtpHeader[12];
185   MakeRTPheader(rtpHeader, payloadType, seqNo, timeStamp, 0);
186   uint16_t lengthBytes = htons(12 + payloadSize + 8);
187   uint16_t plen = htons(12 + payloadSize);
188   uint32_t offsetMs;
189
190   offsetMs = (timeStamp / (frequency / 1000));
191   offsetMs = htonl(offsetMs);
192   if (fwrite(&lengthBytes, 2, 1, _rtpFile) != 1) {
193     return;
194   }
195   if (fwrite(&plen, 2, 1, _rtpFile) != 1) {
196     return;
197   }
198   if (fwrite(&offsetMs, 4, 1, _rtpFile) != 1) {
199     return;
200   }
201   if (fwrite(rtpHeader, 12, 1, _rtpFile) != 1) {
202     return;
203   }
204   if (fwrite(payloadData, 1, payloadSize, _rtpFile) != payloadSize) {
205     return;
206   }
207 }
208
209 uint16_t RTPFile::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData,
210                        uint16_t payloadSize, uint32_t* offset) {
211   uint16_t lengthBytes;
212   uint16_t plen;
213   uint8_t rtpHeader[12];
214   size_t read_len = fread(&lengthBytes, 2, 1, _rtpFile);
215   /* Check if we have reached end of file. */
216   if ((read_len == 0) && feof(_rtpFile)) {
217     _rtpEOF = true;
218     return 0;
219   }
220   EXPECT_EQ(1u, fread(&plen, 2, 1, _rtpFile));
221   EXPECT_EQ(1u, fread(offset, 4, 1, _rtpFile));
222   lengthBytes = ntohs(lengthBytes);
223   plen = ntohs(plen);
224   *offset = ntohl(*offset);
225   EXPECT_GT(plen, 11);
226
227   EXPECT_EQ(1u, fread(rtpHeader, 12, 1, _rtpFile));
228   ParseRTPHeader(rtpInfo, rtpHeader);
229   rtpInfo->type.Audio.isCNG = false;
230   rtpInfo->type.Audio.channel = 1;
231   EXPECT_EQ(lengthBytes, plen + 8);
232
233   if (plen == 0) {
234     return 0;
235   }
236   if (payloadSize < (lengthBytes - 20)) {
237     return 0;
238   }
239   if (lengthBytes < 20) {
240     return 0;
241   }
242   lengthBytes -= 20;
243   EXPECT_EQ(lengthBytes, fread(payloadData, 1, lengthBytes, _rtpFile));
244   return lengthBytes;
245 }
246
247 }  // namespace webrtc