| 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 #include <limits.h> | 5 #include <limits.h> |
| 6 #include <stddef.h> | 6 #include <stddef.h> |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <climits> | 10 #include <climits> |
| 11 #include <cstdarg> | 11 #include <cstdarg> |
| 12 #include <cstdio> | 12 #include <cstdio> |
| 13 #include <deque> | 13 #include <deque> |
| 14 #include <map> | 14 #include <map> |
| 15 #include <memory> |
| 15 #include <string> | 16 #include <string> |
| 16 #include <utility> | 17 #include <utility> |
| 17 | 18 |
| 18 #include "base/at_exit.h" | 19 #include "base/at_exit.h" |
| 19 #include "base/command_line.h" | 20 #include "base/command_line.h" |
| 20 #include "base/logging.h" | 21 #include "base/logging.h" |
| 21 #include "base/memory/ref_counted.h" | 22 #include "base/memory/ref_counted.h" |
| 22 #include "base/memory/scoped_ptr.h" | |
| 23 #include "base/message_loop/message_loop.h" | 23 #include "base/message_loop/message_loop.h" |
| 24 #include "base/synchronization/lock.h" | 24 #include "base/synchronization/lock.h" |
| 25 #include "base/synchronization/waitable_event.h" | 25 #include "base/synchronization/waitable_event.h" |
| 26 #include "base/threading/thread.h" | 26 #include "base/threading/thread.h" |
| 27 #include "base/time/default_tick_clock.h" | 27 #include "base/time/default_tick_clock.h" |
| 28 #include "base/timer/timer.h" | 28 #include "base/timer/timer.h" |
| 29 #include "media/audio/audio_io.h" | 29 #include "media/audio/audio_io.h" |
| 30 #include "media/audio/audio_manager.h" | 30 #include "media/audio/audio_manager.h" |
| 31 #include "media/audio/audio_parameters.h" | 31 #include "media/audio/audio_parameters.h" |
| 32 #include "media/audio/fake_audio_log_factory.h" | 32 #include "media/audio/fake_audio_log_factory.h" |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 base::Bind(&NaivePlayer::StopAudioOutputOnAudioManagerThread, | 227 base::Bind(&NaivePlayer::StopAudioOutputOnAudioManagerThread, |
| 228 base::Unretained(this), | 228 base::Unretained(this), |
| 229 &done)); | 229 &done)); |
| 230 done.Wait(); | 230 done.Wait(); |
| 231 | 231 |
| 232 // Now, stop receiving new frames. | 232 // Now, stop receiving new frames. |
| 233 InProcessReceiver::Stop(); | 233 InProcessReceiver::Stop(); |
| 234 | 234 |
| 235 // Finally, clear out any frames remaining in the queues. | 235 // Finally, clear out any frames remaining in the queues. |
| 236 while (!audio_playout_queue_.empty()) { | 236 while (!audio_playout_queue_.empty()) { |
| 237 const scoped_ptr<AudioBus> to_be_deleted( | 237 const std::unique_ptr<AudioBus> to_be_deleted( |
| 238 audio_playout_queue_.front().second); | 238 audio_playout_queue_.front().second); |
| 239 audio_playout_queue_.pop_front(); | 239 audio_playout_queue_.pop_front(); |
| 240 } | 240 } |
| 241 video_playout_queue_.clear(); | 241 video_playout_queue_.clear(); |
| 242 } | 242 } |
| 243 | 243 |
| 244 private: | 244 private: |
| 245 void StartAudioOutputOnAudioManagerThread() { | 245 void StartAudioOutputOnAudioManagerThread() { |
| 246 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); | 246 DCHECK(AudioManager::Get()->GetTaskRunner()->BelongsToCurrentThread()); |
| 247 DCHECK(!audio_output_stream_); | 247 DCHECK(!audio_output_stream_); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 ScheduleVideoPlayout(); | 279 ScheduleVideoPlayout(); |
| 280 uint16_t frame_no; | 280 uint16_t frame_no; |
| 281 if (media::cast::test::DecodeBarcode(video_frame, &frame_no)) { | 281 if (media::cast::test::DecodeBarcode(video_frame, &frame_no)) { |
| 282 video_play_times_.insert( | 282 video_play_times_.insert( |
| 283 std::pair<uint16_t, base::TimeTicks>(frame_no, playout_time)); | 283 std::pair<uint16_t, base::TimeTicks>(frame_no, playout_time)); |
| 284 } else { | 284 } else { |
| 285 VLOG(2) << "Barcode decode failed!"; | 285 VLOG(2) << "Barcode decode failed!"; |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 | 288 |
| 289 void OnAudioFrame(scoped_ptr<AudioBus> audio_frame, | 289 void OnAudioFrame(std::unique_ptr<AudioBus> audio_frame, |
| 290 const base::TimeTicks& playout_time, | 290 const base::TimeTicks& playout_time, |
| 291 bool is_continuous) final { | 291 bool is_continuous) final { |
| 292 DCHECK(cast_env()->CurrentlyOn(CastEnvironment::MAIN)); | 292 DCHECK(cast_env()->CurrentlyOn(CastEnvironment::MAIN)); |
| 293 LOG_IF(WARNING, !is_continuous) | 293 LOG_IF(WARNING, !is_continuous) |
| 294 << "Audio: Discontinuity in received frames."; | 294 << "Audio: Discontinuity in received frames."; |
| 295 base::AutoLock auto_lock(audio_lock_); | 295 base::AutoLock auto_lock(audio_lock_); |
| 296 uint16_t frame_no; | 296 uint16_t frame_no; |
| 297 if (media::cast::DecodeTimestamp(audio_frame->channel(0), | 297 if (media::cast::DecodeTimestamp(audio_frame->channel(0), |
| 298 audio_frame->frames(), | 298 audio_frame->frames(), |
| 299 &frame_no)) { | 299 &frame_no)) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 << " usec later than intended."; | 443 << " usec later than intended."; |
| 444 } | 444 } |
| 445 | 445 |
| 446 last_popped_video_playout_time_ = video_playout_queue_.front().first; | 446 last_popped_video_playout_time_ = video_playout_queue_.front().first; |
| 447 const scoped_refptr<VideoFrame> ret = video_playout_queue_.front().second; | 447 const scoped_refptr<VideoFrame> ret = video_playout_queue_.front().second; |
| 448 video_playout_queue_.pop_front(); | 448 video_playout_queue_.pop_front(); |
| 449 ++num_video_frames_processed_; | 449 ++num_video_frames_processed_; |
| 450 return ret; | 450 return ret; |
| 451 } | 451 } |
| 452 | 452 |
| 453 scoped_ptr<AudioBus> PopOneAudioFrame(bool was_skipped) { | 453 std::unique_ptr<AudioBus> PopOneAudioFrame(bool was_skipped) { |
| 454 audio_lock_.AssertAcquired(); | 454 audio_lock_.AssertAcquired(); |
| 455 | 455 |
| 456 if (was_skipped) { | 456 if (was_skipped) { |
| 457 VLOG(1) << "AudioFrame[" << num_audio_frames_processed_ | 457 VLOG(1) << "AudioFrame[" << num_audio_frames_processed_ |
| 458 << " (dt=" << (audio_playout_queue_.front().first - | 458 << " (dt=" << (audio_playout_queue_.front().first - |
| 459 last_popped_audio_playout_time_).InMicroseconds() | 459 last_popped_audio_playout_time_).InMicroseconds() |
| 460 << " usec)]: Skipped."; | 460 << " usec)]: Skipped."; |
| 461 } else { | 461 } else { |
| 462 VLOG(1) << "AudioFrame[" << num_audio_frames_processed_ | 462 VLOG(1) << "AudioFrame[" << num_audio_frames_processed_ |
| 463 << " (dt=" << (audio_playout_queue_.front().first - | 463 << " (dt=" << (audio_playout_queue_.front().first - |
| 464 last_popped_audio_playout_time_).InMicroseconds() | 464 last_popped_audio_playout_time_).InMicroseconds() |
| 465 << " usec)]: Playing " | 465 << " usec)]: Playing " |
| 466 << (cast_env()->Clock()->NowTicks() - | 466 << (cast_env()->Clock()->NowTicks() - |
| 467 audio_playout_queue_.front().first).InMicroseconds() | 467 audio_playout_queue_.front().first).InMicroseconds() |
| 468 << " usec later than intended."; | 468 << " usec later than intended."; |
| 469 } | 469 } |
| 470 | 470 |
| 471 last_popped_audio_playout_time_ = audio_playout_queue_.front().first; | 471 last_popped_audio_playout_time_ = audio_playout_queue_.front().first; |
| 472 scoped_ptr<AudioBus> ret(audio_playout_queue_.front().second); | 472 std::unique_ptr<AudioBus> ret(audio_playout_queue_.front().second); |
| 473 audio_playout_queue_.pop_front(); | 473 audio_playout_queue_.pop_front(); |
| 474 ++num_audio_frames_processed_; | 474 ++num_audio_frames_processed_; |
| 475 return ret; | 475 return ret; |
| 476 } | 476 } |
| 477 | 477 |
| 478 void CheckAVSync() { | 478 void CheckAVSync() { |
| 479 if (video_play_times_.size() > 30 && | 479 if (video_play_times_.size() > 30 && |
| 480 audio_play_times_.size() > 30) { | 480 audio_play_times_.size() > 30) { |
| 481 size_t num_events = 0; | 481 size_t num_events = 0; |
| 482 base::TimeDelta delta; | 482 base::TimeDelta delta; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 507 } | 507 } |
| 508 | 508 |
| 509 // Frames in the queue older than this (relative to NowTicks()) will be | 509 // Frames in the queue older than this (relative to NowTicks()) will be |
| 510 // dropped (i.e., playback is falling behind). | 510 // dropped (i.e., playback is falling behind). |
| 511 const base::TimeDelta max_frame_age_; | 511 const base::TimeDelta max_frame_age_; |
| 512 | 512 |
| 513 // Outputs created, started, and destroyed by this NaivePlayer. | 513 // Outputs created, started, and destroyed by this NaivePlayer. |
| 514 #if defined(USE_X11) | 514 #if defined(USE_X11) |
| 515 test::LinuxOutputWindow render_; | 515 test::LinuxOutputWindow render_; |
| 516 #endif // defined(USE_X11) | 516 #endif // defined(USE_X11) |
| 517 scoped_ptr<AudioOutputStream> audio_output_stream_; | 517 std::unique_ptr<AudioOutputStream> audio_output_stream_; |
| 518 | 518 |
| 519 // Video playout queue. | 519 // Video playout queue. |
| 520 typedef std::pair<base::TimeTicks, scoped_refptr<VideoFrame> > | 520 typedef std::pair<base::TimeTicks, scoped_refptr<VideoFrame> > |
| 521 VideoQueueEntry; | 521 VideoQueueEntry; |
| 522 std::deque<VideoQueueEntry> video_playout_queue_; | 522 std::deque<VideoQueueEntry> video_playout_queue_; |
| 523 base::TimeTicks last_popped_video_playout_time_; | 523 base::TimeTicks last_popped_video_playout_time_; |
| 524 int64_t num_video_frames_processed_; | 524 int64_t num_video_frames_processed_; |
| 525 | 525 |
| 526 base::OneShotTimer video_playout_timer_; | 526 base::OneShotTimer video_playout_timer_; |
| 527 | 527 |
| 528 // Audio playout queue, synchronized by |audio_lock_|. | 528 // Audio playout queue, synchronized by |audio_lock_|. |
| 529 base::Lock audio_lock_; | 529 base::Lock audio_lock_; |
| 530 typedef std::pair<base::TimeTicks, AudioBus*> AudioQueueEntry; | 530 typedef std::pair<base::TimeTicks, AudioBus*> AudioQueueEntry; |
| 531 std::deque<AudioQueueEntry> audio_playout_queue_; | 531 std::deque<AudioQueueEntry> audio_playout_queue_; |
| 532 base::TimeTicks last_popped_audio_playout_time_; | 532 base::TimeTicks last_popped_audio_playout_time_; |
| 533 int64_t num_audio_frames_processed_; | 533 int64_t num_audio_frames_processed_; |
| 534 | 534 |
| 535 // These must only be used on the audio thread calling OnMoreData(). | 535 // These must only be used on the audio thread calling OnMoreData(). |
| 536 scoped_ptr<AudioBus> currently_playing_audio_frame_; | 536 std::unique_ptr<AudioBus> currently_playing_audio_frame_; |
| 537 int currently_playing_audio_frame_start_; | 537 int currently_playing_audio_frame_start_; |
| 538 | 538 |
| 539 std::map<uint16_t, base::TimeTicks> audio_play_times_; | 539 std::map<uint16_t, base::TimeTicks> audio_play_times_; |
| 540 std::map<uint16_t, base::TimeTicks> video_play_times_; | 540 std::map<uint16_t, base::TimeTicks> video_play_times_; |
| 541 int32_t last_audio_frame_no_; | 541 int32_t last_audio_frame_no_; |
| 542 }; | 542 }; |
| 543 | 543 |
| 544 } // namespace cast | 544 } // namespace cast |
| 545 } // namespace media | 545 } // namespace media |
| 546 | 546 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 audio_config, | 598 audio_config, |
| 599 video_config, | 599 video_config, |
| 600 window_width, | 600 window_width, |
| 601 window_height); | 601 window_height); |
| 602 player.Start(); | 602 player.Start(); |
| 603 | 603 |
| 604 message_loop.Run(); // Run forever (i.e., until SIGTERM). | 604 message_loop.Run(); // Run forever (i.e., until SIGTERM). |
| 605 NOTREACHED(); | 605 NOTREACHED(); |
| 606 return 0; | 606 return 0; |
| 607 } | 607 } |
| OLD | NEW |