/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_device/win/core_audio_base_win.h"
#include "modules/audio_device/audio_device_buffer.h"

#include <string>

#include "absl/memory/memory.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/time_utils.h"
#include "rtc_base/win/windows_version.h"

using Microsoft::WRL::ComPtr;

namespace webrtc {
namespace webrtc_win {
namespace {

// Even if the device supports low latency and even if IAudioClient3 can be
// used (requires Win10 or higher), we currently disable any attempts to
// initialize the client for low-latency.
// TODO(henrika): more research is needed before we can enable low-latency.
const bool kEnableLowLatencyIfSupported = false;

// Each unit of reference time is 100 nanoseconds, hence |kReftimesPerSec|
// corresponds to one second.
// TODO(henrika): possibly add usage in Init().
// const REFERENCE_TIME kReferenceTimesPerSecond = 10000000;

enum DefaultDeviceType {
  kUndefined = -1,
  kDefault = 0,
  kDefaultCommunications = 1,
  kDefaultDeviceTypeMaxCount = kDefaultCommunications + 1,
};

const char* DirectionToString(CoreAudioBase::Direction direction) {
  switch (direction) {
    case CoreAudioBase::Direction::kOutput:
      return "Output";
    case CoreAudioBase::Direction::kInput:
      return "Input";
    default:
      return "Unkown";
  }
}

const char* SessionStateToString(AudioSessionState state) {
  switch (state) {
    case AudioSessionStateActive:
      return "Active";
    case AudioSessionStateInactive:
      return "Inactive";
    case AudioSessionStateExpired:
      return "Expired";
    default:
      return "Invalid";
  }
}

const char* SessionDisconnectReasonToString(
    AudioSessionDisconnectReason reason) {
  switch (reason) {
    case DisconnectReasonDeviceRemoval:
      return "DeviceRemoval";
    case DisconnectReasonServerShutdown:
      return "ServerShutdown";
    case DisconnectReasonFormatChanged:
      return "FormatChanged";
    case DisconnectReasonSessionLogoff:
      return "SessionLogoff";
    case DisconnectReasonSessionDisconnected:
      return "Disconnected";
    case DisconnectReasonExclusiveModeOverride:
      return "ExclusiveModeOverride";
    default:
      return "Invalid";
  }
}

void Run(void* obj) {
  RTC_DCHECK(obj);
  reinterpret_cast<CoreAudioBase*>(obj)->ThreadRun();
}

// Returns true if the selected audio device supports low latency, i.e, if it
// is possible to initialize the engine using periods less than the default
// period (10ms).
bool IsLowLatencySupported(IAudioClient3* client3,
                           const WAVEFORMATEXTENSIBLE* format,
                           uint32_t* min_period_in_frames) {
  RTC_DLOG(INFO) << __FUNCTION__;

  // Get the range of periodicities supported by the engine for the specified
  // stream format.
  uint32_t default_period = 0;
  uint32_t fundamental_period = 0;
  uint32_t min_period = 0;
  uint32_t max_period = 0;
  if (FAILED(core_audio_utility::GetSharedModeEnginePeriod(
          client3, format, &default_period, &fundamental_period, &min_period,
          &max_period))) {
    return false;
  }

  // Low latency is supported if the shortest allowed period is less than the
  // default engine period.
  // TODO(henrika): verify that this assumption is correct.
  const bool low_latency = min_period < default_period;
  RTC_LOG(INFO) << "low_latency: " << low_latency;
  *min_period_in_frames = low_latency ? min_period : 0;
  return low_latency;
}

}  // namespace

CoreAudioBase::CoreAudioBase(Direction direction,
                             OnDataCallback data_callback,
                             OnErrorCallback error_callback)
    : format_(),
      direction_(direction),
      on_data_callback_(data_callback),
      on_error_callback_(error_callback),
      device_index_(kUndefined),
      is_restarting_(false) {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction) << "]";
  RTC_DLOG(INFO) << "Windows version: " << rtc::rtc_win::GetVersion();

  // Create the event which the audio engine will signal each time a buffer
  // becomes ready to be processed by the client.
  audio_samples_event_.Set(CreateEvent(nullptr, false, false, nullptr));
  RTC_DCHECK(audio_samples_event_.IsValid());

  // Event to be set in Stop() when rendering/capturing shall stop.
  stop_event_.Set(CreateEvent(nullptr, false, false, nullptr));
  RTC_DCHECK(stop_event_.IsValid());

  // Event to be set when it has been detected that an active device has been
  // invalidated or the stream format has changed.
  restart_event_.Set(CreateEvent(nullptr, false, false, nullptr));
  RTC_DCHECK(restart_event_.IsValid());
}

CoreAudioBase::~CoreAudioBase() {
  RTC_DLOG(INFO) << __FUNCTION__;
  RTC_DCHECK_EQ(ref_count_, 1);
}

EDataFlow CoreAudioBase::GetDataFlow() const {
  return direction_ == CoreAudioBase::Direction::kOutput ? eRender : eCapture;
}

bool CoreAudioBase::IsRestarting() const {
  return is_restarting_;
}

int64_t CoreAudioBase::TimeSinceStart() const {
  return rtc::TimeSince(start_time_);
}

int CoreAudioBase::NumberOfActiveDevices() const {
  return core_audio_utility::NumberOfActiveDevices(GetDataFlow());
}

int CoreAudioBase::NumberOfEnumeratedDevices() const {
  const int num_active = NumberOfActiveDevices();
  return num_active > 0 ? num_active + kDefaultDeviceTypeMaxCount : 0;
}

void CoreAudioBase::ReleaseCOMObjects() {
  RTC_DLOG(INFO) << __FUNCTION__;
  // ComPtr::Reset() sets the ComPtr to nullptr releasing any previous
  // reference.
  if (audio_client_) {
    audio_client_.Reset();
  }
  if (audio_clock_.Get()) {
    audio_clock_.Reset();
  }
  if (audio_session_control_.Get()) {
    audio_session_control_.Reset();
  }
}

bool CoreAudioBase::IsDefaultDevice(int index) const {
  return index == kDefault;
}

bool CoreAudioBase::IsDefaultCommunicationsDevice(int index) const {
  return index == kDefaultCommunications;
}

bool CoreAudioBase::IsDefaultDevice(const std::string& device_id) const {
  return (IsInput() &&
          (device_id == core_audio_utility::GetDefaultInputDeviceID())) ||
         (IsOutput() &&
          (device_id == core_audio_utility::GetDefaultOutputDeviceID()));
}

bool CoreAudioBase::IsDefaultCommunicationsDevice(
    const std::string& device_id) const {
  return (IsInput() &&
          (device_id ==
           core_audio_utility::GetCommunicationsInputDeviceID())) ||
         (IsOutput() &&
          (device_id == core_audio_utility::GetCommunicationsOutputDeviceID()));
}

bool CoreAudioBase::IsInput() const {
  return direction_ == CoreAudioBase::Direction::kInput;
}

bool CoreAudioBase::IsOutput() const {
  return direction_ == CoreAudioBase::Direction::kOutput;
}

std::string CoreAudioBase::GetDeviceID(int index) const {
  if (index >= NumberOfEnumeratedDevices()) {
    RTC_LOG(LS_ERROR) << "Invalid device index";
    return std::string();
  }

  std::string device_id;
  if (IsDefaultDevice(index)) {
    device_id = IsInput() ? core_audio_utility::GetDefaultInputDeviceID()
                          : core_audio_utility::GetDefaultOutputDeviceID();
  } else if (IsDefaultCommunicationsDevice(index)) {
    device_id = IsInput()
                    ? core_audio_utility::GetCommunicationsInputDeviceID()
                    : core_audio_utility::GetCommunicationsOutputDeviceID();
  } else {
    AudioDeviceNames device_names;
    bool ok = IsInput()
                  ? core_audio_utility::GetInputDeviceNames(&device_names)
                  : core_audio_utility::GetOutputDeviceNames(&device_names);
    if (ok) {
      device_id = device_names[index].unique_id;
    }
  }
  return device_id;
}

int CoreAudioBase::SetDevice(int index) {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  if (initialized_) {
    return -1;
  }

  std::string device_id = GetDeviceID(index);
  RTC_DLOG(INFO) << "index=" << index << " => device_id: " << device_id;
  device_index_ = index;
  device_id_ = device_id;

  return device_id_.empty() ? -1 : 0;
}

int CoreAudioBase::DeviceName(int index,
                              std::string* name,
                              std::string* guid) const {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  if (index > NumberOfEnumeratedDevices() - 1) {
    RTC_LOG(LS_ERROR) << "Invalid device index";
    return -1;
  }

  AudioDeviceNames device_names;
  bool ok = IsInput() ? core_audio_utility::GetInputDeviceNames(&device_names)
                      : core_audio_utility::GetOutputDeviceNames(&device_names);
  if (!ok) {
    RTC_LOG(LS_ERROR) << "Failed to get the device name";
    return -1;
  }

  *name = device_names[index].device_name;
  RTC_DLOG(INFO) << "name: " << *name;
  if (guid != nullptr) {
    *guid = device_names[index].unique_id;
    RTC_DLOG(INFO) << "guid: " << guid;
  }
  return 0;
}

bool CoreAudioBase::Init() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  RTC_DCHECK(!device_id_.empty());
  RTC_DCHECK(audio_device_buffer_);
  RTC_DCHECK(!audio_client_);
  RTC_DCHECK(!audio_session_control_.Get());

  // Use an existing |device_id_| and set parameters which are required to
  // create an audio client. It is up to the parent class to set |device_id_|.
  std::string device_id = device_id_;
  ERole role = eConsole;
  if (IsDefaultDevice(device_id)) {
    device_id = AudioDeviceName::kDefaultDeviceId;
    role = eConsole;
  } else if (IsDefaultCommunicationsDevice(device_id)) {
    device_id = AudioDeviceName::kDefaultCommunicationsDeviceId;
    role = eCommunications;
  } else {
    RTC_DLOG(LS_WARNING) << "Not using a default device";
  }

  // Create an IAudioClient interface which enables us to create and initialize
  // an audio stream between an audio application and the audio engine.
  ComPtr<IAudioClient> audio_client;
  if (core_audio_utility::GetAudioClientVersion() == 3) {
    RTC_DLOG(INFO) << "Using IAudioClient3";
    audio_client =
        core_audio_utility::CreateClient3(device_id, GetDataFlow(), role);
  } else if (core_audio_utility::GetAudioClientVersion() == 2) {
    RTC_DLOG(INFO) << "Using IAudioClient2";
    audio_client =
        core_audio_utility::CreateClient2(device_id, GetDataFlow(), role);
  } else {
    RTC_DLOG(INFO) << "Using IAudioClient";
    audio_client =
        core_audio_utility::CreateClient(device_id, GetDataFlow(), role);
  }
  if (!audio_client) {
    return false;
  }

  // Set extra client properties before initialization if the audio client
  // supports it.
  // TODO(henrika): evaluate effect(s) of making these changes. Also, perhaps
  // these types of settings belongs to the client and not the utility parts.
  if (core_audio_utility::GetAudioClientVersion() >= 2) {
    if (FAILED(core_audio_utility::SetClientProperties(
            static_cast<IAudioClient2*>(audio_client.Get())))) {
      return false;
    }
  }

  // Retrieve preferred audio input or output parameters for the given client
  // and the specified client properties. Override the preferred rate if sample
  // rate has been defined by the user. Rate conversion will be performed by
  // the audio engine to match the client if needed.
  AudioParameters params;
  HRESULT res = sample_rate_ ? core_audio_utility::GetPreferredAudioParameters(
                                   audio_client.Get(), &params, *sample_rate_)
                             : core_audio_utility::GetPreferredAudioParameters(
                                   audio_client.Get(), &params);
  if (FAILED(res)) {
    return false;
  }

  // Define the output WAVEFORMATEXTENSIBLE format in |format_|.
  WAVEFORMATEX* format = &format_.Format;
  format->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
  // Check the preferred channel configuration and request implicit channel
  // upmixing (audio engine extends from 2 to N channels internally) if the
  // preferred number of channels is larger than two; i.e., initialize the
  // stream in stereo even if the preferred configuration is multi-channel.
  if (params.channels() <= 2) {
    format->nChannels = rtc::dchecked_cast<WORD>(params.channels());
  } else {
    // TODO(henrika): ensure that this approach works on different multi-channel
    // devices. Verified on:
    // - Corsair VOID PRO Surround USB Adapter (supports 7.1)
    RTC_LOG(LS_WARNING)
        << "Using channel upmixing in WASAPI audio engine (2 => "
        << params.channels() << ")";
    format->nChannels = 2;
  }
  format->nSamplesPerSec = params.sample_rate();
  format->wBitsPerSample = rtc::dchecked_cast<WORD>(params.bits_per_sample());
  format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels;
  format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign;
  format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
  // Add the parts which are unique for the WAVE_FORMAT_EXTENSIBLE structure.
  format_.Samples.wValidBitsPerSample =
      rtc::dchecked_cast<WORD>(params.bits_per_sample());
  format_.dwChannelMask =
      format->nChannels == 1 ? KSAUDIO_SPEAKER_MONO : KSAUDIO_SPEAKER_STEREO;
  format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
  RTC_DLOG(INFO) << core_audio_utility::WaveFormatExToString(&format_);

  // Verify that the format is supported but exclude the test if the default
  // sample rate has been overridden. If so, the WASAPI audio engine will do
  // any necessary conversions between the client format we have given it and
  // the playback mix format or recording split format.
  if (!sample_rate_) {
    if (!core_audio_utility::IsFormatSupported(
            audio_client.Get(), AUDCLNT_SHAREMODE_SHARED, &format_)) {
      return false;
    }
  }

  // Check if low-latency is supported and use special initialization if it is.
  // Low-latency initialization requires these things:
  // - IAudioClient3 (>= Win10)
  // - HDAudio driver
  // - kEnableLowLatencyIfSupported changed from false (default) to true.
  // TODO(henrika): IsLowLatencySupported() returns AUDCLNT_E_UNSUPPORTED_FORMAT
  // when |sample_rate_.has_value()| returns true if rate conversion is
  // actually required (i.e., client asks for other than the default rate).
  bool low_latency_support = false;
  uint32_t min_period_in_frames = 0;
  if (kEnableLowLatencyIfSupported &&
      core_audio_utility::GetAudioClientVersion() >= 3) {
    low_latency_support =
        IsLowLatencySupported(static_cast<IAudioClient3*>(audio_client.Get()),
                              &format_, &min_period_in_frames);
  }

  if (low_latency_support) {
    RTC_DCHECK_GE(core_audio_utility::GetAudioClientVersion(), 3);
    // Use IAudioClient3::InitializeSharedAudioStream() API to initialize a
    // low-latency event-driven client. Request the smallest possible
    // periodicity.
    // TODO(henrika): evaluate this scheme in terms of CPU etc.
    if (FAILED(core_audio_utility::SharedModeInitializeLowLatency(
            static_cast<IAudioClient3*>(audio_client.Get()), &format_,
            audio_samples_event_, min_period_in_frames,
            sample_rate_.has_value(), &endpoint_buffer_size_frames_))) {
      return false;
    }
  } else {
    // Initialize the audio stream between the client and the device in shared
    // mode using event-driven buffer handling. Also, using 0 as requested
    // buffer size results in a default (minimum) endpoint buffer size.
    // TODO(henrika): possibly increase |requested_buffer_size| to add
    // robustness.
    const REFERENCE_TIME requested_buffer_size = 0;
    if (FAILED(core_audio_utility::SharedModeInitialize(
            audio_client.Get(), &format_, audio_samples_event_,
            requested_buffer_size, sample_rate_.has_value(),
            &endpoint_buffer_size_frames_))) {
      return false;
    }
  }

  // Check device period and the preferred buffer size and log a warning if
  // WebRTC's buffer size is not an even divisor of the preferred buffer size
  // in Core Audio.
  // TODO(henrika): sort out if a non-perfect match really is an issue.
  // TODO(henrika): compare with IAudioClient3::GetSharedModeEnginePeriod().
  REFERENCE_TIME device_period;
  if (FAILED(core_audio_utility::GetDevicePeriod(
          audio_client.Get(), AUDCLNT_SHAREMODE_SHARED, &device_period))) {
    return false;
  }
  const double device_period_in_seconds =
      static_cast<double>(
          core_audio_utility::ReferenceTimeToTimeDelta(device_period).ms()) /
      1000.0L;
  const int preferred_frames_per_buffer =
      static_cast<int>(params.sample_rate() * device_period_in_seconds + 0.5);
  RTC_DLOG(INFO) << "preferred_frames_per_buffer: "
                 << preferred_frames_per_buffer;
  if (preferred_frames_per_buffer % params.frames_per_buffer()) {
    RTC_LOG(WARNING) << "Buffer size of " << params.frames_per_buffer()
                     << " is not an even divisor of "
                     << preferred_frames_per_buffer;
  }

  // Create an AudioSessionControl interface given the initialized client.
  // The IAudioControl interface enables a client to configure the control
  // parameters for an audio session and to monitor events in the session.
  ComPtr<IAudioSessionControl> audio_session_control =
      core_audio_utility::CreateAudioSessionControl(audio_client.Get());
  if (!audio_session_control.Get()) {
    return false;
  }

  // The Sndvol program displays volume and mute controls for sessions that
  // are in the active and inactive states.
  AudioSessionState state;
  if (FAILED(audio_session_control->GetState(&state))) {
    return false;
  }
  RTC_DLOG(INFO) << "audio session state: " << SessionStateToString(state);
  RTC_DCHECK_EQ(state, AudioSessionStateInactive);

  // Register the client to receive notifications of session events, including
  // changes in the stream state.
  if (FAILED(audio_session_control->RegisterAudioSessionNotification(this))) {
    return false;
  }

  // Store valid COM interfaces.
  audio_client_ = audio_client;
  audio_session_control_ = audio_session_control;

  return true;
}

bool CoreAudioBase::Start() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  if (IsRestarting()) {
    // Audio thread should be alive during internal restart since the restart
    // callback is triggered on that thread and it also makes the restart
    // sequence less complex.
    RTC_DCHECK(audio_thread_);
  }

  // Start an audio thread but only if one does not already exist (which is the
  // case during restart).
  if (!audio_thread_) {
    audio_thread_ = absl::make_unique<rtc::PlatformThread>(
        Run, this, IsInput() ? "wasapi_capture_thread" : "wasapi_render_thread",
        rtc::kRealtimePriority);
    RTC_DCHECK(audio_thread_);
    audio_thread_->Start();
    if (!audio_thread_->IsRunning()) {
      StopThread();
      RTC_LOG(LS_ERROR) << "Failed to start audio thread";
      return false;
    }
    RTC_DLOG(INFO) << "Started thread with name: " << audio_thread_->name()
                   << " and id: " << audio_thread_->GetThreadRef();
  }

  // Start streaming data between the endpoint buffer and the audio engine.
  _com_error error = audio_client_->Start();
  if (FAILED(error.Error())) {
    StopThread();
    RTC_LOG(LS_ERROR) << "IAudioClient::Start failed: "
                      << core_audio_utility::ErrorToString(error);
    return false;
  }

  start_time_ = rtc::TimeMillis();
  num_data_callbacks_ = 0;

  return true;
}

bool CoreAudioBase::Stop() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  RTC_DLOG(INFO) << "total activity time: " << TimeSinceStart();

  // Stop audio streaming.
  _com_error error = audio_client_->Stop();
  if (FAILED(error.Error())) {
    RTC_LOG(LS_ERROR) << "IAudioClient::Stop failed: "
                      << core_audio_utility::ErrorToString(error);
  }
  // Stop and destroy the audio thread but only when a restart attempt is not
  // ongoing.
  if (!IsRestarting()) {
    StopThread();
  }

  // Flush all pending data and reset the audio clock stream position to 0.
  error = audio_client_->Reset();
  if (FAILED(error.Error())) {
    RTC_LOG(LS_ERROR) << "IAudioClient::Reset failed: "
                      << core_audio_utility::ErrorToString(error);
  }

  if (IsOutput()) {
    // Extra safety check to ensure that the buffers are cleared.
    // If the buffers are not cleared correctly, the next call to Start()
    // would fail with AUDCLNT_E_BUFFER_ERROR at
    // IAudioRenderClient::GetBuffer().
    UINT32 num_queued_frames = 0;
    audio_client_->GetCurrentPadding(&num_queued_frames);
    RTC_DCHECK_EQ(0u, num_queued_frames);
  }

  // Delete the previous registration by the client to receive notifications
  // about audio session events.
  RTC_DLOG(INFO) << "audio session state: "
                 << SessionStateToString(GetAudioSessionState());
  error = audio_session_control_->UnregisterAudioSessionNotification(this);
  if (FAILED(error.Error())) {
    RTC_LOG(LS_ERROR)
        << "IAudioSessionControl::UnregisterAudioSessionNotification failed: "
        << core_audio_utility::ErrorToString(error);
  }

  // To ensure that the restart process is as simple as possible, the audio
  // thread is not destroyed during restart attempts triggered by internal
  // error callbacks.
  if (!IsRestarting()) {
    thread_checker_audio_.Detach();
  }

  // Release all allocated COM interfaces to allow for a restart without
  // intermediate destruction.
  ReleaseCOMObjects();

  return true;
}

bool CoreAudioBase::IsVolumeControlAvailable(bool* available) const {
  // A valid IAudioClient is required to access the ISimpleAudioVolume interface
  // properly. It is possible to use IAudioSessionManager::GetSimpleAudioVolume
  // as well but we use the audio client here to ensure that the initialized
  // audio session is visible under group box labeled "Applications" in
  // Sndvol.exe.
  if (!audio_client_) {
    return false;
  }

  // Try to create an ISimpleAudioVolume instance.
  ComPtr<ISimpleAudioVolume> audio_volume =
      core_audio_utility::CreateSimpleAudioVolume(audio_client_.Get());
  if (!audio_volume.Get()) {
    RTC_DLOG(LS_ERROR) << "Volume control is not supported";
    return false;
  }

  // Try to use the valid volume control.
  float volume = 0.0;
  _com_error error = audio_volume->GetMasterVolume(&volume);
  if (error.Error() != S_OK) {
    RTC_LOG(LS_ERROR) << "ISimpleAudioVolume::GetMasterVolume failed: "
                      << core_audio_utility::ErrorToString(error);
    *available = false;
  }
  RTC_DLOG(INFO) << "master volume for output audio session: " << volume;

  *available = true;
  return false;
}

// Internal test method which can be used in tests to emulate a restart signal.
// It simply sets the same event which is normally triggered by session and
// device notifications. Hence, the emulated restart sequence covers most parts
// of a real sequence expect the actual device switch.
bool CoreAudioBase::Restart() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  is_restarting_ = true;
  SetEvent(restart_event_.Get());
  return true;
}

void CoreAudioBase::StopThread() {
  RTC_DLOG(INFO) << __FUNCTION__;
  RTC_DCHECK(!IsRestarting());
  if (audio_thread_) {
    if (audio_thread_->IsRunning()) {
      RTC_DLOG(INFO) << "Sets stop_event...";
      SetEvent(stop_event_.Get());
      RTC_DLOG(INFO) << "PlatformThread::Stop...";
      audio_thread_->Stop();
    }
    audio_thread_.reset();

    // Ensure that we don't quit the main thread loop immediately next
    // time Start() is called.
    ResetEvent(stop_event_.Get());
    ResetEvent(restart_event_.Get());
  }
}

bool CoreAudioBase::HandleRestartEvent() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  RTC_DCHECK_RUN_ON(&thread_checker_audio_);
  RTC_DCHECK(audio_thread_);
  RTC_DCHECK(IsRestarting());
  // Let each client (input and/or output) take care of its own restart
  // sequence since each side might need unique actions.
  // TODO(henrika): revisit and investigate if one common base implementation
  // is possible
  bool restart_ok = on_error_callback_(ErrorType::kStreamDisconnected);
  is_restarting_ = false;
  return restart_ok;
}

bool CoreAudioBase::SwitchDeviceIfNeeded() {
  RTC_DLOG(INFO) << __FUNCTION__ << "[" << DirectionToString(direction())
                 << "]";
  RTC_DCHECK_RUN_ON(&thread_checker_audio_);
  RTC_DCHECK(IsRestarting());

  RTC_DLOG(INFO) << "device_index=" << device_index_
                 << " => device_id: " << device_id_;

  // Ensure that at least one device exists and can be utilized. The most
  // probable cause for ending up here is that a device has been removed.
  if (core_audio_utility::NumberOfActiveDevices(IsInput() ? eCapture
                                                          : eRender) < 1) {
    RTC_DLOG(LS_ERROR) << "All devices are disabled or removed";
    return false;
  }

  // Get the unique device ID for the index which is currently used. It seems
  // safe to assume that if the ID is the same as the existing device ID, then
  // the device configuration is the same as before.
  std::string device_id = GetDeviceID(device_index_);
  if (device_id != device_id_) {
    RTC_LOG(LS_WARNING)
        << "Device configuration has changed => changing device selection...";
    // TODO(henrika): depending on the current state and how we got here, we
    // must select a new device here.
    if (SetDevice(kDefault) == -1) {
      RTC_LOG(LS_WARNING) << "Failed to set new audio device";
      return false;
    }
  } else {
    RTC_LOG(INFO)
        << "Device configuration has not changed => keeping selected device";
  }
  return true;
}

AudioSessionState CoreAudioBase::GetAudioSessionState() const {
  AudioSessionState state = AudioSessionStateInactive;
  RTC_DCHECK(audio_session_control_.Get());
  _com_error error = audio_session_control_->GetState(&state);
  if (FAILED(error.Error())) {
    RTC_DLOG(LS_ERROR) << "IAudioSessionControl::GetState failed: "
                       << core_audio_utility::ErrorToString(error);
  }
  return state;
}

// TODO(henrika): only used for debugging purposes currently.
ULONG CoreAudioBase::AddRef() {
  ULONG new_ref = InterlockedIncrement(&ref_count_);
  // RTC_DLOG(INFO) << "__AddRef => " << new_ref;
  return new_ref;
}

// TODO(henrika): does not call delete this.
ULONG CoreAudioBase::Release() {
  ULONG new_ref = InterlockedDecrement(&ref_count_);
  // RTC_DLOG(INFO) << "__Release => " << new_ref;
  return new_ref;
}

// TODO(henrika): can probably be replaced by "return S_OK" only.
HRESULT CoreAudioBase::QueryInterface(REFIID iid, void** object) {
  if (object == nullptr) {
    return E_POINTER;
  }
  if (iid == IID_IUnknown || iid == __uuidof(IAudioSessionEvents)) {
    *object = static_cast<IAudioSessionEvents*>(this);
    return S_OK;
  };
  *object = nullptr;
  return E_NOINTERFACE;
}

// IAudioSessionEvents::OnStateChanged.
HRESULT CoreAudioBase::OnStateChanged(AudioSessionState new_state) {
  RTC_DLOG(INFO) << "___" << __FUNCTION__ << "["
                 << DirectionToString(direction())
                 << "] new_state: " << SessionStateToString(new_state);
  return S_OK;
}

// When a session is disconnected because of a device removal or format change
// event, we want to inform the audio thread about the lost audio session and
// trigger an attempt to restart audio using a new (default) device.
HRESULT CoreAudioBase::OnSessionDisconnected(
    AudioSessionDisconnectReason disconnect_reason) {
  RTC_DLOG(INFO) << "___" << __FUNCTION__ << "["
                 << DirectionToString(direction()) << "] reason: "
                 << SessionDisconnectReasonToString(disconnect_reason);
  if (disconnect_reason == DisconnectReasonDeviceRemoval ||
      disconnect_reason == DisconnectReasonFormatChanged) {
    is_restarting_ = true;
    SetEvent(restart_event_.Get());
  }
  return S_OK;
}

// IAudioSessionEvents::OnDisplayNameChanged
HRESULT CoreAudioBase::OnDisplayNameChanged(LPCWSTR new_display_name,
                                            LPCGUID event_context) {
  return S_OK;
}

// IAudioSessionEvents::OnIconPathChanged
HRESULT CoreAudioBase::OnIconPathChanged(LPCWSTR new_icon_path,
                                         LPCGUID event_context) {
  return S_OK;
}

// IAudioSessionEvents::OnSimpleVolumeChanged
HRESULT CoreAudioBase::OnSimpleVolumeChanged(float new_simple_volume,
                                             BOOL new_mute,
                                             LPCGUID event_context) {
  return S_OK;
}

// IAudioSessionEvents::OnChannelVolumeChanged
HRESULT CoreAudioBase::OnChannelVolumeChanged(DWORD channel_count,
                                              float new_channel_volumes[],
                                              DWORD changed_channel,
                                              LPCGUID event_context) {
  return S_OK;
}

// IAudioSessionEvents::OnGroupingParamChanged
HRESULT CoreAudioBase::OnGroupingParamChanged(LPCGUID new_grouping_param,
                                              LPCGUID event_context) {
  return S_OK;
}

void CoreAudioBase::ThreadRun() {
  if (!core_audio_utility::IsMMCSSSupported()) {
    RTC_LOG(LS_ERROR) << "MMCSS is not supported";
    return;
  }
  RTC_DLOG(INFO) << "[" << DirectionToString(direction())
                 << "] ThreadRun starts...";
  // TODO(henrika): difference between "Pro Audio" and "Audio"?
  ScopedMMCSSRegistration mmcss_registration(L"Pro Audio");
  ScopedCOMInitializer com_initializer(ScopedCOMInitializer::kMTA);
  RTC_DCHECK(mmcss_registration.Succeeded());
  RTC_DCHECK(com_initializer.Succeeded());
  RTC_DCHECK(stop_event_.IsValid());
  RTC_DCHECK(audio_samples_event_.IsValid());

  bool streaming = true;
  bool error = false;
  HANDLE wait_array[] = {stop_event_.Get(), restart_event_.Get(),
                         audio_samples_event_.Get()};

  // The device frequency is the frequency generated by the hardware clock in
  // the audio device. The GetFrequency() method reports a constant frequency.
  UINT64 device_frequency = 0;
  _com_error result(S_FALSE);
  if (audio_clock_) {
    RTC_DCHECK(IsOutput());
    result = audio_clock_->GetFrequency(&device_frequency);
    if (FAILED(result.Error())) {
      RTC_LOG(LS_ERROR) << "IAudioClock::GetFrequency failed: "
                        << core_audio_utility::ErrorToString(result);
    }
  }

  // Keep streaming audio until the stop event or the stream-switch event
  // is signaled. An error event can also break the main thread loop.
  while (streaming && !error) {
    // Wait for a close-down event, stream-switch event or a new render event.
    DWORD wait_result = WaitForMultipleObjects(arraysize(wait_array),
                                               wait_array, false, INFINITE);
    switch (wait_result) {
      case WAIT_OBJECT_0 + 0:
        // |stop_event_| has been set.
        streaming = false;
        break;
      case WAIT_OBJECT_0 + 1:
        // |restart_event_| has been set.
        error = !HandleRestartEvent();
        break;
      case WAIT_OBJECT_0 + 2:
        // |audio_samples_event_| has been set.
        error = !on_data_callback_(device_frequency);
        break;
      default:
        error = true;
        break;
    }
  }

  if (streaming && error) {
    RTC_LOG(LS_ERROR) << "[" << DirectionToString(direction())
                      << "] WASAPI streaming failed.";
    // Stop audio streaming since something has gone wrong in our main thread
    // loop. Note that, we are still in a "started" state, hence a Stop() call
    // is required to join the thread properly.
    result = audio_client_->Stop();
    if (FAILED(result.Error())) {
      RTC_LOG(LS_ERROR) << "IAudioClient::Stop failed: "
                        << core_audio_utility::ErrorToString(result);
    }

    // TODO(henrika): notify clients that something has gone wrong and that
    // this stream should be destroyed instead of reused in the future.
  }

  RTC_DLOG(INFO) << "[" << DirectionToString(direction())
                 << "] ...ThreadRun stops";
}

}  // namespace webrtc_win
}  // namespace webrtc
