| Index: media/cast/sender/audio_encoder.cc
|
| diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc
|
| index 2d20238238a3e9d006f67539cad0324854ea24d4..f0c5f8555eea167896797b81383a9b6dece5c1c9 100644
|
| --- a/media/cast/sender/audio_encoder.cc
|
| +++ b/media/cast/sender/audio_encoder.cc
|
| @@ -56,7 +56,8 @@ class AudioEncoder::ImplBase
|
| cast_initialization_status_(STATUS_AUDIO_UNINITIALIZED),
|
| buffer_fill_end_(0),
|
| frame_id_(0),
|
| - frame_rtp_timestamp_(0) {
|
| + frame_rtp_timestamp_(0),
|
| + samples_dropped_from_buffer_(0) {
|
| // Support for max sampling rate of 48KHz, 2 channels, 100 ms duration.
|
| const int kMaxSamplesTimesChannelsPerFrame = 48 * 2 * 100;
|
| if (num_channels_ <= 0 || samples_per_frame_ <= 0 ||
|
| @@ -70,6 +71,10 @@ class AudioEncoder::ImplBase
|
| return cast_initialization_status_;
|
| }
|
|
|
| + int samples_per_frame() const {
|
| + return samples_per_frame_;
|
| + }
|
| +
|
| void EncodeAudio(scoped_ptr<AudioBus> audio_bus,
|
| const base::TimeTicks& recorded_time) {
|
| DCHECK_EQ(cast_initialization_status_, STATUS_AUDIO_INITIALIZED);
|
| @@ -90,6 +95,7 @@ class AudioEncoder::ImplBase
|
| recorded_time - (frame_capture_time_ + buffer_fill_duration);
|
| if (amount_ahead_by >
|
| base::TimeDelta::FromMilliseconds(kUnderrunThresholdMillis)) {
|
| + samples_dropped_from_buffer_ += buffer_fill_end_;
|
| buffer_fill_end_ = 0;
|
| buffer_fill_duration = base::TimeDelta();
|
| const int64 num_frames_missed = amount_ahead_by /
|
| @@ -129,7 +135,10 @@ class AudioEncoder::ImplBase
|
| cast_environment_->PostTask(
|
| CastEnvironment::MAIN,
|
| FROM_HERE,
|
| - base::Bind(callback_, base::Passed(&audio_frame)));
|
| + base::Bind(callback_,
|
| + base::Passed(&audio_frame),
|
| + samples_dropped_from_buffer_));
|
| + samples_dropped_from_buffer_ = 0;
|
| }
|
|
|
| // Reset the internal buffer, frame ID, and timestamps for the next frame.
|
| @@ -182,6 +191,10 @@ class AudioEncoder::ImplBase
|
| // the RTP timestamps.
|
| base::TimeTicks frame_capture_time_;
|
|
|
| + // Set to non-zero to indicate the next output frame skipped over audio
|
| + // samples in order to recover from an input underrun.
|
| + int samples_dropped_from_buffer_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(ImplBase);
|
| };
|
|
|
| @@ -365,11 +378,20 @@ CastInitializationStatus AudioEncoder::InitializationResult() const {
|
| return STATUS_UNSUPPORTED_AUDIO_CODEC;
|
| }
|
|
|
| +int AudioEncoder::GetSamplesPerFrame() const {
|
| + DCHECK(insert_thread_checker_.CalledOnValidThread());
|
| + if (InitializationResult() != STATUS_AUDIO_INITIALIZED) {
|
| + NOTREACHED();
|
| + return std::numeric_limits<int>::max();
|
| + }
|
| + return impl_->samples_per_frame();
|
| +}
|
| +
|
| void AudioEncoder::InsertAudio(scoped_ptr<AudioBus> audio_bus,
|
| const base::TimeTicks& recorded_time) {
|
| DCHECK(insert_thread_checker_.CalledOnValidThread());
|
| DCHECK(audio_bus.get());
|
| - if (!impl_.get()) {
|
| + if (InitializationResult() != STATUS_AUDIO_INITIALIZED) {
|
| NOTREACHED();
|
| return;
|
| }
|
|
|