/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_
#define WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_

#include <memory>

#include "webrtc/modules/desktop_capture/desktop_capture_types.h"
#include "webrtc/modules/desktop_capture/desktop_geometry.h"
#include "webrtc/modules/desktop_capture/desktop_region.h"
#include "webrtc/modules/desktop_capture/shared_memory.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/typedefs.h"

namespace webrtc {

// DesktopFrame represents a video frame captured from the screen.
class DesktopFrame {
 public:
  // DesktopFrame objects always hold RGBA data.
  static const int kBytesPerPixel = 4;

  virtual ~DesktopFrame();

  // Size of the frame.
  const DesktopSize& size() const { return size_; }

  // The top-left of the frame in full desktop coordinates. E.g. the top left
  // monitor should start from (0, 0).
  const DesktopVector& top_left() const { return top_left_; }
  void set_top_left(const DesktopVector& top_left) { top_left_ = top_left; }

  // Distance in the buffer between two neighboring rows in bytes.
  int stride() const { return stride_; }

  // Data buffer used for the frame.
  uint8_t* data() const { return data_; }

  // SharedMemory used for the buffer or NULL if memory is allocated on the
  // heap. The result is guaranteed to be deleted only after the frame is
  // deleted (classes that inherit from DesktopFrame must ensure it).
  SharedMemory* shared_memory() const { return shared_memory_; }

  // Indicates region of the screen that has changed since the previous frame.
  const DesktopRegion& updated_region() const { return updated_region_; }
  DesktopRegion* mutable_updated_region() { return &updated_region_; }

  // DPI of the screen being captured. May be set to zero, e.g. if DPI is
  // unknown.
  const DesktopVector& dpi() const { return dpi_; }
  void set_dpi(const DesktopVector& dpi) { dpi_ = dpi; }

  // Time taken to capture the frame in milliseconds.
  int64_t capture_time_ms() const { return capture_time_ms_; }
  void set_capture_time_ms(int64_t time_ms) { capture_time_ms_ = time_ms; }

  // Copies pixels from a buffer or another frame. |dest_rect| rect must lay
  // within bounds of this frame.
  void CopyPixelsFrom(const uint8_t* src_buffer,
                      int src_stride,
                      const DesktopRect& dest_rect);
  void CopyPixelsFrom(const DesktopFrame& src_frame,
                      const DesktopVector& src_pos,
                      const DesktopRect& dest_rect);

  // A helper to return the data pointer of a frame at the specified position.
  uint8_t* GetFrameDataAtPos(const DesktopVector& pos) const;

  // The DesktopCapturer implementation which generates current DesktopFrame.
  // Not all DesktopCapturer implementations set this field; it's set to
  // kUnknown by default.
  uint32_t capturer_id() const { return capturer_id_; }
  void set_capturer_id(uint32_t capturer_id) {
    capturer_id_ = capturer_id;
  }

  // Copies various information from |other|. Anything initialized in
  // constructor are not copied.
  // This function is usually used when sharing a source DesktopFrame with
  // several clients: the original DesktopFrame should be kept unchanged. For
  // example, BasicDesktopFrame::CopyOf() and SharedDesktopFrame::Share().
  void CopyFrameInfoFrom(const DesktopFrame& other);

  // Copies various information from |other|. Anything initialized in
  // constructor are not copied. Not like CopyFrameInfoFrom() function, this
  // function uses swap or move constructor to avoid data copy. It won't break
  // the |other|, but some of its information may be missing after this
  // operation. E.g. other->updated_region_;
  // This function is usually used when wrapping a DesktopFrame: the wrapper
  // instance takes the ownership of |other|, so other components cannot access
  // |other| anymore. For example, CroppedDesktopFrame and
  // DesktopFrameWithCursor.
  void MoveFrameInfoFrom(DesktopFrame* other);

 protected:
  DesktopFrame(DesktopSize size,
               int stride,
               uint8_t* data,
               SharedMemory* shared_memory);

  // Ownership of the buffers is defined by the classes that inherit from this
  // class. They must guarantee that the buffer is not deleted before the frame
  // is deleted.
  uint8_t* const data_;
  SharedMemory* const shared_memory_;

 private:
  const DesktopSize size_;
  const int stride_;

  DesktopRegion updated_region_;
  DesktopVector top_left_;
  DesktopVector dpi_;
  int64_t capture_time_ms_;
  uint32_t capturer_id_;

  RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrame);
};

// A DesktopFrame that stores data in the heap.
class BasicDesktopFrame : public DesktopFrame {
 public:
  explicit BasicDesktopFrame(DesktopSize size);

  ~BasicDesktopFrame() override;

  // Creates a BasicDesktopFrame that contains copy of |frame|.
  // TODO(zijiehe): Return std::unique_ptr<DesktopFrame>
  static DesktopFrame* CopyOf(const DesktopFrame& frame);

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(BasicDesktopFrame);
};

// A DesktopFrame that stores data in shared memory.
class SharedMemoryDesktopFrame : public DesktopFrame {
 public:
  // May return nullptr if |shared_memory_factory| failed to create a
  // SharedMemory instance.
  // |shared_memory_factory| should not be nullptr.
  static std::unique_ptr<DesktopFrame> Create(
      DesktopSize size,
      SharedMemoryFactory* shared_memory_factory);

  // Takes ownership of |shared_memory|.
  // Deprecated, use the next constructor.
  SharedMemoryDesktopFrame(DesktopSize size,
                           int stride,
                           SharedMemory* shared_memory);

  // Preferred.
  SharedMemoryDesktopFrame(DesktopSize size,
                           int stride,
                           std::unique_ptr<SharedMemory> shared_memory);

  ~SharedMemoryDesktopFrame() override;

 private:
  // Avoid unexpected order of parameter evaluation.
  // Executing both std::unique_ptr<T>::operator->() and
  // std::unique_ptr<T>::release() in the member initializer list is not safe.
  // Depends on the order of parameter evaluation,
  // std::unique_ptr<T>::operator->() may trigger assertion failure if it has
  // been evaluated after std::unique_ptr<T>::release(). By using this
  // constructor, std::unique_ptr<T>::operator->() won't be involved anymore.
  SharedMemoryDesktopFrame(DesktopRect rect,
                           int stride,
                           SharedMemory* shared_memory);

  RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemoryDesktopFrame);
};

}  // namespace webrtc

#endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_DESKTOP_FRAME_H_

