OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // This program benchmarks the theoretical throughput of the cast library. | 5 // This program benchmarks the theoretical throughput of the cast library. |
6 // It runs using a fake clock, simulated network and fake codecs. This allows | 6 // It runs using a fake clock, simulated network and fake codecs. This allows |
7 // tests to run much faster than real time. | 7 // tests to run much faster than real time. |
8 // To run the program, run: | 8 // To run the program, run: |
9 // $ ./out/Release/cast_benchmarks | tee benchmarkoutput.asc | 9 // $ ./out/Release/cast_benchmarks | tee benchmarkoutput.asc |
10 // This may take a while, when it is done, you can view the data with | 10 // This may take a while, when it is done, you can view the data with |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include <stdint.h> | 26 #include <stdint.h> |
27 #include <map> | 27 #include <map> |
28 #include <utility> | 28 #include <utility> |
29 #include <vector> | 29 #include <vector> |
30 | 30 |
31 #include "base/at_exit.h" | 31 #include "base/at_exit.h" |
32 #include "base/bind.h" | 32 #include "base/bind.h" |
33 #include "base/bind_helpers.h" | 33 #include "base/bind_helpers.h" |
34 #include "base/command_line.h" | 34 #include "base/command_line.h" |
35 #include "base/debug/profiler.h" | 35 #include "base/debug/profiler.h" |
| 36 #include "base/memory/ptr_util.h" |
36 #include "base/memory/weak_ptr.h" | 37 #include "base/memory/weak_ptr.h" |
37 #include "base/run_loop.h" | 38 #include "base/run_loop.h" |
38 #include "base/stl_util.h" | 39 #include "base/stl_util.h" |
39 #include "base/strings/string_number_conversions.h" | 40 #include "base/strings/string_number_conversions.h" |
40 #include "base/strings/stringprintf.h" | 41 #include "base/strings/stringprintf.h" |
41 #include "base/test/simple_test_tick_clock.h" | 42 #include "base/test/simple_test_tick_clock.h" |
42 #include "base/threading/thread.h" | 43 #include "base/threading/thread.h" |
43 #include "base/time/tick_clock.h" | 44 #include "base/time/tick_clock.h" |
44 #include "media/base/audio_bus.h" | 45 #include "media/base/audio_bus.h" |
45 #include "media/base/fake_single_thread_task_runner.h" | 46 #include "media/base/fake_single_thread_task_runner.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 public: | 88 public: |
88 // Takes ownership of |transport|. | 89 // Takes ownership of |transport|. |
89 void Init(CastTransport* transport, | 90 void Init(CastTransport* transport, |
90 uint64_t* encoded_video_bytes, | 91 uint64_t* encoded_video_bytes, |
91 uint64_t* encoded_audio_bytes) { | 92 uint64_t* encoded_audio_bytes) { |
92 transport_.reset(transport); | 93 transport_.reset(transport); |
93 encoded_video_bytes_ = encoded_video_bytes; | 94 encoded_video_bytes_ = encoded_video_bytes; |
94 encoded_audio_bytes_ = encoded_audio_bytes; | 95 encoded_audio_bytes_ = encoded_audio_bytes; |
95 } | 96 } |
96 | 97 |
97 void InitializeAudio(const CastTransportRtpConfig& config, | 98 void InitializeAudio( |
98 const RtcpCastMessageCallback& cast_message_cb, | 99 const CastTransportRtpConfig& config, |
99 const RtcpRttCallback& rtt_cb, | 100 std::unique_ptr<SenderRtcpObserver> rtcp_observer) final { |
100 const RtcpPliCallback& key_frame_cb) final { | |
101 audio_ssrc_ = config.ssrc; | 101 audio_ssrc_ = config.ssrc; |
102 transport_->InitializeAudio(config, cast_message_cb, rtt_cb, key_frame_cb); | 102 transport_->InitializeAudio(config, std::move(rtcp_observer)); |
103 } | 103 } |
104 | 104 |
105 void InitializeVideo(const CastTransportRtpConfig& config, | 105 void InitializeVideo( |
106 const RtcpCastMessageCallback& cast_message_cb, | 106 const CastTransportRtpConfig& config, |
107 const RtcpRttCallback& rtt_cb, | 107 std::unique_ptr<SenderRtcpObserver> rtcp_observer) final { |
108 const RtcpPliCallback& key_frame_cb) final { | |
109 video_ssrc_ = config.ssrc; | 108 video_ssrc_ = config.ssrc; |
110 transport_->InitializeVideo(config, cast_message_cb, rtt_cb, key_frame_cb); | 109 transport_->InitializeVideo(config, std::move(rtcp_observer)); |
111 } | 110 } |
112 | 111 |
113 void InsertFrame(uint32_t ssrc, const EncodedFrame& frame) final { | 112 void InsertFrame(uint32_t ssrc, const EncodedFrame& frame) final { |
114 if (ssrc == audio_ssrc_) { | 113 if (ssrc == audio_ssrc_) { |
115 *encoded_audio_bytes_ += frame.data.size(); | 114 *encoded_audio_bytes_ += frame.data.size(); |
116 } else if (ssrc == video_ssrc_) { | 115 } else if (ssrc == video_ssrc_) { |
117 *encoded_video_bytes_ += frame.data.size(); | 116 *encoded_video_bytes_ += frame.data.size(); |
118 } | 117 } |
119 transport_->InsertFrame(ssrc, frame); | 118 transport_->InsertFrame(ssrc, frame); |
120 } | 119 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 transport_->AddPli(pli_message); | 167 transport_->AddPli(pli_message); |
169 } | 168 } |
170 | 169 |
171 void SendRtcpFromRtpReceiver() final { | 170 void SendRtcpFromRtpReceiver() final { |
172 transport_->SendRtcpFromRtpReceiver(); | 171 transport_->SendRtcpFromRtpReceiver(); |
173 } | 172 } |
174 | 173 |
175 void SetOptions(const base::DictionaryValue& options) final {} | 174 void SetOptions(const base::DictionaryValue& options) final {} |
176 | 175 |
177 private: | 176 private: |
178 scoped_ptr<CastTransport> transport_; | 177 std::unique_ptr<CastTransport> transport_; |
179 uint32_t audio_ssrc_, video_ssrc_; | 178 uint32_t audio_ssrc_, video_ssrc_; |
180 uint64_t* encoded_video_bytes_; | 179 uint64_t* encoded_video_bytes_; |
181 uint64_t* encoded_audio_bytes_; | 180 uint64_t* encoded_audio_bytes_; |
182 }; | 181 }; |
183 | 182 |
184 struct MeasuringPoint { | 183 struct MeasuringPoint { |
185 MeasuringPoint(double bitrate_, double latency_, double percent_packet_drop_) | 184 MeasuringPoint(double bitrate_, double latency_, double percent_packet_drop_) |
186 : bitrate(bitrate_), | 185 : bitrate(bitrate_), |
187 latency(latency_), | 186 latency(latency_), |
188 percent_packet_drop(percent_packet_drop_) {} | 187 percent_packet_drop(percent_packet_drop_) {} |
(...skipping 21 matching lines...) Expand all Loading... |
210 RunOneBenchmark() | 209 RunOneBenchmark() |
211 : start_time_(), | 210 : start_time_(), |
212 task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)), | 211 task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)), |
213 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_)), | 212 testing_clock_sender_(new test::SkewedTickClock(&testing_clock_)), |
214 task_runner_sender_( | 213 task_runner_sender_( |
215 new test::SkewedSingleThreadTaskRunner(task_runner_)), | 214 new test::SkewedSingleThreadTaskRunner(task_runner_)), |
216 testing_clock_receiver_(new test::SkewedTickClock(&testing_clock_)), | 215 testing_clock_receiver_(new test::SkewedTickClock(&testing_clock_)), |
217 task_runner_receiver_( | 216 task_runner_receiver_( |
218 new test::SkewedSingleThreadTaskRunner(task_runner_)), | 217 new test::SkewedSingleThreadTaskRunner(task_runner_)), |
219 cast_environment_sender_(new CastEnvironment( | 218 cast_environment_sender_(new CastEnvironment( |
220 scoped_ptr<base::TickClock>(testing_clock_sender_), | 219 std::unique_ptr<base::TickClock>(testing_clock_sender_), |
221 task_runner_sender_, | 220 task_runner_sender_, |
222 task_runner_sender_, | 221 task_runner_sender_, |
223 task_runner_sender_)), | 222 task_runner_sender_)), |
224 cast_environment_receiver_(new CastEnvironment( | 223 cast_environment_receiver_(new CastEnvironment( |
225 scoped_ptr<base::TickClock>(testing_clock_receiver_), | 224 std::unique_ptr<base::TickClock>(testing_clock_receiver_), |
226 task_runner_receiver_, | 225 task_runner_receiver_, |
227 task_runner_receiver_, | 226 task_runner_receiver_, |
228 task_runner_receiver_)), | 227 task_runner_receiver_)), |
229 video_bytes_encoded_(0), | 228 video_bytes_encoded_(0), |
230 audio_bytes_encoded_(0), | 229 audio_bytes_encoded_(0), |
231 frames_sent_(0) { | 230 frames_sent_(0) { |
232 testing_clock_.Advance( | 231 testing_clock_.Advance( |
233 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 232 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
234 } | 233 } |
235 | 234 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 task_runner_sender_->SetSkew(1.0 / skew); | 267 task_runner_sender_->SetSkew(1.0 / skew); |
269 } | 268 } |
270 | 269 |
271 void SetReceiverClockSkew(double skew, base::TimeDelta offset) { | 270 void SetReceiverClockSkew(double skew, base::TimeDelta offset) { |
272 testing_clock_receiver_->SetSkew(skew, offset); | 271 testing_clock_receiver_->SetSkew(skew, offset); |
273 task_runner_receiver_->SetSkew(1.0 / skew); | 272 task_runner_receiver_->SetSkew(1.0 / skew); |
274 } | 273 } |
275 | 274 |
276 void Create(const MeasuringPoint& p); | 275 void Create(const MeasuringPoint& p); |
277 | 276 |
278 void ReceivePacket(scoped_ptr<Packet> packet) { | 277 void ReceivePacket(std::unique_ptr<Packet> packet) { |
279 cast_receiver_->ReceivePacket(std::move(packet)); | 278 cast_receiver_->ReceivePacket(std::move(packet)); |
280 } | 279 } |
281 | 280 |
282 virtual ~RunOneBenchmark() { | 281 virtual ~RunOneBenchmark() { |
283 cast_sender_.reset(); | 282 cast_sender_.reset(); |
284 cast_receiver_.reset(); | 283 cast_receiver_.reset(); |
285 task_runner_->RunTasks(); | 284 task_runner_->RunTasks(); |
286 } | 285 } |
287 | 286 |
288 base::TimeDelta VideoTimestamp(int frame_number) { | 287 base::TimeDelta VideoTimestamp(int frame_number) { |
(...skipping 17 matching lines...) Expand all Loading... |
306 void BasicPlayerGotVideoFrame( | 305 void BasicPlayerGotVideoFrame( |
307 const scoped_refptr<media::VideoFrame>& video_frame, | 306 const scoped_refptr<media::VideoFrame>& video_frame, |
308 const base::TimeTicks& render_time, | 307 const base::TimeTicks& render_time, |
309 bool continuous) { | 308 bool continuous) { |
310 video_ticks_.push_back( | 309 video_ticks_.push_back( |
311 std::make_pair(testing_clock_receiver_->NowTicks(), render_time)); | 310 std::make_pair(testing_clock_receiver_->NowTicks(), render_time)); |
312 cast_receiver_->RequestDecodedVideoFrame(base::Bind( | 311 cast_receiver_->RequestDecodedVideoFrame(base::Bind( |
313 &RunOneBenchmark::BasicPlayerGotVideoFrame, base::Unretained(this))); | 312 &RunOneBenchmark::BasicPlayerGotVideoFrame, base::Unretained(this))); |
314 } | 313 } |
315 | 314 |
316 void BasicPlayerGotAudioFrame(scoped_ptr<AudioBus> audio_bus, | 315 void BasicPlayerGotAudioFrame(std::unique_ptr<AudioBus> audio_bus, |
317 const base::TimeTicks& playout_time, | 316 const base::TimeTicks& playout_time, |
318 bool is_continuous) { | 317 bool is_continuous) { |
319 audio_ticks_.push_back( | 318 audio_ticks_.push_back( |
320 std::make_pair(testing_clock_receiver_->NowTicks(), playout_time)); | 319 std::make_pair(testing_clock_receiver_->NowTicks(), playout_time)); |
321 cast_receiver_->RequestDecodedAudioFrame(base::Bind( | 320 cast_receiver_->RequestDecodedAudioFrame(base::Bind( |
322 &RunOneBenchmark::BasicPlayerGotAudioFrame, base::Unretained(this))); | 321 &RunOneBenchmark::BasicPlayerGotAudioFrame, base::Unretained(this))); |
323 } | 322 } |
324 | 323 |
325 void StartBasicPlayer() { | 324 void StartBasicPlayer() { |
326 cast_receiver_->RequestDecodedVideoFrame(base::Bind( | 325 cast_receiver_->RequestDecodedVideoFrame(base::Bind( |
327 &RunOneBenchmark::BasicPlayerGotVideoFrame, base::Unretained(this))); | 326 &RunOneBenchmark::BasicPlayerGotVideoFrame, base::Unretained(this))); |
328 cast_receiver_->RequestDecodedAudioFrame(base::Bind( | 327 cast_receiver_->RequestDecodedAudioFrame(base::Bind( |
329 &RunOneBenchmark::BasicPlayerGotAudioFrame, base::Unretained(this))); | 328 &RunOneBenchmark::BasicPlayerGotAudioFrame, base::Unretained(this))); |
330 } | 329 } |
331 | 330 |
332 scoped_ptr<test::PacketPipe> CreateSimplePipe(const MeasuringPoint& p) { | 331 std::unique_ptr<test::PacketPipe> CreateSimplePipe(const MeasuringPoint& p) { |
333 scoped_ptr<test::PacketPipe> pipe = test::NewBuffer(65536, p.bitrate); | 332 std::unique_ptr<test::PacketPipe> pipe = test::NewBuffer(65536, p.bitrate); |
334 pipe->AppendToPipe(test::NewRandomDrop(p.percent_packet_drop / 100.0)); | 333 pipe->AppendToPipe(test::NewRandomDrop(p.percent_packet_drop / 100.0)); |
335 pipe->AppendToPipe(test::NewConstantDelay(p.latency / 1000.0)); | 334 pipe->AppendToPipe(test::NewConstantDelay(p.latency / 1000.0)); |
336 return pipe; | 335 return pipe; |
337 } | 336 } |
338 | 337 |
339 void Run(const MeasuringPoint& p) { | 338 void Run(const MeasuringPoint& p) { |
340 available_bitrate_ = p.bitrate; | 339 available_bitrate_ = p.bitrate; |
341 Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16); | 340 Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16); |
342 Create(p); | 341 Create(p); |
343 StartBasicPlayer(); | 342 StartBasicPlayer(); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 // These run on the receiver timeline. | 426 // These run on the receiver timeline. |
428 test::SkewedTickClock* testing_clock_receiver_; | 427 test::SkewedTickClock* testing_clock_receiver_; |
429 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; | 428 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; |
430 | 429 |
431 scoped_refptr<CastEnvironment> cast_environment_sender_; | 430 scoped_refptr<CastEnvironment> cast_environment_sender_; |
432 scoped_refptr<CastEnvironment> cast_environment_receiver_; | 431 scoped_refptr<CastEnvironment> cast_environment_receiver_; |
433 | 432 |
434 LoopBackTransport* receiver_to_sender_; // Owned by CastTransportImpl. | 433 LoopBackTransport* receiver_to_sender_; // Owned by CastTransportImpl. |
435 LoopBackTransport* sender_to_receiver_; // Owned by CastTransportImpl. | 434 LoopBackTransport* sender_to_receiver_; // Owned by CastTransportImpl. |
436 CastTransportWrapper transport_sender_; | 435 CastTransportWrapper transport_sender_; |
437 scoped_ptr<CastTransport> transport_receiver_; | 436 std::unique_ptr<CastTransport> transport_receiver_; |
438 uint64_t video_bytes_encoded_; | 437 uint64_t video_bytes_encoded_; |
439 uint64_t audio_bytes_encoded_; | 438 uint64_t audio_bytes_encoded_; |
440 | 439 |
441 scoped_ptr<CastReceiver> cast_receiver_; | 440 std::unique_ptr<CastReceiver> cast_receiver_; |
442 scoped_ptr<CastSender> cast_sender_; | 441 std::unique_ptr<CastSender> cast_sender_; |
443 | 442 |
444 int frames_sent_; | 443 int frames_sent_; |
445 base::TimeDelta frame_duration_; | 444 base::TimeDelta frame_duration_; |
446 double available_bitrate_; | 445 double available_bitrate_; |
447 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > audio_ticks_; | 446 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > audio_ticks_; |
448 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > video_ticks_; | 447 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > video_ticks_; |
449 }; | 448 }; |
450 | 449 |
451 namespace { | 450 namespace { |
452 | 451 |
453 class TransportClient : public CastTransport::Client { | 452 class TransportClient : public CastTransport::Client { |
454 public: | 453 public: |
455 explicit TransportClient(RunOneBenchmark* run_one_benchmark) | 454 explicit TransportClient(RunOneBenchmark* run_one_benchmark) |
456 : run_one_benchmark_(run_one_benchmark) {} | 455 : run_one_benchmark_(run_one_benchmark) {} |
457 | 456 |
458 void OnStatusChanged(CastTransportStatus status) final { | 457 void OnStatusChanged(CastTransportStatus status) final { |
459 bool result = (status == TRANSPORT_AUDIO_INITIALIZED || | 458 bool result = (status == TRANSPORT_AUDIO_INITIALIZED || |
460 status == TRANSPORT_VIDEO_INITIALIZED); | 459 status == TRANSPORT_VIDEO_INITIALIZED); |
461 EXPECT_TRUE(result); | 460 EXPECT_TRUE(result); |
462 }; | 461 }; |
463 void OnLoggingEventsReceived( | 462 void OnLoggingEventsReceived( |
464 scoped_ptr<std::vector<FrameEvent>> frame_events, | 463 std::unique_ptr<std::vector<FrameEvent>> frame_events, |
465 scoped_ptr<std::vector<PacketEvent>> packet_events) final{}; | 464 std::unique_ptr<std::vector<PacketEvent>> packet_events) final{}; |
466 void ProcessRtpPacket(scoped_ptr<Packet> packet) final { | 465 void ProcessRtpPacket(std::unique_ptr<Packet> packet) final { |
467 if (run_one_benchmark_) | 466 if (run_one_benchmark_) |
468 run_one_benchmark_->ReceivePacket(std::move(packet)); | 467 run_one_benchmark_->ReceivePacket(std::move(packet)); |
469 }; | 468 }; |
470 | 469 |
471 private: | 470 private: |
472 RunOneBenchmark* const run_one_benchmark_; | 471 RunOneBenchmark* const run_one_benchmark_; |
473 | 472 |
474 DISALLOW_COPY_AND_ASSIGN(TransportClient); | 473 DISALLOW_COPY_AND_ASSIGN(TransportClient); |
475 }; | 474 }; |
476 | 475 |
477 } // namepspace | 476 } // namepspace |
478 | 477 |
479 void RunOneBenchmark::Create(const MeasuringPoint& p) { | 478 void RunOneBenchmark::Create(const MeasuringPoint& p) { |
480 sender_to_receiver_ = new LoopBackTransport(cast_environment_sender_); | 479 sender_to_receiver_ = new LoopBackTransport(cast_environment_sender_); |
481 transport_sender_.Init( | 480 transport_sender_.Init( |
482 new CastTransportImpl( | 481 new CastTransportImpl( |
483 testing_clock_sender_, base::TimeDelta::FromSeconds(1), | 482 testing_clock_sender_, base::TimeDelta::FromSeconds(1), |
484 make_scoped_ptr(new TransportClient(nullptr)), | 483 base::WrapUnique(new TransportClient(nullptr)), |
485 make_scoped_ptr(sender_to_receiver_), task_runner_sender_), | 484 base::WrapUnique(sender_to_receiver_), task_runner_sender_), |
486 &video_bytes_encoded_, &audio_bytes_encoded_); | 485 &video_bytes_encoded_, &audio_bytes_encoded_); |
487 | 486 |
488 receiver_to_sender_ = new LoopBackTransport(cast_environment_receiver_); | 487 receiver_to_sender_ = new LoopBackTransport(cast_environment_receiver_); |
489 transport_receiver_.reset(new CastTransportImpl( | 488 transport_receiver_.reset(new CastTransportImpl( |
490 testing_clock_receiver_, base::TimeDelta::FromSeconds(1), | 489 testing_clock_receiver_, base::TimeDelta::FromSeconds(1), |
491 make_scoped_ptr(new TransportClient(this)), | 490 base::WrapUnique(new TransportClient(this)), |
492 make_scoped_ptr(receiver_to_sender_), task_runner_receiver_)); | 491 base::WrapUnique(receiver_to_sender_), task_runner_receiver_)); |
493 | 492 |
494 cast_receiver_ = | 493 cast_receiver_ = |
495 CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_, | 494 CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_, |
496 video_receiver_config_, transport_receiver_.get()); | 495 video_receiver_config_, transport_receiver_.get()); |
497 | 496 |
498 cast_sender_ = | 497 cast_sender_ = |
499 CastSender::Create(cast_environment_sender_, &transport_sender_); | 498 CastSender::Create(cast_environment_sender_, &transport_sender_); |
500 | 499 |
501 cast_sender_->InitializeAudio(audio_sender_config_, | 500 cast_sender_->InitializeAudio(audio_sender_config_, |
502 base::Bind(&ExpectAudioSuccess)); | 501 base::Bind(&ExpectAudioSuccess)); |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 media::cast::CastBenchmark benchmark; | 730 media::cast::CastBenchmark benchmark; |
732 if (getenv("PROFILE_FILE")) { | 731 if (getenv("PROFILE_FILE")) { |
733 std::string profile_file(getenv("PROFILE_FILE")); | 732 std::string profile_file(getenv("PROFILE_FILE")); |
734 base::debug::StartProfiling(profile_file); | 733 base::debug::StartProfiling(profile_file); |
735 benchmark.Run(); | 734 benchmark.Run(); |
736 base::debug::StopProfiling(); | 735 base::debug::StopProfiling(); |
737 } else { | 736 } else { |
738 benchmark.Run(); | 737 benchmark.Run(); |
739 } | 738 } |
740 } | 739 } |
OLD | NEW |