// Copyright (c) 2012 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.

#include "content/renderer/media/rtc_video_capturer.h"

#include "base/bind.h"
#include "base/debug/trace_event.h"

namespace content {

RtcVideoCapturer::RtcVideoCapturer(const media::VideoCaptureSessionId id,
                                   VideoCaptureImplManager* vc_manager,
                                   bool is_screencast)
    : is_screencast_(is_screencast),
      delegate_(new RtcVideoCaptureDelegate(id, vc_manager)),
      state_(VIDEO_CAPTURE_STATE_STOPPED) {}

RtcVideoCapturer::~RtcVideoCapturer() {
  DCHECK(VIDEO_CAPTURE_STATE_STOPPED);
  DVLOG(3) << " RtcVideoCapturer::dtor";
}

cricket::CaptureState RtcVideoCapturer::Start(
    const cricket::VideoFormat& capture_format) {
  DVLOG(3) << " RtcVideoCapturer::Start ";
  if (state_ == VIDEO_CAPTURE_STATE_STARTED) {
    DVLOG(1) << "Got a StartCapture when already started!!! ";
    return cricket::CS_FAILED;
  }

  media::VideoCaptureCapability cap;
  cap.width = capture_format.width;
  cap.height = capture_format.height;
  cap.frame_rate = capture_format.framerate();
  cap.color = media::PIXEL_FORMAT_I420;

  SetCaptureFormat(&capture_format);

  state_ = VIDEO_CAPTURE_STATE_STARTED;
  first_frame_timestamp_ = media::kNoTimestamp();
  delegate_->StartCapture(
      cap,
      base::Bind(&RtcVideoCapturer::OnFrameCaptured, base::Unretained(this)),
      base::Bind(&RtcVideoCapturer::OnStateChange, base::Unretained(this)));
  // Update the desired aspect ratio so that later the video frame can be
  // cropped to meet the requirement if the camera returns a different
  // resolution than the |cap|.
  UpdateAspectRatio(cap.width, cap.height);
  return cricket::CS_STARTING;
}

void RtcVideoCapturer::Stop() {
  DVLOG(3) << " RtcVideoCapturer::Stop ";
  if (state_ == VIDEO_CAPTURE_STATE_STOPPED) {
    DVLOG(1) << "Got a StopCapture while not started.";
    return;
  }

  SetCaptureFormat(NULL);
  state_ = VIDEO_CAPTURE_STATE_STOPPED;
  delegate_->StopCapture();
  SignalStateChange(this, cricket::CS_STOPPED);
}

bool RtcVideoCapturer::IsRunning() {
  return state_ == VIDEO_CAPTURE_STATE_STARTED;
}

bool RtcVideoCapturer::GetPreferredFourccs(std::vector<uint32>* fourccs) {
  if (!fourccs)
    return false;
  fourccs->push_back(cricket::FOURCC_I420);
  return true;
}

bool RtcVideoCapturer::IsScreencast() const {
  return is_screencast_;
}

bool RtcVideoCapturer::GetBestCaptureFormat(const cricket::VideoFormat& desired,
                                            cricket::VideoFormat* best_format) {
  if (!best_format) {
    return false;
  }

  // Chrome does not support capability enumeration.
  // Use the desired format as the best format.
  best_format->width = desired.width;
  best_format->height = desired.height;
  best_format->fourcc = cricket::FOURCC_I420;
  best_format->interval = desired.interval;
  return true;
}

void RtcVideoCapturer::OnFrameCaptured(
    const scoped_refptr<media::VideoFrame>& frame) {
  if (first_frame_timestamp_ == media::kNoTimestamp())
    first_frame_timestamp_ = frame->GetTimestamp();

  // Currently, |fourcc| is always I420.
  cricket::CapturedFrame captured_frame;
  captured_frame.width = frame->coded_size().width();
  captured_frame.height = frame->coded_size().height();
  captured_frame.fourcc = cricket::FOURCC_I420;
  // cricket::CapturedFrame time is in nanoseconds.
  captured_frame.elapsed_time =
      (frame->GetTimestamp() - first_frame_timestamp_).InMicroseconds() *
      base::Time::kNanosecondsPerMicrosecond;
  captured_frame.time_stamp = frame->GetTimestamp().InMicroseconds() *
                              base::Time::kNanosecondsPerMicrosecond;
  // TODO(sheu): we assume contiguous layout of image planes.
  captured_frame.data = frame->data(0);
  captured_frame.data_size =
      media::VideoFrame::AllocationSize(frame->format(), frame->coded_size());
  captured_frame.pixel_height = 1;
  captured_frame.pixel_width = 1;

  TRACE_EVENT_INSTANT2(
      "rtc_video_capturer",
      "OnFrameCaptured",
      TRACE_EVENT_SCOPE_THREAD,
      "elapsed time",
      captured_frame.elapsed_time,
      "timestamp_ms",
      captured_frame.time_stamp / talk_base::kNumNanosecsPerMillisec);

  // This signals to libJingle that a new VideoFrame is available.
  // libJingle have no assumptions on what thread this signal come from.
  SignalFrameCaptured(this, &captured_frame);
}

void RtcVideoCapturer::OnStateChange(
    RtcVideoCaptureDelegate::CaptureState state) {
  cricket::CaptureState converted_state = cricket::CS_FAILED;
  DVLOG(3) << " RtcVideoCapturer::OnStateChange " << state;
  switch (state) {
    case RtcVideoCaptureDelegate::CAPTURE_STOPPED:
      converted_state = cricket::CS_STOPPED;
      break;
    case RtcVideoCaptureDelegate::CAPTURE_RUNNING:
      converted_state = cricket::CS_RUNNING;
      break;
    case RtcVideoCaptureDelegate::CAPTURE_FAILED:
      // TODO(perkj): Update the comments in the the definition of
      // cricket::CS_FAILED. According to the comments, cricket::CS_FAILED
      // means that the capturer failed to start. But here and in libjingle it
      // is also used if an error occur during capturing.
      converted_state = cricket::CS_FAILED;
      break;
    default:
      NOTREACHED();
      break;
  }
  SignalStateChange(this, converted_state);
}

}  // namespace content
