// Copyright 2013 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 "content/renderer/media/webrtc_audio_device_impl.h"

#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/trace_event/trace_event.h"
#include "content/renderer/media/webrtc/processed_local_audio_source.h"
#include "content/renderer/media/webrtc_audio_renderer.h"
#include "media/audio/sample_rates.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_parameters.h"

#if defined(OS_WIN)
#include "base/win/windows_version.h"
#endif

using media::AudioParameters;
using media::ChannelLayout;

namespace content {

WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
    : ref_count_(0),
      audio_transport_callback_(NULL),
      output_delay_ms_(0),
      initialized_(false),
      playing_(false),
      recording_(false) {
  DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()";
  // This object can be constructed on either the signaling thread or the main
  // thread, so we need to detach these thread checkers here and have them
  // initialize automatically when the first methods are called.
  signaling_thread_checker_.DetachFromThread();
  main_thread_checker_.DetachFromThread();

  worker_thread_checker_.DetachFromThread();
  audio_renderer_thread_checker_.DetachFromThread();
}

WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()";
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(!initialized_) << "Terminate must have been called.";
}

int32_t WebRtcAudioDeviceImpl::AddRef() const {
  // We can be AddRefed and released on both the UI thread as well as
  // libjingle's signaling thread.
  return base::subtle::Barrier_AtomicIncrement(&ref_count_, 1);
}

int32_t WebRtcAudioDeviceImpl::Release() const {
  // We can be AddRefed and released on both the UI thread as well as
  // libjingle's signaling thread.
  int ret = base::subtle::Barrier_AtomicIncrement(&ref_count_, -1);
  if (ret == 0) {
    delete this;
  }
  return ret;
}

void WebRtcAudioDeviceImpl::RenderData(media::AudioBus* audio_bus,
                                       int sample_rate,
                                       int audio_delay_milliseconds,
                                       base::TimeDelta* current_time) {
  {
    base::AutoLock auto_lock(lock_);
#if DCHECK_IS_ON()
    DCHECK(renderer_->CurrentThreadIsRenderingThread());
    if (!audio_renderer_thread_checker_.CalledOnValidThread()) {
      for (auto* sink : playout_sinks_)
        sink->OnRenderThreadChanged();
    }
#endif
    if (!playing_) {
      // Force silence to AudioBus after stopping playout in case
      // there is lingering audio data in AudioBus.
      audio_bus->Zero();
      return;
    }
    DCHECK(audio_transport_callback_);
    // Store the reported audio delay locally.
    output_delay_ms_ = audio_delay_milliseconds;
  }

  render_buffer_.resize(audio_bus->frames() * audio_bus->channels());
  int frames_per_10_ms = (sample_rate / 100);
  int bytes_per_sample = sizeof(render_buffer_[0]);
  // Client should always ask for 10ms.
  DCHECK_EQ(audio_bus->frames(), frames_per_10_ms);

  // Get 10ms audio and copy result to temporary byte buffer.
  int64_t elapsed_time_ms = -1;
  int64_t ntp_time_ms = -1;
  static const int kBitsPerByte = 8;
  int16_t* audio_data = &render_buffer_[0];

  TRACE_EVENT_BEGIN0("audio", "VoE::PullRenderData");
  audio_transport_callback_->PullRenderData(
      bytes_per_sample * kBitsPerByte, sample_rate, audio_bus->channels(),
      frames_per_10_ms, audio_data, &elapsed_time_ms, &ntp_time_ms);
  TRACE_EVENT_END0("audio", "VoE::PullRenderData");
  if (elapsed_time_ms >= 0) {
    *current_time = base::TimeDelta::FromMilliseconds(elapsed_time_ms);
  }

  // De-interleave each channel and convert to 32-bit floating-point
  // with nominal range -1.0 -> +1.0 to match the callback format.
  audio_bus->FromInterleaved(&render_buffer_[0],
                             audio_bus->frames(),
                             bytes_per_sample);

  // Pass the render data to the playout sinks.
  base::AutoLock auto_lock(lock_);
  for (PlayoutDataSinkList::const_iterator it = playout_sinks_.begin();
       it != playout_sinks_.end(); ++it) {
    (*it)->OnPlayoutData(audio_bus, sample_rate, audio_delay_milliseconds);
  }
}

void WebRtcAudioDeviceImpl::RemoveAudioRenderer(WebRtcAudioRenderer* renderer) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  DCHECK_EQ(renderer, renderer_.get());
  // Notify the playout sink of the change.
  for (PlayoutDataSinkList::const_iterator it = playout_sinks_.begin();
       it != playout_sinks_.end(); ++it) {
    (*it)->OnPlayoutDataSourceChanged();
  }

  renderer_ = NULL;
}

void WebRtcAudioDeviceImpl::AudioRendererThreadStopped() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  audio_renderer_thread_checker_.DetachFromThread();
  // Notify the playout sink of the change.
  // Not holding |lock_| because the caller must guarantee that the audio
  // renderer thread is dead, so no race is possible with |playout_sinks_|
  for (auto* sink : playout_sinks_)
    sink->OnPlayoutDataSourceChanged();
}

int32_t WebRtcAudioDeviceImpl::RegisterAudioCallback(
    webrtc::AudioTransport* audio_callback) {
  DVLOG(1) << "WebRtcAudioDeviceImpl::RegisterAudioCallback()";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  DCHECK_EQ(audio_transport_callback_ == NULL, audio_callback != NULL);
  audio_transport_callback_ = audio_callback;
  return 0;
}

int32_t WebRtcAudioDeviceImpl::Init() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::Init()";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());

  // We need to return a success to continue the initialization of WebRtc VoE
  // because failure on the capturer_ initialization should not prevent WebRTC
  // from working. See issue http://crbug.com/144421 for details.
  initialized_ = true;

  return 0;
}

int32_t WebRtcAudioDeviceImpl::Terminate() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::Terminate()";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());

  // Calling Terminate() multiple times in a row is OK.
  if (!initialized_)
    return 0;

  StopRecording();
  StopPlayout();

  DCHECK(!renderer_.get() || !renderer_->IsStarted())
      << "The shared audio renderer shouldn't be running";

  {
    base::AutoLock auto_lock(lock_);
    capturers_.clear();
  }

  initialized_ = false;
  return 0;
}

bool WebRtcAudioDeviceImpl::Initialized() const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  return initialized_;
}

int32_t WebRtcAudioDeviceImpl::PlayoutIsAvailable(bool* available) {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  *available = initialized_;
  return 0;
}

bool WebRtcAudioDeviceImpl::PlayoutIsInitialized() const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  return initialized_;
}

int32_t WebRtcAudioDeviceImpl::RecordingIsAvailable(bool* available) {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  *available = (!capturers_.empty());
  return 0;
}

bool WebRtcAudioDeviceImpl::RecordingIsInitialized() const {
  DVLOG(1) << "WebRtcAudioDeviceImpl::RecordingIsInitialized()";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  return (!capturers_.empty());
}

int32_t WebRtcAudioDeviceImpl::StartPlayout() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::StartPlayout()";
  DCHECK(worker_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  if (!audio_transport_callback_) {
    LOG(ERROR) << "Audio transport is missing";
    return 0;
  }

  // webrtc::VoiceEngine assumes that it is OK to call Start() twice and
  // that the call is ignored the second time.
  playing_ = true;
  return 0;
}

int32_t WebRtcAudioDeviceImpl::StopPlayout() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::StopPlayout()";
  DCHECK(initialized_);
  // Can be called both from the worker thread (e.g. when called from webrtc)
  // or the signaling thread (e.g. when we call it ourselves internally).
  // The order in this check is important so that we won't incorrectly
  // initialize worker_thread_checker_ on the signaling thread.
  DCHECK(signaling_thread_checker_.CalledOnValidThread() ||
         worker_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  // webrtc::VoiceEngine assumes that it is OK to call Stop() multiple times.
  playing_ = false;
  return 0;
}

bool WebRtcAudioDeviceImpl::Playing() const {
  DCHECK(worker_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  return playing_;
}

int32_t WebRtcAudioDeviceImpl::StartRecording() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::StartRecording()";
  DCHECK(worker_thread_checker_.CalledOnValidThread());
  DCHECK(initialized_);
  base::AutoLock auto_lock(lock_);
  if (!audio_transport_callback_) {
    LOG(ERROR) << "Audio transport is missing";
    return -1;
  }

  recording_ = true;

  return 0;
}

int32_t WebRtcAudioDeviceImpl::StopRecording() {
  DVLOG(1) << "WebRtcAudioDeviceImpl::StopRecording()";
  DCHECK(initialized_);
  // Can be called both from the worker thread (e.g. when called from webrtc)
  // or the signaling thread (e.g. when we call it ourselves internally).
  // The order in this check is important so that we won't incorrectly
  // initialize worker_thread_checker_ on the signaling thread.
  DCHECK(signaling_thread_checker_.CalledOnValidThread() ||
         worker_thread_checker_.CalledOnValidThread());

  base::AutoLock auto_lock(lock_);
  recording_ = false;
  return 0;
}

bool WebRtcAudioDeviceImpl::Recording() const {
  DCHECK(worker_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  return recording_;
}

int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) {
  DVLOG(1) << "WebRtcAudioDeviceImpl::SetMicrophoneVolume(" << volume << ")";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  DCHECK(initialized_);

  // Only one microphone is supported at the moment, which is represented by
  // the default capturer.
  base::AutoLock auto_lock(lock_);
  if (capturers_.empty())
    return -1;
  capturers_.back()->SetVolume(volume);
  return 0;
}

// TODO(henrika): sort out calling thread once we start using this API.
int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const {
  DVLOG(1) << "WebRtcAudioDeviceImpl::MicrophoneVolume()";
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  // We only support one microphone now, which is accessed via the default
  // capturer.
  DCHECK(initialized_);
  base::AutoLock auto_lock(lock_);
  if (capturers_.empty())
    return -1;
  *volume = static_cast<uint32_t>(capturers_.back()->Volume());
  return 0;
}

int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume(uint32_t* max_volume) const {
  DCHECK(initialized_);
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  *max_volume = kMaxVolumeLevel;
  return 0;
}

int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  *min_volume = 0;
  return 0;
}

int32_t WebRtcAudioDeviceImpl::StereoPlayoutIsAvailable(bool* available) const {
  DCHECK(initialized_);
  // This method is called during initialization on the signaling thread and
  // then later on the worker thread.  Due to this we cannot DCHECK on what
  // thread we're on since it might incorrectly initialize the
  // worker_thread_checker_.
  base::AutoLock auto_lock(lock_);
  *available = renderer_.get() && renderer_->channels() == 2;
  return 0;
}

int32_t WebRtcAudioDeviceImpl::StereoRecordingIsAvailable(
    bool* available) const {
  DCHECK(initialized_);
  // This method is called during initialization on the signaling thread and
  // then later on the worker thread.  Due to this we cannot DCHECK on what
  // thread we're on since it might incorrectly initialize the
  // worker_thread_checker_.

  // TODO(xians): These kind of hardware methods do not make much sense since we
  // support multiple sources. Remove or figure out new APIs for such methods.
  base::AutoLock auto_lock(lock_);
  if (capturers_.empty())
    return -1;
  *available = (capturers_.back()->GetInputFormat().channels() == 2);
  return 0;
}

int32_t WebRtcAudioDeviceImpl::PlayoutDelay(uint16_t* delay_ms) const {
  DCHECK(worker_thread_checker_.CalledOnValidThread());
  base::AutoLock auto_lock(lock_);
  *delay_ms = static_cast<uint16_t>(output_delay_ms_);
  return 0;
}

int32_t WebRtcAudioDeviceImpl::RecordingDelay(uint16_t* delay_ms) const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());

  // There is no way to report a correct delay value to WebRTC since there
  // might be multiple ProcessedLocalAudioSource instances.
  NOTREACHED();
  return -1;
}

int32_t WebRtcAudioDeviceImpl::RecordingSampleRate(
    uint32_t* sample_rate) const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  // We use the default capturer as the recording sample rate.
  base::AutoLock auto_lock(lock_);
  if (capturers_.empty())
    return -1;
  const media::AudioParameters& params = capturers_.back()->GetInputFormat();
  *sample_rate = static_cast<uint32_t>(params.sample_rate());
  return 0;
}

int32_t WebRtcAudioDeviceImpl::PlayoutSampleRate(
    uint32_t* sample_rate) const {
  DCHECK(signaling_thread_checker_.CalledOnValidThread());
  *sample_rate = renderer_.get() ? renderer_->sample_rate() : 0;
  return 0;
}

bool WebRtcAudioDeviceImpl::SetAudioRenderer(WebRtcAudioRenderer* renderer) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(renderer);

  // Here we acquire |lock_| in order to protect the internal state.
  {
    base::AutoLock auto_lock(lock_);
    if (renderer_.get())
      return false;
  }

  // We release |lock_| here because invoking |renderer|->Initialize while
  // holding |lock_| would result in locks taken in the sequence
  // (|this->lock_|,  |renderer->lock_|) while another thread (i.e, the
  // AudioOutputDevice thread) might concurrently invoke a renderer method,
  // which can itself invoke a method from |this|, resulting in locks taken in
  // the sequence (|renderer->lock_|, |this->lock_|) in that thread.
  // This order discrepancy can cause a deadlock (see Issue 433993).
  // However, we do not need to hold |this->lock_| in order to invoke
  // |renderer|->Initialize, since it does not involve any unprotected access to
  // the internal state of |this|.
  if (!renderer->Initialize(this))
    return false;

  // The new audio renderer will create a new audio renderer thread. Detach
  // |audio_renderer_thread_checker_| from the old thread, if any, and let
  // it attach later to the new thread.
  audio_renderer_thread_checker_.DetachFromThread();

  // We acquire |lock_| again and assert our precondition, since we are
  // accessing the internal state again.
  base::AutoLock auto_lock(lock_);
  DCHECK(!renderer_.get());
  renderer_ = renderer;
  return true;
}

void WebRtcAudioDeviceImpl::AddAudioCapturer(
    ProcessedLocalAudioSource* capturer) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DVLOG(1) << "WebRtcAudioDeviceImpl::AddAudioCapturer()";
  DCHECK(capturer);
  DCHECK(!capturer->device_info().device.id.empty());

  base::AutoLock auto_lock(lock_);
  DCHECK(std::find(capturers_.begin(), capturers_.end(), capturer) ==
      capturers_.end());
  capturers_.push_back(capturer);
}

void WebRtcAudioDeviceImpl::RemoveAudioCapturer(
    ProcessedLocalAudioSource* capturer) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DVLOG(1) << "WebRtcAudioDeviceImpl::RemoveAudioCapturer()";
  DCHECK(capturer);
  base::AutoLock auto_lock(lock_);
  capturers_.remove(capturer);
}

void WebRtcAudioDeviceImpl::AddPlayoutSink(
    WebRtcPlayoutDataSource::Sink* sink) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(sink);
  base::AutoLock auto_lock(lock_);
  DCHECK(std::find(playout_sinks_.begin(), playout_sinks_.end(), sink) ==
      playout_sinks_.end());
  playout_sinks_.push_back(sink);
}

void WebRtcAudioDeviceImpl::RemovePlayoutSink(
    WebRtcPlayoutDataSource::Sink* sink) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(sink);
  base::AutoLock auto_lock(lock_);
  playout_sinks_.remove(sink);
}

bool WebRtcAudioDeviceImpl::GetAuthorizedDeviceInfoForAudioRenderer(
    int* session_id,
    int* output_sample_rate,
    int* output_frames_per_buffer) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  base::AutoLock lock(lock_);
  // If there is no capturer or there are more than one open capture devices,
  // return false.
  if (capturers_.size() != 1)
    return false;

  // Don't set output parameters unless all of them are valid.
  const StreamDeviceInfo& device_info = capturers_.back()->device_info();
  if (device_info.session_id <= 0 ||
      !device_info.device.matched_output.sample_rate() ||
      !device_info.device.matched_output.frames_per_buffer()) {
    return false;
  }

  *session_id = device_info.session_id;
  *output_sample_rate = device_info.device.matched_output.sample_rate();
  *output_frames_per_buffer =
      device_info.device.matched_output.frames_per_buffer();

  return true;
}

}  // namespace content
