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

#include "modules/video_coding/codecs/test/packet_manipulator.h"

#include <cassert>
#include <cstdio>

namespace webrtc {
namespace test {

PacketManipulatorImpl::PacketManipulatorImpl(PacketReader* packet_reader,
                                             const NetworkingConfig& config,
                                             bool verbose)
    : packet_reader_(packet_reader),
      config_(config),
      active_burst_packets_(0),
      verbose_(verbose) {
  assert(packet_reader);
}

PacketManipulatorImpl::~PacketManipulatorImpl() {
}

int PacketManipulatorImpl::ManipulatePackets(
    webrtc::EncodedImage* encoded_image) {
  assert(encoded_image);
  int nbr_packets_dropped = 0;
  // There's no need to build a copy of the image data since viewing an
  // EncodedImage object, setting the length to a new lower value represents
  // that everything is dropped after that position in the byte array.
  // EncodedImage._size is the allocated bytes.
  // EncodedImage._length is how many that are filled with data.
  int new_length = 0;
  packet_reader_->InitializeReading(encoded_image->_buffer,
                                    encoded_image->_length,
                                    config_.packet_size_in_bytes);
  WebRtc_UWord8* packet = NULL;
  int nbr_bytes_to_read;
  // keep track of if we've lost any packets, since then we shall loose
  // the remains of the current frame:
  bool packet_loss_has_occurred = false;
  while ((nbr_bytes_to_read = packet_reader_->NextPacket(&packet)) > 0) {
    // Check if we're currently in a packet loss burst that is not completed:
    if (active_burst_packets_ > 0) {
      active_burst_packets_--;
      nbr_packets_dropped++;
    } else if (RandomUniform() < config_.packet_loss_probability ||
        packet_loss_has_occurred) {
      packet_loss_has_occurred = true;
      nbr_packets_dropped++;
      if (config_.packet_loss_mode == kBurst) {
        // Initiate a new burst
        active_burst_packets_ = config_.packet_loss_burst_length - 1;
      }
    } else {
      new_length += nbr_bytes_to_read;
    }
  }
  encoded_image->_length = new_length;
  if (nbr_packets_dropped > 0) {
    // Must set completeFrame to false to inform the decoder about this:
    encoded_image->_completeFrame = false;
    if (verbose_) {
      printf("Dropped %d packets for frame %d (frame length: %d)\n",
             nbr_packets_dropped, encoded_image->_timeStamp,
             encoded_image->_length);
    }
  }
  return nbr_packets_dropped;
}

inline double PacketManipulatorImpl::RandomUniform() {
  return (std::rand() + 1.0)/(RAND_MAX + 1.0);
}

const char* PacketLossModeToStr(PacketLossMode e) {
  switch (e) {
    case kUniform:
      return "Uniform";
    case kBurst:
      return "Burst";
    default:
      assert(false);
      return "Unknown";
  }
}

}  // namespace test
}  // namespace webrtcc
