// Copyright 2018 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/shared/starboard/player/filter/player_components.h"

#include <wrl/client.h>

#include <functional>

#include "starboard/common/device_type.h"
#include "starboard/common/log.h"
#include "starboard/common/ref_counted.h"
#include "starboard/common/scoped_ptr.h"
#include "starboard/common/system_property.h"
#include "starboard/shared/opus/opus_audio_decoder.h"
#include "starboard/shared/starboard/media/media_support_internal.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/filter/adaptive_audio_decoder_internal.h"
#include "starboard/shared/starboard/player/filter/audio_decoder_internal.h"
#include "starboard/shared/starboard/player/filter/audio_renderer_internal_pcm.h"
#include "starboard/shared/starboard/player/filter/audio_renderer_sink_impl.h"
#include "starboard/shared/starboard/player/filter/media_time_provider_impl.h"
#include "starboard/shared/starboard/player/filter/video_decoder_internal.h"
#include "starboard/shared/starboard/player/filter/video_render_algorithm.h"
#include "starboard/shared/starboard/player/filter/video_render_algorithm_impl.h"
#include "starboard/shared/starboard/player/filter/video_renderer_internal_impl.h"
#include "starboard/shared/starboard/player/filter/video_renderer_sink.h"
#include "starboard/shared/uwp/application_uwp.h"
#include "starboard/shared/uwp/audio_renderer_passthrough.h"
#include "starboard/shared/uwp/extended_resources_manager.h"
#include "starboard/shared/win32/audio_decoder.h"
#include "starboard/xb1/shared/video_decoder_uwp.h"

#if defined(INTERNAL_BUILD)
#include "internal/starboard/xb1/dav1d_video_decoder.h"
#include "internal/starboard/xb1/vpx_video_decoder.h"
#endif  // defined(INTERNAL_BUILD)

namespace starboard {
namespace shared {
namespace starboard {
namespace player {
namespace filter {

namespace {

using ::starboard::shared::uwp::AudioRendererPassthrough;

double GetRefreshRate() {
  return static_cast<double>(uwp::ApplicationUwp::Get()->GetRefreshRate());
}

bool IsHdrVideo(const media::VideoStreamInfo& video_stream_info) {
  const auto& mime = video_stream_info.mime;
  const auto& primaries = video_stream_info.color_metadata.primaries;
  return mime.find("codecs=\"vp9.2") != mime.npos ||
         mime.find("codecs=\"vp09.02") != mime.npos ||
         primaries == kSbMediaPrimaryIdBt2020;
}

class PlayerComponentsPassthrough
    : public ::starboard::shared::starboard::player::filter::PlayerComponents {
 public:
  PlayerComponentsPassthrough(
      scoped_ptr<AudioRendererPassthrough> audio_renderer,
      scoped_ptr<VideoRenderer> video_renderer)
      : audio_renderer_(audio_renderer.Pass()),
        video_renderer_(video_renderer.Pass()) {}

 private:
  // PlayerComponents methods
  MediaTimeProvider* GetMediaTimeProvider() override {
    return audio_renderer_.get();
  }
  AudioRenderer* GetAudioRenderer() override { return audio_renderer_.get(); }
  VideoRenderer* GetVideoRenderer() override { return video_renderer_.get(); }

  scoped_ptr<AudioRendererPassthrough> audio_renderer_;
  scoped_ptr<VideoRenderer> video_renderer_;
};

class PlayerComponentsFactory : public PlayerComponents::Factory {
  using AudioRendererPassthrough =
      ::starboard::shared::uwp::AudioRendererPassthrough;
  scoped_ptr<PlayerComponents> CreateComponents(
      const CreationParameters& creation_parameters,
      std::string* error_message) override {
    SB_DCHECK(creation_parameters.audio_codec() != kSbMediaAudioCodecNone ||
              creation_parameters.video_codec() != kSbMediaVideoCodecNone);
    SB_DCHECK(error_message);

    if (creation_parameters.audio_codec() != kSbMediaAudioCodecAc3 &&
        creation_parameters.audio_codec() != kSbMediaAudioCodecEac3) {
      SB_LOG(INFO) << "Creating non pass-through components.";
      return PlayerComponents::Factory::CreateComponents(creation_parameters,
                                                         error_message);
    }

    SB_LOG(INFO) << "Creating pass-through components.";

    scoped_ptr<AudioDecoder> audio_decoder;
    scoped_ptr<AudioRendererPassthrough> audio_renderer;
    scoped_ptr<AudioRendererSink> audio_renderer_sink;
    scoped_ptr<VideoDecoder> video_decoder;
    scoped_ptr<VideoRenderAlgorithm> video_render_algorithm;
    scoped_refptr<VideoRendererSink> video_renderer_sink;
    scoped_ptr<VideoRendererImpl> video_renderer;

    if (!CreateSubComponents(creation_parameters, &audio_decoder,
                             &audio_renderer_sink, &video_decoder,
                             &video_render_algorithm, &video_renderer_sink,
                             error_message)) {
      return scoped_ptr<PlayerComponents>();
    }
    audio_renderer =
        scoped_ptr<AudioRendererPassthrough>(new AudioRendererPassthrough(
            audio_decoder.Pass(), creation_parameters.audio_stream_info()));
    if (creation_parameters.video_codec() != kSbMediaVideoCodecNone) {
      SB_DCHECK(video_decoder);
      SB_DCHECK(video_render_algorithm);

      MediaTimeProvider* media_time_provider = audio_renderer.get();
      video_renderer.reset(new VideoRendererImpl(
          video_decoder.Pass(), media_time_provider,
          video_render_algorithm.Pass(), video_renderer_sink));
    }

    return scoped_ptr<PlayerComponents>(new PlayerComponentsPassthrough(
        audio_renderer.Pass(), video_renderer.Pass()));
  }

  bool CreateSubComponents(
      const CreationParameters& creation_parameters,
      scoped_ptr<AudioDecoder>* audio_decoder,
      scoped_ptr<AudioRendererSink>* audio_renderer_sink,
      scoped_ptr<VideoDecoder>* video_decoder,
      scoped_ptr<VideoRenderAlgorithm>* video_render_algorithm,
      scoped_refptr<VideoRendererSink>* video_renderer_sink,
      std::string* error_message) override {
    SB_DCHECK(error_message);

    if (creation_parameters.audio_codec() != kSbMediaAudioCodecNone) {
      SB_DCHECK(audio_decoder);
      SB_DCHECK(audio_renderer_sink);

      auto decoder_creator = [](const media::AudioStreamInfo& audio_stream_info,
                                SbDrmSystem drm_system) {
        using AacAudioDecoder = ::starboard::shared::win32::AudioDecoder;
        using OpusAudioDecoder = ::starboard::shared::opus::OpusAudioDecoder;

        if (audio_stream_info.codec == kSbMediaAudioCodecAac) {
          return scoped_ptr<AudioDecoder>(
              new AacAudioDecoder(audio_stream_info, drm_system));
        } else if (audio_stream_info.codec == kSbMediaAudioCodecOpus) {
          scoped_ptr<OpusAudioDecoder> audio_decoder_impl(
              new OpusAudioDecoder(audio_stream_info));
          if (audio_decoder_impl->is_valid()) {
            return audio_decoder_impl.PassAs<AudioDecoder>();
          }
        } else {
          SB_NOTREACHED();
        }
        return scoped_ptr<AudioDecoder>();
      };

      auto audio_codec = creation_parameters.audio_stream_info().codec;
      if (audio_codec != kSbMediaAudioCodecAc3 &&
          audio_codec != kSbMediaAudioCodecEac3) {
        audio_decoder->reset(new AdaptiveAudioDecoder(
            creation_parameters.audio_stream_info(),
            creation_parameters.drm_system(), decoder_creator));
      } else {
        // Use win32::AudioDecoder to decrypt and reformat the bitstream for the
        // passthrough AudioRenderer.
        audio_decoder->reset(new ::starboard::shared::win32::AudioDecoder(
            creation_parameters.audio_stream_info(),
            creation_parameters.drm_system()));
      }
      audio_renderer_sink->reset(new AudioRendererSinkImpl);
    }

    const auto video_codec = creation_parameters.video_codec();
    if (video_codec == kSbMediaVideoCodecNone) {
      return true;
    }

    using MftVideoDecoder = ::starboard::xb1::shared::VideoDecoderUwp;
    using ExtendedResourcesManager = shared::uwp::ExtendedResourcesManager;

    const auto output_mode = creation_parameters.output_mode();
    const auto is_hdr_video =
        IsHdrVideo(creation_parameters.video_stream_info());

    if (video_codec == kSbMediaVideoCodecH264 ||
        (video_codec == kSbMediaVideoCodecVp9 &&
         MftVideoDecoder::IsHardwareVp9DecoderSupported()) ||
        (video_codec == kSbMediaVideoCodecAv1 &&
         MftVideoDecoder::IsHardwareAv1DecoderSupported())) {
      video_render_algorithm->reset(
          new VideoRenderAlgorithmImpl(std::bind(GetRefreshRate)));
      // The memory heap for gpu decoders isn't used by hw decoders.
      // Release it.
      ExtendedResourcesManager::GetInstance()->ReleaseBuffersHeap();
      video_decoder->reset(new MftVideoDecoder(
          video_codec, output_mode,
          creation_parameters.decode_target_graphics_context_provider(),
          creation_parameters.drm_system()));
      return true;
    }

#if !SB_HAS(GPU_DECODERS_ON_DESKTOP)
#if SB_API_VERSION < 15
    if (SbSystemGetDeviceType() == kSbSystemDeviceTypeDesktopPC) {
      SB_LOG(WARNING) << "GPU decoder disabled on Desktop.";
      return false;
    }
#else
    if (GetSystemPropertyString(kSbSystemPropertyDeviceType) ==
        kSystemDeviceTypeDesktopPC) {
      SB_LOG(WARNING) << "GPU decoder disabled on Desktop.";
      return false;
    }
#endif
#endif  // !SB_HAS(GPU_DECODERS_ON_DESKTOP)
    if (video_codec != kSbMediaVideoCodecVp9 &&
        video_codec != kSbMediaVideoCodecAv1) {
      return false;
    }
    SB_DCHECK(output_mode == kSbPlayerOutputModeDecodeToTexture);

    Microsoft::WRL::ComPtr<ID3D12Device> d3d12device;
    Microsoft::WRL::ComPtr<ID3D12Heap> d3d12buffer_heap;
    void* d3d12queue = nullptr;
    if (!uwp::ExtendedResourcesManager::GetInstance()->GetD3D12Objects(
            &d3d12device, &d3d12buffer_heap, &d3d12queue)) {
      // Somehow extended resources get lost.  Returns directly to trigger an
      // error to the player.
      *error_message =
          "Failed to obtain D3D12Device and/or D3D12queue required for "
          "instantiating GPU based decoders.";
      SB_LOG(ERROR) << *error_message;
      return false;
    }
    SB_DCHECK(d3d12device);
    SB_DCHECK(d3d12buffer_heap);
    SB_DCHECK(d3d12queue);

#if defined(INTERNAL_BUILD)
    using GpuVp9VideoDecoder = ::starboard::xb1::shared::VpxVideoDecoder;
    using GpuAv1VideoDecoder = ::starboard::xb1::shared::Dav1dVideoDecoder;

    if (video_codec == kSbMediaVideoCodecVp9) {
      video_decoder->reset(new GpuVp9VideoDecoder(
          creation_parameters.decode_target_graphics_context_provider(),
          creation_parameters.video_stream_info(), is_hdr_video, d3d12device,
          d3d12buffer_heap, d3d12queue));
    }

    if (video_codec == kSbMediaVideoCodecAv1) {
      video_decoder->reset(new GpuAv1VideoDecoder(
          creation_parameters.decode_target_graphics_context_provider(),
          creation_parameters.video_stream_info(), is_hdr_video, d3d12device,
          d3d12buffer_heap, d3d12queue));
    }
#endif  // defined(INTERNAL_BUILD)

    if (video_decoder) {
      video_render_algorithm->reset(
          new VideoRenderAlgorithmImpl(std::bind(GetRefreshRate)));
      return true;
    }

    *error_message = FormatString(
        "Unsupported video codec %d or insufficient resources to its creation.",
        video_codec);
    SB_LOG(ERROR) << *error_message;
    return false;
  }
};

}  // namespace

// static
scoped_ptr<PlayerComponents::Factory> PlayerComponents::Factory::Create() {
  return make_scoped_ptr<PlayerComponents::Factory>(
      new PlayerComponentsFactory);
}

// static
bool PlayerComponents::Factory::OutputModeSupported(
    SbPlayerOutputMode output_mode,
    SbMediaVideoCodec codec,
    SbDrmSystem drm_system) {
  return output_mode == kSbPlayerOutputModeDecodeToTexture;
}

}  // namespace filter
}  // namespace player
}  // namespace starboard
}  // namespace shared
}  // namespace starboard
