/*
 *  Copyright (c) 2004 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_BASE_FAKEVIDEOCAPTURER_H_
#define WEBRTC_MEDIA_BASE_FAKEVIDEOCAPTURER_H_

#include <string.h>

#include <memory>
#include <vector>

#include "webrtc/base/timeutils.h"
#include "webrtc/media/base/videocapturer.h"
#include "webrtc/media/base/videocommon.h"
#include "webrtc/media/base/videoframe.h"

namespace cricket {

// Fake video capturer that allows the test to manually pump in frames.
class FakeVideoCapturer : public cricket::VideoCapturer {
 public:
  FakeVideoCapturer(bool is_screencast)
      : running_(false),
        initial_timestamp_(rtc::TimeNanos()),
        next_timestamp_(rtc::kNumNanosecsPerMillisec),
        is_screencast_(is_screencast),
        rotation_(webrtc::kVideoRotation_0) {
    // Default supported formats. Use ResetSupportedFormats to over write.
    std::vector<cricket::VideoFormat> formats;
    formats.push_back(cricket::VideoFormat(1280, 720,
        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
    formats.push_back(cricket::VideoFormat(640, 480,
        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
    formats.push_back(cricket::VideoFormat(320, 240,
        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
    formats.push_back(cricket::VideoFormat(160, 120,
        cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));
    formats.push_back(cricket::VideoFormat(1280, 720,
        cricket::VideoFormat::FpsToInterval(60), cricket::FOURCC_I420));
    ResetSupportedFormats(formats);
  }
  FakeVideoCapturer() : FakeVideoCapturer(false) {}

  ~FakeVideoCapturer() {
    SignalDestroyed(this);
  }

  void ResetSupportedFormats(const std::vector<cricket::VideoFormat>& formats) {
    SetSupportedFormats(formats);
  }
  bool CaptureFrame() {
    if (!GetCaptureFormat()) {
      return false;
    }
    return CaptureCustomFrame(GetCaptureFormat()->width,
                              GetCaptureFormat()->height,
                              GetCaptureFormat()->interval,
                              GetCaptureFormat()->fourcc);
  }
  bool CaptureCustomFrame(int width, int height, uint32_t fourcc) {
    // default to 30fps
    return CaptureCustomFrame(width, height, 33333333, fourcc);
  }
  bool CaptureCustomFrame(int width,
                          int height,
                          int64_t timestamp_interval,
                          uint32_t fourcc) {
    if (!running_) {
      return false;
    }
    RTC_CHECK(fourcc == FOURCC_I420);
    RTC_CHECK(width > 0);
    RTC_CHECK(height > 0);

    int adapted_width;
    int adapted_height;
    int crop_width;
    int crop_height;
    int crop_x;
    int crop_y;

    // TODO(nisse): It's a bit silly to have this logic in a fake
    // class. Child classes of VideoCapturer are expected to call
    // AdaptFrame, and the test case
    // VideoCapturerTest.SinkWantsMaxPixelAndMaxPixelCountStepUp
    // depends on this.
    if (AdaptFrame(width, height, 0, 0, &adapted_width, &adapted_height,
                   &crop_width, &crop_height, &crop_x, &crop_y, nullptr)) {
      rtc::scoped_refptr<webrtc::I420Buffer> buffer(
          webrtc::I420Buffer::Create(adapted_width, adapted_height));
      buffer->InitializeData();

      OnFrame(WebRtcVideoFrame(buffer, rotation_,
                               next_timestamp_ / rtc::kNumNanosecsPerMicrosec),
              width, height);
    }
    next_timestamp_ += timestamp_interval;

    return true;
  }

  sigslot::signal1<FakeVideoCapturer*> SignalDestroyed;

  cricket::CaptureState Start(const cricket::VideoFormat& format) override {
    cricket::VideoFormat supported;
    if (GetBestCaptureFormat(format, &supported)) {
      SetCaptureFormat(&supported);
    }
    running_ = true;
    SetCaptureState(cricket::CS_RUNNING);
    return cricket::CS_RUNNING;
  }
  void Stop() override {
    running_ = false;
    SetCaptureFormat(NULL);
    SetCaptureState(cricket::CS_STOPPED);
  }
  bool IsRunning() override { return running_; }
  bool IsScreencast() const override { return is_screencast_; }
  rtc::Optional<bool> NeedsDenoising() const override {
    return needs_denoising_;
  }
  bool GetPreferredFourccs(std::vector<uint32_t>* fourccs) override {
    fourccs->push_back(cricket::FOURCC_I420);
    fourccs->push_back(cricket::FOURCC_MJPG);
    return true;
  }

  void SetRotation(webrtc::VideoRotation rotation) {
    rotation_ = rotation;
  }

  webrtc::VideoRotation GetRotation() { return rotation_; }

  void SetNeedsDenoising(rtc::Optional<bool> needs_denoising) {
    needs_denoising_ = needs_denoising;
  }

 private:
  bool running_;
  int64_t initial_timestamp_;
  int64_t next_timestamp_;
  const bool is_screencast_;
  rtc::Optional<bool> needs_denoising_;
  webrtc::VideoRotation rotation_;
};

}  // namespace cricket

#endif  // WEBRTC_MEDIA_BASE_FAKEVIDEOCAPTURER_H_
