1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
216b6b90a82b796460bb20762761182c7d104cd2dtina.legrand@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
11470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "RTPFile.h"
12543c3eaa46434a7e3974012c4d33ed82fc81fd33kjellander@webrtc.org
13470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include <stdlib.h>
144591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include <limits>
15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
16470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#ifdef WIN32
17470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#   include <Winsock2.h>
18470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#else
19470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#   include <arpa/inet.h>
20470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#endif
21470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
22470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com#include "audio_coding_module.h"
23543c3eaa46434a7e3974012c4d33ed82fc81fd33kjellander@webrtc.org#include "engine_configurations.h"
2498f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
253c0aae17f0e3a70fe90ecc6835926b66a3de18fbkjellander@webrtc.org// TODO(tlegrand): Consider removing usage of gtest.
263c0aae17f0e3a70fe90ecc6835926b66a3de18fbkjellander@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
27470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
28554ae1ad4ed3e6d1d9d807f15324d2f875888d23tina.legrand@webrtc.orgnamespace webrtc {
29554ae1ad4ed3e6d1d9d807f15324d2f875888d23tina.legrand@webrtc.org
30d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPStream::ParseRTPHeader(WebRtcRTPHeader* rtpInfo,
31d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                               const uint8_t* rtpHeader) {
32d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.payloadType = rtpHeader[1];
33d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.sequenceNumber = (static_cast<uint16_t>(rtpHeader[2]) << 8) |
34d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      rtpHeader[3];
35d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.timestamp = (static_cast<uint32_t>(rtpHeader[4]) << 24) |
36d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      (static_cast<uint32_t>(rtpHeader[5]) << 16) |
37d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      (static_cast<uint32_t>(rtpHeader[6]) << 8) | rtpHeader[7];
38d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.ssrc = (static_cast<uint32_t>(rtpHeader[8]) << 24) |
39d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      (static_cast<uint32_t>(rtpHeader[9]) << 16) |
40d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      (static_cast<uint32_t>(rtpHeader[10]) << 8) | rtpHeader[11];
41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
43d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPStream::MakeRTPheader(uint8_t* rtpHeader, uint8_t payloadType,
44d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                              int16_t seqNo, uint32_t timeStamp,
45d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                              uint32_t ssrc) {
46d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[0] = 0x80;
47d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[1] = payloadType;
48d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[2] = (seqNo >> 8) & 0xFF;
49d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[3] = seqNo & 0xFF;
50d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[4] = timeStamp >> 24;
51d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[5] = (timeStamp >> 16) & 0xFF;
52d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[6] = (timeStamp >> 8) & 0xFF;
53d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[7] = timeStamp & 0xFF;
54d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[8] = ssrc >> 24;
55d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[9] = (ssrc >> 16) & 0xFF;
56d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[10] = (ssrc >> 8) & 0xFF;
57d324546ced76d4e792338af4f7d02a5cd8819f92pkasting@chromium.org  rtpHeader[11] = ssrc & 0xFF;
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
60d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgRTPPacket::RTPPacket(uint8_t payloadType, uint32_t timeStamp, int16_t seqNo,
614591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                     const uint8_t* payloadData, size_t payloadSize,
62d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                     uint32_t frequency)
63d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    : payloadType(payloadType),
64d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      timeStamp(timeStamp),
65d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      seqNo(seqNo),
66d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      payloadSize(payloadSize),
67d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org      frequency(frequency) {
68d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if (payloadSize > 0) {
69d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    this->payloadData = new uint8_t[payloadSize];
70d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    memcpy(this->payloadData, payloadData, payloadSize);
71d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
73470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
74d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgRTPPacket::~RTPPacket() {
75d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  delete[] payloadData;
76470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
77470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
78d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgRTPBuffer::RTPBuffer() {
79d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock = RWLockWrapper::CreateRWLock();
80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
82d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgRTPBuffer::~RTPBuffer() {
83d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  delete _queueRWLock;
84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
86d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPBuffer::Write(const uint8_t payloadType, const uint32_t timeStamp,
87d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                      const int16_t seqNo, const uint8_t* payloadData,
884591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                      const size_t payloadSize, uint32_t frequency) {
89d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  RTPPacket *packet = new RTPPacket(payloadType, timeStamp, seqNo, payloadData,
90d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org                                    payloadSize, frequency);
91d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->AcquireLockExclusive();
92d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _rtpQueue.push(packet);
93d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->ReleaseLockExclusive();
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
964591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgsize_t RTPBuffer::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData,
974591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                       size_t payloadSize, uint32_t* offset) {
98d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->AcquireLockShared();
99d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  RTPPacket *packet = _rtpQueue.front();
100d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _rtpQueue.pop();
101d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->ReleaseLockShared();
102d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.markerBit = 1;
103d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.payloadType = packet->payloadType;
104d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.sequenceNumber = packet->seqNo;
105d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.ssrc = 0;
106d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->header.timestamp = packet->timeStamp;
107d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if (packet->payloadSize > 0 && payloadSize >= packet->payloadSize) {
108d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    memcpy(payloadData, packet->payloadData, packet->payloadSize);
109d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  } else {
110741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org    return 0;
111d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
112d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  *offset = (packet->timeStamp / (packet->frequency / 1000));
113d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org
114d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  return packet->payloadSize;
115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
117d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgbool RTPBuffer::EndOfFile() const {
118d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->AcquireLockShared();
119d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  bool eof = _rtpQueue.empty();
120d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  _queueRWLock->ReleaseLockShared();
121d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  return eof;
122470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
123470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
124d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPFile::Open(const char *filename, const char *mode) {
125d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if ((_rtpFile = fopen(filename, mode)) == NULL) {
126d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    printf("Cannot write file %s.\n", filename);
127d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    ADD_FAILURE() << "Unable to write file";
128d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    exit(1);
129d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
132d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPFile::Close() {
133d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if (_rtpFile != NULL) {
134d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    fclose(_rtpFile);
135d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    _rtpFile = NULL;
136d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
139d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPFile::WriteHeader() {
140d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  // Write data in a format that NetEQ and RTP Play can parse
141d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  fprintf(_rtpFile, "#!RTPencode%s\n", "1.0");
142d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint32_t dummy_variable = 0;
143d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  // should be converted to network endian format, but does not matter when 0
1444591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
1454591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
1464591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&dummy_variable, 4, 1, _rtpFile));
1474591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile));
1484591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&dummy_variable, 2, 1, _rtpFile));
149d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  fflush(_rtpFile);
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
152d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.orgvoid RTPFile::ReadHeader() {
153d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint32_t start_sec, start_usec, source;
154d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint16_t port, padding;
155d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  char fileHeader[40];
156d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_TRUE(fgets(fileHeader, 40, _rtpFile) != 0);
157d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&start_sec, 4, 1, _rtpFile));
158d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  start_sec = ntohl(start_sec);
159d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&start_usec, 4, 1, _rtpFile));
160d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  start_usec = ntohl(start_usec);
161d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&source, 4, 1, _rtpFile));
162d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  source = ntohl(source);
163d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&port, 2, 1, _rtpFile));
164d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  port = ntohs(port);
165d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&padding, 2, 1, _rtpFile));
166d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  padding = ntohs(padding);
167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1690946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.orgvoid RTPFile::Write(const uint8_t payloadType, const uint32_t timeStamp,
1700946a56023d821e0deca04029bb016ae1f23aa82pbos@webrtc.org                    const int16_t seqNo, const uint8_t* payloadData,
1714591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                    const size_t payloadSize, uint32_t frequency) {
172d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  /* write RTP packet to file */
173d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint8_t rtpHeader[12];
174d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  MakeRTPheader(rtpHeader, payloadType, seqNo, timeStamp, 0);
1754591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  ASSERT_LE(12 + payloadSize + 8, std::numeric_limits<u_short>::max());
1764591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  uint16_t lengthBytes = htons(static_cast<u_short>(12 + payloadSize + 8));
1774591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  uint16_t plen = htons(static_cast<u_short>(12 + payloadSize));
178d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint32_t offsetMs;
179d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org
180d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  offsetMs = (timeStamp / (frequency / 1000));
181d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  offsetMs = htonl(offsetMs);
1824591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&lengthBytes, 2, 1, _rtpFile));
1834591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&plen, 2, 1, _rtpFile));
1844591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&offsetMs, 4, 1, _rtpFile));
1854591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(1u, fwrite(&rtpHeader, 12, 1, _rtpFile));
1864591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  EXPECT_EQ(payloadSize, fwrite(payloadData, 1, payloadSize, _rtpFile));
187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1894591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.orgsize_t RTPFile::Read(WebRtcRTPHeader* rtpInfo, uint8_t* payloadData,
1904591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                     size_t payloadSize, uint32_t* offset) {
191d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint16_t lengthBytes;
192d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint16_t plen;
193d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  uint8_t rtpHeader[12];
194d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  size_t read_len = fread(&lengthBytes, 2, 1, _rtpFile);
195d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  /* Check if we have reached end of file. */
196d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if ((read_len == 0) && feof(_rtpFile)) {
197d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org    _rtpEOF = true;
198741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org    return 0;
199d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
200d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(&plen, 2, 1, _rtpFile));
201d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(offset, 4, 1, _rtpFile));
202d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  lengthBytes = ntohs(lengthBytes);
203d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  plen = ntohs(plen);
204d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  *offset = ntohl(*offset);
205d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_GT(plen, 11);
206d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org
207d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(1u, fread(rtpHeader, 12, 1, _rtpFile));
208d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  ParseRTPHeader(rtpInfo, rtpHeader);
209d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->type.Audio.isCNG = false;
210d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  rtpInfo->type.Audio.channel = 1;
211d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(lengthBytes, plen + 8);
212d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org
213d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if (plen == 0) {
214741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org    return 0;
215d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
216d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  if (lengthBytes < 20) {
217741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org    return 0;
218741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org  }
2194591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  if (payloadSize < static_cast<size_t>((lengthBytes - 20))) {
220741711a8615ed3ccdc7c3f6898628c21fa072373henrik.lundin@webrtc.org    return 0;
221d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  }
222d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  lengthBytes -= 20;
223d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  EXPECT_EQ(lengthBytes, fread(payloadData, 1, lengthBytes, _rtpFile));
224d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org  return lengthBytes;
225470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
227d5726a1286ce53c47ebd2d21d61b2772fc24aaedtina.legrand@webrtc.org}  // namespace webrtc
228