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/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 video_config.max_number_of_video_buffers_used = 1; | 198 video_config.max_number_of_video_buffers_used = 1; |
199 video_config.number_of_cores = 1; | 199 video_config.number_of_cores = 1; |
200 return video_config; | 200 return video_config; |
201 } | 201 } |
202 | 202 |
203 class SendProcess { | 203 class SendProcess { |
204 public: | 204 public: |
205 SendProcess(scoped_refptr<base::SingleThreadTaskRunner> thread_proxy, | 205 SendProcess(scoped_refptr<base::SingleThreadTaskRunner> thread_proxy, |
206 base::TickClock* clock, | 206 base::TickClock* clock, |
207 const VideoSenderConfig& video_config, | 207 const VideoSenderConfig& video_config, |
208 FrameInput* frame_input) | 208 scoped_refptr<AudioFrameInput> audio_frame_input, |
| 209 scoped_refptr<VideoFrameInput> video_frame_input) |
209 : test_app_thread_proxy_(thread_proxy), | 210 : test_app_thread_proxy_(thread_proxy), |
210 video_config_(video_config), | 211 video_config_(video_config), |
211 audio_diff_(kFrameTimerMs), | 212 audio_diff_(kFrameTimerMs), |
212 frame_input_(frame_input), | 213 audio_frame_input_(audio_frame_input), |
| 214 video_frame_input_(video_frame_input), |
213 synthetic_count_(0), | 215 synthetic_count_(0), |
214 clock_(clock), | 216 clock_(clock), |
215 start_time_(), | 217 start_time_(), |
216 send_time_(), | 218 send_time_(), |
217 weak_factory_(this) { | 219 weak_factory_(this) { |
218 audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, | 220 audio_bus_factory_.reset(new TestAudioBusFactory(kAudioChannels, |
219 kAudioSamplingFrequency, | 221 kAudioSamplingFrequency, |
220 kSoundFrequency, | 222 kSoundFrequency, |
221 kSoundVolume)); | 223 kSoundVolume)); |
222 if (ReadFromFile()) { | 224 if (ReadFromFile()) { |
(...skipping 15 matching lines...) Expand all Loading... |
238 | 240 |
239 void SendFrame() { | 241 void SendFrame() { |
240 // Make sure that we don't drift. | 242 // Make sure that we don't drift. |
241 int num_10ms_blocks = audio_diff_ / 10; | 243 int num_10ms_blocks = audio_diff_ / 10; |
242 // Avoid drift. | 244 // Avoid drift. |
243 audio_diff_ += kFrameTimerMs - num_10ms_blocks * 10; | 245 audio_diff_ += kFrameTimerMs - num_10ms_blocks * 10; |
244 | 246 |
245 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( | 247 scoped_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus( |
246 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); | 248 base::TimeDelta::FromMilliseconds(10) * num_10ms_blocks)); |
247 AudioBus* const audio_bus_ptr = audio_bus.get(); | 249 AudioBus* const audio_bus_ptr = audio_bus.get(); |
248 frame_input_->InsertAudio( | 250 audio_frame_input_->InsertAudio( |
249 audio_bus_ptr, | 251 audio_bus_ptr, |
250 clock_->NowTicks(), | 252 clock_->NowTicks(), |
251 base::Bind(&OwnThatAudioBus, base::Passed(&audio_bus))); | 253 base::Bind(&OwnThatAudioBus, base::Passed(&audio_bus))); |
252 | 254 |
253 gfx::Size size(video_config_.width, video_config_.height); | 255 gfx::Size size(video_config_.width, video_config_.height); |
254 // TODO(mikhal): Use the provided timestamp. | 256 // TODO(mikhal): Use the provided timestamp. |
255 if (start_time_.is_null()) | 257 if (start_time_.is_null()) |
256 start_time_ = clock_->NowTicks(); | 258 start_time_ = clock_->NowTicks(); |
257 base::TimeDelta time_diff = clock_->NowTicks() - start_time_; | 259 base::TimeDelta time_diff = clock_->NowTicks() - start_time_; |
258 scoped_refptr<media::VideoFrame> video_frame = | 260 scoped_refptr<media::VideoFrame> video_frame = |
(...skipping 11 matching lines...) Expand all Loading... |
270 // Sleep if that time has yet to elapse. | 272 // Sleep if that time has yet to elapse. |
271 base::TimeTicks now = clock_->NowTicks(); | 273 base::TimeTicks now = clock_->NowTicks(); |
272 base::TimeDelta video_frame_time = | 274 base::TimeDelta video_frame_time = |
273 base::TimeDelta::FromMilliseconds(kFrameTimerMs); | 275 base::TimeDelta::FromMilliseconds(kFrameTimerMs); |
274 base::TimeDelta elapsed_time = now - send_time_; | 276 base::TimeDelta elapsed_time = now - send_time_; |
275 if (elapsed_time < video_frame_time) { | 277 if (elapsed_time < video_frame_time) { |
276 VLOG(1) << "Wait" << (video_frame_time - elapsed_time).InMilliseconds(); | 278 VLOG(1) << "Wait" << (video_frame_time - elapsed_time).InMilliseconds(); |
277 test_app_thread_proxy_->PostDelayedTask( | 279 test_app_thread_proxy_->PostDelayedTask( |
278 FROM_HERE, | 280 FROM_HERE, |
279 base::Bind(&SendProcess::SendVideoFrameOnTime, | 281 base::Bind(&SendProcess::SendVideoFrameOnTime, |
280 base::Unretained(this), | 282 weak_factory_.GetWeakPtr(), |
281 video_frame), | 283 video_frame), |
282 video_frame_time - elapsed_time); | 284 video_frame_time - elapsed_time); |
283 } else { | 285 } else { |
284 test_app_thread_proxy_->PostTask( | 286 test_app_thread_proxy_->PostTask( |
285 FROM_HERE, | 287 FROM_HERE, |
286 base::Bind(&SendProcess::SendVideoFrameOnTime, | 288 base::Bind(&SendProcess::SendVideoFrameOnTime, |
287 base::Unretained(this), | 289 weak_factory_.GetWeakPtr(), |
288 video_frame)); | 290 video_frame)); |
289 } | 291 } |
290 } | 292 } |
291 | 293 |
292 void SendVideoFrameOnTime(scoped_refptr<media::VideoFrame> video_frame) { | 294 void SendVideoFrameOnTime(scoped_refptr<media::VideoFrame> video_frame) { |
293 send_time_ = clock_->NowTicks(); | 295 send_time_ = clock_->NowTicks(); |
294 frame_input_->InsertRawVideoFrame(video_frame, send_time_); | 296 video_frame_input_->InsertRawVideoFrame(video_frame, send_time_); |
295 test_app_thread_proxy_->PostTask( | 297 test_app_thread_proxy_->PostTask( |
296 FROM_HERE, base::Bind(&SendProcess::SendFrame, base::Unretained(this))); | 298 FROM_HERE, base::Bind(&SendProcess::SendFrame, base::Unretained(this))); |
297 } | 299 } |
298 | 300 |
299 private: | 301 private: |
300 scoped_refptr<base::SingleThreadTaskRunner> test_app_thread_proxy_; | 302 scoped_refptr<base::SingleThreadTaskRunner> test_app_thread_proxy_; |
301 const VideoSenderConfig video_config_; | 303 const VideoSenderConfig video_config_; |
302 int audio_diff_; | 304 int audio_diff_; |
303 const scoped_refptr<FrameInput> frame_input_; | 305 const scoped_refptr<AudioFrameInput> audio_frame_input_; |
| 306 const scoped_refptr<VideoFrameInput> video_frame_input_; |
304 FILE* video_file_; | 307 FILE* video_file_; |
305 uint8 synthetic_count_; | 308 uint8 synthetic_count_; |
306 base::TickClock* const clock_; // Not owned by this class. | 309 base::TickClock* const clock_; // Not owned by this class. |
307 base::TimeTicks start_time_; | 310 base::TimeTicks start_time_; |
308 base::TimeTicks send_time_; | 311 base::TimeTicks send_time_; |
309 scoped_ptr<TestAudioBusFactory> audio_bus_factory_; | 312 scoped_ptr<TestAudioBusFactory> audio_bus_factory_; |
310 base::WeakPtrFactory<SendProcess> weak_factory_; | 313 base::WeakPtrFactory<SendProcess> weak_factory_; |
311 }; | 314 }; |
312 | 315 |
313 } // namespace cast | 316 } // namespace cast |
(...skipping 15 matching lines...) Expand all Loading... |
329 it->type, | 332 it->type, |
330 it->rtp_timestamp, | 333 it->rtp_timestamp, |
331 it->frame_id, | 334 it->frame_id, |
332 it->packet_id, | 335 it->packet_id, |
333 it->max_packet_id, | 336 it->max_packet_id, |
334 it->size); | 337 it->size); |
335 } | 338 } |
336 } | 339 } |
337 | 340 |
338 void InitializationResult(media::cast::CastInitializationStatus result) { | 341 void InitializationResult(media::cast::CastInitializationStatus result) { |
339 CHECK_EQ(result, media::cast::STATUS_INITIALIZED); | 342 bool end_result = result == media::cast::STATUS_AUDIO_INITIALIZED || |
340 VLOG(1) << "Cast Sender initialized"; | 343 result == media::cast::STATUS_VIDEO_INITIALIZED; |
| 344 CHECK(end_result) << "Cast sender uninitialized"; |
341 } | 345 } |
342 | 346 |
343 net::IPEndPoint CreateUDPAddress(std::string ip_str, int port) { | 347 net::IPEndPoint CreateUDPAddress(std::string ip_str, int port) { |
344 net::IPAddressNumber ip_number; | 348 net::IPAddressNumber ip_number; |
345 CHECK(net::ParseIPLiteralToNumber(ip_str, &ip_number)); | 349 CHECK(net::ParseIPLiteralToNumber(ip_str, &ip_number)); |
346 return net::IPEndPoint(ip_number, port); | 350 return net::IPEndPoint(ip_number, port); |
347 } | 351 } |
348 | 352 |
349 void WriteLogsToFileAndStopSubscribing( | 353 void WriteLogsToFileAndStopSubscribing( |
350 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, | 354 const scoped_refptr<media::cast::CastEnvironment>& cast_environment, |
351 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber, | 355 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber, |
352 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber, | 356 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber, |
353 file_util::ScopedFILE log_file) { | 357 file_util::ScopedFILE log_file) { |
354 media::cast::LogSerializer serializer(media::cast::kMaxSerializedLogBytes); | 358 media::cast::LogSerializer serializer(media::cast::kMaxSerializedLogBytes); |
355 | 359 |
356 // Serialize video events. | 360 // Serialize video events. |
357 cast_environment->Logging()->RemoveRawEventSubscriber( | 361 cast_environment->Logging()->RemoveRawEventSubscriber( |
358 video_event_subscriber.get()); | 362 video_event_subscriber.get()); |
359 media::cast::FrameEventMap frame_events; | 363 media::cast::FrameEventMap frame_events; |
360 media::cast::PacketEventMap packet_events; | 364 media::cast::PacketEventMap packet_events; |
361 media::cast::RtpTimestamp first_rtp_timestamp; | 365 media::cast::RtpTimestamp first_rtp_timestamp; |
362 video_event_subscriber->GetEventsAndReset(&frame_events, &packet_events, | 366 video_event_subscriber->GetEventsAndReset( |
363 &first_rtp_timestamp); | 367 &frame_events, &packet_events, &first_rtp_timestamp); |
364 | 368 |
365 VLOG(0) << "Video frame map size: " << frame_events.size(); | 369 VLOG(0) << "Video frame map size: " << frame_events.size(); |
366 VLOG(0) << "Video packet map size: " << packet_events.size(); | 370 VLOG(0) << "Video packet map size: " << packet_events.size(); |
367 | 371 |
368 if (!serializer.SerializeEventsForStream(false, frame_events, packet_events, | 372 if (!serializer.SerializeEventsForStream( |
369 first_rtp_timestamp)) { | 373 false, frame_events, packet_events, first_rtp_timestamp)) { |
370 VLOG(1) << "Failed to serialize video events."; | 374 VLOG(1) << "Failed to serialize video events."; |
371 return; | 375 return; |
372 } | 376 } |
373 | 377 |
374 int length_so_far = serializer.GetSerializedLength(); | 378 int length_so_far = serializer.GetSerializedLength(); |
375 VLOG(0) << "Video events serialized length: " << length_so_far; | 379 VLOG(0) << "Video events serialized length: " << length_so_far; |
376 | 380 |
377 // Serialize audio events. | 381 // Serialize audio events. |
378 cast_environment->Logging()->RemoveRawEventSubscriber( | 382 cast_environment->Logging()->RemoveRawEventSubscriber( |
379 audio_event_subscriber.get()); | 383 audio_event_subscriber.get()); |
380 audio_event_subscriber->GetEventsAndReset(&frame_events, &packet_events, | 384 audio_event_subscriber->GetEventsAndReset( |
381 &first_rtp_timestamp); | 385 &frame_events, &packet_events, &first_rtp_timestamp); |
382 | 386 |
383 VLOG(0) << "Audio frame map size: " << frame_events.size(); | 387 VLOG(0) << "Audio frame map size: " << frame_events.size(); |
384 VLOG(0) << "Audio packet map size: " << packet_events.size(); | 388 VLOG(0) << "Audio packet map size: " << packet_events.size(); |
385 | 389 |
386 if (!serializer.SerializeEventsForStream(true, frame_events, packet_events, | 390 if (!serializer.SerializeEventsForStream( |
387 first_rtp_timestamp)) { | 391 true, frame_events, packet_events, first_rtp_timestamp)) { |
388 VLOG(1) << "Failed to serialize audio events."; | 392 VLOG(1) << "Failed to serialize audio events."; |
389 return; | 393 return; |
390 } | 394 } |
391 | 395 |
392 VLOG(0) << "Audio events serialized length: " | 396 VLOG(0) << "Audio events serialized length: " |
393 << serializer.GetSerializedLength() - length_so_far; | 397 << serializer.GetSerializedLength() - length_so_far; |
394 | 398 |
395 scoped_ptr<std::string> serialized_string = | 399 scoped_ptr<std::string> serialized_string = |
396 serializer.GetSerializedLogAndReset(); | 400 serializer.GetSerializedLogAndReset(); |
397 VLOG(0) << "Serialized string size: " << serialized_string->size(); | 401 VLOG(0) << "Serialized string size: " << serialized_string->size(); |
398 | 402 |
399 size_t ret = fwrite( | 403 size_t ret = fwrite( |
400 &(*serialized_string)[0], 1, serialized_string->size(), log_file.get()); | 404 &(*serialized_string)[0], 1, serialized_string->size(), log_file.get()); |
401 if (ret != serialized_string->size()) | 405 if (ret != serialized_string->size()) |
402 VLOG(1) << "Failed to write logs to file."; | 406 VLOG(1) << "Failed to write logs to file."; |
403 } | 407 } |
404 | 408 |
405 } // namespace | 409 } // namespace |
406 | 410 |
407 int main(int argc, char** argv) { | 411 int main(int argc, char** argv) { |
408 base::AtExitManager at_exit; | 412 base::AtExitManager at_exit; |
409 VLOG(1) << "Cast Sender"; | |
410 base::Thread test_thread("Cast sender test app thread"); | 413 base::Thread test_thread("Cast sender test app thread"); |
411 base::Thread audio_thread("Cast audio encoder thread"); | 414 base::Thread audio_thread("Cast audio encoder thread"); |
412 base::Thread video_thread("Cast video encoder thread"); | 415 base::Thread video_thread("Cast video encoder thread"); |
413 test_thread.Start(); | 416 test_thread.Start(); |
414 audio_thread.Start(); | 417 audio_thread.Start(); |
415 video_thread.Start(); | 418 video_thread.Start(); |
416 | 419 |
417 scoped_ptr<base::TickClock> clock(new base::DefaultTickClock()); | 420 scoped_ptr<base::TickClock> clock(new base::DefaultTickClock()); |
418 base::MessageLoopForIO io_message_loop; | 421 base::MessageLoopForIO io_message_loop; |
419 | 422 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 remote_endpoint, | 468 remote_endpoint, |
466 logging_config, | 469 logging_config, |
467 base::Bind(&UpdateCastTransportStatus), | 470 base::Bind(&UpdateCastTransportStatus), |
468 base::Bind(&LogRawEvents, cast_environment), | 471 base::Bind(&LogRawEvents, cast_environment), |
469 base::TimeDelta::FromSeconds(1), | 472 base::TimeDelta::FromSeconds(1), |
470 io_message_loop.message_loop_proxy()); | 473 io_message_loop.message_loop_proxy()); |
471 | 474 |
472 transport_sender->InitializeAudio(transport_audio_config); | 475 transport_sender->InitializeAudio(transport_audio_config); |
473 transport_sender->InitializeVideo(transport_video_config); | 476 transport_sender->InitializeVideo(transport_video_config); |
474 | 477 |
475 scoped_ptr<media::cast::CastSender> cast_sender( | 478 scoped_ptr<media::cast::CastSender> cast_sender = |
476 media::cast::CastSender::CreateCastSender( | 479 media::cast::CastSender::Create(cast_environment, transport_sender.get()); |
477 cast_environment, | 480 |
478 &audio_config, | 481 cast_sender->InitializeVideo( |
479 &video_config, | 482 video_config, base::Bind(&InitializationResult), NULL); |
480 NULL, // gpu_factories. | 483 cast_sender->InitializeAudio(audio_config, base::Bind(&InitializationResult)); |
481 base::Bind(&InitializationResult), | |
482 transport_sender.get())); | |
483 | 484 |
484 transport_sender->SetPacketReceiver(cast_sender->packet_receiver()); | 485 transport_sender->SetPacketReceiver(cast_sender->packet_receiver()); |
485 | 486 |
486 media::cast::FrameInput* frame_input = cast_sender->frame_input(); | 487 scoped_refptr<media::cast::AudioFrameInput> audio_frame_input = |
| 488 cast_sender->audio_frame_input(); |
| 489 scoped_refptr<media::cast::VideoFrameInput> video_frame_input = |
| 490 cast_sender->video_frame_input(); |
487 scoped_ptr<media::cast::SendProcess> send_process( | 491 scoped_ptr<media::cast::SendProcess> send_process( |
488 new media::cast::SendProcess(test_thread.message_loop_proxy(), | 492 new media::cast::SendProcess(test_thread.message_loop_proxy(), |
489 cast_environment->Clock(), | 493 cast_environment->Clock(), |
490 video_config, | 494 video_config, |
491 frame_input)); | 495 audio_frame_input, |
| 496 video_frame_input)); |
492 | 497 |
493 // Set up event subscribers. | 498 // Set up event subscribers. |
494 int logging_duration = media::cast::GetLoggingDuration(); | 499 int logging_duration = media::cast::GetLoggingDuration(); |
495 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; | 500 scoped_ptr<media::cast::EncodingEventSubscriber> video_event_subscriber; |
496 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; | 501 scoped_ptr<media::cast::EncodingEventSubscriber> audio_event_subscriber; |
497 if (logging_duration > 0) { | 502 if (logging_duration > 0) { |
498 std::string log_file_name(media::cast::GetLogFileDestination()); | 503 std::string log_file_name(media::cast::GetLogFileDestination()); |
499 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 504 video_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
500 media::cast::VIDEO_EVENT, 10000)); | 505 media::cast::VIDEO_EVENT, 10000)); |
501 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( | 506 audio_event_subscriber.reset(new media::cast::EncodingEventSubscriber( |
(...skipping 20 matching lines...) Expand all Loading... |
522 | 527 |
523 test_thread.message_loop_proxy()->PostTask( | 528 test_thread.message_loop_proxy()->PostTask( |
524 FROM_HERE, | 529 FROM_HERE, |
525 base::Bind(&media::cast::SendProcess::SendFrame, | 530 base::Bind(&media::cast::SendProcess::SendFrame, |
526 base::Unretained(send_process.get()))); | 531 base::Unretained(send_process.get()))); |
527 | 532 |
528 io_message_loop.Run(); | 533 io_message_loop.Run(); |
529 | 534 |
530 return 0; | 535 return 0; |
531 } | 536 } |
OLD | NEW |