Home | History | Annotate | Download | only in filters
      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
      3 // found in the LICENSE file.
      4 
      5 #include "media/filters/audio_renderer_impl.h"
      6 
      7 #include <math.h>
      8 
      9 #include <algorithm>
     10 
     11 #include "base/bind.h"
     12 #include "base/callback.h"
     13 #include "base/callback_helpers.h"
     14 #include "base/logging.h"
     15 #include "base/metrics/histogram.h"
     16 #include "base/single_thread_task_runner.h"
     17 #include "media/base/audio_buffer.h"
     18 #include "media/base/audio_buffer_converter.h"
     19 #include "media/base/audio_hardware_config.h"
     20 #include "media/base/audio_splicer.h"
     21 #include "media/base/bind_to_current_loop.h"
     22 #include "media/base/demuxer_stream.h"
     23 #include "media/filters/audio_clock.h"
     24 #include "media/filters/decrypting_demuxer_stream.h"
     25 
     26 namespace media {
     27 
     28 namespace {
     29 
     30 enum AudioRendererEvent {
     31   INITIALIZED,
     32   RENDER_ERROR,
     33   RENDER_EVENT_MAX = RENDER_ERROR,
     34 };
     35 
     36 void HistogramRendererEvent(AudioRendererEvent event) {
     37   UMA_HISTOGRAM_ENUMERATION(
     38       "Media.AudioRendererEvents", event, RENDER_EVENT_MAX + 1);
     39 }
     40 
     41 }  // namespace
     42 
     43 AudioRendererImpl::AudioRendererImpl(
     44     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     45     media::AudioRendererSink* sink,
     46     ScopedVector<AudioDecoder> decoders,
     47     const SetDecryptorReadyCB& set_decryptor_ready_cb,
     48     AudioHardwareConfig* hardware_config)
     49     : task_runner_(task_runner),
     50       sink_(sink),
     51       audio_buffer_stream_(task_runner,
     52                            decoders.Pass(),
     53                            set_decryptor_ready_cb),
     54       hardware_config_(hardware_config),
     55       now_cb_(base::Bind(&base::TimeTicks::Now)),
     56       state_(kUninitialized),
     57       rendering_(false),
     58       sink_playing_(false),
     59       pending_read_(false),
     60       received_end_of_stream_(false),
     61       rendered_end_of_stream_(false),
     62       preroll_aborted_(false),
     63       weak_factory_(this) {
     64   audio_buffer_stream_.set_splice_observer(base::Bind(
     65       &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
     66   audio_buffer_stream_.set_config_change_observer(base::Bind(
     67       &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
     68 }
     69 
     70 AudioRendererImpl::~AudioRendererImpl() {
     71   // Stop() should have been called and |algorithm_| should have been destroyed.
     72   DCHECK(state_ == kUninitialized || state_ == kStopped);
     73   DCHECK(!algorithm_.get());
     74 }
     75 
     76 void AudioRendererImpl::StartRendering() {
     77   DVLOG(1) << __FUNCTION__;
     78   DCHECK(task_runner_->BelongsToCurrentThread());
     79   DCHECK(!rendering_);
     80   rendering_ = true;
     81 
     82   base::AutoLock auto_lock(lock_);
     83   // Wait for an eventual call to SetPlaybackRate() to start rendering.
     84   if (algorithm_->playback_rate() == 0) {
     85     DCHECK(!sink_playing_);
     86     return;
     87   }
     88 
     89   StartRendering_Locked();
     90 }
     91 
     92 void AudioRendererImpl::StartRendering_Locked() {
     93   DVLOG(1) << __FUNCTION__;
     94   DCHECK(task_runner_->BelongsToCurrentThread());
     95   DCHECK(state_ == kPlaying || state_ == kRebuffering || state_ == kUnderflow)
     96       << "state_=" << state_;
     97   DCHECK(!sink_playing_);
     98   DCHECK_NE(algorithm_->playback_rate(), 0);
     99   lock_.AssertAcquired();
    100 
    101   earliest_end_time_ = now_cb_.Run();
    102   sink_playing_ = true;
    103 
    104   base::AutoUnlock auto_unlock(lock_);
    105   sink_->Play();
    106 }
    107 
    108 void AudioRendererImpl::StopRendering() {
    109   DVLOG(1) << __FUNCTION__;
    110   DCHECK(task_runner_->BelongsToCurrentThread());
    111   DCHECK(rendering_);
    112   rendering_ = false;
    113 
    114   base::AutoLock auto_lock(lock_);
    115   // Rendering should have already been stopped with a zero playback rate.
    116   if (algorithm_->playback_rate() == 0) {
    117     DCHECK(!sink_playing_);
    118     return;
    119   }
    120 
    121   StopRendering_Locked();
    122 }
    123 
    124 void AudioRendererImpl::StopRendering_Locked() {
    125   DCHECK(task_runner_->BelongsToCurrentThread());
    126   DCHECK(state_ == kPlaying || state_ == kRebuffering || state_ == kUnderflow)
    127       << "state_=" << state_;
    128   DCHECK(sink_playing_);
    129   lock_.AssertAcquired();
    130 
    131   sink_playing_ = false;
    132 
    133   base::AutoUnlock auto_unlock(lock_);
    134   sink_->Pause();
    135 }
    136 
    137 void AudioRendererImpl::Flush(const base::Closure& callback) {
    138   DVLOG(1) << __FUNCTION__;
    139   DCHECK(task_runner_->BelongsToCurrentThread());
    140 
    141   base::AutoLock auto_lock(lock_);
    142   DCHECK(state_ == kPlaying || state_ == kRebuffering || state_ == kUnderflow)
    143       << "state_=" << state_;
    144   DCHECK(flush_cb_.is_null());
    145 
    146   flush_cb_ = callback;
    147 
    148   if (pending_read_) {
    149     ChangeState_Locked(kFlushing);
    150     return;
    151   }
    152 
    153   ChangeState_Locked(kFlushed);
    154   DoFlush_Locked();
    155 }
    156 
    157 void AudioRendererImpl::DoFlush_Locked() {
    158   DCHECK(task_runner_->BelongsToCurrentThread());
    159   lock_.AssertAcquired();
    160 
    161   DCHECK(!pending_read_);
    162   DCHECK_EQ(state_, kFlushed);
    163 
    164   audio_buffer_stream_.Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone,
    165                                         weak_factory_.GetWeakPtr()));
    166 }
    167 
    168 void AudioRendererImpl::ResetDecoderDone() {
    169   DCHECK(task_runner_->BelongsToCurrentThread());
    170   {
    171     base::AutoLock auto_lock(lock_);
    172     if (state_ == kStopped)
    173       return;
    174 
    175     DCHECK_EQ(state_, kFlushed);
    176     DCHECK(!flush_cb_.is_null());
    177 
    178     audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
    179     received_end_of_stream_ = false;
    180     rendered_end_of_stream_ = false;
    181     preroll_aborted_ = false;
    182 
    183     earliest_end_time_ = now_cb_.Run();
    184     splicer_->Reset();
    185     if (buffer_converter_)
    186       buffer_converter_->Reset();
    187     algorithm_->FlushBuffers();
    188   }
    189   base::ResetAndReturn(&flush_cb_).Run();
    190 }
    191 
    192 void AudioRendererImpl::Stop(const base::Closure& callback) {
    193   DVLOG(1) << __FUNCTION__;
    194   DCHECK(task_runner_->BelongsToCurrentThread());
    195   DCHECK(!callback.is_null());
    196 
    197   // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
    198   // task-running guards that check |state_| with DCHECK().
    199 
    200   {
    201     base::AutoLock auto_lock(lock_);
    202 
    203     if (state_ == kStopped) {
    204       task_runner_->PostTask(FROM_HERE, callback);
    205       return;
    206     }
    207 
    208     ChangeState_Locked(kStopped);
    209     algorithm_.reset();
    210     underflow_cb_.Reset();
    211     time_cb_.Reset();
    212     flush_cb_.Reset();
    213   }
    214 
    215   if (sink_) {
    216     sink_->Stop();
    217     sink_ = NULL;
    218   }
    219 
    220   audio_buffer_stream_.Stop(callback);
    221 }
    222 
    223 void AudioRendererImpl::Preroll(base::TimeDelta time,
    224                                 const PipelineStatusCB& cb) {
    225   DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")";
    226   DCHECK(task_runner_->BelongsToCurrentThread());
    227 
    228   base::AutoLock auto_lock(lock_);
    229   DCHECK(!sink_playing_);
    230   DCHECK_EQ(state_, kFlushed);
    231   DCHECK(!pending_read_) << "Pending read must complete before seeking";
    232   DCHECK(preroll_cb_.is_null());
    233 
    234   ChangeState_Locked(kPrerolling);
    235   preroll_cb_ = cb;
    236   preroll_timestamp_ = time;
    237 
    238   AttemptRead_Locked();
    239 }
    240 
    241 void AudioRendererImpl::Initialize(DemuxerStream* stream,
    242                                    const PipelineStatusCB& init_cb,
    243                                    const StatisticsCB& statistics_cb,
    244                                    const base::Closure& underflow_cb,
    245                                    const TimeCB& time_cb,
    246                                    const base::Closure& ended_cb,
    247                                    const PipelineStatusCB& error_cb) {
    248   DCHECK(task_runner_->BelongsToCurrentThread());
    249   DCHECK(stream);
    250   DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
    251   DCHECK(!init_cb.is_null());
    252   DCHECK(!statistics_cb.is_null());
    253   DCHECK(!underflow_cb.is_null());
    254   DCHECK(!time_cb.is_null());
    255   DCHECK(!ended_cb.is_null());
    256   DCHECK(!error_cb.is_null());
    257   DCHECK_EQ(kUninitialized, state_);
    258   DCHECK(sink_);
    259 
    260   state_ = kInitializing;
    261 
    262   init_cb_ = init_cb;
    263   underflow_cb_ = underflow_cb;
    264   time_cb_ = time_cb;
    265   ended_cb_ = ended_cb;
    266   error_cb_ = error_cb;
    267 
    268   expecting_config_changes_ = stream->SupportsConfigChanges();
    269   if (!expecting_config_changes_) {
    270     // The actual buffer size is controlled via the size of the AudioBus
    271     // provided to Render(), so just choose something reasonable here for looks.
    272     int buffer_size = stream->audio_decoder_config().samples_per_second() / 100;
    273     audio_parameters_.Reset(
    274         AudioParameters::AUDIO_PCM_LOW_LATENCY,
    275         stream->audio_decoder_config().channel_layout(),
    276         ChannelLayoutToChannelCount(
    277             stream->audio_decoder_config().channel_layout()),
    278         0,
    279         stream->audio_decoder_config().samples_per_second(),
    280         stream->audio_decoder_config().bits_per_channel(),
    281         buffer_size);
    282     buffer_converter_.reset();
    283   } else {
    284     // TODO(rileya): Support hardware config changes
    285     const AudioParameters& hw_params = hardware_config_->GetOutputConfig();
    286     audio_parameters_.Reset(
    287         hw_params.format(),
    288         // Always use the source's channel layout and channel count to avoid
    289         // premature downmixing (http://crbug.com/379288), platform specific
    290         // issues around channel layouts (http://crbug.com/266674), and
    291         // unnecessary upmixing overhead.
    292         stream->audio_decoder_config().channel_layout(),
    293         ChannelLayoutToChannelCount(
    294             stream->audio_decoder_config().channel_layout()),
    295         hw_params.input_channels(),
    296         hw_params.sample_rate(),
    297         hw_params.bits_per_sample(),
    298         hardware_config_->GetHighLatencyBufferSize());
    299   }
    300 
    301   audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate()));
    302 
    303   audio_buffer_stream_.Initialize(
    304       stream,
    305       false,
    306       statistics_cb,
    307       base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
    308                  weak_factory_.GetWeakPtr()));
    309 }
    310 
    311 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) {
    312   DCHECK(task_runner_->BelongsToCurrentThread());
    313 
    314   base::AutoLock auto_lock(lock_);
    315 
    316   if (state_ == kStopped) {
    317     base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
    318     return;
    319   }
    320 
    321   if (!success) {
    322     state_ = kUninitialized;
    323     base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
    324     return;
    325   }
    326 
    327   if (!audio_parameters_.IsValid()) {
    328     ChangeState_Locked(kUninitialized);
    329     base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
    330     return;
    331   }
    332 
    333   if (expecting_config_changes_)
    334     buffer_converter_.reset(new AudioBufferConverter(audio_parameters_));
    335   splicer_.reset(new AudioSplicer(audio_parameters_.sample_rate()));
    336 
    337   // We're all good! Continue initializing the rest of the audio renderer
    338   // based on the decoder format.
    339   algorithm_.reset(new AudioRendererAlgorithm());
    340   algorithm_->Initialize(0, audio_parameters_);
    341 
    342   ChangeState_Locked(kFlushed);
    343 
    344   HistogramRendererEvent(INITIALIZED);
    345 
    346   {
    347     base::AutoUnlock auto_unlock(lock_);
    348     sink_->Initialize(audio_parameters_, this);
    349     sink_->Start();
    350 
    351     // Some sinks play on start...
    352     sink_->Pause();
    353   }
    354 
    355   DCHECK(!sink_playing_);
    356 
    357   base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
    358 }
    359 
    360 void AudioRendererImpl::ResumeAfterUnderflow() {
    361   DCHECK(task_runner_->BelongsToCurrentThread());
    362   base::AutoLock auto_lock(lock_);
    363   if (state_ == kUnderflow) {
    364     // The "!preroll_aborted_" is a hack. If preroll is aborted, then we
    365     // shouldn't even reach the kUnderflow state to begin with. But for now
    366     // we're just making sure that the audio buffer capacity (i.e. the
    367     // number of bytes that need to be buffered for preroll to complete)
    368     // does not increase due to an aborted preroll.
    369     // TODO(vrk): Fix this bug correctly! (crbug.com/151352)
    370     if (!preroll_aborted_)
    371       algorithm_->IncreaseQueueCapacity();
    372 
    373     ChangeState_Locked(kRebuffering);
    374   }
    375 }
    376 
    377 void AudioRendererImpl::SetVolume(float volume) {
    378   DCHECK(task_runner_->BelongsToCurrentThread());
    379   DCHECK(sink_);
    380   sink_->SetVolume(volume);
    381 }
    382 
    383 void AudioRendererImpl::DecodedAudioReady(
    384     AudioBufferStream::Status status,
    385     const scoped_refptr<AudioBuffer>& buffer) {
    386   DVLOG(2) << __FUNCTION__ << "(" << status << ")";
    387   DCHECK(task_runner_->BelongsToCurrentThread());
    388 
    389   base::AutoLock auto_lock(lock_);
    390   DCHECK(state_ != kUninitialized);
    391 
    392   CHECK(pending_read_);
    393   pending_read_ = false;
    394 
    395   if (status == AudioBufferStream::ABORTED ||
    396       status == AudioBufferStream::DEMUXER_READ_ABORTED) {
    397     HandleAbortedReadOrDecodeError(false);
    398     return;
    399   }
    400 
    401   if (status == AudioBufferStream::DECODE_ERROR) {
    402     HandleAbortedReadOrDecodeError(true);
    403     return;
    404   }
    405 
    406   DCHECK_EQ(status, AudioBufferStream::OK);
    407   DCHECK(buffer.get());
    408 
    409   if (state_ == kFlushing) {
    410     ChangeState_Locked(kFlushed);
    411     DoFlush_Locked();
    412     return;
    413   }
    414 
    415   if (expecting_config_changes_) {
    416     DCHECK(buffer_converter_);
    417     buffer_converter_->AddInput(buffer);
    418     while (buffer_converter_->HasNextBuffer()) {
    419       if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) {
    420         HandleAbortedReadOrDecodeError(true);
    421         return;
    422       }
    423     }
    424   } else {
    425     if (!splicer_->AddInput(buffer)) {
    426       HandleAbortedReadOrDecodeError(true);
    427       return;
    428     }
    429   }
    430 
    431   if (!splicer_->HasNextBuffer()) {
    432     AttemptRead_Locked();
    433     return;
    434   }
    435 
    436   bool need_another_buffer = false;
    437   while (splicer_->HasNextBuffer())
    438     need_another_buffer = HandleSplicerBuffer(splicer_->GetNextBuffer());
    439 
    440   if (!need_another_buffer && !CanRead_Locked())
    441     return;
    442 
    443   AttemptRead_Locked();
    444 }
    445 
    446 bool AudioRendererImpl::HandleSplicerBuffer(
    447     const scoped_refptr<AudioBuffer>& buffer) {
    448   if (buffer->end_of_stream()) {
    449     received_end_of_stream_ = true;
    450 
    451     // Transition to kPlaying if we are currently handling an underflow since
    452     // no more data will be arriving.
    453     if (state_ == kUnderflow || state_ == kRebuffering)
    454       ChangeState_Locked(kPlaying);
    455   } else {
    456     if (state_ == kPrerolling) {
    457       if (IsBeforePrerollTime(buffer))
    458         return true;
    459 
    460       // Trim off any additional time before the preroll timestamp.
    461       const base::TimeDelta trim_time =
    462           preroll_timestamp_ - buffer->timestamp();
    463       if (trim_time > base::TimeDelta()) {
    464         buffer->TrimStart(buffer->frame_count() *
    465                           (static_cast<double>(trim_time.InMicroseconds()) /
    466                            buffer->duration().InMicroseconds()));
    467       }
    468       // If the entire buffer was trimmed, request a new one.
    469       if (!buffer->frame_count())
    470         return true;
    471     }
    472 
    473     if (state_ != kUninitialized && state_ != kStopped)
    474       algorithm_->EnqueueBuffer(buffer);
    475   }
    476 
    477   switch (state_) {
    478     case kUninitialized:
    479     case kInitializing:
    480     case kFlushing:
    481       NOTREACHED();
    482       return false;
    483 
    484     case kFlushed:
    485       DCHECK(!pending_read_);
    486       return false;
    487 
    488     case kPrerolling:
    489       if (!buffer->end_of_stream() && !algorithm_->IsQueueFull())
    490         return true;
    491       ChangeState_Locked(kPlaying);
    492       base::ResetAndReturn(&preroll_cb_).Run(PIPELINE_OK);
    493       return false;
    494 
    495     case kPlaying:
    496     case kUnderflow:
    497       return false;
    498 
    499     case kRebuffering:
    500       if (!algorithm_->IsQueueFull())
    501         return true;
    502       ChangeState_Locked(kPlaying);
    503       return false;
    504 
    505     case kStopped:
    506       return false;
    507   }
    508   return false;
    509 }
    510 
    511 void AudioRendererImpl::AttemptRead() {
    512   base::AutoLock auto_lock(lock_);
    513   AttemptRead_Locked();
    514 }
    515 
    516 void AudioRendererImpl::AttemptRead_Locked() {
    517   DCHECK(task_runner_->BelongsToCurrentThread());
    518   lock_.AssertAcquired();
    519 
    520   if (!CanRead_Locked())
    521     return;
    522 
    523   pending_read_ = true;
    524   audio_buffer_stream_.Read(base::Bind(&AudioRendererImpl::DecodedAudioReady,
    525                                        weak_factory_.GetWeakPtr()));
    526 }
    527 
    528 bool AudioRendererImpl::CanRead_Locked() {
    529   lock_.AssertAcquired();
    530 
    531   switch (state_) {
    532     case kUninitialized:
    533     case kInitializing:
    534     case kFlushed:
    535     case kFlushing:
    536     case kStopped:
    537       return false;
    538 
    539     case kPrerolling:
    540     case kPlaying:
    541     case kUnderflow:
    542     case kRebuffering:
    543       break;
    544   }
    545 
    546   return !pending_read_ && !received_end_of_stream_ &&
    547       !algorithm_->IsQueueFull();
    548 }
    549 
    550 void AudioRendererImpl::SetPlaybackRate(float playback_rate) {
    551   DVLOG(1) << __FUNCTION__ << "(" << playback_rate << ")";
    552   DCHECK(task_runner_->BelongsToCurrentThread());
    553   DCHECK_GE(playback_rate, 0);
    554   DCHECK(sink_);
    555 
    556   base::AutoLock auto_lock(lock_);
    557 
    558   // We have two cases here:
    559   // Play: current_playback_rate == 0 && playback_rate != 0
    560   // Pause: current_playback_rate != 0 && playback_rate == 0
    561   float current_playback_rate = algorithm_->playback_rate();
    562   algorithm_->SetPlaybackRate(playback_rate);
    563 
    564   if (!rendering_)
    565     return;
    566 
    567   if (current_playback_rate == 0 && playback_rate != 0) {
    568     StartRendering_Locked();
    569     return;
    570   }
    571 
    572   if (current_playback_rate != 0 && playback_rate == 0) {
    573     StopRendering_Locked();
    574     return;
    575   }
    576 }
    577 
    578 bool AudioRendererImpl::IsBeforePrerollTime(
    579     const scoped_refptr<AudioBuffer>& buffer) {
    580   DCHECK_EQ(state_, kPrerolling);
    581   return buffer && !buffer->end_of_stream() &&
    582          (buffer->timestamp() + buffer->duration()) < preroll_timestamp_;
    583 }
    584 
    585 int AudioRendererImpl::Render(AudioBus* audio_bus,
    586                               int audio_delay_milliseconds) {
    587   const int requested_frames = audio_bus->frames();
    588   base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds(
    589       audio_delay_milliseconds);
    590   const int delay_frames = static_cast<int>(playback_delay.InSecondsF() *
    591                                             audio_parameters_.sample_rate());
    592   int frames_written = 0;
    593   base::Closure time_cb;
    594   base::Closure underflow_cb;
    595   {
    596     base::AutoLock auto_lock(lock_);
    597 
    598     // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
    599     if (!algorithm_) {
    600       audio_clock_->WroteSilence(requested_frames, delay_frames);
    601       return 0;
    602     }
    603 
    604     float playback_rate = algorithm_->playback_rate();
    605     if (playback_rate == 0) {
    606       audio_clock_->WroteSilence(requested_frames, delay_frames);
    607       return 0;
    608     }
    609 
    610     // Mute audio by returning 0 when not playing.
    611     if (state_ != kPlaying) {
    612       audio_clock_->WroteSilence(requested_frames, delay_frames);
    613       return 0;
    614     }
    615 
    616     // We use the following conditions to determine end of playback:
    617     //   1) Algorithm can not fill the audio callback buffer
    618     //   2) We received an end of stream buffer
    619     //   3) We haven't already signalled that we've ended
    620     //   4) Our estimated earliest end time has expired
    621     //
    622     // TODO(enal): we should replace (4) with a check that the browser has no
    623     // more audio data or at least use a delayed callback.
    624     //
    625     // We use the following conditions to determine underflow:
    626     //   1) Algorithm can not fill the audio callback buffer
    627     //   2) We have NOT received an end of stream buffer
    628     //   3) We are in the kPlaying state
    629     //
    630     // Otherwise the buffer has data we can send to the device.
    631     const base::TimeDelta media_timestamp_before_filling =
    632         audio_clock_->CurrentMediaTimestamp();
    633     if (algorithm_->frames_buffered() > 0) {
    634       frames_written = algorithm_->FillBuffer(audio_bus, requested_frames);
    635       audio_clock_->WroteAudio(
    636           frames_written, delay_frames, playback_rate, algorithm_->GetTime());
    637     }
    638     audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames);
    639 
    640     if (frames_written == 0) {
    641       const base::TimeTicks now = now_cb_.Run();
    642 
    643       if (received_end_of_stream_ && !rendered_end_of_stream_ &&
    644           now >= earliest_end_time_) {
    645         rendered_end_of_stream_ = true;
    646         ended_cb_.Run();
    647       } else if (!received_end_of_stream_ && state_ == kPlaying) {
    648         ChangeState_Locked(kUnderflow);
    649         underflow_cb = underflow_cb_;
    650       } else {
    651         // We can't write any data this cycle. For example, we may have
    652         // sent all available data to the audio device while not reaching
    653         // |earliest_end_time_|.
    654       }
    655     }
    656 
    657     if (CanRead_Locked()) {
    658       task_runner_->PostTask(FROM_HERE,
    659                              base::Bind(&AudioRendererImpl::AttemptRead,
    660                                         weak_factory_.GetWeakPtr()));
    661     }
    662 
    663     // We only want to execute |time_cb_| if time has progressed and we haven't
    664     // signaled end of stream yet.
    665     if (media_timestamp_before_filling !=
    666             audio_clock_->CurrentMediaTimestamp() &&
    667         !rendered_end_of_stream_) {
    668       time_cb = base::Bind(time_cb_,
    669                            audio_clock_->CurrentMediaTimestamp(),
    670                            audio_clock_->last_endpoint_timestamp());
    671     }
    672 
    673     if (frames_written > 0) {
    674       UpdateEarliestEndTime_Locked(
    675           frames_written, playback_delay, now_cb_.Run());
    676     }
    677   }
    678 
    679   if (!time_cb.is_null())
    680     task_runner_->PostTask(FROM_HERE, time_cb);
    681 
    682   if (!underflow_cb.is_null())
    683     underflow_cb.Run();
    684 
    685   DCHECK_LE(frames_written, requested_frames);
    686   return frames_written;
    687 }
    688 
    689 void AudioRendererImpl::UpdateEarliestEndTime_Locked(
    690     int frames_filled, const base::TimeDelta& playback_delay,
    691     const base::TimeTicks& time_now) {
    692   DCHECK_GT(frames_filled, 0);
    693 
    694   base::TimeDelta predicted_play_time = base::TimeDelta::FromMicroseconds(
    695       static_cast<float>(frames_filled) * base::Time::kMicrosecondsPerSecond /
    696       audio_parameters_.sample_rate());
    697 
    698   lock_.AssertAcquired();
    699   earliest_end_time_ = std::max(
    700       earliest_end_time_, time_now + playback_delay + predicted_play_time);
    701 }
    702 
    703 void AudioRendererImpl::OnRenderError() {
    704   // UMA data tells us this happens ~0.01% of the time. Trigger an error instead
    705   // of trying to gracefully fall back to a fake sink. It's very likely
    706   // OnRenderError() should be removed and the audio stack handle errors without
    707   // notifying clients. See http://crbug.com/234708 for details.
    708   HistogramRendererEvent(RENDER_ERROR);
    709   error_cb_.Run(PIPELINE_ERROR_DECODE);
    710 }
    711 
    712 void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
    713   lock_.AssertAcquired();
    714 
    715   PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK;
    716   switch (state_) {
    717     case kUninitialized:
    718     case kInitializing:
    719       NOTREACHED();
    720       return;
    721     case kFlushing:
    722       ChangeState_Locked(kFlushed);
    723 
    724       if (status == PIPELINE_OK) {
    725         DoFlush_Locked();
    726         return;
    727       }
    728 
    729       error_cb_.Run(status);
    730       base::ResetAndReturn(&flush_cb_).Run();
    731       return;
    732     case kPrerolling:
    733       // This is a signal for abort if it's not an error.
    734       preroll_aborted_ = !is_decode_error;
    735       ChangeState_Locked(kPlaying);
    736       base::ResetAndReturn(&preroll_cb_).Run(status);
    737       return;
    738     case kFlushed:
    739     case kPlaying:
    740     case kUnderflow:
    741     case kRebuffering:
    742     case kStopped:
    743       if (status != PIPELINE_OK)
    744         error_cb_.Run(status);
    745       return;
    746   }
    747 }
    748 
    749 void AudioRendererImpl::ChangeState_Locked(State new_state) {
    750   DVLOG(1) << __FUNCTION__ << " : " << state_ << " -> " << new_state;
    751   lock_.AssertAcquired();
    752   state_ = new_state;
    753 }
    754 
    755 void AudioRendererImpl::OnNewSpliceBuffer(base::TimeDelta splice_timestamp) {
    756   DCHECK(task_runner_->BelongsToCurrentThread());
    757   splicer_->SetSpliceTimestamp(splice_timestamp);
    758 }
    759 
    760 void AudioRendererImpl::OnConfigChange() {
    761   DCHECK(task_runner_->BelongsToCurrentThread());
    762   DCHECK(expecting_config_changes_);
    763   buffer_converter_->ResetTimestampState();
    764   // Drain flushed buffers from the converter so the AudioSplicer receives all
    765   // data ahead of any OnNewSpliceBuffer() calls.  Since discontinuities should
    766   // only appear after config changes, AddInput() should never fail here.
    767   while (buffer_converter_->HasNextBuffer())
    768     CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer()));
    769 }
    770 
    771 }  // namespace media
    772