// 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 COBALT_MEDIA_BASE_VIDEO_FRAME_H_
#define COBALT_MEDIA_BASE_VIDEO_FRAME_H_

#include <memory>
#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/callback.h"
#include "base/md5.h"
#include "base/memory/shared_memory.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "cobalt/math/gpu_memory_buffer.h"
#include "cobalt/math/rect.h"
#include "cobalt/math/size.h"
#include "cobalt/media/base/color_space.h"
#include "cobalt/media/base/video_frame_metadata.h"
#include "cobalt/media/base/video_types.h"
#include "gpu/command_buffer/common/mailbox_holder.h"
#include "starboard/types.h"

#if defined(OS_MACOSX)
#include <CoreVideo/CVPixelBuffer.h>
#include "base/mac/scoped_cftyperef.h"
#endif

namespace cobalt {
namespace media {

class MEDIA_EXPORT VideoFrame : public base::RefCountedThreadSafe<VideoFrame> {
 public:
  enum {
    kFrameSizeAlignment = 16,
    kFrameSizePadding = 16,
    kFrameAddressAlignment = 32
  };

  enum {
    kMaxPlanes = 4,

    kYPlane = 0,
    kARGBPlane = kYPlane,
    kUPlane = 1,
    kUVPlane = kUPlane,
    kVPlane = 2,
    kAPlane = 3,
  };

  // Defines the pixel storage type. Differentiates between directly accessible
  // |data_| and pixels that are only indirectly accessible and not via mappable
  // memory.
  // Note that VideoFrames of any StorageType can also have Texture backing,
  // with "classical" GPU Driver-only textures identified as STORAGE_OPAQUE.
  enum StorageType {
    STORAGE_UNKNOWN = 0,
    STORAGE_OPAQUE = 1,  // We don't know how VideoFrame's pixels are stored.
    STORAGE_UNOWNED_MEMORY = 2,  // External, non owned data pointers.
    STORAGE_OWNED_MEMORY = 3,  // VideoFrame has allocated its own data buffer.
    STORAGE_SHMEM = 4,         // Pixels are backed by Shared Memory.
#if defined(OS_LINUX)
    // TODO(mcasas): Consider turning this type into STORAGE_NATIVE or another
    // meaningful name and handle it appropriately in all cases.
    STORAGE_DMABUFS = 5,  // Each plane is stored into a DmaBuf.
#endif
    STORAGE_GPU_MEMORY_BUFFERS = 6,
    STORAGE_MOJO_SHARED_BUFFER = 7,
    STORAGE_LAST = STORAGE_MOJO_SHARED_BUFFER,
  };

  // CB to be called on the mailbox backing this frame when the frame is
  // destroyed.
  typedef base::Callback<void(const gpu::SyncToken&)> ReleaseMailboxCB;

  // Interface representing client operations on a SyncToken, i.e. insert one in
  // the GPU Command Buffer and wait for it.
  class SyncTokenClient {
   public:
    SyncTokenClient() {}
    virtual void GenerateSyncToken(gpu::SyncToken* sync_token) = 0;
    virtual void WaitSyncToken(const gpu::SyncToken& sync_token) = 0;

   protected:
    virtual ~SyncTokenClient() {}

   private:
    DISALLOW_COPY_AND_ASSIGN(SyncTokenClient);
  };

  // Call prior to CreateFrame to ensure validity of frame configuration. Called
  // automatically by VideoDecoderConfig::IsValidConfig().
  static bool IsValidConfig(VideoPixelFormat format, StorageType storage_type,
                            const math::Size& coded_size,
                            const math::Rect& visible_rect,
                            const math::Size& natural_size);

  // Creates a new YUV frame in system memory with given parameters (|format|
  // must be YUV). Buffers for the frame are allocated but not initialized. The
  // caller most not make assumptions about the actual underlying size(s), but
  // check the returned VideoFrame instead.
  // TODO(mcasas): implement the RGB version of this factory method.
  static scoped_refptr<VideoFrame> CreateFrame(VideoPixelFormat format,
                                               const math::Size& coded_size,
                                               const math::Rect& visible_rect,
                                               const math::Size& natural_size,
                                               base::TimeDelta timestamp);

  // Offers the same functionality as CreateFrame, and additionally zeroes out
  // the initial allocated buffers.
  static scoped_refptr<VideoFrame> CreateZeroInitializedFrame(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      base::TimeDelta timestamp);

  // Wraps a set of native textures with a VideoFrame.
  // |mailbox_holders_release_cb| will be called with a sync token as the
  // argument when the VideoFrame is to be destroyed.
  static scoped_refptr<VideoFrame> WrapNativeTextures(
      VideoPixelFormat format,
      const gpu::MailboxHolder (&mailbox_holder)[kMaxPlanes],
      const ReleaseMailboxCB& mailbox_holders_release_cb,
      const math::Size& coded_size, const math::Rect& visible_rect,
      const math::Size& natural_size, base::TimeDelta timestamp);

  // Wraps packed image data residing in a memory buffer with a VideoFrame.
  // The image data resides in |data| and is assumed to be packed tightly in a
  // buffer of logical dimensions |coded_size| with the appropriate bit depth
  // and plane count as given by |format|. Returns NULL on failure.
  static scoped_refptr<VideoFrame> WrapExternalData(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      uint8_t* data, size_t data_size, base::TimeDelta timestamp);

  // Same as WrapExternalData() with SharedMemoryHandle and its offset.
  static scoped_refptr<VideoFrame> WrapExternalSharedMemory(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      uint8_t* data, size_t data_size, base::SharedMemoryHandle handle,
      size_t shared_memory_offset, base::TimeDelta timestamp);

  // Wraps external YUV data of the given parameters with a VideoFrame.
  // The returned VideoFrame does not own the data passed in.
  static scoped_refptr<VideoFrame> WrapExternalYuvData(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      int32_t y_stride, int32_t u_stride, int32_t v_stride, uint8_t* y_data,
      uint8_t* u_data, uint8_t* v_data, base::TimeDelta timestamp);

  // Wraps external YUV data with the given parameters with a VideoFrame.
  // The returned VideoFrame does not own the GpuMemoryBuffers passed in.
  static scoped_refptr<VideoFrame> WrapExternalYuvGpuMemoryBuffers(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      int32_t y_stride, int32_t u_stride, int32_t v_stride, uint8_t* y_data,
      uint8_t* u_data, uint8_t* v_data,
      const gfx::GpuMemoryBufferHandle& y_handle,
      const gfx::GpuMemoryBufferHandle& u_handle,
      const gfx::GpuMemoryBufferHandle& v_handle, base::TimeDelta timestamp);

  // Wraps external YUVA data of the given parameters with a VideoFrame.
  // The returned VideoFrame does not own the data passed in.
  static scoped_refptr<VideoFrame> WrapExternalYuvaData(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      int32_t y_stride, int32_t u_stride, int32_t v_stride, int32_t a_stride,
      uint8_t* y_data, uint8_t* u_data, uint8_t* v_data, uint8_t* a_data,
      base::TimeDelta timestamp);

#if defined(OS_LINUX)
  // Wraps provided dmabufs
  // (https://www.kernel.org/doc/Documentation/dma-buf-sharing.txt) with a
  // VideoFrame. The dmabuf fds are dup()ed on creation, so that the VideoFrame
  // retains a reference to them, and are automatically close()d on destruction,
  // dropping the reference. The caller may safely close() its reference after
  // calling WrapExternalDmabufs().
  // The image data is only accessible via dmabuf fds, which are usually passed
  // directly to a hardware device and/or to another process, or can also be
  // mapped via mmap() for CPU access.
  // Returns NULL on failure.
  static scoped_refptr<VideoFrame> WrapExternalDmabufs(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      const std::vector<int>& dmabuf_fds, base::TimeDelta timestamp);
#endif

#if defined(OS_MACOSX)
  // Wraps a provided CVPixelBuffer with a VideoFrame. The pixel buffer is
  // retained for the lifetime of the VideoFrame and released upon destruction.
  // The image data is only accessible via the pixel buffer, which could be
  // backed by an IOSurface from another process. All the attributes of the
  // VideoFrame are derived from the pixel buffer, with the exception of the
  // timestamp. If information is missing or is incompatible (for example, a
  // pixel format that has no VideoFrame match), NULL is returned.
  // http://crbug.com/401308
  static scoped_refptr<VideoFrame> WrapCVPixelBuffer(
      CVPixelBufferRef cv_pixel_buffer, base::TimeDelta timestamp);
#endif

  // Wraps |frame|. |visible_rect| must be a sub rect within
  // frame->visible_rect().
  static scoped_refptr<VideoFrame> WrapVideoFrame(
      const scoped_refptr<VideoFrame>& frame, VideoPixelFormat format,
      const math::Rect& visible_rect, const math::Size& natural_size);

  // Creates a frame which indicates end-of-stream.
  static scoped_refptr<VideoFrame> CreateEOSFrame();

  // Allocates YV12 frame based on |size|, and sets its data to the YUV(y,u,v).
  static scoped_refptr<VideoFrame> CreateColorFrame(const math::Size& size,
                                                    uint8_t y, uint8_t u,
                                                    uint8_t v,
                                                    base::TimeDelta timestamp);

  // Allocates YV12 frame based on |size|, and sets its data to the YUV
  // equivalent of RGB(0,0,0).
  static scoped_refptr<VideoFrame> CreateBlackFrame(const math::Size& size);

  // Allocates YV12A frame based on |size|, and sets its data to the YUVA
  // equivalent of RGBA(0,0,0,0).
  static scoped_refptr<VideoFrame> CreateTransparentFrame(
      const math::Size& size);

  static size_t NumPlanes(VideoPixelFormat format);

  // Returns the required allocation size for a (tightly packed) frame of the
  // given coded size and format.
  static size_t AllocationSize(VideoPixelFormat format,
                               const math::Size& coded_size);

  // Returns the plane math::Size (in bytes) for a plane of the given coded size
  // and format.
  static math::Size PlaneSize(VideoPixelFormat format, size_t plane,
                              const math::Size& coded_size);

  // Returns horizontal bits per pixel for given |plane| and |format|.
  static int PlaneHorizontalBitsPerPixel(VideoPixelFormat format, size_t plane);

  // Returns bits per pixel for given |plane| and |format|.
  static int PlaneBitsPerPixel(VideoPixelFormat format, size_t plane);

  // Returns the number of bytes per row for the given plane, format, and width.
  // The width may be aligned to format requirements.
  static size_t RowBytes(size_t plane, VideoPixelFormat format, int width);

  // Returns the number of rows for the given plane, format, and height.
  // The height may be aligned to format requirements.
  static size_t Rows(size_t plane, VideoPixelFormat format, int height);

  // Returns the number of columns for the given plane, format, and width.
  // The width may be aligned to format requirements.
  static size_t Columns(size_t plane, VideoPixelFormat format, int width);

  // Used to keep a running hash of seen frames.  Expects an initialized MD5
  // context.  Calls MD5Update with the context and the contents of the frame.
  static void HashFrameForTesting(base::MD5Context* context,
                                  const scoped_refptr<VideoFrame>& frame);

  // Returns true if |frame| is accessible and mapped in the VideoFrame memory
  // space. If false, clients should refrain from accessing data(),
  // visible_data() etc.
  bool IsMappable() const;

  // Returns true if |frame| has textures with any StorageType and should not be
  // accessed via data(), visible_data() etc.
  bool HasTextures() const;

  // Returns the color space of this frame's content.
  gfx::ColorSpace ColorSpace() const;
  void set_color_space(const gfx::ColorSpace& color_space);

  VideoPixelFormat format() const { return format_; }
  StorageType storage_type() const { return storage_type_; }

  const math::Size& coded_size() const { return coded_size_; }
  const math::Rect& visible_rect() const { return visible_rect_; }
  const math::Size& natural_size() const { return natural_size_; }

  int stride(size_t plane) const;

  // Returns the number of bytes per row and number of rows for a given plane.
  //
  // As opposed to stride(), row_bytes() refers to the bytes representing
  // frame data scanlines (coded_size.width() pixels, without stride padding).
  int row_bytes(size_t plane) const;
  int rows(size_t plane) const;

  // Returns pointer to the buffer for a given plane, if this is an
  // IsMappable() frame type. The memory is owned by VideoFrame object and must
  // not be freed by the caller.
  const uint8_t* data(size_t plane) const;
  uint8_t* data(size_t plane);

  // Returns pointer to the data in the visible region of the frame, for
  // IsMappable() storage types. The returned pointer is offsetted into the
  // plane buffer specified by visible_rect().origin(). Memory is owned by
  // VideoFrame object and must not be freed by the caller.
  const uint8_t* visible_data(size_t plane) const;
  uint8_t* visible_data(size_t plane);

  // Returns a mailbox holder for a given texture.
  // Only valid to call if this is a NATIVE_TEXTURE frame. Before using the
  // mailbox, the caller must wait for the included sync point.
  const gpu::MailboxHolder& mailbox_holder(size_t texture_index) const;

  // Returns the shared-memory handle, if present
  base::SharedMemoryHandle shared_memory_handle() const;

  // Returns the offset into the shared memory where the frame data begins.
  size_t shared_memory_offset() const;

  // Returns the vector of GpuMemoryBuffer handles, if present.
  const std::vector<gfx::GpuMemoryBufferHandle>& gpu_memory_buffer_handles()
      const;

#if defined(OS_LINUX)
  // Returns backing DmaBuf file descriptor for given |plane|, if present, or
  // -1 if not.
  // TODO(mcasas): Rename to DmabufFd() to comply with Style Guide.
  int dmabuf_fd(size_t plane) const;

  // Duplicates internally the |fds_in|, overwriting the current ones. Returns
  // false if something goes wrong, and leaves all internal fds closed.
  bool DuplicateFileDescriptors(const std::vector<int>& fds_in);
#endif

  void AddSharedMemoryHandle(base::SharedMemoryHandle handle);

#if defined(OS_MACOSX)
  // Returns the backing CVPixelBuffer, if present.
  // TODO(mcasas): Rename to CvPixelBuffer() to comply with Style Guide.
  CVPixelBufferRef cv_pixel_buffer() const;
#endif

  // Adds a callback to be run when the VideoFrame is about to be destroyed.
  // The callback may be run from ANY THREAD, and so it is up to the client to
  // ensure thread safety.  Although read-only access to the members of this
  // VideoFrame is permitted while the callback executes (including
  // VideoFrameMetadata), clients should not assume the data pointers are
  // valid.
  void AddDestructionObserver(const base::Closure& callback);

  // Returns a dictionary of optional metadata.  This contains information
  // associated with the frame that downstream clients might use for frame-level
  // logging, quality/performance optimizations, signaling, etc.
  //
  // TODO(miu): Move some of the "extra" members of VideoFrame (below) into
  // here as a later clean-up step.
  const VideoFrameMetadata* metadata() const { return &metadata_; }
  VideoFrameMetadata* metadata() { return &metadata_; }

  // The time span between the current frame and the first frame of the stream.
  // This is the media timestamp, and not the reference time.
  // See VideoFrameMetadata::REFERENCE_TIME for details.
  base::TimeDelta timestamp() const { return timestamp_; }
  void set_timestamp(base::TimeDelta timestamp) { timestamp_ = timestamp; }

  // It uses |client| to insert a new sync point and potentially waits on a
  // older sync point. The final sync point will be used to release this
  // VideoFrame.
  // This method is thread safe. Both blink and compositor threads can call it.
  void UpdateReleaseSyncToken(SyncTokenClient* client);

  // Returns a human-readable string describing |*this|.
  std::string AsHumanReadableString();

  // Unique identifier for this video frame; generated at construction time and
  // guaranteed to be unique within a single process.
  int unique_id() const { return unique_id_; }

 protected:
  friend class base::RefCountedThreadSafe<VideoFrame>;

  // Clients must use the static factory/wrapping methods to create a new frame.
  // Derived classes should create their own factory/wrapping methods, and use
  // this constructor to do basic initialization.
  VideoFrame(VideoPixelFormat format, StorageType storage_type,
             const math::Size& coded_size, const math::Rect& visible_rect,
             const math::Size& natural_size, base::TimeDelta timestamp);

  virtual ~VideoFrame();

  // Creates a summary of the configuration settings provided as parameters.
  static std::string ConfigToString(const VideoPixelFormat format,
                                    const VideoFrame::StorageType storage_type,
                                    const math::Size& coded_size,
                                    const math::Rect& visible_rect,
                                    const math::Size& natural_size);

  // Returns true if |plane| is a valid plane index for the given |format|.
  static bool IsValidPlane(size_t plane, VideoPixelFormat format);

  // Returns |dimensions| adjusted to appropriate boundaries based on |format|.
  static math::Size DetermineAlignedSize(VideoPixelFormat format,
                                         const math::Size& dimensions);

  void set_data(size_t plane, uint8_t* ptr);
  void set_stride(size_t plane, int stride);

 private:
  // Clients must use the static factory/wrapping methods to create a new frame.
  VideoFrame(VideoPixelFormat format, StorageType storage_type,
             const math::Size& coded_size, const math::Rect& visible_rect,
             const math::Size& natural_size, base::TimeDelta timestamp,
             base::SharedMemoryHandle handle, size_t shared_memory_offset);
  VideoFrame(VideoPixelFormat format, StorageType storage_type,
             const math::Size& coded_size, const math::Rect& visible_rect,
             const math::Size& natural_size,
             const gpu::MailboxHolder (&mailbox_holders)[kMaxPlanes],
             const ReleaseMailboxCB& mailbox_holder_release_cb,
             base::TimeDelta timestamp);

  static scoped_refptr<VideoFrame> WrapExternalStorage(
      VideoPixelFormat format, StorageType storage_type,
      const math::Size& coded_size, const math::Rect& visible_rect,
      const math::Size& natural_size, uint8_t* data, size_t data_size,
      base::TimeDelta timestamp, base::SharedMemoryHandle handle,
      size_t data_offset);

  static scoped_refptr<VideoFrame> CreateFrameInternal(
      VideoPixelFormat format, const math::Size& coded_size,
      const math::Rect& visible_rect, const math::Size& natural_size,
      base::TimeDelta timestamp, bool zero_initialize_memory);

  // Returns the pixel size of each subsample for a given |plane| and |format|.
  // E.g. 2x2 for the U-plane in PIXEL_FORMAT_I420.
  static math::Size SampleSize(VideoPixelFormat format, size_t plane);

  // Returns the number of bytes per element for given |plane| and |format|.
  static int BytesPerElement(VideoPixelFormat format, size_t plane);

  // Return the alignment for the whole frame, calculated as the max of the
  // alignment for each individual plane.
  static math::Size CommonAlignment(VideoPixelFormat format);

  void AllocateYUV(bool zero_initialize_memory);

  // Frame format.
  const VideoPixelFormat format_;

  // Storage type for the different planes.
  StorageType storage_type_;  // TODO(mcasas): make const

  // Width and height of the video frame, in pixels. This must include pixel
  // data for the whole image; i.e. for YUV formats with subsampled chroma
  // planes, in the case that the visible portion of the image does not line up
  // on a sample boundary, |coded_size_| must be rounded up appropriately and
  // the pixel data provided for the odd pixels.
  const math::Size coded_size_;

  // Width, height, and offsets of the visible portion of the video frame. Must
  // be a subrect of |coded_size_|. Can be odd with respect to the sample
  // boundaries, e.g. for formats with subsampled chroma.
  const math::Rect visible_rect_;

  // Width and height of the visible portion of the video frame
  // (|visible_rect_.size()|) with aspect ratio taken into account.
  const math::Size natural_size_;

  // Array of strides for each plane, typically greater or equal to the width
  // of the surface divided by the horizontal sampling period.  Note that
  // strides can be negative.
  int32_t strides_[kMaxPlanes];

  // Array of data pointers to each plane.
  // TODO(mcasas): we don't know on ctor if we own |data_| or not. Change
  // to std::unique_ptr<uint8_t, AlignedFreeDeleter> after refactoring
  // VideoFrame.
  uint8_t* data_[kMaxPlanes];

  // Native texture mailboxes, if this is a IsTexture() frame.
  gpu::MailboxHolder mailbox_holders_[kMaxPlanes];
  ReleaseMailboxCB mailbox_holders_release_cb_;

  // Shared memory handle and associated offset inside it, if this frame is
  // a STORAGE_SHMEM one.
  base::SharedMemoryHandle shared_memory_handle_;
  size_t shared_memory_offset_;

  // GpuMemoryBuffer handles attached to the video_frame.
  std::vector<gfx::GpuMemoryBufferHandle> gpu_memory_buffer_handles_;

#if defined(OS_LINUX)
  // Dmabufs for each plane. If set, this frame has DmaBuf backing in some way.
  base::ScopedFD dmabuf_fds_[kMaxPlanes];
#endif

#if defined(OS_MACOSX)
  // CVPixelBuffer, if this frame is wrapping one.
  base::ScopedCFTypeRef<CVPixelBufferRef> cv_pixel_buffer_;
#endif

  std::vector<base::Closure> done_callbacks_;

  base::TimeDelta timestamp_;

  base::Lock release_sync_token_lock_;
  gpu::SyncToken release_sync_token_;

  VideoFrameMetadata metadata_;

  // Generated at construction time.
  const int unique_id_;

  gfx::ColorSpace color_space_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame);
};

}  // namespace media
}  // namespace cobalt

#endif  // COBALT_MEDIA_BASE_VIDEO_FRAME_H_
