Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: webrtc/media/base/rtpdump.cc

Issue 2633453002: Delete unused rtpdump code in media/base. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/media/base/rtpdump.h ('k') | webrtc/media/base/rtpdump_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2010 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/media/base/rtpdump.h"
12
13 #include <ctype.h>
14
15 #include <string>
16
17 #include "webrtc/base/byteorder.h"
18 #include "webrtc/base/logging.h"
19 #include "webrtc/base/timeutils.h"
20 #include "webrtc/media/base/rtputils.h"
21
22 namespace {
23 static const int kRtpSsrcOffset = 8;
24 const int kWarnSlowWritesDelayMs = 50;
25 } // namespace
26
27 namespace cricket {
28
29 const char RtpDumpFileHeader::kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n";
30
31 RtpDumpFileHeader::RtpDumpFileHeader(int64_t start_ms, uint32_t s, uint16_t p)
32 : start_sec(static_cast<uint32_t>(start_ms / 1000)),
33 start_usec(static_cast<uint32_t>(start_ms % 1000 * 1000)),
34 source(s),
35 port(p),
36 padding(0) {}
37
38 void RtpDumpFileHeader::WriteToByteBuffer(rtc::ByteBufferWriter* buf) {
39 buf->WriteUInt32(start_sec);
40 buf->WriteUInt32(start_usec);
41 buf->WriteUInt32(source);
42 buf->WriteUInt16(port);
43 buf->WriteUInt16(padding);
44 }
45
46 static const int kDefaultTimeIncrease = 30;
47
48 bool RtpDumpPacket::IsValidRtpPacket() const {
49 return original_data_len >= data.size() &&
50 data.size() >= kMinRtpPacketLen;
51 }
52
53 bool RtpDumpPacket::IsValidRtcpPacket() const {
54 return original_data_len == 0 &&
55 data.size() >= kMinRtcpPacketLen;
56 }
57
58 bool RtpDumpPacket::GetRtpPayloadType(int* pt) const {
59 return IsValidRtpPacket() &&
60 cricket::GetRtpPayloadType(&data[0], data.size(), pt);
61 }
62
63 bool RtpDumpPacket::GetRtpSeqNum(int* seq_num) const {
64 return IsValidRtpPacket() &&
65 cricket::GetRtpSeqNum(&data[0], data.size(), seq_num);
66 }
67
68 bool RtpDumpPacket::GetRtpTimestamp(uint32_t* ts) const {
69 return IsValidRtpPacket() &&
70 cricket::GetRtpTimestamp(&data[0], data.size(), ts);
71 }
72
73 bool RtpDumpPacket::GetRtpSsrc(uint32_t* ssrc) const {
74 return IsValidRtpPacket() &&
75 cricket::GetRtpSsrc(&data[0], data.size(), ssrc);
76 }
77
78 bool RtpDumpPacket::GetRtpHeaderLen(size_t* len) const {
79 return IsValidRtpPacket() &&
80 cricket::GetRtpHeaderLen(&data[0], data.size(), len);
81 }
82
83 bool RtpDumpPacket::GetRtcpType(int* type) const {
84 return IsValidRtcpPacket() &&
85 cricket::GetRtcpType(&data[0], data.size(), type);
86 }
87
88 ///////////////////////////////////////////////////////////////////////////
89 // Implementation of RtpDumpReader.
90 ///////////////////////////////////////////////////////////////////////////
91
92 void RtpDumpReader::SetSsrc(uint32_t ssrc) {
93 ssrc_override_ = ssrc;
94 }
95
96 rtc::StreamResult RtpDumpReader::ReadPacket(RtpDumpPacket* packet) {
97 if (!packet) return rtc::SR_ERROR;
98
99 rtc::StreamResult res = rtc::SR_SUCCESS;
100 // Read the file header if it has not been read yet.
101 if (!file_header_read_) {
102 res = ReadFileHeader();
103 if (res != rtc::SR_SUCCESS) {
104 return res;
105 }
106 file_header_read_ = true;
107 }
108
109 // Read the RTP dump packet header.
110 char header[RtpDumpPacket::kHeaderLength];
111 res = stream_->ReadAll(header, sizeof(header), NULL, NULL);
112 if (res != rtc::SR_SUCCESS) {
113 return res;
114 }
115 rtc::ByteBufferReader buf(header, sizeof(header));
116 uint16_t dump_packet_len;
117 uint16_t data_len;
118 // Read the full length of the rtpdump packet, including the rtpdump header.
119 buf.ReadUInt16(&dump_packet_len);
120 packet->data.resize(dump_packet_len - sizeof(header));
121 // Read the size of the original packet, which may be larger than the size in
122 // the rtpdump file, in the event that only part of the packet (perhaps just
123 // the header) was recorded. Note that this field is set to zero for RTCP
124 // packets, which have their own internal length field.
125 buf.ReadUInt16(&data_len);
126 packet->original_data_len = data_len;
127 // Read the elapsed time for this packet (different than RTP timestamp).
128 buf.ReadUInt32(&packet->elapsed_time);
129
130 // Read the actual RTP or RTCP packet.
131 res = stream_->ReadAll(&packet->data[0], packet->data.size(), NULL, NULL);
132
133 // If the packet is RTP and we have specified a ssrc, replace the RTP ssrc
134 // with the specified ssrc.
135 if (res == rtc::SR_SUCCESS &&
136 packet->IsValidRtpPacket() &&
137 ssrc_override_ != 0) {
138 rtc::SetBE32(&packet->data[kRtpSsrcOffset], ssrc_override_);
139 }
140
141 return res;
142 }
143
144 rtc::StreamResult RtpDumpReader::ReadFileHeader() {
145 // Read the first line.
146 std::string first_line;
147 rtc::StreamResult res = stream_->ReadLine(&first_line);
148 if (res != rtc::SR_SUCCESS) {
149 return res;
150 }
151 if (!CheckFirstLine(first_line)) {
152 return rtc::SR_ERROR;
153 }
154
155 // Read the 16 byte file header.
156 char header[RtpDumpFileHeader::kHeaderLength];
157 res = stream_->ReadAll(header, sizeof(header), NULL, NULL);
158 if (res == rtc::SR_SUCCESS) {
159 rtc::ByteBufferReader buf(header, sizeof(header));
160 uint32_t start_sec;
161 uint32_t start_usec;
162 buf.ReadUInt32(&start_sec);
163 buf.ReadUInt32(&start_usec);
164 start_time_ms_ = static_cast<int64_t>(start_sec * 1000 + start_usec / 1000);
165 // Increase the length by 1 since first_line does not contain the ending \n.
166 first_line_and_file_header_len_ = first_line.size() + 1 + sizeof(header);
167 }
168 return res;
169 }
170
171 bool RtpDumpReader::CheckFirstLine(const std::string& first_line) {
172 // The first line is like "#!rtpplay1.0 address/port"
173 bool matched = (0 == first_line.find("#!rtpplay1.0 "));
174
175 // The address could be IP or hostname. We do not check it here. Instead, we
176 // check the port at the end.
177 size_t pos = first_line.find('/');
178 matched &= (pos != std::string::npos && pos < first_line.size() - 1);
179 for (++pos; pos < first_line.size() && matched; ++pos) {
180 matched &= (0 != isdigit(first_line[pos]));
181 }
182
183 return matched;
184 }
185
186 ///////////////////////////////////////////////////////////////////////////
187 // Implementation of RtpDumpLoopReader.
188 ///////////////////////////////////////////////////////////////////////////
189 RtpDumpLoopReader::RtpDumpLoopReader(rtc::StreamInterface* stream)
190 : RtpDumpReader(stream),
191 loop_count_(0),
192 elapsed_time_increases_(0),
193 rtp_seq_num_increase_(0),
194 rtp_timestamp_increase_(0),
195 packet_count_(0),
196 frame_count_(0),
197 first_elapsed_time_(0),
198 first_rtp_seq_num_(0),
199 first_rtp_timestamp_(0),
200 prev_elapsed_time_(0),
201 prev_rtp_seq_num_(0),
202 prev_rtp_timestamp_(0) {
203 }
204
205 rtc::StreamResult RtpDumpLoopReader::ReadPacket(RtpDumpPacket* packet) {
206 if (!packet) return rtc::SR_ERROR;
207
208 rtc::StreamResult res = RtpDumpReader::ReadPacket(packet);
209 if (rtc::SR_SUCCESS == res) {
210 if (0 == loop_count_) {
211 // During the first loop, we update the statistics of the input stream.
212 UpdateStreamStatistics(*packet);
213 }
214 } else if (rtc::SR_EOS == res) {
215 if (0 == loop_count_) {
216 // At the end of the first loop, calculate elapsed_time_increases_,
217 // rtp_seq_num_increase_, and rtp_timestamp_increase_, which will be
218 // used during the second and later loops.
219 CalculateIncreases();
220 }
221
222 // Rewind the input stream to the first dump packet and read again.
223 ++loop_count_;
224 if (RewindToFirstDumpPacket()) {
225 res = RtpDumpReader::ReadPacket(packet);
226 }
227 }
228
229 if (rtc::SR_SUCCESS == res && loop_count_ > 0) {
230 // During the second and later loops, we update the elapsed time of the dump
231 // packet. If the dumped packet is a RTP packet, we also update its RTP
232 // sequence number and timestamp.
233 UpdateDumpPacket(packet);
234 }
235
236 return res;
237 }
238
239 void RtpDumpLoopReader::UpdateStreamStatistics(const RtpDumpPacket& packet) {
240 // Get the RTP sequence number and timestamp of the dump packet.
241 int rtp_seq_num = 0;
242 packet.GetRtpSeqNum(&rtp_seq_num);
243 uint32_t rtp_timestamp = 0;
244 packet.GetRtpTimestamp(&rtp_timestamp);
245
246 // Set the timestamps and sequence number for the first dump packet.
247 if (0 == packet_count_++) {
248 first_elapsed_time_ = packet.elapsed_time;
249 first_rtp_seq_num_ = rtp_seq_num;
250 first_rtp_timestamp_ = rtp_timestamp;
251 // The first packet belongs to a new payload frame.
252 ++frame_count_;
253 } else if (rtp_timestamp != prev_rtp_timestamp_) {
254 // The current and previous packets belong to different payload frames.
255 ++frame_count_;
256 }
257
258 prev_elapsed_time_ = packet.elapsed_time;
259 prev_rtp_timestamp_ = rtp_timestamp;
260 prev_rtp_seq_num_ = rtp_seq_num;
261 }
262
263 void RtpDumpLoopReader::CalculateIncreases() {
264 // At this time, prev_elapsed_time_, prev_rtp_seq_num_, and
265 // prev_rtp_timestamp_ are values of the last dump packet in the input stream.
266 rtp_seq_num_increase_ = prev_rtp_seq_num_ - first_rtp_seq_num_ + 1;
267 // If we have only one packet or frame, we use the default timestamp
268 // increase. Otherwise, we use the difference between the first and the last
269 // packets or frames.
270 elapsed_time_increases_ = packet_count_ <= 1 ? kDefaultTimeIncrease :
271 (prev_elapsed_time_ - first_elapsed_time_) * packet_count_ /
272 (packet_count_ - 1);
273 rtp_timestamp_increase_ = frame_count_ <= 1 ? kDefaultTimeIncrease :
274 (prev_rtp_timestamp_ - first_rtp_timestamp_) * frame_count_ /
275 (frame_count_ - 1);
276 }
277
278 void RtpDumpLoopReader::UpdateDumpPacket(RtpDumpPacket* packet) {
279 // Increase the elapsed time of the dump packet.
280 packet->elapsed_time += loop_count_ * elapsed_time_increases_;
281
282 if (packet->IsValidRtpPacket()) {
283 // Get the old RTP sequence number and timestamp.
284 int sequence = 0;
285 packet->GetRtpSeqNum(&sequence);
286 uint32_t timestamp = 0;
287 packet->GetRtpTimestamp(&timestamp);
288 // Increase the RTP sequence number and timestamp.
289 sequence += loop_count_ * rtp_seq_num_increase_;
290 timestamp += loop_count_ * rtp_timestamp_increase_;
291 // Write the updated sequence number and timestamp back to the RTP packet.
292 rtc::ByteBufferWriter buffer;
293 buffer.WriteUInt16(sequence);
294 buffer.WriteUInt32(timestamp);
295 memcpy(&packet->data[2], buffer.Data(), buffer.Length());
296 }
297 }
298
299 ///////////////////////////////////////////////////////////////////////////
300 // Implementation of RtpDumpWriter.
301 ///////////////////////////////////////////////////////////////////////////
302
303 RtpDumpWriter::RtpDumpWriter(rtc::StreamInterface* stream)
304 : stream_(stream),
305 packet_filter_(PF_ALL),
306 file_header_written_(false),
307 start_time_ms_(rtc::TimeMillis()),
308 warn_slow_writes_delay_(kWarnSlowWritesDelayMs) {}
309
310 void RtpDumpWriter::set_packet_filter(int filter) {
311 packet_filter_ = filter;
312 LOG(LS_INFO) << "RtpDumpWriter set_packet_filter to " << packet_filter_;
313 }
314
315 uint32_t RtpDumpWriter::GetElapsedTime() const {
316 return static_cast<uint32_t>(rtc::TimeSince(start_time_ms_));
317 }
318
319 rtc::StreamResult RtpDumpWriter::WriteFileHeader() {
320 rtc::StreamResult res = WriteToStream(
321 RtpDumpFileHeader::kFirstLine,
322 strlen(RtpDumpFileHeader::kFirstLine));
323 if (res != rtc::SR_SUCCESS) {
324 return res;
325 }
326
327 rtc::ByteBufferWriter buf;
328 RtpDumpFileHeader file_header(rtc::TimeMillis(), 0, 0);
329 file_header.WriteToByteBuffer(&buf);
330 return WriteToStream(buf.Data(), buf.Length());
331 }
332
333 rtc::StreamResult RtpDumpWriter::WritePacket(const void* data,
334 size_t data_len,
335 uint32_t elapsed,
336 bool rtcp) {
337 if (!stream_ || !data || 0 == data_len) return rtc::SR_ERROR;
338
339 rtc::StreamResult res = rtc::SR_SUCCESS;
340 // Write the file header if it has not been written yet.
341 if (!file_header_written_) {
342 res = WriteFileHeader();
343 if (res != rtc::SR_SUCCESS) {
344 return res;
345 }
346 file_header_written_ = true;
347 }
348
349 // Figure out what to write.
350 size_t write_len = FilterPacket(data, data_len, rtcp);
351 if (write_len == 0) {
352 return rtc::SR_SUCCESS;
353 }
354
355 // Write the dump packet header.
356 rtc::ByteBufferWriter buf;
357 buf.WriteUInt16(
358 static_cast<uint16_t>(RtpDumpPacket::kHeaderLength + write_len));
359 buf.WriteUInt16(static_cast<uint16_t>(rtcp ? 0 : data_len));
360 buf.WriteUInt32(elapsed);
361 res = WriteToStream(buf.Data(), buf.Length());
362 if (res != rtc::SR_SUCCESS) {
363 return res;
364 }
365
366 // Write the header or full packet as indicated by write_len.
367 return WriteToStream(data, write_len);
368 }
369
370 size_t RtpDumpWriter::FilterPacket(const void* data, size_t data_len,
371 bool rtcp) {
372 size_t filtered_len = 0;
373 if (!rtcp) {
374 if ((packet_filter_ & PF_RTPPACKET) == PF_RTPPACKET) {
375 // RTP header + payload
376 filtered_len = data_len;
377 } else if ((packet_filter_ & PF_RTPHEADER) == PF_RTPHEADER) {
378 // RTP header only
379 size_t header_len;
380 if (GetRtpHeaderLen(data, data_len, &header_len)) {
381 filtered_len = header_len;
382 }
383 }
384 } else {
385 if ((packet_filter_ & PF_RTCPPACKET) == PF_RTCPPACKET) {
386 // RTCP header + payload
387 filtered_len = data_len;
388 }
389 }
390
391 return filtered_len;
392 }
393
394 rtc::StreamResult RtpDumpWriter::WriteToStream(
395 const void* data, size_t data_len) {
396 int64_t before = rtc::TimeMillis();
397 rtc::StreamResult result =
398 stream_->WriteAll(data, data_len, NULL, NULL);
399 int64_t delay = rtc::TimeSince(before);
400 if (delay >= warn_slow_writes_delay_) {
401 LOG(LS_WARNING) << "Slow RtpDump: took " << delay << "ms to write "
402 << data_len << " bytes.";
403 }
404 return result;
405 }
406
407 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/base/rtpdump.h ('k') | webrtc/media/base/rtpdump_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698