// Copyright (c) 2010 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/protocol/rtp_video_writer.h"

#include "base/bind.h"
#include "base/task.h"
#include "net/base/io_buffer.h"
#include "remoting/base/compound_buffer.h"
#include "remoting/base/constants.h"
#include "remoting/proto/video.pb.h"
#include "remoting/protocol/rtp_writer.h"
#include "remoting/protocol/session.h"

namespace remoting {
namespace protocol {

namespace {
const int kMtu = 1200;
}  // namespace

RtpVideoWriter::RtpVideoWriter(base::MessageLoopProxy* message_loop)
    : initialized_(false),
      rtp_writer_(message_loop) {
}

RtpVideoWriter::~RtpVideoWriter() {
  Close();
}

void RtpVideoWriter::Init(protocol::Session* session,
                          const InitializedCallback& callback) {
  initialized_callback_ = callback;
  session->CreateDatagramChannel(
      kVideoRtpChannelName,
      base::Bind(&RtpVideoWriter::OnChannelReady,
                 base::Unretained(this), true));
  session->CreateDatagramChannel(
      kVideoRtcpChannelName,
      base::Bind(&RtpVideoWriter::OnChannelReady,
                 base::Unretained(this), false));
}

void RtpVideoWriter::OnChannelReady(bool rtp, net::Socket* socket) {
  if (!socket) {
    if (!initialized_) {
      initialized_ = true;
      initialized_callback_.Run(false);
    }
    return;
  }

  if (rtp) {
    DCHECK(!rtp_channel_.get());
    rtp_channel_.reset(socket);
    rtp_writer_.Init(socket);
  } else {
    DCHECK(!rtcp_channel_.get());
    rtcp_channel_.reset(socket);
    // TODO(sergeyu): Use RTCP channel somehow.
  }

  if (rtp_channel_.get() && rtcp_channel_.get()) {
    DCHECK(!initialized_);
    initialized_ = true;
    initialized_callback_.Run(true);
  }
}

void RtpVideoWriter::Close() {
  rtp_writer_.Close();
  rtp_channel_.reset();
  rtcp_channel_.reset();
}

void RtpVideoWriter::ProcessVideoPacket(const VideoPacket* packet, Task* done) {
  CHECK(packet->format().encoding() == VideoPacketFormat::ENCODING_VP8)
      << "Only VP8 is supported in RTP.";

  CompoundBuffer payload;
  // TODO(sergeyu): This copy would not be necessary CompoundBuffer was used
  // inside of VideoPacket.
  payload.AppendCopyOf(packet->data().data(), packet->data().size());

  Vp8Descriptor vp8_desriptor;
  // TODO(sergeyu): Add a flag in VideoPacket that indicates whether this is a
  // key frame or not.
  vp8_desriptor.non_reference_frame = false;
  vp8_desriptor.picture_id = kuint32max;

  int position = 0;
  while (position < payload.total_bytes()) {
    int size = std::min(kMtu, payload.total_bytes() - position);

    // Frame beginning flag is set only for the first packet in the first
    // partition.
    vp8_desriptor.frame_beginning =
        (packet->flags() & VideoPacket::FIRST_PACKET) != 0 && position == 0;

    // Marker bit is set only for the last packet in the last partition.
    bool marker = (position + size) == payload.total_bytes() &&
        (packet->flags() & VideoPacket::LAST_PACKET) != 0;

    // Set fragmentation flag appropriately.
    if (position == 0) {
      if (size == payload.total_bytes()) {
        vp8_desriptor.fragmentation_info = Vp8Descriptor::NOT_FRAGMENTED;
      } else {
        vp8_desriptor.fragmentation_info = Vp8Descriptor::FIRST_FRAGMENT;
      }
    } else {
      if (position + size == payload.total_bytes()) {
        vp8_desriptor.fragmentation_info = Vp8Descriptor::LAST_FRAGMENT;
      } else {
        vp8_desriptor.fragmentation_info = Vp8Descriptor::MIDDLE_FRAGMENT;
      }
    }

    // Create CompoundBuffer for the chunk.
    CompoundBuffer chunk;
    chunk.CopyFrom(payload, position, position + size);

    // And send it.
    rtp_writer_.SendPacket(packet->timestamp(), marker, vp8_desriptor, chunk);

    position += size;
  }
  DCHECK_EQ(position, payload.total_bytes());

  done->Run();
  delete done;
}

int RtpVideoWriter::GetPendingPackets() {
  return rtp_writer_.GetPendingPackets();
}

}  // namespace protocol
}  // namespace remoting
