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 |