| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 | 12 |
| 13 #include <iostream> | 13 #include <iostream> |
| 14 #include <memory> | 14 #include <memory> |
| 15 #include <sstream> | 15 #include <sstream> |
| 16 #include <string> | 16 #include <string> |
| 17 | 17 |
| 18 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" | 18 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
| 19 #include "webrtc/logging/rtc_event_log/rtc_event_log_parser.h" | 19 #include "webrtc/logging/rtc_event_log/rtc_event_log_parser.h" |
| 20 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | 20 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 21 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | 21 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" |
| 22 #include "webrtc/rtc_base/checks.h" | 22 #include "webrtc/rtc_base/checks.h" |
| 23 #include "webrtc/rtc_base/flags.h" | 23 #include "webrtc/rtc_base/flags.h" |
| 24 #include "webrtc/test/rtp_file_writer.h" | 24 #include "webrtc/test/rtp_file_writer.h" |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 using MediaType = webrtc::ParsedRtcEventLog::MediaType; | 28 using MediaType = webrtc::ParsedRtcEventLog::MediaType; |
| 29 | 29 |
| 30 DEFINE_bool(noaudio, | 30 DEFINE_bool(audio, |
| 31 false, | 31 true, |
| 32 "Excludes audio packets from the converted RTPdump file."); | 32 "Excludes audio packets from the converted RTPdump file."); |
| 33 DEFINE_bool(novideo, | 33 DEFINE_bool(video, |
| 34 false, | 34 true, |
| 35 "Excludes video packets from the converted RTPdump file."); | 35 "Excludes video packets from the converted RTPdump file."); |
| 36 DEFINE_bool(nodata, | 36 DEFINE_bool(data, |
| 37 false, | 37 true, |
| 38 "Excludes data packets from the converted RTPdump file."); | 38 "Excludes data packets from the converted RTPdump file."); |
| 39 DEFINE_bool(nortp, | 39 DEFINE_bool(rtp, |
| 40 false, | 40 true, |
| 41 "Excludes RTP packets from the converted RTPdump file."); | 41 "Excludes RTP packets from the converted RTPdump file."); |
| 42 DEFINE_bool(nortcp, | 42 DEFINE_bool(rtcp, |
| 43 false, | 43 true, |
| 44 "Excludes RTCP packets from the converted RTPdump file."); | 44 "Excludes RTCP packets from the converted RTPdump file."); |
| 45 DEFINE_string(ssrc, | 45 DEFINE_string(ssrc, |
| 46 "", | 46 "", |
| 47 "Store only packets with this SSRC (decimal or hex, the latter " | 47 "Store only packets with this SSRC (decimal or hex, the latter " |
| 48 "starting with 0x)."); | 48 "starting with 0x)."); |
| 49 DEFINE_bool(help, false, "Prints this message."); | 49 DEFINE_bool(help, false, "Prints this message."); |
| 50 | 50 |
| 51 // Parses the input string for a valid SSRC. If a valid SSRC is found, it is | 51 // Parses the input string for a valid SSRC. If a valid SSRC is found, it is |
| 52 // written to the output variable |ssrc|, and true is returned. Otherwise, | 52 // written to the output variable |ssrc|, and true is returned. Otherwise, |
| 53 // false is returned. | 53 // false is returned. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 115 | 115 |
| 116 std::cout << "Found " << parsed_stream.GetNumberOfEvents() | 116 std::cout << "Found " << parsed_stream.GetNumberOfEvents() |
| 117 << " events in the input file." << std::endl; | 117 << " events in the input file." << std::endl; |
| 118 int rtp_counter = 0, rtcp_counter = 0; | 118 int rtp_counter = 0, rtcp_counter = 0; |
| 119 bool header_only = false; | 119 bool header_only = false; |
| 120 for (size_t i = 0; i < parsed_stream.GetNumberOfEvents(); i++) { | 120 for (size_t i = 0; i < parsed_stream.GetNumberOfEvents(); i++) { |
| 121 // The parsed_stream will assert if the protobuf event is missing | 121 // The parsed_stream will assert if the protobuf event is missing |
| 122 // some required fields and we attempt to access them. We could consider | 122 // some required fields and we attempt to access them. We could consider |
| 123 // a softer failure option, but it does not seem useful to generate | 123 // a softer failure option, but it does not seem useful to generate |
| 124 // RTP dumps based on broken event logs. | 124 // RTP dumps based on broken event logs. |
| 125 if (!FLAG_nortp && | 125 if (FLAG_rtp && |
| 126 parsed_stream.GetEventType(i) == webrtc::ParsedRtcEventLog::RTP_EVENT) { | 126 parsed_stream.GetEventType(i) == webrtc::ParsedRtcEventLog::RTP_EVENT) { |
| 127 webrtc::test::RtpPacket packet; | 127 webrtc::test::RtpPacket packet; |
| 128 webrtc::PacketDirection direction; | 128 webrtc::PacketDirection direction; |
| 129 parsed_stream.GetRtpHeader(i, &direction, packet.data, &packet.length, | 129 parsed_stream.GetRtpHeader(i, &direction, packet.data, &packet.length, |
| 130 &packet.original_length); | 130 &packet.original_length); |
| 131 if (packet.original_length > packet.length) | 131 if (packet.original_length > packet.length) |
| 132 header_only = true; | 132 header_only = true; |
| 133 packet.time_ms = parsed_stream.GetTimestamp(i) / 1000; | 133 packet.time_ms = parsed_stream.GetTimestamp(i) / 1000; |
| 134 | 134 |
| 135 webrtc::RtpUtility::RtpHeaderParser rtp_parser(packet.data, | 135 webrtc::RtpUtility::RtpHeaderParser rtp_parser(packet.data, |
| 136 packet.length); | 136 packet.length); |
| 137 | 137 |
| 138 // TODO(terelius): Maybe add a flag to dump outgoing traffic instead? | 138 // TODO(terelius): Maybe add a flag to dump outgoing traffic instead? |
| 139 if (direction == webrtc::kOutgoingPacket) | 139 if (direction == webrtc::kOutgoingPacket) |
| 140 continue; | 140 continue; |
| 141 | 141 |
| 142 webrtc::RTPHeader parsed_header; | 142 webrtc::RTPHeader parsed_header; |
| 143 rtp_parser.Parse(&parsed_header); | 143 rtp_parser.Parse(&parsed_header); |
| 144 MediaType media_type = | 144 MediaType media_type = |
| 145 parsed_stream.GetMediaType(parsed_header.ssrc, direction); | 145 parsed_stream.GetMediaType(parsed_header.ssrc, direction); |
| 146 if (FLAG_noaudio && media_type == MediaType::AUDIO) | 146 if (!FLAG_audio && media_type == MediaType::AUDIO) |
| 147 continue; | 147 continue; |
| 148 if (FLAG_novideo && media_type == MediaType::VIDEO) | 148 if (!FLAG_video && media_type == MediaType::VIDEO) |
| 149 continue; | 149 continue; |
| 150 if (FLAG_nodata && media_type == MediaType::DATA) | 150 if (!FLAG_data && media_type == MediaType::DATA) |
| 151 continue; | 151 continue; |
| 152 if (strlen(FLAG_ssrc) > 0) { | 152 if (strlen(FLAG_ssrc) > 0) { |
| 153 const uint32_t packet_ssrc = | 153 const uint32_t packet_ssrc = |
| 154 webrtc::ByteReader<uint32_t>::ReadBigEndian( | 154 webrtc::ByteReader<uint32_t>::ReadBigEndian( |
| 155 reinterpret_cast<const uint8_t*>(packet.data + 8)); | 155 reinterpret_cast<const uint8_t*>(packet.data + 8)); |
| 156 if (packet_ssrc != ssrc_filter) | 156 if (packet_ssrc != ssrc_filter) |
| 157 continue; | 157 continue; |
| 158 } | 158 } |
| 159 | 159 |
| 160 rtp_writer->WritePacket(&packet); | 160 rtp_writer->WritePacket(&packet); |
| 161 rtp_counter++; | 161 rtp_counter++; |
| 162 } | 162 } |
| 163 if (!FLAG_nortcp && | 163 if (FLAG_rtcp && |
| 164 parsed_stream.GetEventType(i) == | 164 parsed_stream.GetEventType(i) == |
| 165 webrtc::ParsedRtcEventLog::RTCP_EVENT) { | 165 webrtc::ParsedRtcEventLog::RTCP_EVENT) { |
| 166 webrtc::test::RtpPacket packet; | 166 webrtc::test::RtpPacket packet; |
| 167 webrtc::PacketDirection direction; | 167 webrtc::PacketDirection direction; |
| 168 parsed_stream.GetRtcpPacket(i, &direction, packet.data, &packet.length); | 168 parsed_stream.GetRtcpPacket(i, &direction, packet.data, &packet.length); |
| 169 // For RTCP packets the original_length should be set to 0 in the | 169 // For RTCP packets the original_length should be set to 0 in the |
| 170 // RTPdump format. | 170 // RTPdump format. |
| 171 packet.original_length = 0; | 171 packet.original_length = 0; |
| 172 packet.time_ms = parsed_stream.GetTimestamp(i) / 1000; | 172 packet.time_ms = parsed_stream.GetTimestamp(i) / 1000; |
| 173 | 173 |
| 174 // TODO(terelius): Maybe add a flag to dump outgoing traffic instead? | 174 // TODO(terelius): Maybe add a flag to dump outgoing traffic instead? |
| 175 if (direction == webrtc::kOutgoingPacket) | 175 if (direction == webrtc::kOutgoingPacket) |
| 176 continue; | 176 continue; |
| 177 | 177 |
| 178 // Note that |packet_ssrc| is the sender SSRC. An RTCP message may contain | 178 // Note that |packet_ssrc| is the sender SSRC. An RTCP message may contain |
| 179 // report blocks for many streams, thus several SSRCs and they doen't | 179 // report blocks for many streams, thus several SSRCs and they doen't |
| 180 // necessarily have to be of the same media type. | 180 // necessarily have to be of the same media type. |
| 181 const uint32_t packet_ssrc = webrtc::ByteReader<uint32_t>::ReadBigEndian( | 181 const uint32_t packet_ssrc = webrtc::ByteReader<uint32_t>::ReadBigEndian( |
| 182 reinterpret_cast<const uint8_t*>(packet.data + 4)); | 182 reinterpret_cast<const uint8_t*>(packet.data + 4)); |
| 183 MediaType media_type = parsed_stream.GetMediaType(packet_ssrc, direction); | 183 MediaType media_type = parsed_stream.GetMediaType(packet_ssrc, direction); |
| 184 if (FLAG_noaudio && media_type == MediaType::AUDIO) | 184 if (!FLAG_audio && media_type == MediaType::AUDIO) |
| 185 continue; | 185 continue; |
| 186 if (FLAG_novideo && media_type == MediaType::VIDEO) | 186 if (!FLAG_video && media_type == MediaType::VIDEO) |
| 187 continue; | 187 continue; |
| 188 if (FLAG_nodata && media_type == MediaType::DATA) | 188 if (!FLAG_data && media_type == MediaType::DATA) |
| 189 continue; | 189 continue; |
| 190 if (strlen(FLAG_ssrc) > 0) { | 190 if (strlen(FLAG_ssrc) > 0) { |
| 191 if (packet_ssrc != ssrc_filter) | 191 if (packet_ssrc != ssrc_filter) |
| 192 continue; | 192 continue; |
| 193 } | 193 } |
| 194 | 194 |
| 195 rtp_writer->WritePacket(&packet); | 195 rtp_writer->WritePacket(&packet); |
| 196 rtcp_counter++; | 196 rtcp_counter++; |
| 197 } | 197 } |
| 198 } | 198 } |
| 199 std::cout << "Wrote " << rtp_counter << (header_only ? " header-only" : "") | 199 std::cout << "Wrote " << rtp_counter << (header_only ? " header-only" : "") |
| 200 << " RTP packets and " << rtcp_counter << " RTCP packets to the " | 200 << " RTP packets and " << rtcp_counter << " RTCP packets to the " |
| 201 << "output file." << std::endl; | 201 << "output file." << std::endl; |
| 202 return 0; | 202 return 0; |
| 203 } | 203 } |
| OLD | NEW |