// 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_GPU_V4L2_V4L2_DECODE_SURFACE_H_
#define MEDIA_GPU_V4L2_V4L2_DECODE_SURFACE_H_

#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "media/gpu/v4l2/v4l2_device.h"
#include "ui/gfx/geometry/rect.h"

struct v4l2_ext_controls;
struct v4l2_buffer;

namespace media {

// A V4L2-specific decode surface generated by V4L2DecodeSurfaceHandler.
// It is used to store common picture metadata (e.g. visible_rect) and
// platform-specific metadata (e.g. {input,output}_record). All the methods
// should be called on the same sequence.
class V4L2DecodeSurface : public base::RefCounted<V4L2DecodeSurface> {
 public:
  // V4L2DecodeSurfaceHandler maintains a list of InputRecords, which records
  // the status and metadata of input buffers.
  // |input_buffer| and |output_buffer| are the buffers to be used as input and
  // output in this transaction.
  // |frame| is optional, and allows the caller to keep a reference to a
  // VideoFrame for as long as this decode surface exists.
  V4L2DecodeSurface(V4L2WritableBufferRef input_buffer,
                    V4L2WritableBufferRef output_buffer,
                    scoped_refptr<VideoFrame> frame);

  // Mark the surface as decoded. This will also release all surfaces used for
  // reference, as they are not needed anymore and execute the done callback,
  // if not null.
  void SetDecoded();
  void SetVisibleRect(const gfx::Rect& visible_rect);
  // Take references to each reference surface and keep them until the
  // target surface is decoded.
  void SetReferenceSurfaces(
      std::vector<scoped_refptr<V4L2DecodeSurface>> ref_surfaces);
  // If provided via this method, |done_cb| callback will be executed after
  // decoding into this surface is finished. The callback is reset afterwards,
  // so it needs to be set again before each decode operation.
  void SetDecodeDoneCallback(base::OnceClosure done_cb);
  // Set the callback that will be called when the surface is released. This
  // method must be called one time at most.
  void SetReleaseCallback(base::OnceClosure release_cb);

  // Update the passed v4l2_ext_controls structure to add the request or
  // config store information.
  virtual void PrepareSetCtrls(struct v4l2_ext_controls* ctrls) const = 0;
  // Return the ID to use in order to reference this frame.
  virtual uint64_t GetReferenceID() const = 0;
  // Set controls, queue buffers and submit the request corresponding to this
  // surface.
  virtual bool Submit() = 0;

  bool decoded() const { return decoded_; }
  int input_record() const { return input_record_; }
  V4L2WritableBufferRef& input_buffer() {
    return input_buffer_;
  }
  int output_record() const { return output_record_; }
  V4L2WritableBufferRef& output_buffer() {
    return output_buffer_;
  }
  scoped_refptr<VideoFrame> video_frame() const { return video_frame_; }
  gfx::Rect visible_rect() const { return visible_rect_; }

  std::string ToString() const;

 protected:
  virtual ~V4L2DecodeSurface();
  friend class base::RefCounted<V4L2DecodeSurface>;

  SEQUENCE_CHECKER(sequence_checker_);

 private:
  V4L2WritableBufferRef input_buffer_;
  V4L2WritableBufferRef output_buffer_;
  scoped_refptr<VideoFrame> video_frame_;
  // The index of the corresponding input record.
  const int input_record_;
  // The index of the corresponding output record.
  const int output_record_;
  // The visible size of the buffer.
  gfx::Rect visible_rect_;

  // Indicate whether the surface is decoded or not.
  bool decoded_;
  // Callback function which is called when the instance is destroyed.
  base::OnceClosure release_cb_;
  // Callback function which is called after the surface has been decoded.
  base::OnceClosure done_cb_;

  // The decoded surfaces of the reference frames, which is kept until the
  // surface has been decoded.
  std::vector<scoped_refptr<V4L2DecodeSurface>> reference_surfaces_;

  DISALLOW_COPY_AND_ASSIGN(V4L2DecodeSurface);
};

// An implementation of V4L2DecodeSurface that uses the config store to
// associate controls/buffers to frames.
class V4L2ConfigStoreDecodeSurface : public V4L2DecodeSurface {
 public:
  V4L2ConfigStoreDecodeSurface(V4L2WritableBufferRef input_buffer,
                               V4L2WritableBufferRef output_buffer,
                               scoped_refptr<VideoFrame> frame)
      : V4L2DecodeSurface(std::move(input_buffer),
                          std::move(output_buffer),
                          std::move(frame)),
        // config store IDs are arbitrarily defined to be buffer ID + 1
        config_store_(this->input_buffer().BufferId() + 1) {}

  void PrepareSetCtrls(struct v4l2_ext_controls* ctrls) const override;
  uint64_t GetReferenceID() const override;
  bool Submit() override;

 private:
  ~V4L2ConfigStoreDecodeSurface() override = default;

  // The configuration store of the input buffer.
  uint32_t config_store_;

  DISALLOW_COPY_AND_ASSIGN(V4L2ConfigStoreDecodeSurface);
};

// An implementation of V4L2DecodeSurface that uses requests to associate
// controls/buffers to frames
class V4L2RequestDecodeSurface : public V4L2DecodeSurface {
 public:
  V4L2RequestDecodeSurface(V4L2WritableBufferRef input_buffer,
                           V4L2WritableBufferRef output_buffer,
                           scoped_refptr<VideoFrame> frame,
                           V4L2RequestRef request_ref)
      : V4L2DecodeSurface(std::move(input_buffer),
                          std::move(output_buffer),
                          std::move(frame)),
        request_ref_(std::move(request_ref)) {}

  void PrepareSetCtrls(struct v4l2_ext_controls* ctrls) const override;
  uint64_t GetReferenceID() const override;
  bool Submit() override;

 private:
  ~V4L2RequestDecodeSurface() override = default;

  // Request reference used for the surface.
  V4L2RequestRef request_ref_;

  DISALLOW_COPY_AND_ASSIGN(V4L2RequestDecodeSurface);
};

}  // namespace media

#endif  // MEDIA_GPU_V4L2_V4L2_DECODE_SURFACE_H_
