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

#ifndef MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_
#define MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_

#include <vector>

#include "base/containers/circular_deque.h"
#include "base/threading/thread_checker.h"
#include "base/timer/elapsed_timer.h"
#include "base/timer/timer.h"
#include "gpu/command_buffer/service/ref_counted_lock.h"
#include "gpu/config/gpu_feature_info.h"
#include "gpu/config/gpu_preferences.h"
#include "media/base/android/media_crypto_context.h"
#include "media/base/android_overlay_mojo_factory.h"
#include "media/base/callback_registry.h"
#include "media/base/cdm_context.h"
#include "media/base/overlay_info.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/gpu/android/android_video_surface_chooser.h"
#include "media/gpu/android/codec_allocator.h"
#include "media/gpu/android/codec_wrapper.h"
#include "media/gpu/android/device_info.h"
#include "media/gpu/android/surface_chooser_helper.h"
#include "media/gpu/android/video_frame_factory.h"
#include "media/gpu/media_gpu_export.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

class MediaLog;
class ScopedAsyncTrace;
struct SupportedVideoDecoderConfig;

struct PendingDecode {
  static PendingDecode CreateEos();
  PendingDecode(scoped_refptr<DecoderBuffer> buffer,
                VideoDecoder::DecodeCB decode_cb);
  PendingDecode(PendingDecode&& other);
  ~PendingDecode();

  scoped_refptr<DecoderBuffer> buffer;
  VideoDecoder::DecodeCB decode_cb;

 private:
  DISALLOW_COPY_AND_ASSIGN(PendingDecode);
};

// An Android VideoDecoder that delegates to MediaCodec.
//
// This decoder initializes in two stages. Low overhead initialization is done
// eagerly in Initialize(), but the rest is done lazily and is kicked off by the
// first Decode() (see StartLazyInit()). We do this because there are cases in
// our media pipeline where we'll initialize a decoder but never use it
// (e.g., MSE with no media data appended), and if we eagerly allocator decoder
// resources, like MediaCodecs and TextureOwners, we will block other
// playbacks that need them.
// TODO: Lazy initialization should be handled at a higher layer of the media
// stack for both simplicity and cross platform support.
class MEDIA_GPU_EXPORT MediaCodecVideoDecoder final
    : public VideoDecoder,
      public gpu::RefCountedLockHelperDrDc {
 public:
  static std::vector<SupportedVideoDecoderConfig> GetSupportedConfigs();

  MediaCodecVideoDecoder(const MediaCodecVideoDecoder&) = delete;
  MediaCodecVideoDecoder& operator=(const MediaCodecVideoDecoder&) = delete;

  ~MediaCodecVideoDecoder() override;
  static void DestroyAsync(std::unique_ptr<MediaCodecVideoDecoder>);

  static std::unique_ptr<VideoDecoder> Create(
      const gpu::GpuPreferences& gpu_preferences,
      const gpu::GpuFeatureInfo& gpu_feature_info,
      std::unique_ptr<MediaLog> media_log,
      DeviceInfo* device_info,
      CodecAllocator* codec_allocator,
      std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser,
      AndroidOverlayMojoFactoryCB overlay_factory_cb,
      RequestOverlayInfoCB request_overlay_info_cb,
      std::unique_ptr<VideoFrameFactory> video_frame_factory,
      scoped_refptr<gpu::RefCountedLock> drdc_lock);

  // VideoDecoder implementation:
  VideoDecoderType GetDecoderType() const override;
  void Initialize(const VideoDecoderConfig& config,
                  bool low_delay,
                  CdmContext* cdm_context,
                  InitCB init_cb,
                  const OutputCB& output_cb,
                  const WaitingCB& waiting_cb) override;
  void Decode(scoped_refptr<DecoderBuffer> buffer, DecodeCB decode_cb) override;
  void Reset(base::OnceClosure closure) override;
  bool NeedsBitstreamConversion() const override;
  bool CanReadWithoutStalling() const override;
  int GetMaxDecodeRequests() const override;

 private:
  // The test has access for PumpCodec() and the constructor.
  friend class MediaCodecVideoDecoderTest;

  MediaCodecVideoDecoder(
      const gpu::GpuPreferences& gpu_preferences,
      const gpu::GpuFeatureInfo& gpu_feature_info,
      std::unique_ptr<MediaLog> media_log,
      DeviceInfo* device_info,
      CodecAllocator* codec_allocator,
      std::unique_ptr<AndroidVideoSurfaceChooser> surface_chooser,
      AndroidOverlayMojoFactoryCB overlay_factory_cb,
      RequestOverlayInfoCB request_overlay_info_cb,
      std::unique_ptr<VideoFrameFactory> video_frame_factory,
      scoped_refptr<gpu::RefCountedLock> drdc_lock);

  // Set up |cdm_context| as part of initialization.  Guarantees that |init_cb|
  // will be called depending on the outcome, though not necessarily before this
  // function returns.
  void SetCdm(CdmContext* cdm_context, InitCB init_cb);

  // Called when the Cdm provides |media_crypto|.  Will signal |init_cb| based
  // on the result, and set the codec config properly.
  void OnMediaCryptoReady(InitCB init_cb,
                          JavaObjectPtr media_crypto,
                          bool requires_secure_video_codec);

  enum class State {
    // Initializing resources required to create a codec.
    kInitializing,
    // Initialization has completed and we're running. This is the only state
    // in which |codec_| might be non-null. If |codec_| is null, a codec
    // creation is pending.
    kRunning,
    // A fatal error occurred. A terminal state.
    kError,
    // The output surface was destroyed, but SetOutputSurface() is not supported
    // by the device. In this case the consumer is responsible for destroying us
    // soon, so this is terminal state but not a decode error.
    kSurfaceDestroyed
  };

  enum class DrainType { kForReset, kForDestroy };

  // Finishes initialization.
  void StartLazyInit();
  void OnVideoFrameFactoryInitialized(
      scoped_refptr<gpu::TextureOwner> texture_owner);

  // Callback for the CDM to notify |this|. Resets |waiting_for_key_| to false,
  // indicating that MediaCodec might now accept buffers.
  void OnCdmContextEvent(CdmContext::Event event);

  // Updates |surface_chooser_| with the new overlay info.
  void OnOverlayInfoChanged(const OverlayInfo& overlay_info);
  void OnSurfaceChosen(std::unique_ptr<AndroidOverlay> overlay);
  void OnSurfaceDestroyed(AndroidOverlay* overlay);

  // Whether we have a codec and its surface is not equal to
  // |target_surface_bundle_|.
  bool SurfaceTransitionPending();

  // Sets |codecs_|'s output surface to |target_surface_bundle_|.
  void TransitionToTargetSurface();

  // Creates a codec asynchronously.
  void CreateCodec();

  // Trampoline helper which ensures correct release of MediaCodecBridge and
  // CodecSurfaceBundle even if this class goes away.
  static void OnCodecConfiguredInternal(
      base::WeakPtr<MediaCodecVideoDecoder> weak_this,
      CodecAllocator* codec_allocator,
      scoped_refptr<CodecSurfaceBundle> surface_bundle,
      std::unique_ptr<MediaCodecBridge> codec);
  void OnCodecConfigured(scoped_refptr<CodecSurfaceBundle> surface_bundle,
                         std::unique_ptr<MediaCodecBridge> media_codec);

  // Flushes the codec, or if flush() is not supported, releases it and creates
  // a new one.
  void FlushCodec();

  // Attempts to queue input and dequeue output from the codec. Calls
  // StartTimerOrPumpCodec() even if the codec is idle when |force_start_timer|.
  void PumpCodec(bool force_start_timer);
  bool QueueInput();
  bool DequeueOutput();

  // Starts |pump_codec_timer_| if it's not started and resets the idle timeout.
  void StartTimerOrPumpCodec();
  void StopTimerIfIdle();

  // Runs |eos_decode_cb_| if it's valid and |reset_generation| matches
  // |reset_generation_|.
  void RunEosDecodeCb(int reset_generation);

  // Forwards |frame| via |output_cb_| if |reset_generation| matches
  // |reset_generation_|.  |async_trace| is the (optional) scoped trace that
  // started when we dequeued the corresponding output buffer.  |started_at| is
  // the wall clock time at which we dequeued the output buffer.
  void ForwardVideoFrame(int reset_generation,
                         std::unique_ptr<ScopedAsyncTrace> async_trace,
                         base::TimeTicks started_at,
                         scoped_refptr<VideoFrame> frame);

  // Starts draining the codec by queuing an EOS if required. It skips the drain
  // if possible.
  void StartDrainingCodec(DrainType drain_type);
  void OnCodecDrained();
  void CancelPendingDecodes(DecodeStatus status);

  // Sets |state_| and does common teardown for the terminal states. |state_|
  // must be either kSurfaceDestroyed or kError.  |reason| will be logged to
  // |media_log_| as an info event ("error" indicates that playback will stop,
  // but we don't know that the renderer will do that).
  void EnterTerminalState(State state, const char* reason);
  bool InTerminalState();

  // Releases |codec_| if it's not null.
  void ReleaseCodec();

  // Return true if we have a codec that's outputting to an overlay.
  bool IsUsingOverlay() const;

  // Notify us about a promotion hint.
  void NotifyPromotionHint(PromotionHintAggregator::Hint hint);

  // Update |cached_frame_information_|.
  void CacheFrameInformation();

  // Creates an overlay factory cb based on the value of overlay_info_.
  AndroidOverlayFactoryCB CreateOverlayFactoryCb();

  // Create a callback that will handle promotion hints, and set the overlay
  // position if required.
  PromotionHintAggregator::NotifyPromotionHintCB CreatePromotionHintCB();

  std::unique_ptr<MediaLog> media_log_;

  State state_ = State::kInitializing;

  // Whether initialization still needs to be done on the first decode call.
  bool lazy_init_pending_ = true;
  base::circular_deque<PendingDecode> pending_decodes_;

  // Whether we've seen MediaCodec return MEDIA_CODEC_NO_KEY indicating that
  // the corresponding key was not set yet, and MediaCodec will not accept
  // buffers until OnCdmContextEvent() is called with kHasAdditionalUsableKey.
  bool waiting_for_key_ = false;

  // The reason for the current drain operation if any.
  absl::optional<DrainType> drain_type_;

  // The current reset cb if a Reset() is in progress.
  base::OnceClosure reset_cb_;

  // A generation counter that's incremented every time Reset() is called.
  int reset_generation_ = 0;

  // The EOS decode cb for an EOS currently being processed by the codec. Called
  // when the EOS is output.
  DecodeCB eos_decode_cb_;

  OutputCB output_cb_;
  WaitingCB waiting_cb_;
  VideoDecoderConfig decoder_config_;

  // Codec specific data (SPS and PPS for H264). Some MediaCodecs initialize
  // more reliably if we explicitly pass these (http://crbug.com/649185).
  std::vector<uint8_t> csd0_;
  std::vector<uint8_t> csd1_;

  std::unique_ptr<CodecWrapper> codec_;
  base::ElapsedTimer idle_timer_;
  base::RepeatingTimer pump_codec_timer_;
  CodecAllocator* codec_allocator_;

  // The current target surface that |codec_| should be rendering to. It
  // reflects the latest surface choice by |surface_chooser_|. If the codec is
  // configured with some other surface, then a transition is pending. It's
  // non-null from the first surface choice.
  scoped_refptr<CodecSurfaceBundle> target_surface_bundle_;

  // A TextureOwner bundle that is kept for the lifetime of MCVD so that if we
  // have to synchronously switch surfaces we always have one available.
  scoped_refptr<CodecSurfaceBundle> texture_owner_bundle_;

  // A callback for requesting overlay info updates.
  RequestOverlayInfoCB request_overlay_info_cb_;

  // The current overlay info, which possibly specifies an overlay to render to.
  OverlayInfo overlay_info_;

  // Set to true if the display compositor swap is done using SurfaceControl.
  const bool is_surface_control_enabled_;

  // The helper which manages our surface chooser for us.
  SurfaceChooserHelper surface_chooser_helper_;

  // The factory for creating VideoFrames from CodecOutputBuffers.
  std::unique_ptr<VideoFrameFactory> video_frame_factory_;

  // An optional factory callback for creating mojo AndroidOverlays.
  AndroidOverlayMojoFactoryCB overlay_factory_cb_;

  DeviceInfo* device_info_;
  bool enable_threaded_texture_mailboxes_;

  // Most recently cached frame information, so that we can dispatch it without
  // recomputing it on every frame.  It changes very rarely.
  SurfaceChooserHelper::FrameInformation cached_frame_information_ =
      SurfaceChooserHelper::FrameInformation::NON_OVERLAY_INSECURE;

  // CDM related stuff.

  // Owned by CDM which is external to this decoder.
  MediaCryptoContext* media_crypto_context_ = nullptr;

  // To keep the CdmContext event callback registered.
  std::unique_ptr<CallbackRegistration> event_cb_registration_;

  // Do we need a hw-secure codec?
  bool requires_secure_codec_ = false;

  bool using_async_api_ = false;

  // Should we flush the codec on the next decode, and pretend that it is
  // drained currently?  Note that we'll automatically flush if the codec is
  // drained; this flag indicates that we also elided the drain, so the codec is
  // in some random state, possibly with output buffers pending.
  bool deferred_flush_pending_ = false;

  // Should we upgrade the next flush to a full release / reallocation of the
  // codec?  This lets us update our hints to the decoder about the size of the
  // expected video.
  bool deferred_reallocation_pending_ = false;

  // Width, in pixels, of the resolution that we last told the codec about.
  int last_width_ = 0;

  // KEY_MAX_INPUT_SIZE configured for the current codec.
  size_t max_input_size_ = 0;

  // Optional crypto object from the Cdm.
  base::android::ScopedJavaGlobalRef<jobject> media_crypto_;

  // For A/B power testing, this causes all non-L1 content to avoid overlays.
  // This is only for A/B power testing, and can be removed after that.
  // See https://crbug.com/1081346 .
  bool allow_nonsecure_overlays_ = true;

  base::WeakPtrFactory<MediaCodecVideoDecoder> weak_factory_{this};
  base::WeakPtrFactory<MediaCodecVideoDecoder> codec_allocator_weak_factory_{
      this};
};

}  // namespace media

namespace std {

// Specialize std::default_delete to call Destroy().
template <>
struct MEDIA_GPU_EXPORT default_delete<media::MediaCodecVideoDecoder>
    : public default_delete<media::VideoDecoder> {};

}  // namespace std

#endif  // MEDIA_GPU_ANDROID_MEDIA_CODEC_VIDEO_DECODER_H_
