OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 // Test application that simulates a cast sender - Data can be either generated | 5 // Test application that simulates a cast sender - Data can be either generated |
6 // or read from a file. | 6 // or read from a file. |
7 | 7 |
8 #include "base/at_exit.h" | 8 #include "base/at_exit.h" |
9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
13 #include "base/files/memory_mapped_file.h" | 13 #include "base/files/memory_mapped_file.h" |
14 #include "base/files/scoped_file.h" | 14 #include "base/files/scoped_file.h" |
| 15 #include "base/json/json_writer.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
18 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
19 #include "base/threading/thread.h" | 20 #include "base/threading/thread.h" |
20 #include "base/time/default_tick_clock.h" | 21 #include "base/time/default_tick_clock.h" |
| 22 #include "base/values.h" |
21 #include "media/base/media.h" | 23 #include "media/base/media.h" |
22 #include "media/base/video_frame.h" | 24 #include "media/base/video_frame.h" |
23 #include "media/base/video_util.h" | 25 #include "media/base/video_util.h" |
24 #include "media/cast/cast_config.h" | 26 #include "media/cast/cast_config.h" |
25 #include "media/cast/cast_environment.h" | 27 #include "media/cast/cast_environment.h" |
26 #include "media/cast/cast_sender.h" | 28 #include "media/cast/cast_sender.h" |
27 #include "media/cast/logging/encoding_event_subscriber.h" | 29 #include "media/cast/logging/encoding_event_subscriber.h" |
28 #include "media/cast/logging/log_serializer.h" | 30 #include "media/cast/logging/log_serializer.h" |
29 #include "media/cast/logging/logging_defines.h" | 31 #include "media/cast/logging/logging_defines.h" |
30 #include "media/cast/logging/proto/raw_events.pb.h" | 32 #include "media/cast/logging/proto/raw_events.pb.h" |
| 33 #include "media/cast/logging/receiver_time_offset_estimator_impl.h" |
| 34 #include "media/cast/logging/stats_event_subscriber.h" |
31 #include "media/cast/test/utility/audio_utility.h" | 35 #include "media/cast/test/utility/audio_utility.h" |
32 #include "media/cast/test/utility/default_config.h" | 36 #include "media/cast/test/utility/default_config.h" |
33 #include "media/cast/test/utility/input_builder.h" | 37 #include "media/cast/test/utility/input_builder.h" |
34 #include "media/cast/test/utility/video_utility.h" | 38 #include "media/cast/test/utility/video_utility.h" |
35 #include "media/cast/transport/cast_transport_defines.h" | 39 #include "media/cast/transport/cast_transport_defines.h" |
36 #include "media/cast/transport/cast_transport_sender.h" | 40 #include "media/cast/transport/cast_transport_sender.h" |
37 #include "media/cast/transport/transport/udp_transport.h" | 41 #include "media/cast/transport/transport/udp_transport.h" |
38 #include "media/ffmpeg/ffmpeg_common.h" | 42 #include "media/ffmpeg/ffmpeg_common.h" |
39 #include "media/filters/ffmpeg_demuxer.h" | 43 #include "media/filters/ffmpeg_demuxer.h" |
40 #include "media/filters/ffmpeg_glue.h" | 44 #include "media/filters/ffmpeg_glue.h" |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 return; | 469 return; |
466 } | 470 } |
467 | 471 |
468 VLOG(0) << "Events serialized length: " << event_log_bytes; | 472 VLOG(0) << "Events serialized length: " << event_log_bytes; |
469 | 473 |
470 int ret = fwrite(event_log.get(), 1, event_log_bytes, log_file.get()); | 474 int ret = fwrite(event_log.get(), 1, event_log_bytes, log_file.get()); |
471 if (ret != event_log_bytes) | 475 if (ret != event_log_bytes) |
472 VLOG(0) << "Failed to write logs to file."; | 476 VLOG(0) << "Failed to write logs to file."; |
473 } | 477 } |
474 | 478 |
475 void WriteLogsToFileAndStopSubscribing( | 479 void WriteLogsToFileAndDestroySubscribers( |
476 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, | 480 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
477 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber, | 481 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber, |
478 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber, | 482 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber, |
479 base::ScopedFILE video_log_file, | 483 base::ScopedFILE video_log_file, |
480 base::ScopedFILE audio_log_file) { | 484 base::ScopedFILE audio_log_file) { |
481 cast_environment->Logging()->RemoveRawEventSubscriber( | 485 cast_environment->Logging()->RemoveRawEventSubscriber( |
482 video_event_subscriber.get()); | 486 video_event_subscriber.get()); |
483 cast_environment->Logging()->RemoveRawEventSubscriber( | 487 cast_environment->Logging()->RemoveRawEventSubscriber( |
484 audio_event_subscriber.get()); | 488 audio_event_subscriber.get()); |
485 | 489 |
(...skipping 12 matching lines...) Expand all Loading... |
498 VLOG(0) << "Dumping logging data for audio stream."; | 502 VLOG(0) << "Dumping logging data for audio stream."; |
499 audio_event_subscriber->GetEventsAndReset( | 503 audio_event_subscriber->GetEventsAndReset( |
500 &log_metadata, &frame_events, &packet_events); | 504 &log_metadata, &frame_events, &packet_events); |
501 | 505 |
502 DumpLoggingData(log_metadata, | 506 DumpLoggingData(log_metadata, |
503 frame_events, | 507 frame_events, |
504 packet_events, | 508 packet_events, |
505 audio_log_file.Pass()); | 509 audio_log_file.Pass()); |
506 } | 510 } |
507 | 511 |
| 512 void WriteStatsAndDestroySubscribers( |
| 513 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
| 514 scoped_ptr<media::cast::StatsEventSubscriber> video_event_subscriber, |
| 515 scoped_ptr<media::cast::StatsEventSubscriber> audio_event_subscriber, |
| 516 scoped_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> estimator) { |
| 517 cast_environment->Logging()->RemoveRawEventSubscriber( |
| 518 video_event_subscriber.get()); |
| 519 cast_environment->Logging()->RemoveRawEventSubscriber( |
| 520 audio_event_subscriber.get()); |
| 521 cast_environment->Logging()->RemoveRawEventSubscriber(estimator.get()); |
| 522 |
| 523 scoped_ptr<base::DictionaryValue> stats = video_event_subscriber->GetStats(); |
| 524 std::string json; |
| 525 base::JSONWriter::WriteWithOptions( |
| 526 stats.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
| 527 VLOG(0) << "Video stats: " << json; |
| 528 |
| 529 stats = audio_event_subscriber->GetStats(); |
| 530 json.clear(); |
| 531 base::JSONWriter::WriteWithOptions( |
| 532 stats.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
| 533 VLOG(0) << "Audio stats: " << json; |
| 534 } |
| 535 |
508 } // namespace | 536 } // namespace |
509 | 537 |
510 int main(int argc, char** argv) { | 538 int main(int argc, char** argv) { |
511 base::AtExitManager at_exit; | 539 base::AtExitManager at_exit; |
512 CommandLine::Init(argc, argv); | 540 CommandLine::Init(argc, argv); |
513 InitLogging(logging::LoggingSettings()); | 541 InitLogging(logging::LoggingSettings()); |
514 | 542 |
515 // Load the media module for FFmpeg decoding. | 543 // Load the media module for FFmpeg decoding. |
516 base::FilePath path; | 544 base::FilePath path; |
517 PathService::Get(base::DIR_MODULE, &path); | 545 PathService::Get(base::DIR_MODULE, &path); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 audio_frame_input, | 631 audio_frame_input, |
604 video_frame_input)); | 632 video_frame_input)); |
605 | 633 |
606 // Set up event subscribers. | 634 // Set up event subscribers. |
607 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; | 635 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; |
608 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; | 636 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; |
609 std::string video_log_file_name("/tmp/video_events.log.gz"); | 637 std::string video_log_file_name("/tmp/video_events.log.gz"); |
610 std::string audio_log_file_name("/tmp/audio_events.log.gz"); | 638 std::string audio_log_file_name("/tmp/audio_events.log.gz"); |
611 LOG(INFO) << "Logging audio events to: " << audio_log_file_name; | 639 LOG(INFO) << "Logging audio events to: " << audio_log_file_name; |
612 LOG(INFO) << "Logging video events to: " << video_log_file_name; | 640 LOG(INFO) << "Logging video events to: " << video_log_file_name; |
| 641 |
| 642 // Subscribers for raw events. |
613 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 643 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
614 media::cast::VIDEO_EVENT, 10000)); | 644 media::cast::VIDEO_EVENT, 10000)); |
615 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 645 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
| 646 media::cast::AUDIO_EVENT, 10000)); |
| 647 cast_environment->Logging()->AddRawEventSubscriber( |
| 648 video_event_subscriber.get()); |
| 649 cast_environment->Logging()->AddRawEventSubscriber( |
| 650 audio_event_subscriber.get()); |
| 651 |
| 652 // Subscribers for stats. |
| 653 scoped_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> offset_estimator( |
| 654 new media::cast::ReceiverTimeOffsetEstimatorImpl); |
| 655 cast_environment->Logging()->AddRawEventSubscriber(offset_estimator.get()); |
| 656 scoped_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber( |
| 657 new media::cast::StatsEventSubscriber(media::cast::VIDEO_EVENT, |
| 658 cast_environment->Clock(), |
| 659 offset_estimator.get())); |
| 660 scoped_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber( |
| 661 new media::cast::StatsEventSubscriber(media::cast::AUDIO_EVENT, |
| 662 cast_environment->Clock(), |
| 663 offset_estimator.get())); |
| 664 cast_environment->Logging()->AddRawEventSubscriber( |
| 665 video_stats_subscriber.get()); |
| 666 cast_environment->Logging()->AddRawEventSubscriber( |
| 667 audio_stats_subscriber.get()); |
| 668 |
| 669 std::string video_log_file_name( |
| 670 media::cast::GetVideoLogFileDestination(compress)); |
| 671 std::string audio_log_file_name( |
| 672 media::cast::GetAudioLogFileDestination(compress)); |
| 673 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
| 674 media::cast::VIDEO_EVENT, 10000)); |
| 675 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
616 media::cast::AUDIO_EVENT, 10000)); | 676 media::cast::AUDIO_EVENT, 10000)); |
617 cast_environment->Logging()->AddRawEventSubscriber( | 677 cast_environment->Logging()->AddRawEventSubscriber( |
618 video_event_subscriber.get()); | 678 video_event_subscriber.get()); |
619 cast_environment->Logging()->AddRawEventSubscriber( | 679 cast_environment->Logging()->AddRawEventSubscriber( |
620 audio_event_subscriber.get()); | 680 audio_event_subscriber.get()); |
621 | 681 |
622 base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w")); | 682 base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w")); |
623 if (!video_log_file) { | 683 if (!video_log_file) { |
624 VLOG(1) << "Failed to open video log file for writing."; | 684 VLOG(1) << "Failed to open video log file for writing."; |
625 exit(-1); | 685 exit(-1); |
626 } | 686 } |
627 | 687 |
628 base::ScopedFILE audio_log_file(fopen(audio_log_file_name.c_str(), "w")); | 688 base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w")); |
629 if (!audio_log_file) { | 689 if (!video_log_file) { |
630 VLOG(1) << "Failed to open audio log file for writing."; | 690 VLOG(1) << "Failed to open video log file for writing."; |
631 exit(-1); | 691 exit(-1); |
632 } | 692 } |
633 | 693 |
634 const int logging_duration_seconds = 300; | 694 const int logging_duration_seconds = 300; |
635 io_message_loop.message_loop_proxy()->PostDelayedTask( | 695 io_message_loop.message_loop_proxy()->PostDelayedTask( |
636 FROM_HERE, | 696 FROM_HERE, |
637 base::Bind(&WriteLogsToFileAndStopSubscribing, | 697 base::Bind(&WriteLogsToFileAndDestroySubscribers, |
638 cast_environment, | 698 cast_environment, |
639 base::Passed(&video_event_subscriber), | 699 base::Passed(&video_event_subscriber), |
640 base::Passed(&audio_event_subscriber), | 700 base::Passed(&audio_event_subscriber), |
641 base::Passed(&video_log_file), | 701 base::Passed(&video_log_file), |
642 base::Passed(&audio_log_file)), | 702 base::Passed(&audio_log_file)), |
643 base::TimeDelta::FromSeconds(logging_duration_seconds)); | 703 base::TimeDelta::FromSeconds(logging_duration_seconds)); |
644 | 704 |
| 705 io_message_loop.message_loop_proxy()->PostDelayedTask( |
| 706 FROM_HERE, |
| 707 base::Bind(&WriteStatsAndDestroySubscribers, |
| 708 cast_environment, |
| 709 base::Passed(&video_stats_subscriber), |
| 710 base::Passed(&audio_stats_subscriber), |
| 711 base::Passed(&offset_estimator)), |
| 712 base::TimeDelta::FromSeconds(logging_duration_seconds)); |
| 713 } |
| 714 |
645 test_thread.message_loop_proxy()->PostTask( | 715 test_thread.message_loop_proxy()->PostTask( |
646 FROM_HERE, | 716 FROM_HERE, |
647 base::Bind(&media::cast::SendProcess::SendNextFrame, | 717 base::Bind(&media::cast::SendProcess::SendNextFrame, |
648 base::Unretained(send_process.get()))); | 718 base::Unretained(send_process.get()))); |
649 | 719 |
650 io_message_loop.Run(); | 720 io_message_loop.Run(); |
651 | 721 |
652 return 0; | 722 return 0; |
653 } | 723 } |
OLD | NEW |