| 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 <stdint.h> | 8 #include <stdint.h> |
| 9 |
| 10 #include <memory> |
| 9 #include <queue> | 11 #include <queue> |
| 10 #include <utility> | 12 #include <utility> |
| 11 | 13 |
| 12 #include "base/at_exit.h" | 14 #include "base/at_exit.h" |
| 13 #include "base/base_paths.h" | 15 #include "base/base_paths.h" |
| 14 #include "base/command_line.h" | 16 #include "base/command_line.h" |
| 15 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 16 #include "base/json/json_writer.h" | 18 #include "base/json/json_writer.h" |
| 17 #include "base/logging.h" | 19 #include "base/logging.h" |
| 18 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/ptr_util.h" |
| 19 #include "base/path_service.h" | 21 #include "base/path_service.h" |
| 20 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/threading/thread.h" | 23 #include "base/threading/thread.h" |
| 22 #include "base/time/default_tick_clock.h" | 24 #include "base/time/default_tick_clock.h" |
| 23 #include "base/values.h" | 25 #include "base/values.h" |
| 24 #include "media/base/media.h" | 26 #include "media/base/media.h" |
| 25 #include "media/base/video_frame.h" | 27 #include "media/base/video_frame.h" |
| 26 #include "media/cast/cast_config.h" | 28 #include "media/cast/cast_config.h" |
| 27 #include "media/cast/cast_environment.h" | 29 #include "media/cast/cast_environment.h" |
| 28 #include "media/cast/cast_sender.h" | 30 #include "media/cast/cast_sender.h" |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 return net::IPEndPoint(ip_address, port); | 86 return net::IPEndPoint(ip_address, port); |
| 85 } | 87 } |
| 86 | 88 |
| 87 void DumpLoggingData(const media::cast::proto::LogMetadata& log_metadata, | 89 void DumpLoggingData(const media::cast::proto::LogMetadata& log_metadata, |
| 88 const media::cast::FrameEventList& frame_events, | 90 const media::cast::FrameEventList& frame_events, |
| 89 const media::cast::PacketEventList& packet_events, | 91 const media::cast::PacketEventList& packet_events, |
| 90 base::ScopedFILE log_file) { | 92 base::ScopedFILE log_file) { |
| 91 VLOG(0) << "Frame map size: " << frame_events.size(); | 93 VLOG(0) << "Frame map size: " << frame_events.size(); |
| 92 VLOG(0) << "Packet map size: " << packet_events.size(); | 94 VLOG(0) << "Packet map size: " << packet_events.size(); |
| 93 | 95 |
| 94 scoped_ptr<char[]> event_log(new char[kMaxSerializedLogBytes]); | 96 std::unique_ptr<char[]> event_log(new char[kMaxSerializedLogBytes]); |
| 95 int event_log_bytes; | 97 int event_log_bytes; |
| 96 if (!media::cast::SerializeEvents(log_metadata, | 98 if (!media::cast::SerializeEvents(log_metadata, |
| 97 frame_events, | 99 frame_events, |
| 98 packet_events, | 100 packet_events, |
| 99 true, | 101 true, |
| 100 kMaxSerializedLogBytes, | 102 kMaxSerializedLogBytes, |
| 101 event_log.get(), | 103 event_log.get(), |
| 102 &event_log_bytes)) { | 104 &event_log_bytes)) { |
| 103 VLOG(0) << "Failed to serialize events."; | 105 VLOG(0) << "Failed to serialize events."; |
| 104 return; | 106 return; |
| 105 } | 107 } |
| 106 | 108 |
| 107 VLOG(0) << "Events serialized length: " << event_log_bytes; | 109 VLOG(0) << "Events serialized length: " << event_log_bytes; |
| 108 | 110 |
| 109 int ret = fwrite(event_log.get(), 1, event_log_bytes, log_file.get()); | 111 int ret = fwrite(event_log.get(), 1, event_log_bytes, log_file.get()); |
| 110 if (ret != event_log_bytes) | 112 if (ret != event_log_bytes) |
| 111 VLOG(0) << "Failed to write logs to file."; | 113 VLOG(0) << "Failed to write logs to file."; |
| 112 } | 114 } |
| 113 | 115 |
| 114 void WriteLogsToFileAndDestroySubscribers( | 116 void WriteLogsToFileAndDestroySubscribers( |
| 115 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, | 117 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
| 116 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber, | 118 std::unique_ptr<media::cast::EncodingEventSubscriber> |
| 117 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber, | 119 video_event_subscriber, |
| 120 std::unique_ptr<media::cast::EncodingEventSubscriber> |
| 121 audio_event_subscriber, |
| 118 base::ScopedFILE video_log_file, | 122 base::ScopedFILE video_log_file, |
| 119 base::ScopedFILE audio_log_file) { | 123 base::ScopedFILE audio_log_file) { |
| 120 cast_environment->logger()->Unsubscribe(video_event_subscriber.get()); | 124 cast_environment->logger()->Unsubscribe(video_event_subscriber.get()); |
| 121 cast_environment->logger()->Unsubscribe(audio_event_subscriber.get()); | 125 cast_environment->logger()->Unsubscribe(audio_event_subscriber.get()); |
| 122 | 126 |
| 123 VLOG(0) << "Dumping logging data for video stream."; | 127 VLOG(0) << "Dumping logging data for video stream."; |
| 124 media::cast::proto::LogMetadata log_metadata; | 128 media::cast::proto::LogMetadata log_metadata; |
| 125 media::cast::FrameEventList frame_events; | 129 media::cast::FrameEventList frame_events; |
| 126 media::cast::PacketEventList packet_events; | 130 media::cast::PacketEventList packet_events; |
| 127 video_event_subscriber->GetEventsAndReset( | 131 video_event_subscriber->GetEventsAndReset( |
| 128 &log_metadata, &frame_events, &packet_events); | 132 &log_metadata, &frame_events, &packet_events); |
| 129 | 133 |
| 130 DumpLoggingData(log_metadata, frame_events, packet_events, | 134 DumpLoggingData(log_metadata, frame_events, packet_events, |
| 131 std::move(video_log_file)); | 135 std::move(video_log_file)); |
| 132 | 136 |
| 133 VLOG(0) << "Dumping logging data for audio stream."; | 137 VLOG(0) << "Dumping logging data for audio stream."; |
| 134 audio_event_subscriber->GetEventsAndReset( | 138 audio_event_subscriber->GetEventsAndReset( |
| 135 &log_metadata, &frame_events, &packet_events); | 139 &log_metadata, &frame_events, &packet_events); |
| 136 | 140 |
| 137 DumpLoggingData(log_metadata, frame_events, packet_events, | 141 DumpLoggingData(log_metadata, frame_events, packet_events, |
| 138 std::move(audio_log_file)); | 142 std::move(audio_log_file)); |
| 139 } | 143 } |
| 140 | 144 |
| 141 void WriteStatsAndDestroySubscribers( | 145 void WriteStatsAndDestroySubscribers( |
| 142 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, | 146 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
| 143 scoped_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber, | 147 std::unique_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber, |
| 144 scoped_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber, | 148 std::unique_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber, |
| 145 scoped_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> estimator) { | 149 std::unique_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> estimator) { |
| 146 cast_environment->logger()->Unsubscribe(video_stats_subscriber.get()); | 150 cast_environment->logger()->Unsubscribe(video_stats_subscriber.get()); |
| 147 cast_environment->logger()->Unsubscribe(audio_stats_subscriber.get()); | 151 cast_environment->logger()->Unsubscribe(audio_stats_subscriber.get()); |
| 148 cast_environment->logger()->Unsubscribe(estimator.get()); | 152 cast_environment->logger()->Unsubscribe(estimator.get()); |
| 149 | 153 |
| 150 scoped_ptr<base::DictionaryValue> stats = video_stats_subscriber->GetStats(); | 154 std::unique_ptr<base::DictionaryValue> stats = |
| 155 video_stats_subscriber->GetStats(); |
| 151 std::string json; | 156 std::string json; |
| 152 base::JSONWriter::WriteWithOptions( | 157 base::JSONWriter::WriteWithOptions( |
| 153 *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); | 158 *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
| 154 VLOG(0) << "Video stats: " << json; | 159 VLOG(0) << "Video stats: " << json; |
| 155 | 160 |
| 156 stats = audio_stats_subscriber->GetStats(); | 161 stats = audio_stats_subscriber->GetStats(); |
| 157 json.clear(); | 162 json.clear(); |
| 158 base::JSONWriter::WriteWithOptions( | 163 base::JSONWriter::WriteWithOptions( |
| 159 *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); | 164 *stats, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json); |
| 160 VLOG(0) << "Audio stats: " << json; | 165 VLOG(0) << "Audio stats: " << json; |
| 161 } | 166 } |
| 162 | 167 |
| 163 class TransportClient : public media::cast::CastTransport::Client { | 168 class TransportClient : public media::cast::CastTransport::Client { |
| 164 public: | 169 public: |
| 165 explicit TransportClient( | 170 explicit TransportClient( |
| 166 media::cast::LogEventDispatcher* log_event_dispatcher) | 171 media::cast::LogEventDispatcher* log_event_dispatcher) |
| 167 : log_event_dispatcher_(log_event_dispatcher) {} | 172 : log_event_dispatcher_(log_event_dispatcher) {} |
| 168 | 173 |
| 169 void OnStatusChanged(media::cast::CastTransportStatus status) final { | 174 void OnStatusChanged(media::cast::CastTransportStatus status) final { |
| 170 VLOG(1) << "Transport status: " << status; | 175 VLOG(1) << "Transport status: " << status; |
| 171 }; | 176 }; |
| 172 void OnLoggingEventsReceived( | 177 void OnLoggingEventsReceived( |
| 173 scoped_ptr<std::vector<media::cast::FrameEvent>> frame_events, | 178 std::unique_ptr<std::vector<media::cast::FrameEvent>> frame_events, |
| 174 scoped_ptr<std::vector<media::cast::PacketEvent>> packet_events) final { | 179 std::unique_ptr<std::vector<media::cast::PacketEvent>> packet_events) |
| 180 final { |
| 175 DCHECK(log_event_dispatcher_); | 181 DCHECK(log_event_dispatcher_); |
| 176 log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events), | 182 log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events), |
| 177 std::move(packet_events)); | 183 std::move(packet_events)); |
| 178 }; | 184 }; |
| 179 void ProcessRtpPacket(scoped_ptr<media::cast::Packet> packet) final {} | 185 void ProcessRtpPacket(std::unique_ptr<media::cast::Packet> packet) final {} |
| 180 | 186 |
| 181 private: | 187 private: |
| 182 media::cast::LogEventDispatcher* const | 188 media::cast::LogEventDispatcher* const |
| 183 log_event_dispatcher_; // Not owned by this class. | 189 log_event_dispatcher_; // Not owned by this class. |
| 184 | 190 |
| 185 DISALLOW_COPY_AND_ASSIGN(TransportClient); | 191 DISALLOW_COPY_AND_ASSIGN(TransportClient); |
| 186 }; | 192 }; |
| 187 | 193 |
| 188 } // namespace | 194 } // namespace |
| 189 | 195 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 | 230 |
| 225 // Running transport on the main thread. | 231 // Running transport on the main thread. |
| 226 // Setting up transport config. | 232 // Setting up transport config. |
| 227 net::IPEndPoint remote_endpoint = | 233 net::IPEndPoint remote_endpoint = |
| 228 CreateUDPAddress(remote_ip_address, static_cast<uint16_t>(remote_port)); | 234 CreateUDPAddress(remote_ip_address, static_cast<uint16_t>(remote_port)); |
| 229 | 235 |
| 230 // Enable raw event and stats logging. | 236 // Enable raw event and stats logging. |
| 231 // Running transport on the main thread. | 237 // Running transport on the main thread. |
| 232 scoped_refptr<media::cast::CastEnvironment> cast_environment( | 238 scoped_refptr<media::cast::CastEnvironment> cast_environment( |
| 233 new media::cast::CastEnvironment( | 239 new media::cast::CastEnvironment( |
| 234 make_scoped_ptr<base::TickClock>(new base::DefaultTickClock()), | 240 base::WrapUnique<base::TickClock>(new base::DefaultTickClock()), |
| 235 io_message_loop.task_runner(), | 241 io_message_loop.task_runner(), audio_thread.task_runner(), |
| 236 audio_thread.task_runner(), | |
| 237 video_thread.task_runner())); | 242 video_thread.task_runner())); |
| 238 | 243 |
| 239 // SendProcess initialization. | 244 // SendProcess initialization. |
| 240 scoped_ptr<media::cast::FakeMediaSource> fake_media_source( | 245 std::unique_ptr<media::cast::FakeMediaSource> fake_media_source( |
| 241 new media::cast::FakeMediaSource(test_thread.task_runner(), | 246 new media::cast::FakeMediaSource(test_thread.task_runner(), |
| 242 cast_environment->Clock(), | 247 cast_environment->Clock(), audio_config, |
| 243 audio_config, | 248 video_config, false)); |
| 244 video_config, | |
| 245 false)); | |
| 246 | 249 |
| 247 int final_fps = 0; | 250 int final_fps = 0; |
| 248 if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps), | 251 if (!base::StringToInt(cmd->GetSwitchValueASCII(kSwitchFps), |
| 249 &final_fps)){ | 252 &final_fps)){ |
| 250 final_fps = 0; | 253 final_fps = 0; |
| 251 } | 254 } |
| 252 base::FilePath source_path = cmd->GetSwitchValuePath(kSwitchSourceFile); | 255 base::FilePath source_path = cmd->GetSwitchValuePath(kSwitchSourceFile); |
| 253 if (!source_path.empty()) { | 256 if (!source_path.empty()) { |
| 254 LOG(INFO) << "Source: " << source_path.value(); | 257 LOG(INFO) << "Source: " << source_path.value(); |
| 255 fake_media_source->SetSourceFile(source_path, final_fps); | 258 fake_media_source->SetSourceFile(source_path, final_fps); |
| 256 } | 259 } |
| 257 if (cmd->HasSwitch(kSwitchVaryFrameSizes)) | 260 if (cmd->HasSwitch(kSwitchVaryFrameSizes)) |
| 258 fake_media_source->SetVariableFrameSizeMode(true); | 261 fake_media_source->SetVariableFrameSizeMode(true); |
| 259 | 262 |
| 260 // CastTransport initialization. | 263 // CastTransport initialization. |
| 261 scoped_ptr<media::cast::CastTransport> transport_sender = | 264 std::unique_ptr<media::cast::CastTransport> transport_sender = |
| 262 media::cast::CastTransport::Create( | 265 media::cast::CastTransport::Create( |
| 263 cast_environment->Clock(), base::TimeDelta::FromSeconds(1), | 266 cast_environment->Clock(), base::TimeDelta::FromSeconds(1), |
| 264 make_scoped_ptr(new TransportClient(cast_environment->logger())), | 267 base::WrapUnique(new TransportClient(cast_environment->logger())), |
| 265 make_scoped_ptr(new media::cast::UdpTransport( | 268 base::WrapUnique(new media::cast::UdpTransport( |
| 266 nullptr, io_message_loop.task_runner(), net::IPEndPoint(), | 269 nullptr, io_message_loop.task_runner(), net::IPEndPoint(), |
| 267 remote_endpoint, base::Bind(&UpdateCastTransportStatus))), | 270 remote_endpoint, base::Bind(&UpdateCastTransportStatus))), |
| 268 io_message_loop.task_runner()); | 271 io_message_loop.task_runner()); |
| 269 | 272 |
| 270 // Set up event subscribers. | 273 // Set up event subscribers. |
| 271 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; | 274 std::unique_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; |
| 272 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; | 275 std::unique_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; |
| 273 std::string video_log_file_name("/tmp/video_events.log.gz"); | 276 std::string video_log_file_name("/tmp/video_events.log.gz"); |
| 274 std::string audio_log_file_name("/tmp/audio_events.log.gz"); | 277 std::string audio_log_file_name("/tmp/audio_events.log.gz"); |
| 275 LOG(INFO) << "Logging audio events to: " << audio_log_file_name; | 278 LOG(INFO) << "Logging audio events to: " << audio_log_file_name; |
| 276 LOG(INFO) << "Logging video events to: " << video_log_file_name; | 279 LOG(INFO) << "Logging video events to: " << video_log_file_name; |
| 277 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 280 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
| 278 media::cast::VIDEO_EVENT, 10000)); | 281 media::cast::VIDEO_EVENT, 10000)); |
| 279 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 282 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
| 280 media::cast::AUDIO_EVENT, 10000)); | 283 media::cast::AUDIO_EVENT, 10000)); |
| 281 cast_environment->logger()->Subscribe(video_event_subscriber.get()); | 284 cast_environment->logger()->Subscribe(video_event_subscriber.get()); |
| 282 cast_environment->logger()->Subscribe(audio_event_subscriber.get()); | 285 cast_environment->logger()->Subscribe(audio_event_subscriber.get()); |
| 283 | 286 |
| 284 // Subscribers for stats. | 287 // Subscribers for stats. |
| 285 scoped_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> offset_estimator( | 288 std::unique_ptr<media::cast::ReceiverTimeOffsetEstimatorImpl> |
| 286 new media::cast::ReceiverTimeOffsetEstimatorImpl()); | 289 offset_estimator(new media::cast::ReceiverTimeOffsetEstimatorImpl()); |
| 287 cast_environment->logger()->Subscribe(offset_estimator.get()); | 290 cast_environment->logger()->Subscribe(offset_estimator.get()); |
| 288 scoped_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber( | 291 std::unique_ptr<media::cast::StatsEventSubscriber> video_stats_subscriber( |
| 289 new media::cast::StatsEventSubscriber(media::cast::VIDEO_EVENT, | 292 new media::cast::StatsEventSubscriber(media::cast::VIDEO_EVENT, |
| 290 cast_environment->Clock(), | 293 cast_environment->Clock(), |
| 291 offset_estimator.get())); | 294 offset_estimator.get())); |
| 292 scoped_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber( | 295 std::unique_ptr<media::cast::StatsEventSubscriber> audio_stats_subscriber( |
| 293 new media::cast::StatsEventSubscriber(media::cast::AUDIO_EVENT, | 296 new media::cast::StatsEventSubscriber(media::cast::AUDIO_EVENT, |
| 294 cast_environment->Clock(), | 297 cast_environment->Clock(), |
| 295 offset_estimator.get())); | 298 offset_estimator.get())); |
| 296 cast_environment->logger()->Subscribe(video_stats_subscriber.get()); | 299 cast_environment->logger()->Subscribe(video_stats_subscriber.get()); |
| 297 cast_environment->logger()->Subscribe(audio_stats_subscriber.get()); | 300 cast_environment->logger()->Subscribe(audio_stats_subscriber.get()); |
| 298 | 301 |
| 299 base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w")); | 302 base::ScopedFILE video_log_file(fopen(video_log_file_name.c_str(), "w")); |
| 300 if (!video_log_file) { | 303 if (!video_log_file) { |
| 301 VLOG(1) << "Failed to open video log file for writing."; | 304 VLOG(1) << "Failed to open video log file for writing."; |
| 302 exit(-1); | 305 exit(-1); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 322 io_message_loop.task_runner()->PostDelayedTask( | 325 io_message_loop.task_runner()->PostDelayedTask( |
| 323 FROM_HERE, | 326 FROM_HERE, |
| 324 base::Bind(&WriteStatsAndDestroySubscribers, | 327 base::Bind(&WriteStatsAndDestroySubscribers, |
| 325 cast_environment, | 328 cast_environment, |
| 326 base::Passed(&video_stats_subscriber), | 329 base::Passed(&video_stats_subscriber), |
| 327 base::Passed(&audio_stats_subscriber), | 330 base::Passed(&audio_stats_subscriber), |
| 328 base::Passed(&offset_estimator)), | 331 base::Passed(&offset_estimator)), |
| 329 base::TimeDelta::FromSeconds(logging_duration_seconds)); | 332 base::TimeDelta::FromSeconds(logging_duration_seconds)); |
| 330 | 333 |
| 331 // CastSender initialization. | 334 // CastSender initialization. |
| 332 scoped_ptr<media::cast::CastSender> cast_sender = | 335 std::unique_ptr<media::cast::CastSender> cast_sender = |
| 333 media::cast::CastSender::Create(cast_environment, transport_sender.get()); | 336 media::cast::CastSender::Create(cast_environment, transport_sender.get()); |
| 334 io_message_loop.PostTask( | 337 io_message_loop.PostTask( |
| 335 FROM_HERE, | 338 FROM_HERE, |
| 336 base::Bind(&media::cast::CastSender::InitializeVideo, | 339 base::Bind(&media::cast::CastSender::InitializeVideo, |
| 337 base::Unretained(cast_sender.get()), | 340 base::Unretained(cast_sender.get()), |
| 338 fake_media_source->get_video_config(), | 341 fake_media_source->get_video_config(), |
| 339 base::Bind(&QuitLoopOnInitializationResult), | 342 base::Bind(&QuitLoopOnInitializationResult), |
| 340 media::cast::CreateDefaultVideoEncodeAcceleratorCallback(), | 343 media::cast::CreateDefaultVideoEncodeAcceleratorCallback(), |
| 341 media::cast::CreateDefaultVideoEncodeMemoryCallback())); | 344 media::cast::CreateDefaultVideoEncodeMemoryCallback())); |
| 342 io_message_loop.Run(); // Wait for video initialization. | 345 io_message_loop.Run(); // Wait for video initialization. |
| 343 io_message_loop.PostTask( | 346 io_message_loop.PostTask( |
| 344 FROM_HERE, | 347 FROM_HERE, |
| 345 base::Bind(&media::cast::CastSender::InitializeAudio, | 348 base::Bind(&media::cast::CastSender::InitializeAudio, |
| 346 base::Unretained(cast_sender.get()), | 349 base::Unretained(cast_sender.get()), |
| 347 audio_config, | 350 audio_config, |
| 348 base::Bind(&QuitLoopOnInitializationResult))); | 351 base::Bind(&QuitLoopOnInitializationResult))); |
| 349 io_message_loop.Run(); // Wait for audio initialization. | 352 io_message_loop.Run(); // Wait for audio initialization. |
| 350 | 353 |
| 351 fake_media_source->Start(cast_sender->audio_frame_input(), | 354 fake_media_source->Start(cast_sender->audio_frame_input(), |
| 352 cast_sender->video_frame_input()); | 355 cast_sender->video_frame_input()); |
| 353 io_message_loop.Run(); | 356 io_message_loop.Run(); |
| 354 return 0; | 357 return 0; |
| 355 } | 358 } |
| OLD | NEW |