1e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org/* 2e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * 4e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * Use of this source code is governed by a BSD-style license 5e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * that can be found in the LICENSE file in the root of the source 6e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * tree. An additional intellectual property rights grant can be found 7e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * in the file PATENTS. All contributing project authors may 8e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org * be found in the AUTHORS file in the root of the source tree. 9e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org */ 10e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 11e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include <stdio.h> 12e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 13e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h" 14e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include "webrtc/modules/remote_bitrate_estimator/tools/bwe_rtp.h" 15e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 16e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 17e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h" 18ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org#include "webrtc/test/rtp_file_reader.h" 19e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 20e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.orgclass Observer : public webrtc::RemoteBitrateObserver { 21e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org public: 22e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org explicit Observer(webrtc::Clock* clock) : clock_(clock) {} 23e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 24e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org // Called when a receive channel group has a new bitrate estimate for the 25e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org // incoming streams. 26e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs, 27e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org unsigned int bitrate) { 28e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("[%u] Num SSRCs: %d, bitrate: %u\n", 29e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org static_cast<uint32_t>(clock_->TimeInMilliseconds()), 30e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org static_cast<int>(ssrcs.size()), bitrate); 31e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 32e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 33e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org virtual ~Observer() {} 34e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 35e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org private: 36e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::Clock* clock_; 37e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org}; 38e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 39e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.orgint main(int argc, char** argv) { 40e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (argc < 4) { 41e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("Usage: bwe_rtp_play <extension type> <extension id> " 42e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org "<input_file.rtp>\n"); 43e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("<extension type> can either be:\n" 44e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org " abs for absolute send time or\n" 45e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org " tsoffset for timestamp offset.\n" 46e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org "<extension id> is the id associated with the extension.\n"); 47e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org return -1; 48e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 49ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org webrtc::test::RtpFileReader* reader; 50e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::RemoteBitrateEstimator* estimator; 51e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::RtpHeaderParser* parser; 52e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org std::string estimator_used; 53e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::SimulatedClock clock(0); 54e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org Observer observer(&clock); 55e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (!ParseArgsAndSetupEstimator(argc, argv, &clock, &observer, &reader, 56e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org &parser, &estimator, &estimator_used)) { 57e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org return -1; 58e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 59ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org webrtc::scoped_ptr<webrtc::test::RtpFileReader> rtp_reader(reader); 60e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::scoped_ptr<webrtc::RtpHeaderParser> rtp_parser(parser); 61e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::scoped_ptr<webrtc::RemoteBitrateEstimator> rbe(estimator); 62e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org 63e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org // Process the file. 64e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int packet_counter = 0; 65e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int64_t next_process_time_ms = 0; 66e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int64_t next_rtp_time_ms = 0; 67e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int64_t first_rtp_time_ms = -1; 68e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int non_zero_abs_send_time = 0; 69e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int non_zero_ts_offsets = 0; 70e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org while (true) { 71e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (next_rtp_time_ms <= clock.TimeInMilliseconds()) { 72ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org webrtc::test::RtpFileReader::Packet packet; 73ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org if (!rtp_reader->NextPacket(&packet)) { 74e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org break; 75e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 76e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (first_rtp_time_ms == -1) 77ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org first_rtp_time_ms = packet.time_ms; 78ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org packet.time_ms = packet.time_ms - first_rtp_time_ms; 79e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org webrtc::RTPHeader header; 80ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org parser->Parse(packet.data, packet.length, &header); 81e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (header.extension.absoluteSendTime != 0) 82e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org ++non_zero_abs_send_time; 83e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (header.extension.transmissionTimeOffset != 0) 84e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org ++non_zero_ts_offsets; 85e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org rbe->IncomingPacket(clock.TimeInMilliseconds(), 86ac772a43f023d08fc0222473e669924113274bddpbos@webrtc.org static_cast<int>(packet.length - header.headerLength), 87e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org header); 88e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org ++packet_counter; 89e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 90e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org next_process_time_ms = rbe->TimeUntilNextProcess() + 91e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org clock.TimeInMilliseconds(); 92e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org if (next_process_time_ms <= clock.TimeInMilliseconds()) { 93e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org rbe->Process(); 94e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 95e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org int time_until_next_event = 96e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org std::min(next_process_time_ms, next_rtp_time_ms) - 97e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org clock.TimeInMilliseconds(); 98e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org clock.AdvanceTimeMilliseconds(std::max(time_until_next_event, 0)); 99e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org } 100e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("Parsed %d packets\nTime passed: %u ms\n", packet_counter, 101e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org static_cast<uint32_t>(clock.TimeInMilliseconds())); 102e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("Estimator used: %s\n", estimator_used.c_str()); 103e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("Packets with non-zero absolute send time: %d\n", 104e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org non_zero_abs_send_time); 105e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org printf("Packets with non-zero timestamp offset: %d\n", 106e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org non_zero_ts_offsets); 107e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org return 0; 108e1c99022cc666e440e9fc74dc7cf8414987a47a5stefan@webrtc.org} 109