// Copyright 2015 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 "media/cast/sender/size_adaptable_video_encoder_base.h"

#include <utility>

#include "base/bind.h"
#include "base/location.h"
#include "media/base/video_frame.h"

namespace media {
namespace cast {

SizeAdaptableVideoEncoderBase::SizeAdaptableVideoEncoderBase(
    const scoped_refptr<CastEnvironment>& cast_environment,
    const FrameSenderConfig& video_config,
    const StatusChangeCallback& status_change_cb)
    : cast_environment_(cast_environment),
      video_config_(video_config),
      status_change_cb_(status_change_cb),
      frames_in_encoder_(0),
      next_frame_id_(FrameId::first()),
      weak_factory_(this) {
  cast_environment_->PostTask(
      CastEnvironment::MAIN, FROM_HERE,
      base::Bind(status_change_cb_, STATUS_INITIALIZED));
}

SizeAdaptableVideoEncoderBase::~SizeAdaptableVideoEncoderBase() {
  DestroyEncoder();
}

bool SizeAdaptableVideoEncoderBase::EncodeVideoFrame(
    const scoped_refptr<media::VideoFrame>& video_frame,
    const base::TimeTicks& reference_time,
    const FrameEncodedCallback& frame_encoded_callback) {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));

  const gfx::Size frame_size = video_frame->visible_rect().size();
  if (frame_size.IsEmpty()) {
    DVLOG(1) << "Rejecting empty video frame.";
    return false;
  }
  if (frames_in_encoder_ == kEncoderIsInitializing) {
    VLOG(1) << "Dropping frame since encoder initialization is in-progress.";
    return false;
  }
  if (frame_size != frame_size_ || !encoder_) {
    VLOG(1) << "Dropping this frame, and future frames until a replacement "
               "encoder is spun-up to handle size "
            << frame_size.ToString();
    TrySpawningReplacementEncoder(frame_size);
    return false;
  }

  const bool is_frame_accepted = encoder_->EncodeVideoFrame(
      video_frame, reference_time,
      base::Bind(&SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame,
                 weak_factory_.GetWeakPtr(), frame_encoded_callback));
  if (is_frame_accepted) ++frames_in_encoder_;
  return is_frame_accepted;
}

void SizeAdaptableVideoEncoderBase::SetBitRate(int new_bit_rate) {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  video_config_.start_bitrate = new_bit_rate;
  if (encoder_) encoder_->SetBitRate(new_bit_rate);
}

void SizeAdaptableVideoEncoderBase::GenerateKeyFrame() {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  if (encoder_) encoder_->GenerateKeyFrame();
}

std::unique_ptr<VideoFrameFactory>
SizeAdaptableVideoEncoderBase::CreateVideoFrameFactory() {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  return nullptr;
}

void SizeAdaptableVideoEncoderBase::EmitFrames() {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  if (encoder_) encoder_->EmitFrames();
}

StatusChangeCallback
SizeAdaptableVideoEncoderBase::CreateEncoderStatusChangeCallback() {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  return base::Bind(&SizeAdaptableVideoEncoderBase::OnEncoderStatusChange,
                    weak_factory_.GetWeakPtr());
}

void SizeAdaptableVideoEncoderBase::OnEncoderReplaced(
    VideoEncoder* replacement_encoder) {}

void SizeAdaptableVideoEncoderBase::DestroyEncoder() {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  // The weak pointers are invalidated to prevent future calls back to |this|.
  // This effectively cancels any of |encoder_|'s posted tasks that have not yet
  // run.
  weak_factory_.InvalidateWeakPtrs();
  encoder_.reset();
}

void SizeAdaptableVideoEncoderBase::TrySpawningReplacementEncoder(
    const gfx::Size& size_needed) {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));

  // If prior frames are still encoding in the current encoder, let them finish
  // first.
  if (frames_in_encoder_ > 0) {
    encoder_->EmitFrames();
    // Check again, since EmitFrames() is a synchronous operation for some
    // encoders.
    if (frames_in_encoder_ > 0) return;
  }

  if (frames_in_encoder_ == kEncoderIsInitializing) return;  // Already spawned.

  DestroyEncoder();
  frames_in_encoder_ = kEncoderIsInitializing;
  OnEncoderStatusChange(STATUS_CODEC_REINIT_PENDING);
  VLOG(1) << "Creating replacement video encoder (for frame size change from "
          << frame_size_.ToString() << " to " << size_needed.ToString() << ").";
  frame_size_ = size_needed;
  encoder_ = CreateEncoder();
  DCHECK(encoder_);
}

void SizeAdaptableVideoEncoderBase::OnEncoderStatusChange(
    OperationalStatus status) {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  if (frames_in_encoder_ == kEncoderIsInitializing &&
      status == STATUS_INITIALIZED) {
    // Begin using the replacement encoder.
    frames_in_encoder_ = 0;
    OnEncoderReplaced(encoder_.get());
  }
  status_change_cb_.Run(status);
}

void SizeAdaptableVideoEncoderBase::OnEncodedVideoFrame(
    const FrameEncodedCallback& frame_encoded_callback,
    std::unique_ptr<SenderEncodedFrame> encoded_frame) {
  DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
  --frames_in_encoder_;
  DCHECK_GE(frames_in_encoder_, 0);

  if (encoded_frame) next_frame_id_ = encoded_frame->frame_id + 1;
  frame_encoded_callback.Run(std::move(encoded_frame));
}

}  // namespace cast
}  // namespace media
