| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "content/renderer/media/webrtc_audio_renderer.h" | 5 #include "content/renderer/media/webrtc_audio_renderer.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 | 416 |
| 417 media::OutputDeviceStatus WebRtcAudioRenderer::GetDeviceStatus() { | 417 media::OutputDeviceStatus WebRtcAudioRenderer::GetDeviceStatus() { |
| 418 DCHECK(thread_checker_.CalledOnValidThread()); | 418 DCHECK(thread_checker_.CalledOnValidThread()); |
| 419 if (!sink_.get()) | 419 if (!sink_.get()) |
| 420 return media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; | 420 return media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; |
| 421 | 421 |
| 422 return sink_->GetDeviceStatus(); | 422 return sink_->GetDeviceStatus(); |
| 423 } | 423 } |
| 424 | 424 |
| 425 int WebRtcAudioRenderer::Render(media::AudioBus* audio_bus, | 425 int WebRtcAudioRenderer::Render(media::AudioBus* audio_bus, |
| 426 uint32_t audio_delay_milliseconds, | 426 uint32_t frames_delayed, |
| 427 uint32_t frames_skipped) { | 427 uint32_t frames_skipped) { |
| 428 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread()); | 428 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread()); |
| 429 base::AutoLock auto_lock(lock_); | 429 base::AutoLock auto_lock(lock_); |
| 430 if (!source_) | 430 if (!source_) |
| 431 return 0; | 431 return 0; |
| 432 | 432 |
| 433 // TODO(grunell): Converting from frames to milliseconds will potentially lose |
| 434 // hundreds of microseconds which may cause audio video drift. Update |
| 435 // this class and all usage of render delay msec -> frames (possibly even |
| 436 // using a double type for frames). See http://crbug.com/586540 |
| 437 uint32_t audio_delay_milliseconds = static_cast<double>(frames_delayed) * |
| 438 base::Time::kMillisecondsPerSecond / |
| 439 sink_params_.sample_rate(); |
| 440 |
| 433 DVLOG(2) << "WebRtcAudioRenderer::Render()"; | 441 DVLOG(2) << "WebRtcAudioRenderer::Render()"; |
| 434 DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds; | 442 DVLOG(2) << "audio_delay_milliseconds: " << audio_delay_milliseconds; |
| 435 | 443 |
| 436 DCHECK_LE(audio_delay_milliseconds, static_cast<uint32_t>(INT_MAX)); | 444 DCHECK_LE(audio_delay_milliseconds, static_cast<uint32_t>(INT_MAX)); |
| 437 audio_delay_milliseconds_ = static_cast<int>(audio_delay_milliseconds); | 445 audio_delay_milliseconds_ = static_cast<int>(audio_delay_milliseconds); |
| 438 | 446 |
| 439 // If there are skipped frames, pull and throw away the same amount. We always | 447 // If there are skipped frames, pull and throw away the same amount. We always |
| 440 // pull 10 ms of data from the source (see PrepareSink()), so the fifo is only | 448 // pull 10 ms of data from the source (see PrepareSink()), so the fifo is only |
| 441 // required if the number of frames to drop doesn't correspond to 10 ms. | 449 // required if the number of frames to drop doesn't correspond to 10 ms. |
| 442 if (frames_skipped > 0) { | 450 if (frames_skipped > 0) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 // Called by AudioPullFifo when more data is necessary. | 482 // Called by AudioPullFifo when more data is necessary. |
| 475 void WebRtcAudioRenderer::SourceCallback( | 483 void WebRtcAudioRenderer::SourceCallback( |
| 476 int fifo_frame_delay, media::AudioBus* audio_bus) { | 484 int fifo_frame_delay, media::AudioBus* audio_bus) { |
| 477 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread()); | 485 DCHECK(audio_renderer_thread_checker_.CalledOnValidThread()); |
| 478 base::TimeTicks start_time = base::TimeTicks::Now(); | 486 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 479 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback(" | 487 DVLOG(2) << "WebRtcAudioRenderer::SourceCallback(" |
| 480 << fifo_frame_delay << ", " | 488 << fifo_frame_delay << ", " |
| 481 << audio_bus->frames() << ")"; | 489 << audio_bus->frames() << ")"; |
| 482 | 490 |
| 483 int output_delay_milliseconds = audio_delay_milliseconds_; | 491 int output_delay_milliseconds = audio_delay_milliseconds_; |
| 492 // TODO(grunell): This integer division by sample_rate will cause loss of |
| 493 // partial milliseconds, and may cause avsync drift. http://crbug.com/586540 |
| 484 output_delay_milliseconds += fifo_frame_delay * | 494 output_delay_milliseconds += fifo_frame_delay * |
| 485 base::Time::kMillisecondsPerSecond / | 495 base::Time::kMillisecondsPerSecond / |
| 486 sink_params_.sample_rate(); | 496 sink_params_.sample_rate(); |
| 487 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds; | 497 DVLOG(2) << "output_delay_milliseconds: " << output_delay_milliseconds; |
| 488 | 498 |
| 489 // We need to keep render data for the |source_| regardless of |state_|, | 499 // We need to keep render data for the |source_| regardless of |state_|, |
| 490 // otherwise the data will be buffered up inside |source_|. | 500 // otherwise the data will be buffered up inside |source_|. |
| 491 source_->RenderData(audio_bus, sink_params_.sample_rate(), | 501 source_->RenderData(audio_bus, sink_params_.sample_rate(), |
| 492 output_delay_milliseconds, | 502 output_delay_milliseconds, |
| 493 ¤t_time_); | 503 ¤t_time_); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 base::Bind(&WebRtcAudioRenderer::SourceCallback, | 673 base::Bind(&WebRtcAudioRenderer::SourceCallback, |
| 664 base::Unretained(this)))); | 674 base::Unretained(this)))); |
| 665 } | 675 } |
| 666 sink_params_ = new_sink_params; | 676 sink_params_ = new_sink_params; |
| 667 } | 677 } |
| 668 | 678 |
| 669 sink_->Initialize(new_sink_params, this); | 679 sink_->Initialize(new_sink_params, this); |
| 670 } | 680 } |
| 671 | 681 |
| 672 } // namespace content | 682 } // namespace content |
| OLD | NEW |