// Copyright 2014 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 "remoting/client/software_video_renderer.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner_util.h"
#include "remoting/base/util.h"
#include "remoting/client/client_context.h"
#include "remoting/codec/video_decoder.h"
#include "remoting/codec/video_decoder_verbatim.h"
#include "remoting/codec/video_decoder_vpx.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/frame_consumer.h"
#include "remoting/protocol/frame_stats.h"
#include "remoting/protocol/performance_tracker.h"
#include "remoting/protocol/session_config.h"
#include "third_party/libyuv/include/libyuv/convert_argb.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"

using remoting::protocol::ChannelConfig;
using remoting::protocol::SessionConfig;

namespace remoting {

namespace {

std::unique_ptr<webrtc::DesktopFrame> DoDecodeFrame(
    VideoDecoder* decoder,
    std::unique_ptr<VideoPacket> packet,
    std::unique_ptr<webrtc::DesktopFrame> frame) {
  if (!decoder->DecodePacket(*packet, frame.get()))
    frame.reset();
  return frame;
}

}  // namespace

SoftwareVideoRenderer::SoftwareVideoRenderer(protocol::FrameConsumer* consumer)
    : consumer_(consumer), weak_factory_(this) {
  thread_checker_.DetachFromThread();
}

SoftwareVideoRenderer::SoftwareVideoRenderer(
    std::unique_ptr<protocol::FrameConsumer> consumer)
    : SoftwareVideoRenderer(consumer.get()) {
  owned_consumer_ = std::move(consumer);
}

SoftwareVideoRenderer::~SoftwareVideoRenderer() {
  if (decoder_)
    decode_task_runner_->DeleteSoon(FROM_HERE, decoder_.release());
}

bool SoftwareVideoRenderer::Initialize(
    const ClientContext& client_context,
    protocol::FrameStatsConsumer* stats_consumer) {
  DCHECK(thread_checker_.CalledOnValidThread());
  decode_task_runner_ = client_context.decode_task_runner();
  stats_consumer_ = stats_consumer;
  return true;
}

void SoftwareVideoRenderer::OnSessionConfig(
    const protocol::SessionConfig& config) {
  DCHECK(thread_checker_.CalledOnValidThread());

  // Initialize decoder based on the selected codec.
  ChannelConfig::Codec codec = config.video_config().codec;
  if (codec == ChannelConfig::CODEC_VERBATIM) {
    decoder_.reset(new VideoDecoderVerbatim());
  } else if (codec == ChannelConfig::CODEC_VP8) {
    decoder_ = VideoDecoderVpx::CreateForVP8();
  } else if (codec == ChannelConfig::CODEC_VP9) {
    decoder_ = VideoDecoderVpx::CreateForVP9();
  } else {
    NOTREACHED() << "Invalid Encoding found: " << codec;
  }

  decoder_->SetPixelFormat(
      (consumer_->GetPixelFormat() == protocol::FrameConsumer::FORMAT_BGRA)
          ? VideoDecoder::PixelFormat::BGRA
          : VideoDecoder::PixelFormat::RGBA);
}

protocol::VideoStub* SoftwareVideoRenderer::GetVideoStub() {
  DCHECK(thread_checker_.CalledOnValidThread());
  return this;
}

protocol::FrameConsumer* SoftwareVideoRenderer::GetFrameConsumer() {
  return consumer_;
}

protocol::FrameStatsConsumer* SoftwareVideoRenderer::GetFrameStatsConsumer() {
  return stats_consumer_;
}

void SoftwareVideoRenderer::ProcessVideoPacket(
    std::unique_ptr<VideoPacket> packet,
    const base::Closure& done) {
  DCHECK(thread_checker_.CalledOnValidThread());

  base::ScopedClosureRunner done_runner(done);

  std::unique_ptr<protocol::FrameStats> frame_stats(new protocol::FrameStats());
  frame_stats->host_stats =
      protocol::HostFrameStats::GetForVideoPacket(*packet);
  frame_stats->client_stats.time_received = base::TimeTicks::Now();

  // If the video packet is empty then there is nothing to decode. Empty packets
  // are used to maintain activity on the network. Stats for such packets still
  // need to be reported.
  if (!packet->has_data() || packet->data().size() == 0) {
    if (stats_consumer_)
      stats_consumer_->OnVideoFrameStats(*frame_stats);
    return;
  }

  if (packet->format().has_screen_width() &&
      packet->format().has_screen_height()) {
    source_size_.set(packet->format().screen_width(),
                     packet->format().screen_height());
  }

  if (packet->format().has_x_dpi() && packet->format().has_y_dpi()) {
    webrtc::DesktopVector source_dpi(packet->format().x_dpi(),
                                     packet->format().y_dpi());
    if (!source_dpi.equals(source_dpi_)) {
      source_dpi_ = source_dpi;
    }
  }

  if (source_size_.is_empty()) {
    LOG(ERROR) << "Received VideoPacket with unknown size.";
    return;
  }

  std::unique_ptr<webrtc::DesktopFrame> frame =
      consumer_->AllocateFrame(source_size_);
  frame->set_dpi(source_dpi_);

  base::PostTaskAndReplyWithResult(
      decode_task_runner_.get(), FROM_HERE,
      base::Bind(&DoDecodeFrame, decoder_.get(), base::Passed(&packet),
                 base::Passed(&frame)),
      base::Bind(&SoftwareVideoRenderer::RenderFrame,
                 weak_factory_.GetWeakPtr(), base::Passed(&frame_stats),
                 done_runner.Release()));
}

void SoftwareVideoRenderer::RenderFrame(
    std::unique_ptr<protocol::FrameStats> stats,
    const base::Closure& done,
    std::unique_ptr<webrtc::DesktopFrame> frame) {
  DCHECK(thread_checker_.CalledOnValidThread());

  stats->client_stats.time_decoded = base::TimeTicks::Now();
  if (!frame) {
    if (!done.is_null())
      done.Run();
    return;
  }

  consumer_->DrawFrame(
      std::move(frame),
      base::Bind(&SoftwareVideoRenderer::OnFrameRendered,
                 weak_factory_.GetWeakPtr(), base::Passed(&stats), done));
}

void SoftwareVideoRenderer::OnFrameRendered(
    std::unique_ptr<protocol::FrameStats> stats,
    const base::Closure& done) {
  DCHECK(thread_checker_.CalledOnValidThread());

  stats->client_stats.time_rendered = base::TimeTicks::Now();
  if (stats_consumer_)
    stats_consumer_->OnVideoFrameStats(*stats);

  if (!done.is_null())
    done.Run();
}

}  // namespace remoting
