Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / neteq / tools / rtp_file_source.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/neteq/tools/rtp_file_source.h"
12
13 #include <assert.h>
14 #include <string.h>
15 #ifdef WIN32
16 #include <winsock2.h>
17 #else
18 #include <netinet/in.h>
19 #endif
20
21 #include "webrtc/modules/audio_coding/neteq/tools/packet.h"
22 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
23
24 namespace webrtc {
25 namespace test {
26
27 RtpFileSource* RtpFileSource::Create(const std::string& file_name) {
28   RtpFileSource* source = new RtpFileSource;
29   assert(source);
30   if (!source->OpenFile(file_name) || !source->SkipFileHeader()) {
31     assert(false);
32     delete source;
33     return NULL;
34   }
35   return source;
36 }
37
38 RtpFileSource::~RtpFileSource() {
39   if (in_file_)
40     fclose(in_file_);
41 }
42
43 bool RtpFileSource::RegisterRtpHeaderExtension(RTPExtensionType type,
44                                                uint8_t id) {
45   assert(parser_.get());
46   return parser_->RegisterRtpHeaderExtension(type, id);
47 }
48
49 Packet* RtpFileSource::NextPacket() {
50   while (!EndOfFile()) {
51     uint16_t length;
52     if (fread(&length, sizeof(length), 1, in_file_) == 0) {
53       assert(false);
54       return NULL;
55     }
56     length = ntohs(length);
57
58     uint16_t plen;
59     if (fread(&plen, sizeof(plen), 1, in_file_) == 0) {
60       assert(false);
61       return NULL;
62     }
63     plen = ntohs(plen);
64
65     uint32_t offset;
66     if (fread(&offset, sizeof(offset), 1, in_file_) == 0) {
67       assert(false);
68       return NULL;
69     }
70     offset = ntohl(offset);
71
72     // Use length here because a plen of 0 specifies RTCP.
73     assert(length >= kPacketHeaderSize);
74     size_t packet_size_bytes = length - kPacketHeaderSize;
75     if (packet_size_bytes == 0) {
76       // May be an RTCP packet.
77       // Read the next one.
78       continue;
79     }
80     scoped_ptr<uint8_t> packet_memory(new uint8_t[packet_size_bytes]);
81     if (fread(packet_memory.get(), 1, packet_size_bytes, in_file_) !=
82         packet_size_bytes) {
83       assert(false);
84       return NULL;
85     }
86     scoped_ptr<Packet> packet(new Packet(packet_memory.release(),
87                                          packet_size_bytes,
88                                          plen,
89                                          offset,
90                                          *parser_.get()));
91     if (!packet->valid_header()) {
92       assert(false);
93       return NULL;
94     }
95     if (filter_.test(packet->header().payloadType)) {
96       // This payload type should be filtered out. Continue to the next packet.
97       continue;
98     }
99     return packet.release();
100   }
101   return NULL;
102 }
103
104 bool RtpFileSource::EndOfFile() const {
105   assert(in_file_);
106   return ftell(in_file_) >= file_end_;
107 }
108
109 RtpFileSource::RtpFileSource()
110     : PacketSource(),
111       in_file_(NULL),
112       file_end_(-1),
113       parser_(RtpHeaderParser::Create()) {}
114
115 bool RtpFileSource::OpenFile(const std::string& file_name) {
116   in_file_ = fopen(file_name.c_str(), "rb");
117   assert(in_file_);
118   if (in_file_ == NULL) {
119     return false;
120   }
121
122   // Find out how long the file is.
123   fseek(in_file_, 0, SEEK_END);
124   file_end_ = ftell(in_file_);
125   rewind(in_file_);
126   return true;
127 }
128
129 bool RtpFileSource::SkipFileHeader() {
130   char firstline[kFirstLineLength];
131   assert(in_file_);
132   if (fgets(firstline, kFirstLineLength, in_file_) == NULL) {
133     assert(false);
134     return false;
135   }
136   // Check that the first line is ok.
137   if ((strncmp(firstline, "#!rtpplay1.0", 12) != 0) &&
138       (strncmp(firstline, "#!RTPencode1.0", 14) != 0)) {
139     assert(false);
140     return false;
141   }
142   // Skip the file header.
143   if (fseek(in_file_, kRtpFileHeaderSize, SEEK_CUR) != 0) {
144     assert(false);
145     return false;
146   }
147   return true;
148 }
149
150 }  // namespace test
151 }  // namespace webrtc