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

#ifndef STARBOARD_ANDROID_SHARED_MEDIA_DECODER_H_
#define STARBOARD_ANDROID_SHARED_MEDIA_DECODER_H_

#include <jni.h>

#include <deque>
#include <string>
#include <vector>

#include "starboard/android/shared/drm_system.h"
#include "starboard/android/shared/media_codec_bridge.h"
#include "starboard/common/atomic.h"
#include "starboard/common/condition_variable.h"
#include "starboard/common/mutex.h"
#include "starboard/common/optional.h"
#include "starboard/common/ref_counted.h"
#include "starboard/media.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/media/media_util.h"
#include "starboard/shared/starboard/player/filter/common.h"
#include "starboard/shared/starboard/player/input_buffer_internal.h"
#include "starboard/shared/starboard/player/job_queue.h"
#include "starboard/shared/starboard/thread_checker.h"

namespace starboard {
namespace android {
namespace shared {

// TODO: Better encapsulation the MediaCodecBridge so the decoders no longer
//       need to talk directly to the MediaCodecBridge.
class MediaDecoder
    : private MediaCodecBridge::Handler,
      protected ::starboard::shared::starboard::player::JobQueue::JobOwner {
 public:
  typedef ::starboard::shared::starboard::media::AudioStreamInfo
      AudioStreamInfo;
  typedef ::starboard::shared::starboard::player::filter::ErrorCB ErrorCB;
  typedef ::starboard::shared::starboard::player::InputBuffer InputBuffer;
  typedef ::starboard::shared::starboard::player::InputBuffers InputBuffers;
  typedef std::function<void(int64_t)> FrameRenderedCB;

  // This class should be implemented by the users of MediaDecoder to receive
  // various notifications.  Note that all such functions are called on the
  // decoder thread.
  // TODO: Replace this with std::function<> based callbacks.
  class Host {
   public:
    virtual void ProcessOutputBuffer(MediaCodecBridge* media_codec_bridge,
                                     const DequeueOutputResult& output) = 0;
    virtual void OnEndOfStreamWritten(MediaCodecBridge* media_codec_bridge) = 0;
    virtual void RefreshOutputFormat(MediaCodecBridge* media_codec_bridge) = 0;
    // This function gets called frequently on the decoding thread to give the
    // Host a chance to process when the MediaDecoder is decoding.
    // TODO: Revise the scheduling logic to give the host a chance to process in
    //       a more elegant way.
    virtual bool Tick(MediaCodecBridge* media_codec_bridge) = 0;
    // This function gets called before calling Flush() on the contained
    // MediaCodecBridge so the host can have a chance to do necessary cleanups
    // before the MediaCodecBridge is flushed.
    virtual void OnFlushing() = 0;

   protected:
    ~Host() {}
  };

  MediaDecoder(Host* host,
               const AudioStreamInfo& audio_stream_info,
               SbDrmSystem drm_system);
  MediaDecoder(Host* host,
               SbMediaVideoCodec video_codec,
               // `width_hint` and `height_hint` are used to create the Android
               // video format, which don't have to be directly related to the
               // resolution of the video.
               int width_hint,
               int height_hint,
               optional<int> max_width,
               optional<int> max_height,
               int fps,
               jobject j_output_surface,
               SbDrmSystem drm_system,
               const SbMediaColorMetadata* color_metadata,
               bool require_software_codec,
               const FrameRenderedCB& frame_rendered_cb,
               int tunnel_mode_audio_session_id,
               bool force_big_endian_hdr_metadata,
               int max_video_input_size,
               std::string* error_message);
  ~MediaDecoder();

  void Initialize(const ErrorCB& error_cb);
  void WriteInputBuffers(const InputBuffers& input_buffers);
  void WriteEndOfStream();

  void SetPlaybackRate(double playback_rate);

  size_t GetNumberOfPendingTasks() const {
    return number_of_pending_tasks_.load();
  }

  bool is_valid() const { return media_codec_bridge_ != NULL; }

  bool Flush();

 private:
  struct Event {
    enum Type {
      kInvalid,
      kWriteCodecConfig,
      kWriteInputBuffer,
      kWriteEndOfStream,
    };

    explicit Event(Type type = kInvalid) : type(type) {
      SB_DCHECK(type != kWriteInputBuffer && type != kWriteCodecConfig);
    }
    explicit Event(const std::vector<uint8_t>& codec_config)
        : type(kWriteCodecConfig), codec_config(codec_config) {
      SB_DCHECK(!this->codec_config.empty());
    }
    explicit Event(const scoped_refptr<InputBuffer>& input_buffer)
        : type(kWriteInputBuffer), input_buffer(input_buffer) {}

    Type type;
    scoped_refptr<InputBuffer> input_buffer;
    std::vector<uint8_t> codec_config;
  };

  struct QueueInputBufferTask {
    DequeueInputResult dequeue_input_result;
    Event event;
  };

  static void* DecoderThreadEntryPoint(void* context);
  void DecoderThreadFunc();

  void TeardownCodec();

  void CollectPendingData_Locked(
      std::deque<Event>* pending_tasks,
      std::vector<int>* input_buffer_indices,
      std::vector<DequeueOutputResult>* dequeue_output_results);
  bool ProcessOneInputBuffer(std::deque<Event>* pending_tasks,
                             std::vector<int>* input_buffer_indices);
  void HandleError(const char* action_name, jint status);
  void ReportError(const SbPlayerError error, const std::string error_message);

  // MediaCodecBridge::Handler methods
  // Note that these methods are called from the default looper and is not on
  // the decoder thread.
  void OnMediaCodecError(bool is_recoverable,
                         bool is_transient,
                         const std::string& diagnostic_info) override;
  void OnMediaCodecInputBufferAvailable(int buffer_index) override;
  void OnMediaCodecOutputBufferAvailable(int buffer_index,
                                         int flags,
                                         int offset,
                                         int64_t presentation_time_us,
                                         int size) override;
  void OnMediaCodecOutputFormatChanged() override;
  void OnMediaCodecFrameRendered(int64_t frame_timestamp) override;

  ::starboard::shared::starboard::ThreadChecker thread_checker_;

  const SbMediaType media_type_;
  Host* host_;
  DrmSystem* const drm_system_;
  const FrameRenderedCB frame_rendered_cb_;
  const bool tunnel_mode_enabled_;

  ErrorCB error_cb_;

  bool error_occurred_ = false;
  SbPlayerError error_;
  std::string error_message_;

  atomic_bool stream_ended_;

  atomic_bool destroying_;

  optional<QueueInputBufferTask> pending_queue_input_buffer_task_;

  atomic_int32_t number_of_pending_tasks_;

  Mutex mutex_;
  ConditionVariable condition_variable_;
  std::deque<Event> pending_tasks_;
  std::vector<int> input_buffer_indices_;
  std::vector<DequeueOutputResult> dequeue_output_results_;

  bool is_output_restricted_ = false;
  bool first_call_on_handler_thread_ = true;

  // Working thread to avoid lengthy decoding work block the player thread.
  SbThread decoder_thread_ = kSbThreadInvalid;
  scoped_ptr<MediaCodecBridge> media_codec_bridge_;
};

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

#endif  // STARBOARD_ANDROID_SHARED_MEDIA_DECODER_H_
