// Copyright 2017 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/android/shared/audio_track_audio_sink_type.h"

#include <algorithm>
#include <vector>

#include "starboard/shared/starboard/player/filter/common.h"

namespace {
starboard::android::shared::AudioTrackAudioSinkType*
    audio_track_audio_sink_type_;
}

namespace starboard {
namespace android {
namespace shared {
namespace {

// The same as AudioTrack.ERROR_DEAD_OBJECT.
const int kAudioTrackErrorDeadObject = -6;

// The maximum number of frames that can be written to android audio track per
// write request. If we don't set this cap for writing frames to audio track,
// we will repeatedly allocate a large byte array which cannot be consumed by
// audio track completely.
const int kMaxFramesPerRequest = 65536;

// Most Android audio HAL updates audio time for A/V synchronization on audio
// sync frames. For example, audio HAL may try to render when it gets an entire
// sync frame and then update audio time. Shorter duration of sync frame
// improves the accuracy of audio time, especially at the beginning of a
// playback, as otherwise the audio time during the initial update may be too
// large (non zero) and results in dropped video frames.
const SbTime kMaxDurationPerRequestInTunnelMode = 16 * kSbTimeMillisecond;

const jint kNoOffset = 0;
const size_t kSilenceFramesPerAppend = 1024;

const int kMaxRequiredFrames = 16 * 1024;
const int kRequiredFramesIncrement = 2 * 1024;
const int kMinStablePlayedFrames = 12 * 1024;

const int kSampleFrequency22050 = 22050;
const int kSampleFrequency48000 = 48000;

// Helper function to compute the size of the two valid starboard audio sample
// types.
size_t GetSampleSize(SbMediaAudioSampleType sample_type) {
  switch (sample_type) {
    case kSbMediaAudioSampleTypeFloat32:
      return sizeof(float);
    case kSbMediaAudioSampleTypeInt16Deprecated:
      return sizeof(int16_t);
  }
  SB_NOTREACHED();
  return 0u;
}

int GetAudioFormatSampleType(SbMediaAudioSampleType sample_type) {
  switch (sample_type) {
    case kSbMediaAudioSampleTypeFloat32:
      // Android AudioFormat.ENCODING_PCM_FLOAT.
      return 4;
    case kSbMediaAudioSampleTypeInt16Deprecated:
      // Android AudioFormat.ENCODING_PCM_16BIT.
      return 2;
  }
  SB_NOTREACHED();
  return 0u;
}

void* IncrementPointerByBytes(void* pointer, size_t offset) {
  return static_cast<uint8_t*>(pointer) + offset;
}

int GetMaxFramesPerRequestForTunnelMode(int sampling_frequency_hz) {
  auto max_frames = kMaxDurationPerRequestInTunnelMode * sampling_frequency_hz /
                    kSbTimeSecond;
  return (max_frames + 15) / 16 * 16;  // align to 16
}

}  // namespace

AudioTrackAudioSink::AudioTrackAudioSink(
    Type* type,
    int channels,
    int sampling_frequency_hz,
    SbMediaAudioSampleType sample_type,
    SbAudioSinkFrameBuffers frame_buffers,
    int frames_per_channel,
    int preferred_buffer_size_in_bytes,
    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
    ConsumeFramesFunc consume_frames_func,
    SbAudioSinkPrivate::ErrorFunc error_func,
    SbTime start_time,
    int tunnel_mode_audio_session_id,
    void* context)
    : type_(type),
      channels_(channels),
      sampling_frequency_hz_(sampling_frequency_hz),
      sample_type_(sample_type),
      frame_buffer_(frame_buffers[0]),
      frames_per_channel_(frames_per_channel),
      update_source_status_func_(update_source_status_func),
      consume_frames_func_(consume_frames_func),
      error_func_(error_func),
      start_time_(start_time),
      tunnel_mode_audio_session_id_(tunnel_mode_audio_session_id),
      max_frames_per_request_(
          tunnel_mode_audio_session_id_ == -1
              ? kMaxFramesPerRequest
              : GetMaxFramesPerRequestForTunnelMode(sampling_frequency_hz_)),
      context_(context) {
  SB_DCHECK(update_source_status_func_);
  SB_DCHECK(consume_frames_func_);
  SB_DCHECK(frame_buffer_);
  SB_DCHECK(SbAudioSinkIsAudioSampleTypeSupported(sample_type));

  // TODO: Support query if platform supports float type for tunnel mode.
  if (tunnel_mode_audio_session_id_ != -1) {
    SB_DCHECK(sample_type_ == kSbMediaAudioSampleTypeInt16Deprecated);
  }

  SB_LOG(INFO) << "Creating audio sink starts at " << start_time_;

  JniEnvExt* env = JniEnvExt::Get();
  ScopedLocalJavaRef<jobject> j_audio_output_manager(
      env->CallStarboardObjectMethodOrAbort(
          "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
  jobject j_audio_track_bridge = env->CallObjectMethodOrAbort(
      j_audio_output_manager.Get(), "createAudioTrackBridge",
      "(IIIII)Ldev/cobalt/media/AudioTrackBridge;",
      GetAudioFormatSampleType(sample_type_), sampling_frequency_hz_, channels_,
      preferred_buffer_size_in_bytes, tunnel_mode_audio_session_id_);
  if (!j_audio_track_bridge) {
    // One of the cases that this may hit is when output happened to be switched
    // to a device that doesn't support tunnel mode.
    // TODO: Find a way to exclude the device from tunnel mode playback, to
    //       avoid infinite loop in creating the audio sink on a device
    //       claims to support tunnel mode but fails to create the audio sink.
    // TODO: Currently this will be reported as a general decode error,
    //       investigate if this can be reported as a capability changed error.
    return;
  }
  j_audio_track_bridge_ = env->ConvertLocalRefToGlobalRef(j_audio_track_bridge);
  if (sample_type_ == kSbMediaAudioSampleTypeFloat32) {
    j_audio_data_ = env->NewFloatArray(channels_ * max_frames_per_request_);
  } else if (sample_type_ == kSbMediaAudioSampleTypeInt16Deprecated) {
    j_audio_data_ = env->NewByteArray(channels_ * GetSampleSize(sample_type_) *
                                      max_frames_per_request_);
  } else {
    SB_NOTREACHED();
  }
  SB_CHECK(j_audio_data_) << "Failed to allocate |j_audio_data_|";

  j_audio_data_ = env->ConvertLocalRefToGlobalRef(j_audio_data_);

  audio_out_thread_ = SbThreadCreate(
      0, kSbThreadPriorityRealTime, kSbThreadNoAffinity, true,
      "audio_track_audio_out", &AudioTrackAudioSink::ThreadEntryPoint, this);
  SB_DCHECK(SbThreadIsValid(audio_out_thread_));
}

AudioTrackAudioSink::~AudioTrackAudioSink() {
  quit_ = true;

  if (SbThreadIsValid(audio_out_thread_)) {
    SbThreadJoin(audio_out_thread_, NULL);
  }

  JniEnvExt* env = JniEnvExt::Get();
  if (j_audio_track_bridge_) {
    ScopedLocalJavaRef<jobject> j_audio_output_manager(
        env->CallStarboardObjectMethodOrAbort(
            "getAudioOutputManager",
            "()Ldev/cobalt/media/AudioOutputManager;"));
    env->CallVoidMethodOrAbort(
        j_audio_output_manager.Get(), "destroyAudioTrackBridge",
        "(Ldev/cobalt/media/AudioTrackBridge;)V", j_audio_track_bridge_);
    env->DeleteGlobalRef(j_audio_track_bridge_);
    j_audio_track_bridge_ = NULL;
  }

  if (j_audio_data_) {
    env->DeleteGlobalRef(j_audio_data_);
    j_audio_data_ = NULL;
  }
}

void AudioTrackAudioSink::SetPlaybackRate(double playback_rate) {
  SB_DCHECK(playback_rate >= 0.0);
  if (playback_rate != 0.0 && playback_rate != 1.0) {
    SB_NOTIMPLEMENTED() << "TODO: Only playback rates of 0.0 and 1.0 are "
                           "currently supported.";
    playback_rate = (playback_rate > 0.0) ? 1.0 : 0.0;
  }
  ScopedLock lock(mutex_);
  playback_rate_ = playback_rate;
}

// static
void* AudioTrackAudioSink::ThreadEntryPoint(void* context) {
  SB_DCHECK(context);
  AudioTrackAudioSink* sink = reinterpret_cast<AudioTrackAudioSink*>(context);
  sink->AudioThreadFunc();

  return NULL;
}

// TODO: Break down the function into manageable pieces.
void AudioTrackAudioSink::AudioThreadFunc() {
  JniEnvExt* env = JniEnvExt::Get();
  bool was_playing = false;

  SB_LOG(INFO) << "AudioTrackAudioSink thread started.";

  int accumulated_written_frames = 0;
  // TODO: |last_playback_head_changed_at| is also resetted when a warning is
  //       logged after the playback head position hasn't been updated for a
  //       while.  We should refine the name to make it better reflect its
  //       usage.
  SbTime last_playback_head_changed_at = -1;
  SbTime playback_head_not_changed_duration = 0;
  SbTime last_written_succeeded_at = -1;

  while (!quit_) {
    int playback_head_position = 0;
    SbTime frames_consumed_at = 0;

    if (was_playing) {
      ScopedLocalJavaRef<jobject> j_audio_timestamp(
          env->CallObjectMethodOrAbort(j_audio_track_bridge_,
                                       "getAudioTimestamp",
                                       "()Landroid/media/AudioTimestamp;"));
      playback_head_position = env->GetLongFieldOrAbort(j_audio_timestamp.Get(),
                                                        "framePosition", "J");
      frames_consumed_at =
          env->GetLongFieldOrAbort(j_audio_timestamp.Get(), "nanoTime", "J") /
          1000;

      SB_DCHECK(playback_head_position >= last_playback_head_position_);

      playback_head_position =
          std::max(playback_head_position, last_playback_head_position_);
      int frames_consumed =
          playback_head_position - last_playback_head_position_;
      SbTime now = SbTimeGetMonotonicNow();

      if (last_playback_head_changed_at == -1) {
        last_playback_head_changed_at = now;
      }
      if (last_playback_head_position_ == playback_head_position) {
        SbTime elapsed = now - last_playback_head_changed_at;
        if (elapsed > 5 * kSbTimeSecond) {
          playback_head_not_changed_duration += elapsed;
          last_playback_head_changed_at = now;
          SB_LOG(INFO) << "last playback head position is "
                       << last_playback_head_position_
                       << " and it hasn't been updated for " << elapsed
                       << " microseconds.";
        }
      } else {
        last_playback_head_changed_at = now;
        playback_head_not_changed_duration = 0;
      }

      last_playback_head_position_ = playback_head_position;
      frames_consumed = std::min(frames_consumed, written_frames_);

      if (frames_consumed != 0) {
        SB_DCHECK(frames_consumed >= 0);
        consume_frames_func_(frames_consumed, frames_consumed_at, context_);
        written_frames_ -= frames_consumed;
      }
    }

    int frames_in_buffer;
    int offset_in_frames;
    bool is_playing;
    bool is_eos_reached;
    update_source_status_func_(&frames_in_buffer, &offset_in_frames,
                               &is_playing, &is_eos_reached, context_);
    {
      ScopedLock lock(mutex_);
      if (playback_rate_ == 0.0) {
        is_playing = false;
      }
    }

    if (was_playing && !is_playing) {
      was_playing = false;
      env->CallVoidMethodOrAbort(j_audio_track_bridge_, "pause", "()V");
      SB_LOG(INFO) << "AudioTrackAudioSink paused.";
    } else if (!was_playing && is_playing) {
      was_playing = true;
      last_playback_head_changed_at = -1;
      playback_head_not_changed_duration = 0;
      last_written_succeeded_at = -1;
      env->CallVoidMethodOrAbort(j_audio_track_bridge_, "play", "()V");
      SB_LOG(INFO) << "AudioTrackAudioSink playing.";
    }

    if (!is_playing || frames_in_buffer == 0) {
      SbThreadSleep(10 * kSbTimeMillisecond);
      continue;
    }

    int start_position =
        (offset_in_frames + written_frames_) % frames_per_channel_;
    int expected_written_frames = 0;
    if (frames_per_channel_ > offset_in_frames + written_frames_) {
      expected_written_frames =
          std::min(frames_per_channel_ - (offset_in_frames + written_frames_),
                   frames_in_buffer - written_frames_);
    } else {
      expected_written_frames = frames_in_buffer - written_frames_;
    }

    expected_written_frames =
        std::min(expected_written_frames, max_frames_per_request_);
    if (expected_written_frames == 0) {
      // It is possible that all the frames in buffer are written to the
      // soundcard, but those are not being consumed. If eos is reached,
      // write silence to make sure audio track start working and avoid
      // underflow. Android audio track would not start working before
      // its buffer is fully filled once.
      if (is_eos_reached) {
        // Currently AudioDevice and AudioRenderer will write tail silence.
        // It should be reached only in tests. It's not ideal to allocate
        // a new silence buffer every time.
        const int silence_frames_per_append =
            std::min<int>(kSilenceFramesPerAppend, max_frames_per_request_);
        std::vector<uint8_t> silence_buffer(channels_ *
                                            GetSampleSize(sample_type_) *
                                            silence_frames_per_append);
        auto sync_time = start_time_ + accumulated_written_frames *
                                           kSbTimeSecond /
                                           sampling_frequency_hz_;
        // Not necessary to handle error of WriteData(), even for
        // kAudioTrackErrorDeadObject, as the audio has reached the end of
        // stream.
        // TODO: Ensure that the audio stream can still reach the end when an
        //       error occurs.
        WriteData(env, silence_buffer.data(), silence_frames_per_append,
                  sync_time);
      }

      // While WriteData() returns kAudioTrackErrorDeadObject on dead object,
      // getAudioTimestamp() doesn't, it just no longer updates its return
      // value.  If the dead object error occurs when there isn't any audio data
      // to write, there is no way to detect it by checking the return value of
      // getAudioTimestamp().  Instead, we have to check if its return value has
      // been changed during a certain period of time, to detect the underlying
      // dead object error.
      // Note that dead object would occur while switching audio end points in
      // tunnel mode.  Under non-tunnel mode, the Android native AudioTrack will
      // handle audio track dead object automatically if the new end point can
      // support current audio format.
      // TODO: Investigate to handle this error in non-tunnel mode.
      if (tunnel_mode_audio_session_id_ != -1 &&
          last_written_succeeded_at != -1) {
        const SbTime kAudioSinkBlockedDuration = kSbTimeSecond;
        auto time_since_last_written_success =
            SbTimeGetMonotonicNow() - last_written_succeeded_at;
        if (time_since_last_written_success > kAudioSinkBlockedDuration &&
            playback_head_not_changed_duration > kAudioSinkBlockedDuration &&
            tunnel_mode_audio_session_id_ != -1) {
          SB_LOG(INFO) << "Over one second without frames written and consumed";
          consume_frames_func_(written_frames_, SbTimeGetMonotonicNow(),
                               context_);
          error_func_(kSbPlayerErrorCapabilityChanged, context_);
          break;
        }
      }

      SbThreadSleep(10 * kSbTimeMillisecond);
      continue;
    }
    SB_DCHECK(expected_written_frames > 0);
    auto sync_time = start_time_ + accumulated_written_frames * kSbTimeSecond /
                                       sampling_frequency_hz_;

    SB_CHECK(start_position + expected_written_frames <= frames_per_channel_);
    int written_frames = WriteData(
        env,
        IncrementPointerByBytes(frame_buffer_, start_position * channels_ *
                                                   GetSampleSize(sample_type_)),
        expected_written_frames, sync_time);
    SbTime now = SbTimeGetMonotonicNow();

    if (written_frames < 0) {
      // Take all |written_frames_| as consumed since audio track could be dead.
      consume_frames_func_(written_frames_, now, context_);
      error_func_(written_frames == kAudioTrackErrorDeadObject
                      ? kSbPlayerErrorCapabilityChanged
                      : kSbPlayerErrorDecode,
                  context_);
      break;
    } else if (written_frames > 0) {
      last_written_succeeded_at = now;
    }
    written_frames_ += written_frames;
    accumulated_written_frames += written_frames;

    bool written_fully = (written_frames == expected_written_frames);
    auto unplayed_frames_in_time =
        written_frames_ * kSbTimeSecond / sampling_frequency_hz_ -
        (now - frames_consumed_at);
    // As long as there is enough data in the buffer, run the loop in lower
    // frequency to avoid taking too much CPU.  Note that the threshold should
    // be big enough to account for the unstable playback head reported at the
    // beginning of the playback and during underrun.
    if (playback_head_position > 0 &&
        unplayed_frames_in_time > 500 * kSbTimeMillisecond) {
      SbThreadSleep(40 * kSbTimeMillisecond);
    } else if (!written_fully) {
      // Only sleep if the buffer is nearly full and the last write is partial.
      SbThreadSleep(10 * kSbTimeMillisecond);
    }
  }

  // For an immediate stop, use pause(), followed by flush() to discard audio
  // data that hasn't been played back yet.
  env->CallVoidMethodOrAbort(j_audio_track_bridge_, "pause", "()V");
  // Flushes the audio data currently queued for playback. Any data that has
  // been written but not yet presented will be discarded.
  env->CallVoidMethodOrAbort(j_audio_track_bridge_, "flush", "()V");
}

int AudioTrackAudioSink::WriteData(JniEnvExt* env,
                                   void* buffer,
                                   int expected_written_frames,
                                   SbTime sync_time) {
  if (sample_type_ == kSbMediaAudioSampleTypeFloat32) {
    int expected_written_size = expected_written_frames * channels_;
    env->SetFloatArrayRegion(static_cast<jfloatArray>(j_audio_data_), kNoOffset,
                             expected_written_size,
                             static_cast<const float*>(buffer));
    int written =
        env->CallIntMethodOrAbort(j_audio_track_bridge_, "write", "([FI)I",
                                  j_audio_data_, expected_written_size);
    if (written < 0) {
      // Error code returned as negative value, like kAudioTrackErrorDeadObject.
      return written;
    }
    SB_DCHECK(written % channels_ == 0);
    return written / channels_;
  }
  if (sample_type_ == kSbMediaAudioSampleTypeInt16Deprecated) {
    int expected_written_size =
        expected_written_frames * channels_ * GetSampleSize(sample_type_);
    env->SetByteArrayRegion(static_cast<jbyteArray>(j_audio_data_), kNoOffset,
                            expected_written_size,
                            static_cast<const jbyte*>(buffer));

    int written = env->CallIntMethodOrAbort(j_audio_track_bridge_, "write",
                                            "([BIJ)I", j_audio_data_,
                                            expected_written_size, sync_time);
    if (written < 0) {
      // Error code returned as negative value, like kAudioTrackErrorDeadObject.
      return written;
    }
    SB_DCHECK(written % (channels_ * GetSampleSize(sample_type_)) == 0);
    return written / (channels_ * GetSampleSize(sample_type_));
  }
  SB_NOTREACHED();
  return 0;
}

void AudioTrackAudioSink::SetVolume(double volume) {
  auto* env = JniEnvExt::Get();
  jint status = env->CallIntMethodOrAbort(j_audio_track_bridge_, "setVolume",
                                          "(F)I", static_cast<float>(volume));
  if (status != 0) {
    SB_LOG(ERROR) << "Failed to set volume";
  }
}

int AudioTrackAudioSink::GetUnderrunCount() {
  auto* env = JniEnvExt::Get();
  jint underrun_count = env->CallIntMethodOrAbort(j_audio_track_bridge_,
                                                  "getUnderrunCount", "()I");
  return underrun_count;
}

// static
int AudioTrackAudioSinkType::GetMinBufferSizeInFrames(
    int channels,
    SbMediaAudioSampleType sample_type,
    int sampling_frequency_hz) {
  SB_DCHECK(audio_track_audio_sink_type_);

  JniEnvExt* env = JniEnvExt::Get();
  ScopedLocalJavaRef<jobject> j_audio_output_manager(
      env->CallStarboardObjectMethodOrAbort(
          "getAudioOutputManager", "()Ldev/cobalt/media/AudioOutputManager;"));
  int audio_track_min_buffer_size = static_cast<int>(env->CallIntMethodOrAbort(
      j_audio_output_manager.Get(), "getMinBufferSize", "(III)I",
      GetAudioFormatSampleType(sample_type), sampling_frequency_hz, channels));
  int audio_track_min_buffer_size_in_frames =
      audio_track_min_buffer_size / channels / GetSampleSize(sample_type);
  return std::max(
      audio_track_min_buffer_size_in_frames,
      audio_track_audio_sink_type_->GetMinBufferSizeInFramesInternal(
          channels, sample_type, sampling_frequency_hz));
}

AudioTrackAudioSinkType::AudioTrackAudioSinkType()
    : min_required_frames_tester_(kMaxRequiredFrames,
                                  kRequiredFramesIncrement,
                                  kMinStablePlayedFrames) {}

SbAudioSink AudioTrackAudioSinkType::Create(
    int channels,
    int sampling_frequency_hz,
    SbMediaAudioSampleType audio_sample_type,
    SbMediaAudioFrameStorageType audio_frame_storage_type,
    SbAudioSinkFrameBuffers frame_buffers,
    int frames_per_channel,
    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
    SbAudioSinkPrivate::ConsumeFramesFunc consume_frames_func,
    SbAudioSinkPrivate::ErrorFunc error_func,
    void* context) {
  const SbTime kStartTime = 0;
  const int kTunnelModeAudioSessionId = -1;  // disable tunnel mode
  return Create(channels, sampling_frequency_hz, audio_sample_type,
                audio_frame_storage_type, frame_buffers, frames_per_channel,
                update_source_status_func, consume_frames_func, error_func,
                kStartTime, kTunnelModeAudioSessionId, context);
}

SbAudioSink AudioTrackAudioSinkType::Create(
    int channels,
    int sampling_frequency_hz,
    SbMediaAudioSampleType audio_sample_type,
    SbMediaAudioFrameStorageType audio_frame_storage_type,
    SbAudioSinkFrameBuffers frame_buffers,
    int frames_per_channel,
    SbAudioSinkUpdateSourceStatusFunc update_source_status_func,
    SbAudioSinkPrivate::ConsumeFramesFunc consume_frames_func,
    SbAudioSinkPrivate::ErrorFunc error_func,
    SbTime start_media_time,
    int tunnel_mode_audio_session_id,
    void* context) {
  int min_required_frames = SbAudioSinkGetMinBufferSizeInFrames(
      channels, audio_sample_type, sampling_frequency_hz);
  SB_DCHECK(frames_per_channel >= min_required_frames);
  int preferred_buffer_size_in_bytes =
      min_required_frames * channels * GetSampleSize(audio_sample_type);
  AudioTrackAudioSink* audio_sink = new AudioTrackAudioSink(
      this, channels, sampling_frequency_hz, audio_sample_type, frame_buffers,
      frames_per_channel, preferred_buffer_size_in_bytes,
      update_source_status_func, consume_frames_func, error_func,
      start_media_time, tunnel_mode_audio_session_id, context);
  if (!audio_sink->IsAudioTrackValid()) {
    SB_DLOG(ERROR)
        << "AudioTrackAudioSinkType::Create failed to create audio track";
    Destroy(audio_sink);
    return kSbAudioSinkInvalid;
  }
  return audio_sink;
}

void AudioTrackAudioSinkType::TestMinRequiredFrames() {
  auto onMinRequiredFramesForWebAudioReceived =
      [&](int number_of_channels, SbMediaAudioSampleType sample_type,
          int sample_rate, int min_required_frames) {
        SB_LOG(INFO) << "Received min required frames " << min_required_frames
                     << " for " << number_of_channels << " channels, "
                     << sample_rate << "hz.";
        ScopedLock lock(min_required_frames_map_mutex_);
        min_required_frames_map_[sample_rate] = min_required_frames;
      };

  SbMediaAudioSampleType sample_type = kSbMediaAudioSampleTypeFloat32;
  if (!SbAudioSinkIsAudioSampleTypeSupported(sample_type)) {
    sample_type = kSbMediaAudioSampleTypeInt16Deprecated;
    SB_DCHECK(SbAudioSinkIsAudioSampleTypeSupported(sample_type));
  }
  min_required_frames_tester_.AddTest(2, sample_type, kSampleFrequency48000,
                                      onMinRequiredFramesForWebAudioReceived,
                                      8 * 1024);
  min_required_frames_tester_.AddTest(2, sample_type, kSampleFrequency22050,
                                      onMinRequiredFramesForWebAudioReceived,
                                      4 * 1024);
  min_required_frames_tester_.Start();
}

int AudioTrackAudioSinkType::GetMinBufferSizeInFramesInternal(
    int channels,
    SbMediaAudioSampleType sample_type,
    int sampling_frequency_hz) {
  if (sampling_frequency_hz <= kSampleFrequency22050) {
    ScopedLock lock(min_required_frames_map_mutex_);
    if (min_required_frames_map_.find(kSampleFrequency22050) !=
        min_required_frames_map_.end()) {
      return min_required_frames_map_[kSampleFrequency22050];
    }
  } else if (sampling_frequency_hz <= kSampleFrequency48000) {
    ScopedLock lock(min_required_frames_map_mutex_);
    if (min_required_frames_map_.find(kSampleFrequency48000) !=
        min_required_frames_map_.end()) {
      return min_required_frames_map_[kSampleFrequency48000];
    }
  }
  return kMaxRequiredFrames;
}

}  // namespace shared
}  // namespace android
}  // namespace starboard

// static
void SbAudioSinkPrivate::PlatformInitialize() {
  SB_DCHECK(!audio_track_audio_sink_type_);
  audio_track_audio_sink_type_ =
      new starboard::android::shared::AudioTrackAudioSinkType;
  SetPrimaryType(audio_track_audio_sink_type_);
  EnableFallbackToStub();
  audio_track_audio_sink_type_->TestMinRequiredFrames();
}

// static
void SbAudioSinkPrivate::PlatformTearDown() {
  SB_DCHECK(audio_track_audio_sink_type_ == GetPrimaryType());
  SetPrimaryType(NULL);
  delete audio_track_audio_sink_type_;
  audio_track_audio_sink_type_ = NULL;
}
