// Copyright 2016 Google Inc. 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 "media/base/starboard_player.h"

#include <algorithm>

#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "media/base/shell_media_platform.h"
#include "media/base/starboard_utils.h"
#include "starboard/configuration.h"
#include "starboard/memory.h"

namespace media {

StarboardPlayer::StarboardPlayer(
    const scoped_refptr<base::MessageLoopProxy>& message_loop,
    const AudioDecoderConfig& audio_config,
    const VideoDecoderConfig& video_config,
    SbWindow window,
    SbDrmSystem drm_system,
    Host* host,
    SbPlayerSetBoundsHelper* set_bounds_helper,
    bool prefer_decode_to_texture)
    : message_loop_(message_loop),
      window_(window),
      drm_system_(drm_system),
      host_(host),
      set_bounds_helper_(set_bounds_helper),
      weak_this_(AsWeakPtr()),
      frame_width_(1),
      frame_height_(1),
      ticket_(SB_PLAYER_INITIAL_TICKET),
      volume_(1.0),
      playback_rate_(0.0),
      seek_pending_(false),
      state_(kPlaying) {
  DCHECK(audio_config.IsValidConfig());
  DCHECK(video_config.IsValidConfig());
  DCHECK(host_);
  DCHECK(set_bounds_helper_);

  audio_config_.CopyFrom(audio_config);
  video_config_.CopyFrom(video_config);

#if SB_API_VERSION >= 4
  output_mode_ = ComputeSbPlayerOutputMode(
      MediaVideoCodecToSbMediaVideoCodec(video_config.codec()), drm_system,
      prefer_decode_to_texture);
#endif  // SB_API_VERSION >= 4
  CreatePlayer();

  message_loop->PostTask(
      FROM_HERE,
      base::Bind(&StarboardPlayer::ClearDecoderBufferCache, weak_this_));
}

StarboardPlayer::~StarboardPlayer() {
  DCHECK(message_loop_->BelongsToCurrentThread());

  set_bounds_helper_->SetPlayer(NULL);

  ShellMediaPlatform::Instance()->GetVideoFrameProvider()->SetOutputMode(
      ShellVideoFrameProvider::kOutputModeInvalid);
#if SB_API_VERSION >= 4
  ShellMediaPlatform::Instance()
      ->GetVideoFrameProvider()
      ->ResetGetCurrentSbDecodeTargetFunction();
#endif  // SB_API_VERSION >= 4

  SbPlayerDestroy(player_);
}

void StarboardPlayer::UpdateVideoResolution(int frame_width, int frame_height) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  frame_width_ = frame_width;
  frame_height_ = frame_height;
}

void StarboardPlayer::WriteBuffer(DemuxerStream::Type type,
                                  const scoped_refptr<DecoderBuffer>& buffer) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  // When |state_| is kPlaying, cache all buffer appended.  When |state_| is
  // kSuspended, there may still be left-over buffers appended from the pipeline
  // so they also should be cached.
  // When |state_| is resuming, all buffers come from the cache and shouldn't be
  // cached.
  if (state_ != kResuming) {
    decoder_buffer_cache_.AddBuffer(type, buffer);
  }

  if (state_ == kSuspended) {
    DCHECK(!SbPlayerIsValid(player_));
    return;
  }

  DCHECK(SbPlayerIsValid(player_));

  if (buffer->IsEndOfStream()) {
    SbPlayerWriteEndOfStream(player_, DemuxerStreamTypeToSbMediaType(type));
    return;
  }

  DecodingBuffers::iterator iter = decoding_buffers_.find(buffer->GetData());
  if (iter == decoding_buffers_.end()) {
    decoding_buffers_[buffer->GetData()] = std::make_pair(buffer, 1);
  } else {
    ++iter->second.second;
  }

  SbDrmSampleInfo drm_info;
  SbDrmSubSampleMapping subsample_mapping;
  bool is_encrypted = buffer->GetDecryptConfig();
  SbMediaVideoSampleInfo video_info;

  drm_info.subsample_count = 0;
  video_info.is_key_frame = buffer->IsKeyframe();
  video_info.frame_width = frame_width_;
  video_info.frame_height = frame_height_;

#if SB_API_VERSION >= 4
  SbMediaColorMetadata sb_media_color_metadata =
      MediaToSbMediaColorMetadata(video_config_.webm_color_metadata());
  video_info.color_metadata = &sb_media_color_metadata;
#endif
  if (is_encrypted) {
    FillDrmSampleInfo(buffer, &drm_info, &subsample_mapping);
  }
#if SB_API_VERSION >= 4
  const void* sample_buffers[] = {buffer->GetData()};
  int sample_buffer_sizes[] = {buffer->GetDataSize()};
  SbPlayerWriteSample(player_, DemuxerStreamTypeToSbMediaType(type),
                      sample_buffers, sample_buffer_sizes, 1,
                      TimeDeltaToSbMediaTime(buffer->GetTimestamp()),
                      type == DemuxerStream::VIDEO ? &video_info : NULL,
                      drm_info.subsample_count > 0 ? &drm_info : NULL);
#else   // SB_API_VERSION >= 4
  SbPlayerWriteSample(player_, DemuxerStreamTypeToSbMediaType(type),
                      buffer->GetData(), buffer->GetDataSize(),
                      TimeDeltaToSbMediaTime(buffer->GetTimestamp()),
                      type == DemuxerStream::VIDEO ? &video_info : NULL,
                      drm_info.subsample_count > 0 ? &drm_info : NULL);
#endif  // SB_API_VERSION >= 4
}

void StarboardPlayer::SetBounds(const gfx::Rect& rect) {
  DCHECK(SbPlayerIsValid(player_));

#if SB_API_VERSION >= 4
  const int kZIndex = 0;
  SbPlayerSetBounds(player_, kZIndex, rect.x(), rect.y(), rect.width(),
                    rect.height());
#else   // SB_API_VERSION >= 4
  SbPlayerSetBounds(player_, rect.x(), rect.y(), rect.width(), rect.height());
#endif  // SB_API_VERSION >= 4
}

void StarboardPlayer::PrepareForSeek() {
  DCHECK(message_loop_->BelongsToCurrentThread());
  ++ticket_;
#if SB_API_VERSION < 4
  SbPlayerSetPause(player_, true);
#else   // SB_API_VERSION < 4
  SbPlayerSetPlaybackRate(player_, 0.f);
#endif  // SB_API_VERSION < 4
  seek_pending_ = true;
}

void StarboardPlayer::Seek(base::TimeDelta time) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  decoder_buffer_cache_.ClearAll();

  if (state_ == kSuspended) {
    DCHECK(!SbPlayerIsValid(player_));
    preroll_timestamp_ = time;
    return;
  }

  // If a seek happens during resuming, the pipeline will write samples from the
  // seek target time again so resuming can be aborted.
  if (state_ == kResuming) {
    state_ = kPlaying;
  }

  DCHECK(SbPlayerIsValid(player_));

  ++ticket_;
  SbPlayerSeek(player_, TimeDeltaToSbMediaTime(time), ticket_);
  seek_pending_ = false;
#if SB_API_VERSION < 4
  SbPlayerSetPause(player_, playback_rate_ == 0.0);
#else  // SB_API_VERSION < 4
  SbPlayerSetPlaybackRate(player_, playback_rate_);
#endif  // SB_API_VERSION < 4
}

void StarboardPlayer::SetVolume(float volume) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  volume_ = volume;

  if (state_ == kSuspended) {
    DCHECK(!SbPlayerIsValid(player_));
    return;
  }

  DCHECK(SbPlayerIsValid(player_));
  SbPlayerSetVolume(player_, volume);
}

void StarboardPlayer::SetPlaybackRate(double playback_rate) {
  DCHECK(message_loop_->BelongsToCurrentThread());
  DCHECK(SbPlayerIsValid(player_));

  playback_rate_ = playback_rate;
#if SB_API_VERSION < 4
  SbPlayerSetPause(player_, playback_rate == 0.0);
#else   // SB_API_VERSION < 4
  SbPlayerSetPlaybackRate(player_, playback_rate);
#endif  // SB_API_VERSION < 4
}

void StarboardPlayer::GetInfo(uint32* video_frames_decoded,
                              uint32* video_frames_dropped,
                              base::TimeDelta* media_time) {
  DCHECK(video_frames_decoded || video_frames_dropped || media_time);

  base::AutoLock auto_lock(lock_);
  if (state_ == kSuspended) {
    DCHECK(!SbPlayerIsValid(player_));

    if (video_frames_decoded) {
      *video_frames_decoded = cached_video_frames_decoded_;
    }
    if (video_frames_dropped) {
      *video_frames_dropped = cached_video_frames_dropped_;
    }
    if (media_time) {
      *media_time = preroll_timestamp_;
    }
    return;
  }

  DCHECK(SbPlayerIsValid(player_));

  SbPlayerInfo info;
  SbPlayerGetInfo(player_, &info);
  if (video_frames_decoded) {
    *video_frames_decoded = info.total_video_frames;
  }
  if (video_frames_dropped) {
    *video_frames_dropped = info.dropped_video_frames;
  }
  if (media_time) {
    *media_time = SbMediaTimeToTimeDelta(info.current_media_pts);
  }
}

void StarboardPlayer::Suspend() {
  DCHECK(message_loop_->BelongsToCurrentThread());

  // Check if the player is already suspended.
  if (state_ == kSuspended) {
    DCHECK(!SbPlayerIsValid(player_));
    return;
  }

  DCHECK(SbPlayerIsValid(player_));

#if SB_API_VERSION < 4
  SbPlayerSetPause(player_, true);
#else   // SB_API_VERSION < 4
  SbPlayerSetPlaybackRate(player_, 0.0);
#endif  // SB_API_VERSION < 4

  base::AutoLock auto_lock(lock_);

  state_ = kSuspended;

  SbPlayerInfo info;
  SbPlayerGetInfo(player_, &info);
  cached_video_frames_decoded_ = info.total_video_frames;
  cached_video_frames_dropped_ = info.dropped_video_frames;
  preroll_timestamp_ = SbMediaTimeToTimeDelta(info.current_media_pts);

  set_bounds_helper_->SetPlayer(NULL);
  SbPlayerDestroy(player_);

  player_ = kSbPlayerInvalid;
}

void StarboardPlayer::Resume() {
  DCHECK(message_loop_->BelongsToCurrentThread());

  // Check if the player is already resumed.
  if (state_ != kSuspended) {
    DCHECK(SbPlayerIsValid(player_));
    return;
  }

  DCHECK(!SbPlayerIsValid(player_));

  decoder_buffer_cache_.StartResuming();

  CreatePlayer();

  base::AutoLock auto_lock(lock_);
  state_ = kResuming;
}

namespace {
#if SB_API_VERSION >= 4
ShellVideoFrameProvider::OutputMode ToVideoFrameProviderOutputMode(
    SbPlayerOutputMode output_mode) {
  switch (output_mode) {
    case kSbPlayerOutputModeDecodeToTexture:
      return ShellVideoFrameProvider::kOutputModeDecodeToTexture;
    case kSbPlayerOutputModePunchOut:
      return ShellVideoFrameProvider::kOutputModePunchOut;
    case kSbPlayerOutputModeInvalid:
      return ShellVideoFrameProvider::kOutputModeInvalid;
  }

  NOTREACHED();
  return ShellVideoFrameProvider::kOutputModeInvalid;
}
#endif  // #if SB_API_VERSION >= 4
}  // namespace

void StarboardPlayer::CreatePlayer() {
  DCHECK(message_loop_->BelongsToCurrentThread());

  SbMediaAudioHeader audio_header;
  // TODO: Make this work with non AAC audio.
  audio_header.format_tag = 0x00ff;
  audio_header.number_of_channels =
      ChannelLayoutToChannelCount(audio_config_.channel_layout());
  audio_header.samples_per_second = audio_config_.samples_per_second();
  audio_header.average_bytes_per_second = 1;
  audio_header.block_alignment = 4;
  audio_header.bits_per_sample = audio_config_.bits_per_channel();
  audio_header.audio_specific_config_size = static_cast<uint16_t>(
      std::min(audio_config_.extra_data_size(),
               sizeof(audio_header.audio_specific_config)));
  if (audio_header.audio_specific_config_size > 0) {
    SbMemoryCopy(audio_header.audio_specific_config, audio_config_.extra_data(),
                 audio_header.audio_specific_config_size);
  }

  SbMediaAudioCodec audio_codec =
      MediaAudioCodecToSbMediaAudioCodec(audio_config_.codec());
  SbMediaVideoCodec video_codec =
      MediaVideoCodecToSbMediaVideoCodec(video_config_.codec());

#if SB_API_VERSION >= 4
  DCHECK(SbPlayerOutputModeSupported(output_mode_, video_codec, drm_system_));
#endif  // SB_API_VERSION >= 4

  player_ = SbPlayerCreate(
      window_, video_codec, audio_codec, SB_PLAYER_NO_DURATION, drm_system_,
      &audio_header, &StarboardPlayer::DeallocateSampleCB,
      &StarboardPlayer::DecoderStatusCB, &StarboardPlayer::PlayerStatusCB, this
#if SB_API_VERSION >= 4
      ,
      output_mode_,
      ShellMediaPlatform::Instance()->GetSbDecodeTargetGraphicsContextProvider()
#elif SB_API_VERSION >= 3
      ,
      ShellMediaPlatform::Instance()->GetSbDecodeTargetProvider()  // provider
#endif  // SB_API_VERSION >= 3
          );

#if SB_API_VERSION >= 4
  if (output_mode_ == kSbPlayerOutputModeDecodeToTexture) {
    // If the player is setup to decode to texture, then provide Cobalt with
    // a method of querying that texture.
    ShellMediaPlatform::Instance()
        ->GetVideoFrameProvider()
        ->SetGetCurrentSbDecodeTargetFunction(
            base::Bind(&StarboardPlayer::GetCurrentSbDecodeTarget,
                       base::Unretained(this)));
  }
  ShellMediaPlatform::Instance()->GetVideoFrameProvider()->SetOutputMode(
      ToVideoFrameProviderOutputMode(output_mode_));
#else   // SB_API_VERSION >= 4
  ShellMediaPlatform::Instance()->GetVideoFrameProvider()->SetOutputMode(
      ShellVideoFrameProvider::kOutputModePunchOut);
#endif  // SB_API_VERSION >= 4
  set_bounds_helper_->SetPlayer(this);
}

#if SB_API_VERSION >= 4
SbDecodeTarget StarboardPlayer::GetCurrentSbDecodeTarget() {
  return SbPlayerGetCurrentFrame(player_);
}
SbPlayerOutputMode StarboardPlayer::GetSbPlayerOutputMode() {
  return output_mode_;
}
#endif  // SB_API_VERSION >= 4

void StarboardPlayer::ClearDecoderBufferCache() {
  DCHECK(message_loop_->BelongsToCurrentThread());

  base::TimeDelta media_time;
  GetInfo(NULL, NULL, &media_time);
  decoder_buffer_cache_.ClearSegmentsBeforeMediaTime(media_time);

  message_loop_->PostDelayedTask(
      FROM_HERE,
      base::Bind(&StarboardPlayer::ClearDecoderBufferCache, weak_this_),
      base::TimeDelta::FromMilliseconds(
          kClearDecoderCacheIntervalInMilliseconds));
}

void StarboardPlayer::OnDecoderStatus(SbPlayer player,
                                      SbMediaType type,
                                      SbPlayerDecoderState state,
                                      int ticket) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  if (player_ != player || ticket != ticket_) {
    return;
  }

  DCHECK_NE(state_, kSuspended);

  switch (state) {
    case kSbPlayerDecoderStateNeedsData:
      break;
    case kSbPlayerDecoderStateBufferFull:
      DLOG(WARNING) << "kSbPlayerDecoderStateBufferFull has been deprecated.";
      return;
    case kSbPlayerDecoderStateDestroyed:
      return;
  }

  if (state_ == kResuming) {
    DemuxerStream::Type stream_type = SbMediaTypeToDemuxerStreamType(type);
    if (decoder_buffer_cache_.GetBuffer(stream_type)) {
      WriteBuffer(stream_type, decoder_buffer_cache_.GetBuffer(stream_type));
      decoder_buffer_cache_.AdvanceToNextBuffer(stream_type);
      return;
    }
    if (!decoder_buffer_cache_.GetBuffer(DemuxerStream::AUDIO) &&
        !decoder_buffer_cache_.GetBuffer(DemuxerStream::VIDEO)) {
      state_ = kPlaying;
    }
  }

  host_->OnNeedData(SbMediaTypeToDemuxerStreamType(type));
}

void StarboardPlayer::OnPlayerStatus(SbPlayer player,
                                     SbPlayerState state,
                                     int ticket) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  if (player_ != player) {
    return;
  }

  DCHECK_NE(state_, kSuspended);

  if (ticket != SB_PLAYER_INITIAL_TICKET && ticket != ticket_) {
    return;
  }

  if (state == kSbPlayerStateInitialized) {
    if (ticket_ == SB_PLAYER_INITIAL_TICKET) {
      ++ticket_;
    }
    SbPlayerSeek(player_, TimeDeltaToSbMediaTime(preroll_timestamp_), ticket_);
    SetVolume(volume_);
#if SB_API_VERSION < 4
    SbPlayerSetPause(player_, playback_rate_ == 0.0);
#else  // SB_API_VERSION < 4
    SbPlayerSetPlaybackRate(player_, playback_rate_);
#endif  // SB_API_VERSION < 4
    return;
  }
  host_->OnPlayerStatus(state);
}

void StarboardPlayer::OnDeallocateSample(const void* sample_buffer) {
  DCHECK(message_loop_->BelongsToCurrentThread());

  DecodingBuffers::iterator iter = decoding_buffers_.find(sample_buffer);
  DCHECK(iter != decoding_buffers_.end());
  if (iter == decoding_buffers_.end()) {
    LOG(ERROR) << "StarboardPlayer::OnDeallocateSample encounters unknown "
               << "sample_buffer " << sample_buffer;
    return;
  }
  --iter->second.second;
  if (iter->second.second == 0) {
    decoding_buffers_.erase(iter);
  }
}

// static
void StarboardPlayer::DecoderStatusCB(SbPlayer player,
                                      void* context,
                                      SbMediaType type,
                                      SbPlayerDecoderState state,
                                      int ticket) {
  StarboardPlayer* helper = reinterpret_cast<StarboardPlayer*>(context);
  helper->message_loop_->PostTask(
      FROM_HERE, base::Bind(&StarboardPlayer::OnDecoderStatus,
                            helper->weak_this_, player, type, state, ticket));
}

// static
void StarboardPlayer::PlayerStatusCB(SbPlayer player,
                                     void* context,
                                     SbPlayerState state,
                                     int ticket) {
  StarboardPlayer* helper = reinterpret_cast<StarboardPlayer*>(context);
  helper->message_loop_->PostTask(
      FROM_HERE, base::Bind(&StarboardPlayer::OnPlayerStatus,
                            helper->weak_this_, player, state, ticket));
}

// static
void StarboardPlayer::DeallocateSampleCB(SbPlayer player,
                                         void* context,
                                         const void* sample_buffer) {
  StarboardPlayer* helper = reinterpret_cast<StarboardPlayer*>(context);
  helper->message_loop_->PostTask(
      FROM_HERE, base::Bind(&StarboardPlayer::OnDeallocateSample,
                            helper->weak_this_, sample_buffer));
}

#if SB_API_VERSION >= 4
// static
SbPlayerOutputMode StarboardPlayer::ComputeSbPlayerOutputMode(
    SbMediaVideoCodec codec,
    SbDrmSystem drm_system,
    bool prefer_decode_to_texture) {
  // Try to choose the output mode according to the passed in value of
  // |prefer_decode_to_texture|.  If the preferred output mode is unavailable
  // though, fallback to an output mode that is available.
  SbPlayerOutputMode output_mode = kSbPlayerOutputModeInvalid;
  if (SbPlayerOutputModeSupported(kSbPlayerOutputModePunchOut, codec,
                                  drm_system)) {
    output_mode = kSbPlayerOutputModePunchOut;
  }
  if ((prefer_decode_to_texture || output_mode == kSbPlayerOutputModeInvalid) &&
      SbPlayerOutputModeSupported(kSbPlayerOutputModeDecodeToTexture, codec,
                                  drm_system)) {
    output_mode = kSbPlayerOutputModeDecodeToTexture;
  }
  CHECK_NE(kSbPlayerOutputModeInvalid, output_mode);

  return output_mode;
}
#endif  // SB_API_VERSION >= 4

}  // namespace media
