/*
 *  Copyright (c) 2016 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 "webrtc/modules/audio_coding/neteq/tools/encode_neteq_input.h"

#include <utility>

#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/safe_conversions.h"

namespace webrtc {
namespace test {

EncodeNetEqInput::EncodeNetEqInput(std::unique_ptr<Generator> generator,
                                   std::unique_ptr<AudioEncoder> encoder,
                                   int64_t input_duration_ms)
    : generator_(std::move(generator)),
      encoder_(std::move(encoder)),
      input_duration_ms_(input_duration_ms) {
  CreatePacket();
}

rtc::Optional<int64_t> EncodeNetEqInput::NextPacketTime() const {
  RTC_DCHECK(packet_data_);
  return rtc::Optional<int64_t>(static_cast<int64_t>(packet_data_->time_ms));
}

rtc::Optional<int64_t> EncodeNetEqInput::NextOutputEventTime() const {
  return rtc::Optional<int64_t>(next_output_event_ms_);
}

std::unique_ptr<NetEqInput::PacketData> EncodeNetEqInput::PopPacket() {
  RTC_DCHECK(packet_data_);
  // Grab the packet to return...
  std::unique_ptr<PacketData> packet_to_return = std::move(packet_data_);
  // ... and line up the next packet for future use.
  CreatePacket();

  return packet_to_return;
}

void EncodeNetEqInput::AdvanceOutputEvent() {
  next_output_event_ms_ += kOutputPeriodMs;
}

rtc::Optional<RTPHeader> EncodeNetEqInput::NextHeader() const {
  RTC_DCHECK(packet_data_);
  return rtc::Optional<RTPHeader>(packet_data_->header);
}

void EncodeNetEqInput::CreatePacket() {
  // Create a new PacketData object.
  RTC_DCHECK(!packet_data_);
  packet_data_.reset(new NetEqInput::PacketData);
  RTC_DCHECK_EQ(packet_data_->payload.size(), 0);

  // Loop until we get a packet.
  AudioEncoder::EncodedInfo info;
  RTC_DCHECK(!info.send_even_if_empty);
  int num_blocks = 0;
  while (packet_data_->payload.size() == 0 && !info.send_even_if_empty) {
    const size_t num_samples = rtc::CheckedDivExact(
        static_cast<int>(encoder_->SampleRateHz() * kOutputPeriodMs), 1000);

    info = encoder_->Encode(rtp_timestamp_, generator_->Generate(num_samples),
                            &packet_data_->payload);

    rtp_timestamp_ += rtc::dchecked_cast<uint32_t>(
        num_samples * encoder_->RtpTimestampRateHz() /
        encoder_->SampleRateHz());
    ++num_blocks;
  }
  packet_data_->header.timestamp = info.encoded_timestamp;
  packet_data_->header.payloadType = info.payload_type;
  packet_data_->header.sequenceNumber = sequence_number_++;
  packet_data_->time_ms = next_packet_time_ms_;
  next_packet_time_ms_ += num_blocks * kOutputPeriodMs;
}

}  // namespace test
}  // namespace webrtc
