| 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 |