diff options
Diffstat (limited to 'webrtc/modules/remote_bitrate_estimator/tools')
4 files changed, 351 insertions, 0 deletions
diff --git a/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc new file mode 100644 index 0000000000..9493805a1c --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.cc @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" + +#include <sstream> +#include <stdio.h> +#include <string> + +#include "gflags/gflags.h" +#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h" +#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/test/rtp_file_reader.h" + +namespace flags { + +DEFINE_string(extension_type, + "abs", + "Extension type, either abs for absolute send time or tsoffset " + "for timestamp offset."); +std::string ExtensionType() { + return static_cast<std::string>(FLAGS_extension_type); +} + +DEFINE_int32(extension_id, 3, "Extension id."); +int ExtensionId() { + return static_cast<int>(FLAGS_extension_id); +} + +DEFINE_string(input_file, "", "Input file."); +std::string InputFile() { + return static_cast<std::string>(FLAGS_input_file); +} + +DEFINE_string(ssrc_filter, + "", + "Comma-separated list of SSRCs in hexadecimal which are to be " + "used as input to the BWE (only applicable to pcap files)."); +std::set<uint32_t> SsrcFilter() { + std::string ssrc_filter_string = static_cast<std::string>(FLAGS_ssrc_filter); + if (ssrc_filter_string.empty()) + return std::set<uint32_t>(); + std::stringstream ss; + std::string ssrc_filter = ssrc_filter_string; + std::set<uint32_t> ssrcs; + + // Parse the ssrcs in hexadecimal format. + ss << std::hex << ssrc_filter; + uint32_t ssrc; + while (ss >> ssrc) { + ssrcs.insert(ssrc); + ss.ignore(1, ','); + } + return ssrcs; +} +} // namespace flags + +bool ParseArgsAndSetupEstimator(int argc, + char** argv, + webrtc::Clock* clock, + webrtc::RemoteBitrateObserver* observer, + webrtc::test::RtpFileReader** rtp_reader, + webrtc::RtpHeaderParser** parser, + webrtc::RemoteBitrateEstimator** estimator, + std::string* estimator_used) { + google::ParseCommandLineFlags(&argc, &argv, true); + std::string filename = flags::InputFile(); + + std::set<uint32_t> ssrc_filter = flags::SsrcFilter(); + fprintf(stderr, "Filter on SSRC: "); + for (auto& s : ssrc_filter) { + fprintf(stderr, "0x%08x, ", s); + } + fprintf(stderr, "\n"); + if (filename.substr(filename.find_last_of(".")) == ".pcap") { + fprintf(stderr, "Opening as pcap\n"); + *rtp_reader = webrtc::test::RtpFileReader::Create( + webrtc::test::RtpFileReader::kPcap, filename.c_str(), + flags::SsrcFilter()); + } else { + fprintf(stderr, "Opening as rtp\n"); + *rtp_reader = webrtc::test::RtpFileReader::Create( + webrtc::test::RtpFileReader::kRtpDump, filename.c_str()); + } + if (!*rtp_reader) { + fprintf(stderr, "Cannot open input file %s\n", filename.c_str()); + return false; + } + fprintf(stderr, "Input file: %s\n\n", filename.c_str()); + + webrtc::RTPExtensionType extension = webrtc::kRtpExtensionAbsoluteSendTime; + if (flags::ExtensionType() == "tsoffset") { + extension = webrtc::kRtpExtensionTransmissionTimeOffset; + fprintf(stderr, "Extension: toffset\n"); + } else if (flags::ExtensionType() == "abs") { + fprintf(stderr, "Extension: abs\n"); + } else { + fprintf(stderr, "Unknown extension type\n"); + return false; + } + + // Setup the RTP header parser and the bitrate estimator. + *parser = webrtc::RtpHeaderParser::Create(); + (*parser)->RegisterRtpHeaderExtension(extension, flags::ExtensionId()); + if (estimator) { + switch (extension) { + case webrtc::kRtpExtensionAbsoluteSendTime: { + *estimator = + new webrtc::RemoteBitrateEstimatorAbsSendTime(observer, clock); + *estimator_used = "AbsoluteSendTimeRemoteBitrateEstimator"; + break; + } + case webrtc::kRtpExtensionTransmissionTimeOffset: { + *estimator = + new webrtc::RemoteBitrateEstimatorSingleStream(observer, clock); + *estimator_used = "RemoteBitrateEstimator"; + break; + } + default: + assert(false); + } + } + return true; +} diff --git a/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h new file mode 100644 index 0000000000..2d12a8083f --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TOOLS_BWE_RTP_H_ +#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TOOLS_BWE_RTP_H_ + +#include <string> + +namespace webrtc { +class Clock; +class RemoteBitrateEstimator; +class RemoteBitrateObserver; +class RtpHeaderParser; +namespace test { +class RtpFileReader; +} +} + +bool ParseArgsAndSetupEstimator( + int argc, + char** argv, + webrtc::Clock* clock, + webrtc::RemoteBitrateObserver* observer, + webrtc::test::RtpFileReader** rtp_reader, + webrtc::RtpHeaderParser** parser, + webrtc::RemoteBitrateEstimator** estimator, + std::string* estimator_used); + +#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TOOLS_BWE_RTP_H_ diff --git a/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc new file mode 100644 index 0000000000..19e4a07b4d --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp_play.cc @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdio.h> + +#include "webrtc/base/format_macros.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" +#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/test/rtp_file_reader.h" + +class Observer : public webrtc::RemoteBitrateObserver { + public: + explicit Observer(webrtc::Clock* clock) : clock_(clock) {} + + // Called when a receive channel group has a new bitrate estimate for the + // incoming streams. + virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs, + unsigned int bitrate) { + printf("[%u] Num SSRCs: %d, bitrate: %u\n", + static_cast<uint32_t>(clock_->TimeInMilliseconds()), + static_cast<int>(ssrcs.size()), bitrate); + } + + virtual ~Observer() {} + + private: + webrtc::Clock* clock_; +}; + +int main(int argc, char** argv) { + webrtc::test::RtpFileReader* reader; + webrtc::RemoteBitrateEstimator* estimator; + webrtc::RtpHeaderParser* parser; + std::string estimator_used; + webrtc::SimulatedClock clock(0); + Observer observer(&clock); + if (!ParseArgsAndSetupEstimator(argc, argv, &clock, &observer, &reader, + &parser, &estimator, &estimator_used)) { + return -1; + } + rtc::scoped_ptr<webrtc::test::RtpFileReader> rtp_reader(reader); + rtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_parser(parser); + rtc::scoped_ptr<webrtc::RemoteBitrateEstimator> rbe(estimator); + + // Process the file. + int packet_counter = 0; + int64_t next_rtp_time_ms = 0; + int64_t first_rtp_time_ms = -1; + int abs_send_time_count = 0; + int ts_offset_count = 0; + webrtc::test::RtpPacket packet; + if (!rtp_reader->NextPacket(&packet)) { + printf("No RTP packet found\n"); + return 0; + } + first_rtp_time_ms = packet.time_ms; + packet.time_ms = packet.time_ms - first_rtp_time_ms; + while (true) { + if (next_rtp_time_ms <= clock.TimeInMilliseconds()) { + if (!parser->IsRtcp(packet.data, packet.length)) { + webrtc::RTPHeader header; + parser->Parse(packet.data, packet.length, &header); + if (header.extension.hasAbsoluteSendTime) + ++abs_send_time_count; + if (header.extension.hasTransmissionTimeOffset) + ++ts_offset_count; + size_t packet_length = packet.length; + // Some RTP dumps only include the header, in which case packet.length + // is equal to the header length. In those cases packet.original_length + // usually contains the original packet length. + if (packet.original_length > 0) { + packet_length = packet.original_length; + } + rbe->IncomingPacket(clock.TimeInMilliseconds(), + packet_length - header.headerLength, header, true); + ++packet_counter; + } + if (!rtp_reader->NextPacket(&packet)) { + break; + } + packet.time_ms = packet.time_ms - first_rtp_time_ms; + next_rtp_time_ms = packet.time_ms; + } + int64_t time_until_process_ms = rbe->TimeUntilNextProcess(); + if (time_until_process_ms <= 0) { + rbe->Process(); + } + int64_t time_until_next_event = + std::min(rbe->TimeUntilNextProcess(), + next_rtp_time_ms - clock.TimeInMilliseconds()); + clock.AdvanceTimeMilliseconds(std::max<int64_t>(time_until_next_event, 0)); + } + printf("Parsed %d packets\nTime passed: %" PRId64 " ms\n", packet_counter, + clock.TimeInMilliseconds()); + printf("Estimator used: %s\n", estimator_used.c_str()); + printf("Packets with absolute send time: %d\n", + abs_send_time_count); + printf("Packets with timestamp offset: %d\n", + ts_offset_count); + printf("Packets with no extension: %d\n", + packet_counter - ts_offset_count - abs_send_time_count); + return 0; +} diff --git a/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc b/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc new file mode 100644 index 0000000000..e277481886 --- /dev/null +++ b/webrtc/modules/remote_bitrate_estimator/tools/rtp_to_text.cc @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <stdio.h> +#include <sstream> + +#include "webrtc/base/format_macros.h" +#include "webrtc/base/scoped_ptr.h" +#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" +#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" +#include "webrtc/test/rtp_file_reader.h" + +int main(int argc, char** argv) { + webrtc::test::RtpFileReader* reader; + webrtc::RtpHeaderParser* parser; + if (!ParseArgsAndSetupEstimator(argc, argv, NULL, NULL, &reader, &parser, + NULL, NULL)) { + return -1; + } + bool arrival_time_only = (argc >= 5 && strncmp(argv[4], "-t", 2) == 0); + rtc::scoped_ptr<webrtc::test::RtpFileReader> rtp_reader(reader); + rtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_parser(parser); + fprintf(stdout, "seqnum timestamp ts_offset abs_sendtime recvtime " + "markerbit ssrc size original_size\n"); + int packet_counter = 0; + int non_zero_abs_send_time = 0; + int non_zero_ts_offsets = 0; + webrtc::test::RtpPacket packet; + while (rtp_reader->NextPacket(&packet)) { + webrtc::RTPHeader header; + parser->Parse(packet.data, packet.length, &header); + if (header.extension.absoluteSendTime != 0) + ++non_zero_abs_send_time; + if (header.extension.transmissionTimeOffset != 0) + ++non_zero_ts_offsets; + if (arrival_time_only) { + std::stringstream ss; + ss << static_cast<int64_t>(packet.time_ms) * 1000000; + fprintf(stdout, "%s\n", ss.str().c_str()); + } else { + fprintf(stdout, + "%u %u %d %u %u %d %u %" PRIuS " %" PRIuS "\n", + header.sequenceNumber, + header.timestamp, + header.extension.transmissionTimeOffset, + header.extension.absoluteSendTime, + packet.time_ms, + header.markerBit, + header.ssrc, + packet.length, + packet.original_length); + } + ++packet_counter; + } + fprintf(stderr, "Parsed %d packets\n", packet_counter); + fprintf(stderr, "Packets with non-zero absolute send time: %d\n", + non_zero_abs_send_time); + fprintf(stderr, "Packets with non-zero timestamp offset: %d\n", + non_zero_ts_offsets); + return 0; +} |