/*
 *  Copyright (c) 2011 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_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
#define WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_

#include <memory>

#include "webrtc/base/buffer.h"
#include "webrtc/base/refcount.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/common_types.h"
#include "webrtc/common_video/include/video_frame_buffer.h"
#include "webrtc/media/base/videoframe.h"

namespace cricket {

struct CapturedFrame;

// TODO(nisse): This class will be deleted when the cricket::VideoFrame and
// webrtc::VideoFrame classes are merged. See
// https://bugs.chromium.org/p/webrtc/issues/detail?id=5682. Try to use only the
// preferred constructor, and the non-deprecated methods of the VideoFrame base
// class.
class WebRtcVideoFrame : public VideoFrame {
 public:
  // TODO(nisse): Deprecated. Using the default constructor violates the
  // reasonable assumption that video_frame_buffer() returns a valid buffer.
  WebRtcVideoFrame();

  // Preferred constructor.
  WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
                   webrtc::VideoRotation rotation,
                   int64_t timestamp_us,
                   uint32_t transport_frame_id);

  // Alternative constructor, when not knowing or caring about the
  // transport_frame_id. Which is set to zero.
  WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
                   webrtc::VideoRotation rotation,
                   int64_t timestamp_us);

  // TODO(nisse): Deprecated, delete as soon as all callers have switched to the
  // above constructor with microsecond timestamp.
  WebRtcVideoFrame(const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer,
                   int64_t timestamp_ns,
                   webrtc::VideoRotation rotation);

  ~WebRtcVideoFrame();

  // Creates a frame from a raw sample with FourCC "format" and size "w" x "h".
  // "h" can be negative indicating a vertically flipped image.
  // "dh" is destination height if cropping is desired and is always positive.
  // Returns "true" if successful.
  bool Init(uint32_t format,
            int w,
            int h,
            int dw,
            int dh,
            uint8_t* sample,
            size_t sample_size,
            int64_t timestamp_ns,
            webrtc::VideoRotation rotation);

  // TODO(nisse): We're moving to have all timestamps use the same
  // time scale as rtc::TimeMicros. However, this method is used by
  // WebRtcVideoFrameFactory::CreateAliasedFrame this code path
  // currently does not conform to the new timestamp conventions and
  // may use the camera's own clock instead. It's unclear if this
  // should be fixed, or if instead all of the VideoFrameFactory
  // abstraction should be eliminated.
  bool Init(const CapturedFrame* frame, int dw, int dh, bool apply_rotation);

  void InitToEmptyBuffer(int w, int h);

  int width() const override;
  int height() const override;

  const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& video_frame_buffer()
      const override;

  uint32_t transport_frame_id() const override;

  int64_t timestamp_us() const override;
  void set_timestamp_us(int64_t time_us) override;

  webrtc::VideoRotation rotation() const override;

 protected:
  // Creates a frame from a raw sample with FourCC |format| and size |w| x |h|.
  // |h| can be negative indicating a vertically flipped image.
  // |dw| is destination width; can be less than |w| if cropping is desired.
  // |dh| is destination height, like |dw|, but must be a positive number.
  // Returns whether the function succeeded or failed.
  bool Reset(uint32_t format,
             int w,
             int h,
             int dw,
             int dh,
             uint8_t* sample,
             size_t sample_size,
             int64_t timestamp_us,
             webrtc::VideoRotation rotation,
             bool apply_rotation);

 private:
  // Tests mutate |rotation_|, so the base test class is a friend.
  friend class WebRtcVideoFrameTest;

  // An opaque reference counted handle that stores the pixel data.
  rtc::scoped_refptr<webrtc::VideoFrameBuffer> video_frame_buffer_;
  int64_t timestamp_us_;
  uint32_t transport_frame_id_;
  webrtc::VideoRotation rotation_;

  // This is mutable as the calculation is expensive but once calculated, it
  // remains const.
  mutable std::unique_ptr<VideoFrame> rotated_frame_;
};

}  // namespace cricket

#endif  // WEBRTC_MEDIA_ENGINE_WEBRTCVIDEOFRAME_H_
