OLD | NEW |
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 27 matching lines...) Expand all Loading... |
38 | 38 |
39 namespace { | 39 namespace { |
40 static const int kRtpSsrcOffset = 8; | 40 static const int kRtpSsrcOffset = 8; |
41 const int kWarnSlowWritesDelayMs = 50; | 41 const int kWarnSlowWritesDelayMs = 50; |
42 } // namespace | 42 } // namespace |
43 | 43 |
44 namespace cricket { | 44 namespace cricket { |
45 | 45 |
46 const char RtpDumpFileHeader::kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n"; | 46 const char RtpDumpFileHeader::kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n"; |
47 | 47 |
48 RtpDumpFileHeader::RtpDumpFileHeader(uint32 start_ms, uint32 s, uint16 p) | 48 RtpDumpFileHeader::RtpDumpFileHeader(uint32_t start_ms, uint32_t s, uint16_t p) |
49 : start_sec(start_ms / 1000), | 49 : start_sec(start_ms / 1000), |
50 start_usec(start_ms % 1000 * 1000), | 50 start_usec(start_ms % 1000 * 1000), |
51 source(s), | 51 source(s), |
52 port(p), | 52 port(p), |
53 padding(0) { | 53 padding(0) { |
54 } | 54 } |
55 | 55 |
56 void RtpDumpFileHeader::WriteToByteBuffer(rtc::ByteBuffer* buf) { | 56 void RtpDumpFileHeader::WriteToByteBuffer(rtc::ByteBuffer* buf) { |
57 buf->WriteUInt32(start_sec); | 57 buf->WriteUInt32(start_sec); |
58 buf->WriteUInt32(start_usec); | 58 buf->WriteUInt32(start_usec); |
59 buf->WriteUInt32(source); | 59 buf->WriteUInt32(source); |
60 buf->WriteUInt16(port); | 60 buf->WriteUInt16(port); |
61 buf->WriteUInt16(padding); | 61 buf->WriteUInt16(padding); |
62 } | 62 } |
63 | 63 |
64 static const uint32 kDefaultTimeIncrease = 30; | 64 static const uint32_t kDefaultTimeIncrease = 30; |
65 | 65 |
66 bool RtpDumpPacket::IsValidRtpPacket() const { | 66 bool RtpDumpPacket::IsValidRtpPacket() const { |
67 return original_data_len >= data.size() && | 67 return original_data_len >= data.size() && |
68 data.size() >= kMinRtpPacketLen; | 68 data.size() >= kMinRtpPacketLen; |
69 } | 69 } |
70 | 70 |
71 bool RtpDumpPacket::IsValidRtcpPacket() const { | 71 bool RtpDumpPacket::IsValidRtcpPacket() const { |
72 return original_data_len == 0 && | 72 return original_data_len == 0 && |
73 data.size() >= kMinRtcpPacketLen; | 73 data.size() >= kMinRtcpPacketLen; |
74 } | 74 } |
75 | 75 |
76 bool RtpDumpPacket::GetRtpPayloadType(int* pt) const { | 76 bool RtpDumpPacket::GetRtpPayloadType(int* pt) const { |
77 return IsValidRtpPacket() && | 77 return IsValidRtpPacket() && |
78 cricket::GetRtpPayloadType(&data[0], data.size(), pt); | 78 cricket::GetRtpPayloadType(&data[0], data.size(), pt); |
79 } | 79 } |
80 | 80 |
81 bool RtpDumpPacket::GetRtpSeqNum(int* seq_num) const { | 81 bool RtpDumpPacket::GetRtpSeqNum(int* seq_num) const { |
82 return IsValidRtpPacket() && | 82 return IsValidRtpPacket() && |
83 cricket::GetRtpSeqNum(&data[0], data.size(), seq_num); | 83 cricket::GetRtpSeqNum(&data[0], data.size(), seq_num); |
84 } | 84 } |
85 | 85 |
86 bool RtpDumpPacket::GetRtpTimestamp(uint32* ts) const { | 86 bool RtpDumpPacket::GetRtpTimestamp(uint32_t* ts) const { |
87 return IsValidRtpPacket() && | 87 return IsValidRtpPacket() && |
88 cricket::GetRtpTimestamp(&data[0], data.size(), ts); | 88 cricket::GetRtpTimestamp(&data[0], data.size(), ts); |
89 } | 89 } |
90 | 90 |
91 bool RtpDumpPacket::GetRtpSsrc(uint32* ssrc) const { | 91 bool RtpDumpPacket::GetRtpSsrc(uint32_t* ssrc) const { |
92 return IsValidRtpPacket() && | 92 return IsValidRtpPacket() && |
93 cricket::GetRtpSsrc(&data[0], data.size(), ssrc); | 93 cricket::GetRtpSsrc(&data[0], data.size(), ssrc); |
94 } | 94 } |
95 | 95 |
96 bool RtpDumpPacket::GetRtpHeaderLen(size_t* len) const { | 96 bool RtpDumpPacket::GetRtpHeaderLen(size_t* len) const { |
97 return IsValidRtpPacket() && | 97 return IsValidRtpPacket() && |
98 cricket::GetRtpHeaderLen(&data[0], data.size(), len); | 98 cricket::GetRtpHeaderLen(&data[0], data.size(), len); |
99 } | 99 } |
100 | 100 |
101 bool RtpDumpPacket::GetRtcpType(int* type) const { | 101 bool RtpDumpPacket::GetRtcpType(int* type) const { |
102 return IsValidRtcpPacket() && | 102 return IsValidRtcpPacket() && |
103 cricket::GetRtcpType(&data[0], data.size(), type); | 103 cricket::GetRtcpType(&data[0], data.size(), type); |
104 } | 104 } |
105 | 105 |
106 /////////////////////////////////////////////////////////////////////////// | 106 /////////////////////////////////////////////////////////////////////////// |
107 // Implementation of RtpDumpReader. | 107 // Implementation of RtpDumpReader. |
108 /////////////////////////////////////////////////////////////////////////// | 108 /////////////////////////////////////////////////////////////////////////// |
109 | 109 |
110 void RtpDumpReader::SetSsrc(uint32 ssrc) { | 110 void RtpDumpReader::SetSsrc(uint32_t ssrc) { |
111 ssrc_override_ = ssrc; | 111 ssrc_override_ = ssrc; |
112 } | 112 } |
113 | 113 |
114 rtc::StreamResult RtpDumpReader::ReadPacket(RtpDumpPacket* packet) { | 114 rtc::StreamResult RtpDumpReader::ReadPacket(RtpDumpPacket* packet) { |
115 if (!packet) return rtc::SR_ERROR; | 115 if (!packet) return rtc::SR_ERROR; |
116 | 116 |
117 rtc::StreamResult res = rtc::SR_SUCCESS; | 117 rtc::StreamResult res = rtc::SR_SUCCESS; |
118 // Read the file header if it has not been read yet. | 118 // Read the file header if it has not been read yet. |
119 if (!file_header_read_) { | 119 if (!file_header_read_) { |
120 res = ReadFileHeader(); | 120 res = ReadFileHeader(); |
121 if (res != rtc::SR_SUCCESS) { | 121 if (res != rtc::SR_SUCCESS) { |
122 return res; | 122 return res; |
123 } | 123 } |
124 file_header_read_ = true; | 124 file_header_read_ = true; |
125 } | 125 } |
126 | 126 |
127 // Read the RTP dump packet header. | 127 // Read the RTP dump packet header. |
128 char header[RtpDumpPacket::kHeaderLength]; | 128 char header[RtpDumpPacket::kHeaderLength]; |
129 res = stream_->ReadAll(header, sizeof(header), NULL, NULL); | 129 res = stream_->ReadAll(header, sizeof(header), NULL, NULL); |
130 if (res != rtc::SR_SUCCESS) { | 130 if (res != rtc::SR_SUCCESS) { |
131 return res; | 131 return res; |
132 } | 132 } |
133 rtc::ByteBuffer buf(header, sizeof(header)); | 133 rtc::ByteBuffer buf(header, sizeof(header)); |
134 uint16 dump_packet_len; | 134 uint16_t dump_packet_len; |
135 uint16 data_len; | 135 uint16_t data_len; |
136 // Read the full length of the rtpdump packet, including the rtpdump header. | 136 // Read the full length of the rtpdump packet, including the rtpdump header. |
137 buf.ReadUInt16(&dump_packet_len); | 137 buf.ReadUInt16(&dump_packet_len); |
138 packet->data.resize(dump_packet_len - sizeof(header)); | 138 packet->data.resize(dump_packet_len - sizeof(header)); |
139 // Read the size of the original packet, which may be larger than the size in | 139 // Read the size of the original packet, which may be larger than the size in |
140 // the rtpdump file, in the event that only part of the packet (perhaps just | 140 // the rtpdump file, in the event that only part of the packet (perhaps just |
141 // the header) was recorded. Note that this field is set to zero for RTCP | 141 // the header) was recorded. Note that this field is set to zero for RTCP |
142 // packets, which have their own internal length field. | 142 // packets, which have their own internal length field. |
143 buf.ReadUInt16(&data_len); | 143 buf.ReadUInt16(&data_len); |
144 packet->original_data_len = data_len; | 144 packet->original_data_len = data_len; |
145 // Read the elapsed time for this packet (different than RTP timestamp). | 145 // Read the elapsed time for this packet (different than RTP timestamp). |
(...skipping 22 matching lines...) Expand all Loading... |
168 } | 168 } |
169 if (!CheckFirstLine(first_line)) { | 169 if (!CheckFirstLine(first_line)) { |
170 return rtc::SR_ERROR; | 170 return rtc::SR_ERROR; |
171 } | 171 } |
172 | 172 |
173 // Read the 16 byte file header. | 173 // Read the 16 byte file header. |
174 char header[RtpDumpFileHeader::kHeaderLength]; | 174 char header[RtpDumpFileHeader::kHeaderLength]; |
175 res = stream_->ReadAll(header, sizeof(header), NULL, NULL); | 175 res = stream_->ReadAll(header, sizeof(header), NULL, NULL); |
176 if (res == rtc::SR_SUCCESS) { | 176 if (res == rtc::SR_SUCCESS) { |
177 rtc::ByteBuffer buf(header, sizeof(header)); | 177 rtc::ByteBuffer buf(header, sizeof(header)); |
178 uint32 start_sec; | 178 uint32_t start_sec; |
179 uint32 start_usec; | 179 uint32_t start_usec; |
180 buf.ReadUInt32(&start_sec); | 180 buf.ReadUInt32(&start_sec); |
181 buf.ReadUInt32(&start_usec); | 181 buf.ReadUInt32(&start_usec); |
182 start_time_ms_ = start_sec * 1000 + start_usec / 1000; | 182 start_time_ms_ = start_sec * 1000 + start_usec / 1000; |
183 // Increase the length by 1 since first_line does not contain the ending \n. | 183 // Increase the length by 1 since first_line does not contain the ending \n. |
184 first_line_and_file_header_len_ = first_line.size() + 1 + sizeof(header); | 184 first_line_and_file_header_len_ = first_line.size() + 1 + sizeof(header); |
185 } | 185 } |
186 return res; | 186 return res; |
187 } | 187 } |
188 | 188 |
189 bool RtpDumpReader::CheckFirstLine(const std::string& first_line) { | 189 bool RtpDumpReader::CheckFirstLine(const std::string& first_line) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 UpdateDumpPacket(packet); | 251 UpdateDumpPacket(packet); |
252 } | 252 } |
253 | 253 |
254 return res; | 254 return res; |
255 } | 255 } |
256 | 256 |
257 void RtpDumpLoopReader::UpdateStreamStatistics(const RtpDumpPacket& packet) { | 257 void RtpDumpLoopReader::UpdateStreamStatistics(const RtpDumpPacket& packet) { |
258 // Get the RTP sequence number and timestamp of the dump packet. | 258 // Get the RTP sequence number and timestamp of the dump packet. |
259 int rtp_seq_num = 0; | 259 int rtp_seq_num = 0; |
260 packet.GetRtpSeqNum(&rtp_seq_num); | 260 packet.GetRtpSeqNum(&rtp_seq_num); |
261 uint32 rtp_timestamp = 0; | 261 uint32_t rtp_timestamp = 0; |
262 packet.GetRtpTimestamp(&rtp_timestamp); | 262 packet.GetRtpTimestamp(&rtp_timestamp); |
263 | 263 |
264 // Set the timestamps and sequence number for the first dump packet. | 264 // Set the timestamps and sequence number for the first dump packet. |
265 if (0 == packet_count_++) { | 265 if (0 == packet_count_++) { |
266 first_elapsed_time_ = packet.elapsed_time; | 266 first_elapsed_time_ = packet.elapsed_time; |
267 first_rtp_seq_num_ = rtp_seq_num; | 267 first_rtp_seq_num_ = rtp_seq_num; |
268 first_rtp_timestamp_ = rtp_timestamp; | 268 first_rtp_timestamp_ = rtp_timestamp; |
269 // The first packet belongs to a new payload frame. | 269 // The first packet belongs to a new payload frame. |
270 ++frame_count_; | 270 ++frame_count_; |
271 } else if (rtp_timestamp != prev_rtp_timestamp_) { | 271 } else if (rtp_timestamp != prev_rtp_timestamp_) { |
(...skipping 22 matching lines...) Expand all Loading... |
294 } | 294 } |
295 | 295 |
296 void RtpDumpLoopReader::UpdateDumpPacket(RtpDumpPacket* packet) { | 296 void RtpDumpLoopReader::UpdateDumpPacket(RtpDumpPacket* packet) { |
297 // Increase the elapsed time of the dump packet. | 297 // Increase the elapsed time of the dump packet. |
298 packet->elapsed_time += loop_count_ * elapsed_time_increases_; | 298 packet->elapsed_time += loop_count_ * elapsed_time_increases_; |
299 | 299 |
300 if (packet->IsValidRtpPacket()) { | 300 if (packet->IsValidRtpPacket()) { |
301 // Get the old RTP sequence number and timestamp. | 301 // Get the old RTP sequence number and timestamp. |
302 int sequence = 0; | 302 int sequence = 0; |
303 packet->GetRtpSeqNum(&sequence); | 303 packet->GetRtpSeqNum(&sequence); |
304 uint32 timestamp = 0; | 304 uint32_t timestamp = 0; |
305 packet->GetRtpTimestamp(×tamp); | 305 packet->GetRtpTimestamp(×tamp); |
306 // Increase the RTP sequence number and timestamp. | 306 // Increase the RTP sequence number and timestamp. |
307 sequence += loop_count_ * rtp_seq_num_increase_; | 307 sequence += loop_count_ * rtp_seq_num_increase_; |
308 timestamp += loop_count_ * rtp_timestamp_increase_; | 308 timestamp += loop_count_ * rtp_timestamp_increase_; |
309 // Write the updated sequence number and timestamp back to the RTP packet. | 309 // Write the updated sequence number and timestamp back to the RTP packet. |
310 rtc::ByteBuffer buffer; | 310 rtc::ByteBuffer buffer; |
311 buffer.WriteUInt16(sequence); | 311 buffer.WriteUInt16(sequence); |
312 buffer.WriteUInt32(timestamp); | 312 buffer.WriteUInt32(timestamp); |
313 memcpy(&packet->data[2], buffer.Data(), buffer.Length()); | 313 memcpy(&packet->data[2], buffer.Data(), buffer.Length()); |
314 } | 314 } |
315 } | 315 } |
316 | 316 |
317 /////////////////////////////////////////////////////////////////////////// | 317 /////////////////////////////////////////////////////////////////////////// |
318 // Implementation of RtpDumpWriter. | 318 // Implementation of RtpDumpWriter. |
319 /////////////////////////////////////////////////////////////////////////// | 319 /////////////////////////////////////////////////////////////////////////// |
320 | 320 |
321 RtpDumpWriter::RtpDumpWriter(rtc::StreamInterface* stream) | 321 RtpDumpWriter::RtpDumpWriter(rtc::StreamInterface* stream) |
322 : stream_(stream), | 322 : stream_(stream), |
323 packet_filter_(PF_ALL), | 323 packet_filter_(PF_ALL), |
324 file_header_written_(false), | 324 file_header_written_(false), |
325 start_time_ms_(rtc::Time()), | 325 start_time_ms_(rtc::Time()), |
326 warn_slow_writes_delay_(kWarnSlowWritesDelayMs) { | 326 warn_slow_writes_delay_(kWarnSlowWritesDelayMs) { |
327 } | 327 } |
328 | 328 |
329 void RtpDumpWriter::set_packet_filter(int filter) { | 329 void RtpDumpWriter::set_packet_filter(int filter) { |
330 packet_filter_ = filter; | 330 packet_filter_ = filter; |
331 LOG(LS_INFO) << "RtpDumpWriter set_packet_filter to " << packet_filter_; | 331 LOG(LS_INFO) << "RtpDumpWriter set_packet_filter to " << packet_filter_; |
332 } | 332 } |
333 | 333 |
334 uint32 RtpDumpWriter::GetElapsedTime() const { | 334 uint32_t RtpDumpWriter::GetElapsedTime() const { |
335 return rtc::TimeSince(start_time_ms_); | 335 return rtc::TimeSince(start_time_ms_); |
336 } | 336 } |
337 | 337 |
338 rtc::StreamResult RtpDumpWriter::WriteFileHeader() { | 338 rtc::StreamResult RtpDumpWriter::WriteFileHeader() { |
339 rtc::StreamResult res = WriteToStream( | 339 rtc::StreamResult res = WriteToStream( |
340 RtpDumpFileHeader::kFirstLine, | 340 RtpDumpFileHeader::kFirstLine, |
341 strlen(RtpDumpFileHeader::kFirstLine)); | 341 strlen(RtpDumpFileHeader::kFirstLine)); |
342 if (res != rtc::SR_SUCCESS) { | 342 if (res != rtc::SR_SUCCESS) { |
343 return res; | 343 return res; |
344 } | 344 } |
345 | 345 |
346 rtc::ByteBuffer buf; | 346 rtc::ByteBuffer buf; |
347 RtpDumpFileHeader file_header(rtc::Time(), 0, 0); | 347 RtpDumpFileHeader file_header(rtc::Time(), 0, 0); |
348 file_header.WriteToByteBuffer(&buf); | 348 file_header.WriteToByteBuffer(&buf); |
349 return WriteToStream(buf.Data(), buf.Length()); | 349 return WriteToStream(buf.Data(), buf.Length()); |
350 } | 350 } |
351 | 351 |
352 rtc::StreamResult RtpDumpWriter::WritePacket( | 352 rtc::StreamResult RtpDumpWriter::WritePacket(const void* data, |
353 const void* data, size_t data_len, uint32 elapsed, bool rtcp) { | 353 size_t data_len, |
| 354 uint32_t elapsed, |
| 355 bool rtcp) { |
354 if (!stream_ || !data || 0 == data_len) return rtc::SR_ERROR; | 356 if (!stream_ || !data || 0 == data_len) return rtc::SR_ERROR; |
355 | 357 |
356 rtc::StreamResult res = rtc::SR_SUCCESS; | 358 rtc::StreamResult res = rtc::SR_SUCCESS; |
357 // Write the file header if it has not been written yet. | 359 // Write the file header if it has not been written yet. |
358 if (!file_header_written_) { | 360 if (!file_header_written_) { |
359 res = WriteFileHeader(); | 361 res = WriteFileHeader(); |
360 if (res != rtc::SR_SUCCESS) { | 362 if (res != rtc::SR_SUCCESS) { |
361 return res; | 363 return res; |
362 } | 364 } |
363 file_header_written_ = true; | 365 file_header_written_ = true; |
364 } | 366 } |
365 | 367 |
366 // Figure out what to write. | 368 // Figure out what to write. |
367 size_t write_len = FilterPacket(data, data_len, rtcp); | 369 size_t write_len = FilterPacket(data, data_len, rtcp); |
368 if (write_len == 0) { | 370 if (write_len == 0) { |
369 return rtc::SR_SUCCESS; | 371 return rtc::SR_SUCCESS; |
370 } | 372 } |
371 | 373 |
372 // Write the dump packet header. | 374 // Write the dump packet header. |
373 rtc::ByteBuffer buf; | 375 rtc::ByteBuffer buf; |
374 buf.WriteUInt16(static_cast<uint16>( | 376 buf.WriteUInt16( |
375 RtpDumpPacket::kHeaderLength + write_len)); | 377 static_cast<uint16_t>(RtpDumpPacket::kHeaderLength + write_len)); |
376 buf.WriteUInt16(static_cast<uint16>(rtcp ? 0 : data_len)); | 378 buf.WriteUInt16(static_cast<uint16_t>(rtcp ? 0 : data_len)); |
377 buf.WriteUInt32(elapsed); | 379 buf.WriteUInt32(elapsed); |
378 res = WriteToStream(buf.Data(), buf.Length()); | 380 res = WriteToStream(buf.Data(), buf.Length()); |
379 if (res != rtc::SR_SUCCESS) { | 381 if (res != rtc::SR_SUCCESS) { |
380 return res; | 382 return res; |
381 } | 383 } |
382 | 384 |
383 // Write the header or full packet as indicated by write_len. | 385 // Write the header or full packet as indicated by write_len. |
384 return WriteToStream(data, write_len); | 386 return WriteToStream(data, write_len); |
385 } | 387 } |
386 | 388 |
(...skipping 16 matching lines...) Expand all Loading... |
403 // RTCP header + payload | 405 // RTCP header + payload |
404 filtered_len = data_len; | 406 filtered_len = data_len; |
405 } | 407 } |
406 } | 408 } |
407 | 409 |
408 return filtered_len; | 410 return filtered_len; |
409 } | 411 } |
410 | 412 |
411 rtc::StreamResult RtpDumpWriter::WriteToStream( | 413 rtc::StreamResult RtpDumpWriter::WriteToStream( |
412 const void* data, size_t data_len) { | 414 const void* data, size_t data_len) { |
413 uint32 before = rtc::Time(); | 415 uint32_t before = rtc::Time(); |
414 rtc::StreamResult result = | 416 rtc::StreamResult result = |
415 stream_->WriteAll(data, data_len, NULL, NULL); | 417 stream_->WriteAll(data, data_len, NULL, NULL); |
416 uint32 delay = rtc::TimeSince(before); | 418 uint32_t delay = rtc::TimeSince(before); |
417 if (delay >= warn_slow_writes_delay_) { | 419 if (delay >= warn_slow_writes_delay_) { |
418 LOG(LS_WARNING) << "Slow RtpDump: took " << delay << "ms to write " | 420 LOG(LS_WARNING) << "Slow RtpDump: took " << delay << "ms to write " |
419 << data_len << " bytes."; | 421 << data_len << " bytes."; |
420 } | 422 } |
421 return result; | 423 return result; |
422 } | 424 } |
423 | 425 |
424 } // namespace cricket | 426 } // namespace cricket |
OLD | NEW |