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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 #include "testing/gtest/include/gtest/gtest.h" | 64 #include "testing/gtest/include/gtest/gtest.h" |
65 | 65 |
66 namespace media { | 66 namespace media { |
67 namespace cast { | 67 namespace cast { |
68 | 68 |
69 namespace { | 69 namespace { |
70 | 70 |
71 static const int64_t kStartMillisecond = INT64_C(1245); | 71 static const int64_t kStartMillisecond = INT64_C(1245); |
72 static const int kTargetPlayoutDelayMs = 400; | 72 static const int kTargetPlayoutDelayMs = 400; |
73 | 73 |
74 void UpdateCastTransportStatus(CastTransportStatus status) { | |
75 bool result = (status == TRANSPORT_AUDIO_INITIALIZED || | |
76 status == TRANSPORT_VIDEO_INITIALIZED); | |
77 EXPECT_TRUE(result); | |
78 } | |
79 | |
80 void ExpectVideoSuccess(OperationalStatus status) { | 74 void ExpectVideoSuccess(OperationalStatus status) { |
81 EXPECT_EQ(STATUS_INITIALIZED, status); | 75 EXPECT_EQ(STATUS_INITIALIZED, status); |
82 } | 76 } |
83 | 77 |
84 void ExpectAudioSuccess(OperationalStatus status) { | 78 void ExpectAudioSuccess(OperationalStatus status) { |
85 EXPECT_EQ(STATUS_INITIALIZED, status); | 79 EXPECT_EQ(STATUS_INITIALIZED, status); |
86 } | 80 } |
87 | 81 |
88 void IgnoreRawEvents(scoped_ptr<std::vector<FrameEvent>> frame_events, | |
89 scoped_ptr<std::vector<PacketEvent>> packet_events) {} | |
90 | |
91 } // namespace | 82 } // namespace |
92 | 83 |
93 // Wraps a CastTransportSender and records some statistics about | 84 // Wraps a CastTransportSender and records some statistics about |
94 // the data that goes through it. | 85 // the data that goes through it. |
95 class CastTransportSenderWrapper : public CastTransportSender { | 86 class CastTransportSenderWrapper : public CastTransportSender { |
96 public: | 87 public: |
97 // Takes ownership of |transport|. | 88 // Takes ownership of |transport|. |
98 void Init(CastTransportSender* transport, | 89 void Init(CastTransportSender* transport, |
99 uint64_t* encoded_video_bytes, | 90 uint64_t* encoded_video_bytes, |
100 uint64_t* encoded_audio_bytes) { | 91 uint64_t* encoded_audio_bytes) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 const RtpReceiverStatistics* rtp_receiver_statistics) final { | 152 const RtpReceiverStatistics* rtp_receiver_statistics) final { |
162 return transport_->SendRtcpFromRtpReceiver(ssrc, | 153 return transport_->SendRtcpFromRtpReceiver(ssrc, |
163 sender_ssrc, | 154 sender_ssrc, |
164 time_data, | 155 time_data, |
165 cast_message, | 156 cast_message, |
166 target_delay, | 157 target_delay, |
167 rtcp_events, | 158 rtcp_events, |
168 rtp_receiver_statistics); | 159 rtp_receiver_statistics); |
169 } | 160 } |
170 | 161 |
| 162 void SetOptions(const base::DictionaryValue& options) final {} |
| 163 |
171 private: | 164 private: |
172 scoped_ptr<CastTransportSender> transport_; | 165 scoped_ptr<CastTransportSender> transport_; |
173 uint32_t audio_ssrc_, video_ssrc_; | 166 uint32_t audio_ssrc_, video_ssrc_; |
174 uint64_t* encoded_video_bytes_; | 167 uint64_t* encoded_video_bytes_; |
175 uint64_t* encoded_audio_bytes_; | 168 uint64_t* encoded_audio_bytes_; |
176 }; | 169 }; |
177 | 170 |
178 struct MeasuringPoint { | 171 struct MeasuringPoint { |
179 MeasuringPoint(double bitrate_, double latency_, double percent_packet_drop_) | 172 MeasuringPoint(double bitrate_, double latency_, double percent_packet_drop_) |
180 : bitrate(bitrate_), | 173 : bitrate(bitrate_), |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 cast_environment_sender_(new CastEnvironment( | 206 cast_environment_sender_(new CastEnvironment( |
214 scoped_ptr<base::TickClock>(testing_clock_sender_), | 207 scoped_ptr<base::TickClock>(testing_clock_sender_), |
215 task_runner_sender_, | 208 task_runner_sender_, |
216 task_runner_sender_, | 209 task_runner_sender_, |
217 task_runner_sender_)), | 210 task_runner_sender_)), |
218 cast_environment_receiver_(new CastEnvironment( | 211 cast_environment_receiver_(new CastEnvironment( |
219 scoped_ptr<base::TickClock>(testing_clock_receiver_), | 212 scoped_ptr<base::TickClock>(testing_clock_receiver_), |
220 task_runner_receiver_, | 213 task_runner_receiver_, |
221 task_runner_receiver_, | 214 task_runner_receiver_, |
222 task_runner_receiver_)), | 215 task_runner_receiver_)), |
223 receiver_to_sender_(cast_environment_receiver_), | |
224 sender_to_receiver_(cast_environment_sender_), | |
225 video_bytes_encoded_(0), | 216 video_bytes_encoded_(0), |
226 audio_bytes_encoded_(0), | 217 audio_bytes_encoded_(0), |
227 frames_sent_(0) { | 218 frames_sent_(0) { |
228 testing_clock_.Advance( | 219 testing_clock_.Advance( |
229 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 220 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
230 } | 221 } |
231 | 222 |
232 void Configure(Codec video_codec, | 223 void Configure(Codec video_codec, |
233 Codec audio_codec) { | 224 Codec audio_codec) { |
234 audio_sender_config_ = GetDefaultAudioSenderConfig(); | 225 audio_sender_config_ = GetDefaultAudioSenderConfig(); |
(...skipping 27 matching lines...) Expand all Loading... |
262 void SetSenderClockSkew(double skew, base::TimeDelta offset) { | 253 void SetSenderClockSkew(double skew, base::TimeDelta offset) { |
263 testing_clock_sender_->SetSkew(skew, offset); | 254 testing_clock_sender_->SetSkew(skew, offset); |
264 task_runner_sender_->SetSkew(1.0 / skew); | 255 task_runner_sender_->SetSkew(1.0 / skew); |
265 } | 256 } |
266 | 257 |
267 void SetReceiverClockSkew(double skew, base::TimeDelta offset) { | 258 void SetReceiverClockSkew(double skew, base::TimeDelta offset) { |
268 testing_clock_receiver_->SetSkew(skew, offset); | 259 testing_clock_receiver_->SetSkew(skew, offset); |
269 task_runner_receiver_->SetSkew(1.0 / skew); | 260 task_runner_receiver_->SetSkew(1.0 / skew); |
270 } | 261 } |
271 | 262 |
272 void Create(const MeasuringPoint& p) { | 263 void Create(const MeasuringPoint& p); |
273 net::IPEndPoint dummy_endpoint; | |
274 transport_sender_.Init( | |
275 new CastTransportSenderImpl( | |
276 NULL, | |
277 testing_clock_sender_, | |
278 dummy_endpoint, | |
279 dummy_endpoint, | |
280 make_scoped_ptr(new base::DictionaryValue), | |
281 base::Bind(&UpdateCastTransportStatus), | |
282 base::Bind(&IgnoreRawEvents), | |
283 base::TimeDelta::FromSeconds(1), | |
284 task_runner_sender_, | |
285 PacketReceiverCallback(), | |
286 &sender_to_receiver_), | |
287 &video_bytes_encoded_, | |
288 &audio_bytes_encoded_); | |
289 | |
290 transport_receiver_.reset( | |
291 new CastTransportSenderImpl( | |
292 NULL, | |
293 testing_clock_receiver_, | |
294 dummy_endpoint, | |
295 dummy_endpoint, | |
296 make_scoped_ptr(new base::DictionaryValue), | |
297 base::Bind(&UpdateCastTransportStatus), | |
298 base::Bind(&IgnoreRawEvents), | |
299 base::TimeDelta::FromSeconds(1), | |
300 task_runner_receiver_, | |
301 base::Bind(&RunOneBenchmark::ReceivePacket, base::Unretained(this)), | |
302 &receiver_to_sender_)); | |
303 | |
304 cast_receiver_ = CastReceiver::Create(cast_environment_receiver_, | |
305 audio_receiver_config_, | |
306 video_receiver_config_, | |
307 transport_receiver_.get()); | |
308 | |
309 cast_sender_ = | |
310 CastSender::Create(cast_environment_sender_, &transport_sender_); | |
311 | |
312 cast_sender_->InitializeAudio( | |
313 audio_sender_config_, | |
314 base::Bind(&ExpectAudioSuccess)); | |
315 cast_sender_->InitializeVideo( | |
316 video_sender_config_, | |
317 base::Bind(&ExpectVideoSuccess), | |
318 CreateDefaultVideoEncodeAcceleratorCallback(), | |
319 CreateDefaultVideoEncodeMemoryCallback()); | |
320 | |
321 receiver_to_sender_.Initialize(CreateSimplePipe(p), | |
322 transport_sender_.PacketReceiverForTesting(), | |
323 task_runner_, &testing_clock_); | |
324 sender_to_receiver_.Initialize( | |
325 CreateSimplePipe(p), transport_receiver_->PacketReceiverForTesting(), | |
326 task_runner_, &testing_clock_); | |
327 | |
328 task_runner_->RunTasks(); | |
329 } | |
330 | 264 |
331 void ReceivePacket(scoped_ptr<Packet> packet) { | 265 void ReceivePacket(scoped_ptr<Packet> packet) { |
332 cast_receiver_->ReceivePacket(std::move(packet)); | 266 cast_receiver_->ReceivePacket(std::move(packet)); |
333 } | 267 } |
334 | 268 |
335 virtual ~RunOneBenchmark() { | 269 virtual ~RunOneBenchmark() { |
336 cast_sender_.reset(); | 270 cast_sender_.reset(); |
337 cast_receiver_.reset(); | 271 cast_receiver_.reset(); |
338 task_runner_->RunTasks(); | 272 task_runner_->RunTasks(); |
339 } | 273 } |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 test::SkewedTickClock* testing_clock_sender_; | 411 test::SkewedTickClock* testing_clock_sender_; |
478 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_sender_; | 412 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_sender_; |
479 | 413 |
480 // These run on the receiver timeline. | 414 // These run on the receiver timeline. |
481 test::SkewedTickClock* testing_clock_receiver_; | 415 test::SkewedTickClock* testing_clock_receiver_; |
482 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; | 416 scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_; |
483 | 417 |
484 scoped_refptr<CastEnvironment> cast_environment_sender_; | 418 scoped_refptr<CastEnvironment> cast_environment_sender_; |
485 scoped_refptr<CastEnvironment> cast_environment_receiver_; | 419 scoped_refptr<CastEnvironment> cast_environment_receiver_; |
486 | 420 |
487 LoopBackTransport receiver_to_sender_; | 421 LoopBackTransport* receiver_to_sender_; // Owned by CastTransportSenderImpl. |
488 LoopBackTransport sender_to_receiver_; | 422 LoopBackTransport* sender_to_receiver_; // Owned by CastTransportSenderImpl. |
489 CastTransportSenderWrapper transport_sender_; | 423 CastTransportSenderWrapper transport_sender_; |
490 scoped_ptr<CastTransportSender> transport_receiver_; | 424 scoped_ptr<CastTransportSender> transport_receiver_; |
491 uint64_t video_bytes_encoded_; | 425 uint64_t video_bytes_encoded_; |
492 uint64_t audio_bytes_encoded_; | 426 uint64_t audio_bytes_encoded_; |
493 | 427 |
494 scoped_ptr<CastReceiver> cast_receiver_; | 428 scoped_ptr<CastReceiver> cast_receiver_; |
495 scoped_ptr<CastSender> cast_sender_; | 429 scoped_ptr<CastSender> cast_sender_; |
496 | 430 |
497 int frames_sent_; | 431 int frames_sent_; |
498 base::TimeDelta frame_duration_; | 432 base::TimeDelta frame_duration_; |
499 double available_bitrate_; | 433 double available_bitrate_; |
500 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > audio_ticks_; | 434 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > audio_ticks_; |
501 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > video_ticks_; | 435 std::vector<std::pair<base::TimeTicks, base::TimeTicks> > video_ticks_; |
502 }; | 436 }; |
503 | 437 |
| 438 namespace { |
| 439 |
| 440 class TransportClient : public CastTransportSender::Client { |
| 441 public: |
| 442 explicit TransportClient(RunOneBenchmark* run_one_benchmark) |
| 443 : run_one_benchmark_(run_one_benchmark) {} |
| 444 |
| 445 void OnStatusChanged(CastTransportStatus status) final { |
| 446 bool result = (status == TRANSPORT_AUDIO_INITIALIZED || |
| 447 status == TRANSPORT_VIDEO_INITIALIZED); |
| 448 EXPECT_TRUE(result); |
| 449 }; |
| 450 void OnLoggingEventsReceived( |
| 451 scoped_ptr<std::vector<FrameEvent>> frame_events, |
| 452 scoped_ptr<std::vector<PacketEvent>> packet_events) final{}; |
| 453 void ProcessRtpPacket(scoped_ptr<Packet> packet) final { |
| 454 if (run_one_benchmark_) |
| 455 run_one_benchmark_->ReceivePacket(std::move(packet)); |
| 456 }; |
| 457 |
| 458 private: |
| 459 RunOneBenchmark* const run_one_benchmark_; |
| 460 |
| 461 DISALLOW_COPY_AND_ASSIGN(TransportClient); |
| 462 }; |
| 463 |
| 464 } // namepspace |
| 465 |
| 466 void RunOneBenchmark::Create(const MeasuringPoint& p) { |
| 467 sender_to_receiver_ = new LoopBackTransport(cast_environment_sender_); |
| 468 transport_sender_.Init( |
| 469 new CastTransportSenderImpl( |
| 470 testing_clock_sender_, base::TimeDelta::FromSeconds(1), |
| 471 make_scoped_ptr(new TransportClient(nullptr)), |
| 472 make_scoped_ptr(sender_to_receiver_), task_runner_sender_), |
| 473 &video_bytes_encoded_, &audio_bytes_encoded_); |
| 474 |
| 475 receiver_to_sender_ = new LoopBackTransport(cast_environment_receiver_); |
| 476 transport_receiver_.reset(new CastTransportSenderImpl( |
| 477 testing_clock_receiver_, base::TimeDelta::FromSeconds(1), |
| 478 make_scoped_ptr(new TransportClient(this)), |
| 479 make_scoped_ptr(receiver_to_sender_), task_runner_receiver_)); |
| 480 |
| 481 cast_receiver_ = |
| 482 CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_, |
| 483 video_receiver_config_, transport_receiver_.get()); |
| 484 |
| 485 cast_sender_ = |
| 486 CastSender::Create(cast_environment_sender_, &transport_sender_); |
| 487 |
| 488 cast_sender_->InitializeAudio(audio_sender_config_, |
| 489 base::Bind(&ExpectAudioSuccess)); |
| 490 cast_sender_->InitializeVideo(video_sender_config_, |
| 491 base::Bind(&ExpectVideoSuccess), |
| 492 CreateDefaultVideoEncodeAcceleratorCallback(), |
| 493 CreateDefaultVideoEncodeMemoryCallback()); |
| 494 |
| 495 receiver_to_sender_->Initialize(CreateSimplePipe(p), |
| 496 transport_sender_.PacketReceiverForTesting(), |
| 497 task_runner_, &testing_clock_); |
| 498 sender_to_receiver_->Initialize( |
| 499 CreateSimplePipe(p), transport_receiver_->PacketReceiverForTesting(), |
| 500 task_runner_, &testing_clock_); |
| 501 |
| 502 task_runner_->RunTasks(); |
| 503 } |
| 504 |
504 enum CacheResult { FOUND_TRUE, FOUND_FALSE, NOT_FOUND }; | 505 enum CacheResult { FOUND_TRUE, FOUND_FALSE, NOT_FOUND }; |
505 | 506 |
506 template <class T> | 507 template <class T> |
507 class BenchmarkCache { | 508 class BenchmarkCache { |
508 public: | 509 public: |
509 CacheResult Lookup(const T& x) { | 510 CacheResult Lookup(const T& x) { |
510 base::AutoLock key(lock_); | 511 base::AutoLock key(lock_); |
511 for (size_t i = 0; i < results_.size(); i++) { | 512 for (size_t i = 0; i < results_.size(); i++) { |
512 if (results_[i].second) { | 513 if (results_[i].second) { |
513 if (x <= results_[i].first) { | 514 if (x <= results_[i].first) { |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 media::cast::CastBenchmark benchmark; | 718 media::cast::CastBenchmark benchmark; |
718 if (getenv("PROFILE_FILE")) { | 719 if (getenv("PROFILE_FILE")) { |
719 std::string profile_file(getenv("PROFILE_FILE")); | 720 std::string profile_file(getenv("PROFILE_FILE")); |
720 base::debug::StartProfiling(profile_file); | 721 base::debug::StartProfiling(profile_file); |
721 benchmark.Run(); | 722 benchmark.Run(); |
722 base::debug::StopProfiling(); | 723 base::debug::StopProfiling(); |
723 } else { | 724 } else { |
724 benchmark.Run(); | 725 benchmark.Run(); |
725 } | 726 } |
726 } | 727 } |
OLD | NEW |