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