| Index: media/audio/linux/alsa_output.cc
|
| diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
|
| index 1ecd685d14e2bc3aa0ba913a35dc41daad02d521..0726effc9efe62cc48d78c60cb2fc8ec964387ea 100644
|
| --- a/media/audio/linux/alsa_output.cc
|
| +++ b/media/audio/linux/alsa_output.cc
|
| @@ -474,21 +474,25 @@ void AlsaPcmOutputStream::BufferPacket(Packet* packet) {
|
| if (packet->used >= packet->size) {
|
| // Before making a request to source for data. We need to determine the
|
| // delay (in bytes) for the requested data to be played.
|
| - snd_pcm_sframes_t delay;
|
| - int error = wrapper_->PcmDelay(playback_handle_, &delay);
|
| - if (error < 0) {
|
| - error = wrapper_->PcmRecover(playback_handle_,
|
| - error,
|
| - kPcmRecoverIsSilent);
|
| - if (error < 0) {
|
| - LOG(ERROR) << "Failed querying delay: " << wrapper_->StrError(error);
|
| + snd_pcm_sframes_t delay = 0;
|
| +
|
| + // Don't query ALSA's delay if we have underrun since it'll be jammed at
|
| + // some non-zero value and potentially even negative!
|
| + if (wrapper_->PcmState(playback_handle_) != SND_PCM_STATE_XRUN) {
|
| + int error = wrapper_->PcmDelay(playback_handle_, &delay);
|
| + if (error >= 0) {
|
| + // Convert frames to bytes, but watch out for those negatives!
|
| + delay = (delay < 0 ? 0 : delay) * bytes_per_output_frame_;
|
| + } else {
|
| + // Assume a delay of zero and attempt to recover the device.
|
| + delay = 0;
|
| + error = wrapper_->PcmRecover(playback_handle_,
|
| + error,
|
| + kPcmRecoverIsSilent);
|
| + if (error < 0) {
|
| + LOG(ERROR) << "Failed querying delay: " << wrapper_->StrError(error);
|
| + }
|
| }
|
| -
|
| - // TODO(hclam): If we cannot query the delay, we may want to stop
|
| - // the playback and report an error.
|
| - delay = 0;
|
| - } else {
|
| - delay *= bytes_per_output_frame_;
|
| }
|
|
|
| packet->used = 0;
|
|
|