| Index: media/cast/test/simulator.cc
|
| diff --git a/media/cast/test/simulator.cc b/media/cast/test/simulator.cc
|
| index b96f4793e101173356d5588b77a31354a1f0e161..c9a750b3a828da3a008c60a76521f09fc7c73438 100644
|
| --- a/media/cast/test/simulator.cc
|
| +++ b/media/cast/test/simulator.cc
|
| @@ -46,6 +46,7 @@
|
| #include "media/cast/test/fake_media_source.h"
|
| #include "media/cast/test/fake_single_thread_task_runner.h"
|
| #include "media/cast/test/loopback_transport.h"
|
| +#include "media/cast/test/proto/network_simulation_model.pb.h"
|
| #include "media/cast/test/skewed_tick_clock.h"
|
| #include "media/cast/test/utility/audio_utility.h"
|
| #include "media/cast/test/utility/default_config.h"
|
| @@ -57,14 +58,19 @@
|
| #include "media/cast/transport/cast_transport_sender.h"
|
| #include "media/cast/transport/cast_transport_sender_impl.h"
|
|
|
| +using media::cast::proto::IPPModel;
|
| +using media::cast::proto::NetworkSimulationModel;
|
| +using media::cast::proto::NetworkSimulationModelType;
|
| +
|
| namespace media {
|
| namespace cast {
|
| namespace {
|
| -
|
| const int kTargetDelay = 300;
|
| const char kSourcePath[] = "source";
|
| +const char kModelPath[] = "model";
|
| const char kOutputPath[] = "output";
|
| const char kSimulationId[] = "sim-id";
|
| +const char kLibDir[] = "lib-dir";
|
|
|
| void UpdateCastTransportStatus(transport::CastTransportStatus status) {
|
| LOG(INFO) << "Cast transport status: " << status;
|
| @@ -158,7 +164,8 @@ void AppendLog(EncodingEventSubscriber* subscriber,
|
| // |extra_data| is extra tagging information to write to log.
|
| void RunSimulation(const base::FilePath& source_path,
|
| const base::FilePath& output_path,
|
| - const std::string& extra_data) {
|
| + const std::string& extra_data,
|
| + const NetworkSimulationModel& model) {
|
| // Fake clock. Make sure start time is non zero.
|
| base::SimpleTestTickClock testing_clock;
|
| testing_clock.Advance(base::TimeDelta::FromSeconds(1));
|
| @@ -243,27 +250,18 @@ void RunSimulation(const base::FilePath& source_path,
|
| CastSender::Create(sender_env, transport_sender.get()));
|
|
|
| // Build packet pipe.
|
| - // TODO(hclam): Allow user to input these parameters. Following
|
| - // parameters are taken from a session from real-world data. It is
|
| - // chosen here because it gives a difficult environment.
|
| - std::vector<double> average_rates;
|
| - average_rates.push_back(0.609);
|
| - average_rates.push_back(0.495);
|
| - average_rates.push_back(0.561);
|
| - average_rates.push_back(0.458);
|
| - average_rates.push_back(0.538);
|
| - average_rates.push_back(0.513);
|
| - average_rates.push_back(0.585);
|
| - average_rates.push_back(0.592);
|
| - average_rates.push_back(0.658);
|
| - average_rates.push_back(0.556);
|
| - average_rates.push_back(0.371);
|
| - average_rates.push_back(0.595);
|
| - average_rates.push_back(0.490);
|
| - average_rates.push_back(0.980);
|
| - average_rates.push_back(0.781);
|
| - average_rates.push_back(0.463);
|
| - test::InterruptedPoissonProcess ipp(average_rates, 0.3, 4.1, 0);
|
| + if (model.type() != media::cast::proto::INTERRUPTED_POISSON_PROCESS) {
|
| + LOG(ERROR) << "Unknown model type " << model.type() << ".";
|
| + return;
|
| + }
|
| +
|
| + const IPPModel& ipp_model = model.ipp();
|
| +
|
| + std::vector<double> average_rates(ipp_model.average_rate_size());
|
| + std::copy(ipp_model.average_rate().begin(), ipp_model.average_rate().end(),
|
| + average_rates.begin());
|
| + test::InterruptedPoissonProcess ipp(average_rates,
|
| + ipp_model.coef_burstiness(), ipp_model.coef_variance(), 0);
|
|
|
| // Connect sender to receiver. This initializes the pipe.
|
| receiver_to_sender.Initialize(
|
| @@ -301,9 +299,9 @@ void RunSimulation(const base::FilePath& source_path,
|
| media_source.Start(cast_sender->audio_frame_input(),
|
| cast_sender->video_frame_input());
|
|
|
| - // Run for 5 minutes.
|
| + // Run for 3 minutes.
|
| base::TimeDelta elapsed_time;
|
| - while (elapsed_time.InMinutes() < 5) {
|
| + while (elapsed_time.InMinutes() < 3) {
|
| // Each step is 100us.
|
| base::TimeDelta step = base::TimeDelta::FromMicroseconds(100);
|
| task_runner->Sleep(step);
|
| @@ -326,6 +324,78 @@ void RunSimulation(const base::FilePath& source_path,
|
| AppendLog(&audio_event_subscriber, extra_data, output_path);
|
| }
|
|
|
| +NetworkSimulationModel DefaultModel() {
|
| + NetworkSimulationModel model;
|
| + model.set_type(cast::proto::INTERRUPTED_POISSON_PROCESS);
|
| + IPPModel* ipp = model.mutable_ipp();
|
| + ipp->set_coef_burstiness(0.609);
|
| + ipp->set_coef_variance(4.1);
|
| +
|
| + ipp->add_average_rate(0.609);
|
| + ipp->add_average_rate(0.495);
|
| + ipp->add_average_rate(0.561);
|
| + ipp->add_average_rate(0.458);
|
| + ipp->add_average_rate(0.538);
|
| + ipp->add_average_rate(0.513);
|
| + ipp->add_average_rate(0.585);
|
| + ipp->add_average_rate(0.592);
|
| + ipp->add_average_rate(0.658);
|
| + ipp->add_average_rate(0.556);
|
| + ipp->add_average_rate(0.371);
|
| + ipp->add_average_rate(0.595);
|
| + ipp->add_average_rate(0.490);
|
| + ipp->add_average_rate(0.980);
|
| + ipp->add_average_rate(0.781);
|
| + ipp->add_average_rate(0.463);
|
| +
|
| + return model;
|
| +}
|
| +
|
| +bool IsModelValid(const NetworkSimulationModel& model) {
|
| + if (!model.has_type())
|
| + return false;
|
| + NetworkSimulationModelType type = model.type();
|
| + if (type == media::cast::proto::INTERRUPTED_POISSON_PROCESS) {
|
| + if (!model.has_ipp())
|
| + return false;
|
| + const IPPModel& ipp = model.ipp();
|
| + if (ipp.coef_burstiness() <= 0.0 || ipp.coef_variance() <= 0.0)
|
| + return false;
|
| + if (ipp.average_rate_size() == 0)
|
| + return false;
|
| + for (int i = 0; i < ipp.average_rate_size(); i++) {
|
| + if (ipp.average_rate(i) <= 0.0)
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +NetworkSimulationModel LoadModel(const base::FilePath& model_path) {
|
| + if (model_path.empty()) {
|
| + LOG(ERROR) << "Model path not set.";
|
| + return DefaultModel();
|
| + }
|
| + std::string model_str;
|
| + if (!base::ReadFileToString(model_path, &model_str)) {
|
| + LOG(ERROR) << "Failed to read model file.";
|
| + return DefaultModel();
|
| + }
|
| +
|
| + NetworkSimulationModel model;
|
| + if (!model.ParseFromString(model_str)) {
|
| + LOG(ERROR) << "Failed to parse model.";
|
| + return DefaultModel();
|
| + }
|
| + if (!IsModelValid(model)) {
|
| + LOG(ERROR) << "Invalid model.";
|
| + return DefaultModel();
|
| + }
|
| +
|
| + return model;
|
| +}
|
| +
|
| } // namespace
|
| } // namespace cast
|
| } // namespace media
|
| @@ -335,14 +405,20 @@ int main(int argc, char** argv) {
|
| CommandLine::Init(argc, argv);
|
| InitLogging(logging::LoggingSettings());
|
|
|
| - base::FilePath media_path;
|
| - if (!PathService::Get(base::DIR_MODULE, &media_path)) {
|
| - LOG(ERROR) << "Failed to load FFmpeg.";
|
| + const CommandLine* cmd = CommandLine::ForCurrentProcess();
|
| + base::FilePath media_path = cmd->GetSwitchValuePath(media::cast::kLibDir);
|
| + if (media_path.empty()) {
|
| + if (!PathService::Get(base::DIR_MODULE, &media_path)) {
|
| + LOG(ERROR) << "Failed to load FFmpeg.";
|
| + return 1;
|
| + }
|
| + }
|
| +
|
| + if (!media::InitializeMediaLibrary(media_path)) {
|
| + LOG(ERROR) << "Failed to initialize FFmpeg.";
|
| return 1;
|
| }
|
| - media::InitializeMediaLibrary(media_path);
|
|
|
| - const CommandLine* cmd = CommandLine::ForCurrentProcess();
|
| base::FilePath source_path = cmd->GetSwitchValuePath(
|
| media::cast::kSourcePath);
|
| base::FilePath output_path = cmd->GetSwitchValuePath(
|
| @@ -353,6 +429,9 @@ int main(int argc, char** argv) {
|
| }
|
| std::string sim_id = cmd->GetSwitchValueASCII(media::cast::kSimulationId);
|
|
|
| + NetworkSimulationModel model = media::cast::LoadModel(
|
| + cmd->GetSwitchValuePath(media::cast::kModelPath));
|
| +
|
| base::DictionaryValue values;
|
| values.SetBoolean("sim", true);
|
| values.SetString("sim-id", sim_id);
|
| @@ -361,6 +440,6 @@ int main(int argc, char** argv) {
|
| base::JSONWriter::Write(&values, &extra_data);
|
|
|
| // Run.
|
| - media::cast::RunSimulation(source_path, output_path, extra_data);
|
| + media::cast::RunSimulation(source_path, output_path, extra_data, model);
|
| return 0;
|
| }
|
|
|