// Copyright 2018 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_FRAME_LAYOUT_H_
#define MEDIA_BASE_VIDEO_FRAME_LAYOUT_H_

#include <stddef.h>
#include <stdint.h>

#include <ostream>
#include <string>
#include <utility>
#include <vector>

#include "base/optional.h"
#include "media/base/media_export.h"
#include "media/base/video_types.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/native_pixmap_handle.h"

namespace media {

// A class to describes how physical buffer is allocated for video frame.
// In stores format, coded size of the frame and size of physical buffers
// which can be used to allocate buffer(s) hardware expected.
// It also stores stride (bytes per line) and offset per color plane as Plane.
// stride is to calculate each color plane's size (note that a buffer may
// contains multiple color planes.)
// offset is to describe a start point of each plane from buffer's dmabuf fd.
// Note that it is copyable.
class MEDIA_EXPORT VideoFrameLayout {
 public:
  // Default alignment for buffers.
  // Note: This value is dependent on what's used by ffmpeg, do not change
  // without inspecting av_frame_get_buffer() first.
  static constexpr size_t kBufferAddressAlignment = 32;

  struct Plane {
    Plane() = default;
    Plane(int32_t stride, size_t offset) : stride(stride), offset(offset) {}
    Plane(int32_t stride, size_t offset, uint64_t modifier)
        : stride(stride), offset(offset), modifier(modifier) {}

    bool operator==(const Plane& rhs) const;
    bool operator!=(const Plane& rhs) const;

    // Strides of a plane, typically greater or equal to the
    // width of the surface divided by the horizontal sampling period. Note that
    // strides can be negative if the image layout is bottom-up.
    int32_t stride = 0;

    // Offset of a plane, which stands for the offset of a start point of a
    // color plane from a buffer fd.
    size_t offset = 0;

    // Modifier of a plane. The modifier is retrieved from GBM library. This can
    // be a different value from kNoModifier only if the VideoFrame is created
    // by using NativePixmap.
    uint64_t modifier = gfx::NativePixmapPlane::kNoModifier;
  };

  // Factory functions.
  // |format| and |coded_size| must be specified.
  // |strides|, |planes| and |buffer_sizes| are optional, whereas they should
  //  be specified if |buffer_sizes| are given.
  // The size of |buffer_sizes| must be less than or equal to |planes|.
  // Unless they are specified, num_planes() is NumPlanes(|format|) and
  // num_buffers() is 0.
  // |buffer_addr_align| can be specified to request a specific buffer memory
  // alignment.
  // The returned base::Optional will be base::nullopt if the configured values
  // are invalid.
  static base::Optional<VideoFrameLayout> Create(VideoPixelFormat format,
                                                 const gfx::Size& coded_size);

  // The size of |strides| must be NumPlanes(|format|). Planes' offset will be
  // 0.
  static base::Optional<VideoFrameLayout> CreateWithStrides(
      VideoPixelFormat format,
      const gfx::Size& coded_size,
      std::vector<int32_t> strides,
      std::vector<size_t> buffer_sizes = {});

  // The size of |planes| must be NumPlanes(|format|).
  static base::Optional<VideoFrameLayout> CreateWithPlanes(
      VideoPixelFormat format,
      const gfx::Size& coded_size,
      std::vector<Plane> planes,
      std::vector<size_t> buffer_sizes = {},
      size_t buffer_addr_align = kBufferAddressAlignment);

  VideoFrameLayout() = delete;
  VideoFrameLayout(const VideoFrameLayout&);
  VideoFrameLayout(VideoFrameLayout&&);
  VideoFrameLayout& operator=(const VideoFrameLayout&);
  ~VideoFrameLayout();

  static size_t NumPlanes(VideoPixelFormat format);

  VideoPixelFormat format() const { return format_; }
  const gfx::Size& coded_size() const { return coded_size_; }

  // Return number of buffers. Note that num_planes >= num_buffers.
  size_t num_buffers() const { return buffer_sizes_.size(); }

  // Returns number of planes. Note that num_planes >= num_buffers.
  size_t num_planes() const { return planes_.size(); }

  const std::vector<Plane>& planes() const { return planes_; }
  const std::vector<size_t>& buffer_sizes() const { return buffer_sizes_; }

  // Returns sum of bytes of all buffers.
  size_t GetTotalBufferSize() const;

  bool operator==(const VideoFrameLayout& rhs) const;
  bool operator!=(const VideoFrameLayout& rhs) const;

  // Returns the required memory alignment for buffers.
  size_t buffer_addr_align() const {
    return buffer_addr_align_;
  }

 private:
  VideoFrameLayout(VideoPixelFormat format,
                   const gfx::Size& coded_size,
                   std::vector<Plane> planes,
                   std::vector<size_t> buffer_sizes,
                   size_t buffer_addr_align);

  VideoPixelFormat format_;

  // 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.
  gfx::Size coded_size_;

  // Layout property for each color planes, e.g. stride and buffer offset.
  std::vector<Plane> planes_;

  // Vector of sizes for each buffer, typically greater or equal to the area of
  // |coded_size_|.
  std::vector<size_t> buffer_sizes_;

  // Memory address alignment of the buffers. This is only relevant when
  // allocating physical memory for the buffer, so it doesn't need to be
  // serialized when frames are passed through Mojo.
  size_t buffer_addr_align_;
};

// Outputs VideoFrameLayout::Plane to stream.
MEDIA_EXPORT std::ostream& operator<<(std::ostream& ostream,
                                      const VideoFrameLayout::Plane& plane);

// Outputs VideoFrameLayout to stream.
MEDIA_EXPORT std::ostream& operator<<(std::ostream& ostream,
                                      const VideoFrameLayout& layout);

}  // namespace media

#endif  // MEDIA_BASE_VIDEO_FRAME_LAYOUT_H_
