// Copyright (c) 2012 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_BASE_VIDEO_DECODER_H_
#define MEDIA_BASE_VIDEO_DECODER_H_

#include <string>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/decode_status.h"
#include "media/base/media_export.h"
#include "media/base/pipeline_status.h"
#include "media/base/waiting.h"
#include "ui/gfx/geometry/size.h"

namespace media {

class CdmContext;
class DecoderBuffer;
class VideoDecoderConfig;
class VideoFrame;

class MEDIA_EXPORT VideoDecoder {
 public:
  // Callback for VideoDecoder initialization.
  using InitCB = base::Callback<void(bool success)>;

  // Callback for VideoDecoder to return a decoded frame whenever it becomes
  // available. Only non-EOS frames should be returned via this callback.
  using OutputCB = base::Callback<void(const scoped_refptr<VideoFrame>&)>;

  // Callback type for Decode(). Called after the decoder has completed decoding
  // corresponding DecoderBuffer, indicating that it's ready to accept another
  // buffer to decode.
  using DecodeCB = base::Callback<void(DecodeStatus)>;

  VideoDecoder();

  // Returns the name of the decoder for logging and decoder selection purposes.
  // This name should be available immediately after construction (e.g. before
  // Initialize() is called). It should also be stable in the sense that the
  // name does not change across multiple constructions.
  virtual std::string GetDisplayName() const = 0;

  // Returns true if the implementation is expected to be implemented by the
  // platform. The value should be available immediately after construction and
  // should not change within the lifetime of a decoder instance. The value is
  // used for logging and metrics recording.
  //
  // TODO(sandersd): Use this to decide when to switch to software decode for
  // low-resolution videos. https://crbug.com/684792
  virtual bool IsPlatformDecoder() const;

  // Initializes a VideoDecoder with the given |config|, executing the
  // |init_cb| upon completion. |output_cb| is called for each output frame
  // decoded by Decode().
  //
  // If |low_delay| is true then the decoder is not allowed to queue frames,
  // except for out-of-order frames, i.e. if the next frame can be returned it
  // must be returned without waiting for Decode() to be called again.
  // Initialization should fail if |low_delay| is true and the decoder cannot
  // satisfy the requirements above.
  //
  // |cdm_context| can be used to handle encrypted buffers. May be null if the
  // stream is not encrypted.
  //
  // |waiting_cb| is called whenever the decoder is stalled waiting for
  // something, e.g. decryption key. May be called at any time after
  // Initialize().
  //
  // Note:
  // 1) The VideoDecoder will be reinitialized if it was initialized before.
  //    Upon reinitialization, all internal buffered frames will be dropped.
  // 2) This method should not be called during pending decode or reset.
  // 3) No VideoDecoder calls should be made before |init_cb| is executed.
  // 4) VideoDecoders should take care to run |output_cb| as soon as the frame
  // is ready (i.e. w/o thread trampolining) since it can strongly affect frame
  // delivery times with high-frame-rate material.  See Decode() for additional
  // notes.
  // 5) |init_cb| may be called before this returns.
  virtual void Initialize(const VideoDecoderConfig& config,
                          bool low_delay,
                          CdmContext* cdm_context,
                          const InitCB& init_cb,
                          const OutputCB& output_cb,
                          const WaitingCB& waiting_cb) = 0;

  // Requests a |buffer| to be decoded. The status of the decoder and decoded
  // frame are returned via the provided callback. Some decoders may allow
  // decoding multiple buffers in parallel. Callers should call
  // GetMaxDecodeRequests() to get number of buffers that may be decoded in
  // parallel.
  //
  // Implementations guarantee that the |decode_cb| will not be called from
  // within this method, and that it will be called even if Decode() is never
  // called again.
  //
  // After decoding is finished the decoder calls |output_cb| specified in
  // Initialize() for each decoded frame. |output_cb| may be called before or
  // after |decode_cb|, including before Decode() returns.
  //
  // If |buffer| is an EOS buffer then the decoder must be flushed, i.e.
  // |output_cb| must be called for each frame pending in the queue and
  // |decode_cb| must be called after that. Callers will not call Decode()
  // again until after the flush completes.
  virtual void Decode(scoped_refptr<DecoderBuffer> buffer,
                      const DecodeCB& decode_cb) = 0;

  // Resets decoder state. All pending Decode() requests will be finished or
  // aborted before |closure| is called.
  // Note: No VideoDecoder calls should be made before |closure| is executed.
  virtual void Reset(const base::Closure& closure) = 0;

  // Returns true if the decoder needs bitstream conversion before decoding.
  virtual bool NeedsBitstreamConversion() const;

  // Returns true if the decoder currently has the ability to decode and return
  // a VideoFrame. Most implementations can allocate a new VideoFrame and hence
  // this will always return true. Override and return false for decoders that
  // use a fixed set of VideoFrames for decoding.
  virtual bool CanReadWithoutStalling() const;

  // Returns maximum number of parallel decode requests.
  virtual int GetMaxDecodeRequests() const;

  // Returns the recommended number of threads for software video decoding. If
  // the --video-threads command line option is specified and is valid, that
  // value is returned. Otherwise |desired_threads| is clamped to the number of
  // logical processors and then further clamped to
  // [|limits::kMinVideoDecodeThreads|, |limits::kMaxVideoDecodeThreads|].
  static int GetRecommendedThreadCount(int desired_threads);

 protected:
  // Deletion is only allowed via Destroy().
  virtual ~VideoDecoder();

 private:
  friend struct std::default_delete<VideoDecoder>;

  // Fires any pending callbacks, stops and destroys the decoder. After this
  // call, external resources (e.g. raw pointers) |this| holds might be
  // invalidated immediately. So if the decoder is destroyed asynchronously
  // (e.g. DeleteSoon), external resources must be released in this call.
  virtual void Destroy();

  DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
};

}  // namespace media

namespace std {

// Specialize std::default_delete to call Destroy().
template <>
struct MEDIA_EXPORT default_delete<media::VideoDecoder> {
  constexpr default_delete() = default;

  template <typename U,
            typename = typename std::enable_if<
                std::is_convertible<U*, media::VideoDecoder*>::value>::type>
  default_delete(const default_delete<U>& d) {}

  void operator()(media::VideoDecoder* ptr) const;
};

}  // namespace std

#endif  // MEDIA_BASE_VIDEO_DECODER_H_
