/*
 *  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/timeutils.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_.DetachFromThread();
  }

  // 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
