// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "media/audio/mac/audio_auhal_mac.h"

#include <CoreServices/CoreServices.h>

#include <algorithm>
#include <cstddef>
#include <memory>
#include <string>
#include <utility>

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/mac/mac_logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h"
#include "media/audio/mac/core_audio_util_mac.h"
#include "media/base/audio_pull_fifo.h"
#include "media/base/audio_timestamp_helper.h"

namespace media {

namespace {

// Mapping from Chrome's channel layout to CoreAudio layout. This must match the
// layout of the Channels enum in |channel_layout.h|
static const AudioChannelLabel kCoreAudioChannelMapping[] = {
    kAudioChannelLabel_Left,
    kAudioChannelLabel_Right,
    kAudioChannelLabel_Center,
    kAudioChannelLabel_LFEScreen,
    kAudioChannelLabel_RearSurroundLeft,
    kAudioChannelLabel_RearSurroundRight,
    kAudioChannelLabel_LeftCenter,
    kAudioChannelLabel_RightCenter,
    kAudioChannelLabel_CenterSurround,
    kAudioChannelLabel_LeftSurround,
    kAudioChannelLabel_RightSurround
};
static_assert(0 == LEFT && 1 == RIGHT && 2 == CENTER && 3 == LFE &&
                  4 == BACK_LEFT &&
                  5 == BACK_RIGHT &&
                  6 == LEFT_OF_CENTER &&
                  7 == RIGHT_OF_CENTER &&
                  8 == BACK_CENTER &&
                  9 == SIDE_LEFT &&
                  10 == SIDE_RIGHT &&
                  10 == CHANNELS_MAX,
              "Channel positions must match CoreAudio channel order.");

void WrapBufferList(AudioBufferList* buffer_list, AudioBus* bus, int frames) {
  const int channels = bus->channels();
  const int buffer_list_channels = buffer_list->mNumberBuffers;
  CHECK_EQ(channels, buffer_list_channels);

  // Copy pointers from AudioBufferList.
  for (int i = 0; i < channels; ++i)
    bus->SetChannelData(i, static_cast<float*>(buffer_list->mBuffers[i].mData));

  // Finally set the actual length.
  bus->set_frames(frames);
}

// Sets the stream format on the AUHAL to PCM Float32 non-interleaved for the
// given number of channels on the given scope and element. The created stream
// description will be stored in |desc|.
bool SetStreamFormat(int channels,
                     int sample_rate,
                     AudioUnit audio_unit,
                     AudioStreamBasicDescription* format) {
  format->mSampleRate = sample_rate;
  format->mFormatID = kAudioFormatLinearPCM;
  format->mFormatFlags = AudioFormatFlags{kAudioFormatFlagsNativeFloatPacked} |
                         kLinearPCMFormatFlagIsNonInterleaved;
  format->mBytesPerPacket = sizeof(Float32);
  format->mFramesPerPacket = 1;
  format->mBytesPerFrame = sizeof(Float32);
  format->mChannelsPerFrame = channels;
  format->mBitsPerChannel = 32;
  format->mReserved = 0;

  // Set stream formats. See Apple's tech note for details on the peculiar way
  // that inputs and outputs are handled in the AUHAL concerning scope and bus
  // (element) numbers:
  // http://developer.apple.com/library/mac/#technotes/tn2091/_index.html
  return AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat,
                              kAudioUnitScope_Input, AUElement::OUTPUT, format,
                              sizeof(*format)) == noErr;
}

// Converts |channel_layout| into CoreAudio format and sets up the AUHAL with
// our layout information so it knows how to remap the channels.
void SetAudioChannelLayout(int channels,
                           ChannelLayout channel_layout,
                           AudioUnit audio_unit) {
  DCHECK(audio_unit);
  DCHECK_GT(channels, 0);
  DCHECK_GT(channel_layout, CHANNEL_LAYOUT_UNSUPPORTED);

  // AudioChannelLayout is structure ending in a variable length array, so we
  // can't directly allocate one. Instead compute the size and and allocate one
  // inside of a byte array.
  //
  // Code modeled after example from Apple documentation here:
  // https://developer.apple.com/library/content/qa/qa1627/_index.html
  const size_t layout_size =
      offsetof(AudioChannelLayout, mChannelDescriptions[channels]);
  std::unique_ptr<uint8_t[]> layout_storage(new uint8_t[layout_size]);
  memset(layout_storage.get(), 0, layout_size);
  AudioChannelLayout* coreaudio_layout =
      reinterpret_cast<AudioChannelLayout*>(layout_storage.get());

  coreaudio_layout->mNumberChannelDescriptions = channels;
  coreaudio_layout->mChannelLayoutTag =
      kAudioChannelLayoutTag_UseChannelDescriptions;
  AudioChannelDescription* descriptions =
      coreaudio_layout->mChannelDescriptions;

  if (channel_layout == CHANNEL_LAYOUT_DISCRETE) {
    // For the discrete case just assume common input mappings; once we run out
    // of known channels mark them as unknown.
    for (int ch = 0; ch < channels; ++ch) {
      descriptions[ch].mChannelLabel = ch > CHANNELS_MAX
                                           ? kAudioChannelLabel_Unknown
                                           : kCoreAudioChannelMapping[ch];
      descriptions[ch].mChannelFlags = kAudioChannelFlags_AllOff;
    }
  } else if (channel_layout == CHANNEL_LAYOUT_MONO) {
    // CoreAudio has a special label for mono.
    DCHECK_EQ(channels, 1);
    descriptions[0].mChannelLabel = kAudioChannelLabel_Mono;
    descriptions[0].mChannelFlags = kAudioChannelFlags_AllOff;
  } else {
    for (int ch = 0; ch <= CHANNELS_MAX; ++ch) {
      const int order = ChannelOrder(channel_layout, static_cast<Channels>(ch));
      if (order == -1)
        continue;
      descriptions[order].mChannelLabel = kCoreAudioChannelMapping[ch];
      descriptions[order].mChannelFlags = kAudioChannelFlags_AllOff;
    }
  }

  OSStatus result = AudioUnitSetProperty(
      audio_unit, kAudioUnitProperty_AudioChannelLayout, kAudioUnitScope_Input,
      AUElement::OUTPUT, coreaudio_layout, layout_size);
  if (result != noErr) {
    OSSTATUS_DLOG(ERROR, result)
        << "Failed to set audio channel layout. Using default layout.";
  }
}

void ReportFramesRequestedUma(int number_of_frames_requested) {
  // A value of 0 indicates that we got the buffer size we asked for.
  base::UmaHistogramCounts1M("Media.Audio.Render.FramesRequested",
                             number_of_frames_requested);
}

}  // namespace

AUHALStream::AUHALStream(AudioIOStreamClient* client,
                         const AudioParameters& params,
                         AudioDeviceID device,
                         const AudioManager::LogCallback& log_callback)
    : client_(client),
      params_(params),
      source_(nullptr),
      device_(device),
      volume_(1),
      stopped_(true),
      last_sample_time_(0.0),
      last_number_of_frames_(0),
      glitch_reporter_(SystemGlitchReporter::StreamType::kRender),
      log_callback_(log_callback) {
  // We must have a manager.
  DVLOG(1) << __FUNCTION__ << " this " << this << " params "
           << params.AsHumanReadableString();
  DCHECK(client_);
  DCHECK(params_.IsValid());
#if BUILDFLAG(IS_MAC)
  DCHECK_NE(device, kAudioObjectUnknown);
#endif
}

AUHALStream::~AUHALStream() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  CHECK(!audio_unit_);
}

bool AUHALStream::Open() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(!output_bus_);
  DCHECK(!audio_unit_);

  // The output bus will wrap the AudioBufferList given to us in
  // the Render() callback.
  output_bus_ = AudioBus::CreateWrapper(params_.channels());

  bool configured = ConfigureAUHAL();
  if (configured) {
    DCHECK(audio_unit_);
    DCHECK(audio_unit_->is_valid());
    hardware_latency_ = core_audio_mac::GetHardwareLatency(
        audio_unit_->audio_unit(), device_, kAudioObjectPropertyScopeOutput,
        params_.sample_rate());
  }

  DVLOG(1) << __FUNCTION__ << " this " << this << " received hardware latency "
           << hardware_latency_;
  return configured;
}

void AUHALStream::Close() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DVLOG(1) << __FUNCTION__ << " this " << this;

  if (audio_unit_) {
    Stop();

    // Clear the render callback to try and prevent any callbacks from coming
    // in after we've called stop. https://crbug.com/737527.
    AURenderCallbackStruct callback = {0};
    auto result = AudioUnitSetProperty(
        audio_unit_->audio_unit(), kAudioUnitProperty_SetRenderCallback,
        kAudioUnitScope_Input, AUElement::OUTPUT, &callback, sizeof(callback));
    OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
        << "Failed to clear input callback.";
  }

  audio_unit_.reset();
  // Inform the audio manager that we have been closed. This will cause our
  // destruction. Also include the device ID as a signal to the audio manager
  // that it should try to increase the native I/O buffer size after the stream
  // has been closed.
  client_->ReleaseOutputStreamUsingRealDevice(this, device_);
}

void AUHALStream::Start(AudioSourceCallback* callback) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK(callback);
  if (!audio_unit_) {
    DLOG(ERROR) << "Open() has not been called successfully";
    return;
  }

  if (!stopped_) {
    base::AutoLock al(lock_);
    CHECK_EQ(source_, callback);
    return;
  }

  DVLOG(1) << __FUNCTION__ << " this " << this;

#if BUILDFLAG(IS_MAC)
  // Check if we should defer Start() for http://crbug.com/160920.
  base::TimeDelta defer_start = client_->GetDeferStreamStartTimeout();
  if (!defer_start.is_zero()) {
    // Use a cancellable closure so that if Stop() is called before Start()
    // actually runs, we can cancel the pending start.
    deferred_start_cb_.Reset(
        base::BindOnce(&AUHALStream::Start, base::Unretained(this), callback));
    client_->GetTaskRunner()->PostDelayedTask(
        FROM_HERE, deferred_start_cb_.callback(), defer_start);
    return;
  }
#endif

  stopped_ = false;

  {
    base::AutoLock al(lock_);
    DCHECK(!audio_fifo_);
    source_ = callback;
  }

#if BUILDFLAG(IS_MAC)
  peak_detector_ = std::make_unique<AmplitudePeakDetector>(base::BindRepeating(
      &AudioIOStreamClient::StopAmplitudePeakTrace, base::Unretained(client_)));
#endif

  OSStatus result = AudioOutputUnitStart(audio_unit_->audio_unit());
  if (result == noErr)
    return;

  Stop();
  OSSTATUS_DLOG(ERROR, result) << "AudioOutputUnitStart() failed.";
  callback->OnError(AudioSourceCallback::ErrorType::kUnknown);
}

// This stream is always used with sub second buffer sizes, where it's
// sufficient to simply always flush upon Start().
void AUHALStream::Flush() {}

void AUHALStream::Stop() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  deferred_start_cb_.Cancel();
  if (stopped_)
    return;

  DVLOG(1) << __FUNCTION__ << " this " << this;

  OSStatus result = AudioOutputUnitStop(audio_unit_->audio_unit());
  OSSTATUS_DLOG_IF(ERROR, result != noErr, result)
      << "AudioOutputUnitStop() failed.";

  {
    base::AutoLock al(lock_);
    if (result != noErr)
      source_->OnError(AudioSourceCallback::ErrorType::kUnknown);
    source_ = nullptr;

    if (last_sample_time_) {  // Report stats if the stream has been active.
      if (!audio_fifo_)  // Unexpected buffer size has never been requested.
        ReportFramesRequestedUma(0);

      SystemGlitchReporter::Stats stats =
          glitch_reporter_.GetLongTermStatsAndReset();

      std::string log_message = base::StringPrintf(
          "AU out: (num_glitches_detected=[%d], cumulative_audio_lost=[%llu "
          "ms], "
          "largest_glitch=[%llu ms])",
          stats.glitches_detected, stats.total_glitch_duration.InMilliseconds(),
          stats.largest_glitch_duration.InMilliseconds());

      if (!log_callback_.is_null())
        log_callback_.Run(log_message);
      if (stats.glitches_detected > 0) {
        DLOG(WARNING) << log_message;
      }
    }

    last_sample_time_ = 0;
    last_number_of_frames_ = 0;
    audio_fifo_.reset();
  }

#if BUILDFLAG(IS_MAC)
  peak_detector_.reset();
#endif

  stopped_ = true;
}

void AUHALStream::SetVolume(double volume) {
  volume_ = static_cast<float>(volume);
}

void AUHALStream::GetVolume(double* volume) {
  *volume = volume_;
}

// Pulls on our provider to get rendered audio stream.
// Note to future hackers of this function: Do not add locks which can
// be contended in the middle of stream processing here (starting and stopping
// the stream are ok) because this is running on a real-time thread.
OSStatus AUHALStream::Render(AudioUnitRenderActionFlags* flags,
                             const AudioTimeStamp* output_time_stamp,
                             UInt32 bus_number,
                             UInt32 number_of_frames,
                             AudioBufferList* data) {
  TRACE_EVENT2("audio", "AUHALStream::Render", "input buffer size",
               params_.frames_per_buffer(), "output buffer size",
               number_of_frames);

  base::AutoLock al(lock_);

  // There's no documentation on what we should return here, but if we're here
  // something is wrong so just return an AudioUnit error that looks reasonable.
  if (!source_)
    return kAudioUnitErr_Uninitialized;

  UpdatePlayoutTimestamp(output_time_stamp);

  // If the stream parameters change for any reason, we need to insert a FIFO
  // since the OnMoreData() pipeline can't handle frame size changes.
  if (number_of_frames != static_cast<UInt32>(params_.frames_per_buffer())) {
    // Create a FIFO on the fly to handle any discrepancies in callback rates.
    if (!audio_fifo_) {
      DVLOG(1) << __FUNCTION__ << " this " << this
               << "Audio frame size changed from "
               << params_.frames_per_buffer() << " to " << number_of_frames
               << " adding FIFO to compensate.";
      audio_fifo_ = std::make_unique<AudioPullFifo>(
          params_.channels(), params_.frames_per_buffer(),
          base::BindRepeating(&AUHALStream::ProvideInput,
                              base::Unretained(this)));
      // Report it only once the first time the change happens.
      ReportFramesRequestedUma(number_of_frames);
    } else if (last_number_of_frames_ != number_of_frames) {
      DVLOG(3) << __FUNCTION__ << " this " << this
               << "Audio frame size changed from " << last_number_of_frames_
               << " to " << number_of_frames << " FIFO already exists.";
    }
  }

  // Make |output_bus_| wrap the output AudioBufferList.
  WrapBufferList(data, output_bus_.get(), number_of_frames);

  current_playout_time_ = GetPlayoutTime(output_time_stamp);

  if (audio_fifo_)
    audio_fifo_->Consume(output_bus_.get(), output_bus_->frames());
  else
    ProvideInput(0, output_bus_.get());

#if BUILDFLAG(IS_MAC)
  peak_detector_->FindPeak(output_bus_.get());
#endif

  last_number_of_frames_ = number_of_frames;

  return noErr;
}

void AUHALStream::ProvideInput(int frame_delay, AudioBus* dest) {
  TRACE_EVENT1("audio", "AUHALStream::ProvideInput", "frames", dest->frames());
  lock_.AssertAcquired();
  DCHECK(source_);

  const base::TimeTicks playout_time =
      current_playout_time_ +
      AudioTimestampHelper::FramesToTime(frame_delay, params_.sample_rate());
  const base::TimeTicks now = base::TimeTicks::Now();
  const base::TimeDelta delay = playout_time - now;

  // Supply the input data and render the output data.
  source_->OnMoreData(delay, now, glitch_info_accumulator_.GetAndReset(), dest);
  dest->Scale(volume_);
}

// AUHAL callback.
OSStatus AUHALStream::InputProc(void* user_data,
                                AudioUnitRenderActionFlags* flags,
                                const AudioTimeStamp* output_time_stamp,
                                UInt32 bus_number,
                                UInt32 number_of_frames,
                                AudioBufferList* io_data) {
  // Dispatch to our class method.
  AUHALStream* audio_output = static_cast<AUHALStream*>(user_data);
  if (!audio_output)
    return -1;

  return audio_output->Render(flags, output_time_stamp, bus_number,
                              number_of_frames, io_data);
}

base::TimeTicks AUHALStream::GetPlayoutTime(
    const AudioTimeStamp* output_time_stamp) {
  // A platform bug has been observed where the platform sometimes reports that
  // the next frames will be output at an invalid time or a time in the past.
  // Because the target playout time cannot be invalid or in the past, return
  // "now" in these cases.
  if ((output_time_stamp->mFlags & kAudioTimeStampHostTimeValid) == 0)
    return base::TimeTicks::Now();

  return std::max(base::TimeTicks::FromMachAbsoluteTime(
                      output_time_stamp->mHostTime),
                  base::TimeTicks::Now()) +
         hardware_latency_;
}

void AUHALStream::UpdatePlayoutTimestamp(const AudioTimeStamp* timestamp) {
  lock_.AssertAcquired();

  if ((timestamp->mFlags & kAudioTimeStampSampleTimeValid) == 0)
    return;

  if (last_sample_time_) {
    DCHECK_NE(0U, last_number_of_frames_);
    UInt32 sample_time_diff =
        static_cast<UInt32>(timestamp->mSampleTime - last_sample_time_);
    DCHECK_GE(sample_time_diff, last_number_of_frames_);
    UInt32 lost_frames = sample_time_diff - last_number_of_frames_;
    base::TimeDelta lost_audio_duration =
        AudioTimestampHelper::FramesToTime(lost_frames, params_.sample_rate());
    glitch_reporter_.UpdateStats(lost_audio_duration);
    if (!lost_audio_duration.is_zero()) {
      glitch_info_accumulator_.Add(
          AudioGlitchInfo{.duration = lost_audio_duration, .count = 1});
    }
  }

  // Store the last sample time for use next time we get called back.
  last_sample_time_ = timestamp->mSampleTime;
}

bool AUHALStream::ConfigureAUHAL() {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  std::unique_ptr<ScopedAudioUnit> local_audio_unit(
      new ScopedAudioUnit(device_, AUElement::OUTPUT));
  if (!local_audio_unit->is_valid())
    return false;

  if (!SetStreamFormat(params_.channels(), params_.sample_rate(),
                       local_audio_unit->audio_unit(), &output_format_)) {
    return false;
  }

  if (!client_->MaybeChangeBufferSize(device_, local_audio_unit->audio_unit(),
                                      0, params_.frames_per_buffer())) {
    return false;
  }

  // Setup callback.
  AURenderCallbackStruct callback;
  callback.inputProc = InputProc;
  callback.inputProcRefCon = this;
  OSStatus result = AudioUnitSetProperty(
      local_audio_unit->audio_unit(), kAudioUnitProperty_SetRenderCallback,
      kAudioUnitScope_Input, AUElement::OUTPUT, &callback, sizeof(callback));
  if (result != noErr)
    return false;

  SetAudioChannelLayout(params_.channels(), params_.channel_layout(),
                        local_audio_unit->audio_unit());

  result = AudioUnitInitialize(local_audio_unit->audio_unit());
  if (result != noErr) {
    OSSTATUS_DLOG(ERROR, result) << "AudioUnitInitialize() failed.";
    return false;
  }

  audio_unit_ = std::move(local_audio_unit);
  return true;
}

}  // namespace media
