/*
 *  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 MEDIA_BASE_FAKEVIDEOCAPTURER_H_
#define MEDIA_BASE_FAKEVIDEOCAPTURER_H_

#include <string.h>

#include <memory>
#include <vector>

#include "api/video/i420_buffer.h"
#include "api/video/video_frame.h"
#include "media/base/videocapturer.h"
#include "media/base/videocommon.h"
#include "rtc_base/timeutils.h"

namespace cricket {

// Fake video capturer that allows the test to manually pump in frames.
class FakeVideoCapturer : public cricket::VideoCapturer {
 public:
  explicit 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, rtc::kNumNanosecsPerSec / 30,
                              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,
                   next_timestamp_ / rtc::kNumNanosecsPerMicrosec,
                   next_timestamp_ / rtc::kNumNanosecsPerMicrosec,
                   &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(webrtc::VideoFrame(
                  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 {
    SetCaptureFormat(&format);
    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_; }
  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_; }

 private:
  bool running_;
  int64_t initial_timestamp_;
  int64_t next_timestamp_;
  const bool is_screencast_;
  webrtc::VideoRotation rotation_;
};

}  // namespace cricket

#endif  // MEDIA_BASE_FAKEVIDEOCAPTURER_H_
