Chromium Code Reviews| 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 // Simulate end to end streaming. | 5 // Simulate end to end streaming. |
| 6 // | 6 // |
| 7 // Input: | 7 // Input: |
| 8 // --source= | 8 // --source= |
| 9 // WebM used as the source of video and audio frames. | 9 // WebM used as the source of video and audio frames. |
| 10 // --output= | 10 // --output= |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 int* counter, | 138 int* counter, |
| 139 CastReceiver* cast_receiver, | 139 CastReceiver* cast_receiver, |
| 140 scoped_ptr<AudioBus> audio_bus, | 140 scoped_ptr<AudioBus> audio_bus, |
| 141 const base::TimeTicks& playout_time, | 141 const base::TimeTicks& playout_time, |
| 142 bool is_continuous) { | 142 bool is_continuous) { |
| 143 ++*counter; | 143 ++*counter; |
| 144 cast_receiver->RequestDecodedAudioFrame( | 144 cast_receiver->RequestDecodedAudioFrame( |
| 145 base::Bind(&GotAudioFrame, counter, cast_receiver)); | 145 base::Bind(&GotAudioFrame, counter, cast_receiver)); |
| 146 } | 146 } |
| 147 | 147 |
| 148 void AppendLog(EncodingEventSubscriber* subscriber, | 148 // Serialize |frame_events| and |packet_events| and append to the file |
| 149 const std::string& extra_data, | 149 // located at |output_path|. |
| 150 const base::FilePath& output_path) { | 150 void AppendLogToFile(media::cast::proto::LogMetadata* metadata, |
| 151 media::cast::proto::LogMetadata metadata; | 151 const media::cast::FrameEventList& frame_events, |
| 152 metadata.set_extra_data(extra_data); | 152 const media::cast::PacketEventList& packet_events, |
| 153 | 153 const base::FilePath& output_path) { |
| 154 media::cast::FrameEventList frame_events; | |
| 155 media::cast::PacketEventList packet_events; | |
| 156 subscriber->GetEventsAndReset( | |
| 157 &metadata, &frame_events, &packet_events); | |
| 158 media::cast::proto::GeneralDescription* gen_desc = | 154 media::cast::proto::GeneralDescription* gen_desc = |
| 159 metadata.mutable_general_description(); | 155 metadata->mutable_general_description(); |
| 160 gen_desc->set_product("Cast Simulator"); | 156 gen_desc->set_product("Cast Simulator"); |
| 161 gen_desc->set_product_version("0.1"); | 157 gen_desc->set_product_version("0.1"); |
| 162 | 158 |
| 163 scoped_ptr<char[]> serialized_log(new char[media::cast::kMaxSerializedBytes]); | 159 scoped_ptr<char[]> serialized_log(new char[media::cast::kMaxSerializedBytes]); |
| 164 int output_bytes; | 160 int output_bytes; |
| 165 bool success = media::cast::SerializeEvents(metadata, | 161 bool success = media::cast::SerializeEvents(*metadata, |
| 166 frame_events, | 162 frame_events, |
| 167 packet_events, | 163 packet_events, |
| 168 true, | 164 true, |
| 169 media::cast::kMaxSerializedBytes, | 165 media::cast::kMaxSerializedBytes, |
| 170 serialized_log.get(), | 166 serialized_log.get(), |
| 171 &output_bytes); | 167 &output_bytes); |
| 172 | 168 |
| 173 if (!success) { | 169 if (!success) { |
| 174 LOG(ERROR) << "Failed to serialize log."; | 170 LOG(ERROR) << "Failed to serialize log."; |
| 175 return; | 171 return; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 // Run for 3 minutes. | 320 // Run for 3 minutes. |
| 325 base::TimeDelta elapsed_time; | 321 base::TimeDelta elapsed_time; |
| 326 while (elapsed_time.InMinutes() < 3) { | 322 while (elapsed_time.InMinutes() < 3) { |
| 327 // Each step is 100us. | 323 // Each step is 100us. |
| 328 base::TimeDelta step = base::TimeDelta::FromMicroseconds(100); | 324 base::TimeDelta step = base::TimeDelta::FromMicroseconds(100); |
| 329 task_runner->Sleep(step); | 325 task_runner->Sleep(step); |
| 330 elapsed_time += step; | 326 elapsed_time += step; |
| 331 } | 327 } |
| 332 | 328 |
| 333 LOG(INFO) << "Audio frame count: " << audio_frame_count; | 329 LOG(INFO) << "Audio frame count: " << audio_frame_count; |
| 334 LOG(INFO) << "Video frame count: " << video_frame_count; | |
| 335 LOG(INFO) << "Writing log: " << output_path.value(); | |
| 336 | 330 |
| 337 // Truncate file and then write serialized log. | 331 // Truncate file and then write serialized log. |
| 338 { | 332 { |
| 339 base::ScopedFILE file(base::OpenFile(output_path, "wb")); | 333 base::ScopedFILE file(base::OpenFile(output_path, "wb")); |
| 340 if (!file.get()) { | 334 if (!file.get()) { |
| 341 LOG(INFO) << "Cannot write to log."; | 335 LOG(INFO) << "Cannot write to log."; |
| 342 return; | 336 return; |
| 343 } | 337 } |
| 344 } | 338 } |
| 345 AppendLog(&video_event_subscriber, extra_data, output_path); | 339 |
| 346 AppendLog(&audio_event_subscriber, extra_data, output_path); | 340 // Get event logs for audio and video. |
| 341 media::cast::proto::LogMetadata audio_metadata, video_metadata; | |
|
hubbe
2014/08/05 17:46:59
Optional: Put metadata, frame_events and packet_ev
Alpha Left Google
2014/08/06 01:51:57
I'm not sure how using a struct will make it clean
| |
| 342 media::cast::FrameEventList audio_frame_events, video_frame_events; | |
| 343 media::cast::PacketEventList audio_packet_events, video_packet_events; | |
| 344 audio_metadata.set_extra_data(extra_data); | |
| 345 video_metadata.set_extra_data(extra_data); | |
| 346 audio_event_subscriber.GetEventsAndReset( | |
| 347 &audio_metadata, &audio_frame_events, &audio_packet_events); | |
| 348 video_event_subscriber.GetEventsAndReset( | |
| 349 &video_metadata, &video_frame_events, &video_packet_events); | |
| 350 | |
| 351 // Compute and print statistics for video: | |
| 352 // | |
| 353 // * Total video frames captured. | |
| 354 // * Total video frames encoded. | |
| 355 // * Total video frames dropped. | |
| 356 // * Total video frames received late. | |
| 357 // * Average target bitrate. | |
| 358 // * Average encoded bitrate. | |
| 359 int total_video_frames = 0; | |
| 360 int encoded_video_frames = 0; | |
| 361 int dropped_video_frames = 0; | |
| 362 int late_video_frames = 0; | |
| 363 int64 encoded_size = 0; | |
| 364 int64 target_bitrate = 0; | |
| 365 for (size_t i = 0; i < video_frame_events.size(); ++i) { | |
| 366 const media::cast::proto::AggregatedFrameEvent& event = | |
| 367 *video_frame_events[i]; | |
| 368 ++total_video_frames; | |
| 369 if (event.has_encoded_frame_size()) { | |
| 370 ++encoded_video_frames; | |
| 371 encoded_size += event.encoded_frame_size(); | |
| 372 target_bitrate += event.target_bitrate(); | |
| 373 } else { | |
| 374 ++dropped_video_frames; | |
| 375 } | |
| 376 if (event.has_delay_millis() && event.delay_millis() < 0) | |
| 377 ++late_video_frames; | |
| 378 } | |
| 379 | |
| 380 double avg_encoded_bitrate = | |
| 381 !encoded_video_frames ? 0 : | |
| 382 8.0 * encoded_size * video_sender_config.max_frame_rate / | |
| 383 encoded_video_frames / 1000; | |
| 384 double avg_target_bitrate = | |
| 385 !encoded_video_frames ? 0 : target_bitrate / encoded_video_frames / 1000; | |
| 386 | |
| 387 LOG(INFO) << "Total video frames: " << total_video_frames; | |
| 388 LOG(INFO) << "Dropped video frames " << dropped_video_frames; | |
| 389 LOG(INFO) << "Late video frames: " << late_video_frames; | |
| 390 LOG(INFO) << "Average encoded bitrate (kbps): " << avg_encoded_bitrate; | |
| 391 LOG(INFO) << "Average target bitrate (kbps): " << avg_target_bitrate; | |
| 392 LOG(INFO) << "Writing log: " << output_path.value(); | |
| 393 | |
| 394 AppendLogToFile(&video_metadata, video_frame_events, video_packet_events, | |
| 395 output_path); | |
| 396 AppendLogToFile(&audio_metadata, audio_frame_events, audio_packet_events, | |
| 397 output_path); | |
| 347 } | 398 } |
| 348 | 399 |
| 349 NetworkSimulationModel DefaultModel() { | 400 NetworkSimulationModel DefaultModel() { |
| 350 NetworkSimulationModel model; | 401 NetworkSimulationModel model; |
| 351 model.set_type(cast::proto::INTERRUPTED_POISSON_PROCESS); | 402 model.set_type(cast::proto::INTERRUPTED_POISSON_PROCESS); |
| 352 IPPModel* ipp = model.mutable_ipp(); | 403 IPPModel* ipp = model.mutable_ipp(); |
| 353 ipp->set_coef_burstiness(0.609); | 404 ipp->set_coef_burstiness(0.609); |
| 354 ipp->set_coef_variance(4.1); | 405 ipp->set_coef_variance(4.1); |
| 355 | 406 |
| 356 ipp->add_average_rate(0.609); | 407 ipp->add_average_rate(0.609); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 458 values.SetBoolean("sim", true); | 509 values.SetBoolean("sim", true); |
| 459 values.SetString("sim-id", sim_id); | 510 values.SetString("sim-id", sim_id); |
| 460 | 511 |
| 461 std::string extra_data; | 512 std::string extra_data; |
| 462 base::JSONWriter::Write(&values, &extra_data); | 513 base::JSONWriter::Write(&values, &extra_data); |
| 463 | 514 |
| 464 // Run. | 515 // Run. |
| 465 media::cast::RunSimulation(source_path, output_path, extra_data, model); | 516 media::cast::RunSimulation(source_path, output_path, extra_data, model); |
| 466 return 0; | 517 return 0; |
| 467 } | 518 } |
| OLD | NEW |