// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/renderer/media/cast_receiver_audio_valve.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "media/audio/audio_parameters.h" CastReceiverAudioValve::CastReceiverAudioValve( const media::AudioParameters& params, media::AudioCapturerSource::CaptureCallback* cb) : cb_(cb), fifo_(base::Bind(&CastReceiverAudioValve::DeliverRebufferedAudio, base::Unretained(this))), sample_rate_(params.sample_rate()) { fifo_.Reset(params.frames_per_buffer()); } CastReceiverAudioValve::~CastReceiverAudioValve() {} void CastReceiverAudioValve::DeliverDecodedAudio( const media::AudioBus* audio_bus, base::TimeTicks playout_time) { current_playout_time_ = playout_time; // The following will result in zero, one, or multiple synchronous calls to // DeliverRebufferedAudio(). fifo_.Push(*audio_bus); } void CastReceiverAudioValve::DeliverRebufferedAudio( const media::AudioBus& audio_bus, int frame_delay) { const base::TimeTicks playout_time = current_playout_time_ + base::TimeDelta::FromMicroseconds( frame_delay * base::Time::kMicrosecondsPerSecond / sample_rate_); base::AutoLock lock(lock_); if (cb_) { // The AudioCapturerSource::Callback interface provides timing information // only as a relative delay value that means "captured N milliseconds ago." // Therefore, translate the playout time to these semantics. Since playout // time is generally in the future, because audio should be decoded well // ahead of when it should be played out, the audio delay value will // generally be negative. // // TimeTicks::Now() is being called after the |lock_| was acquired in order // to provide the most accurate delay value. const int audio_delay_milliseconds = (base::TimeTicks::Now() - playout_time).InMilliseconds(); cb_->Capture(&audio_bus, audio_delay_milliseconds, 1.0 /* volume */, false /* key_pressed */); } } void CastReceiverAudioValve::Stop() { base::AutoLock lock(lock_); cb_ = nullptr; }