/*
 *  Copyright (c) 2014 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/main/acm2/acm_send_test.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/checks.h"
#include "webrtc/modules/audio_coding/main/interface/audio_coding_module.h"
#include "webrtc/modules/audio_coding/neteq/tools/input_audio_file.h"
#include "webrtc/modules/audio_coding/neteq/tools/packet.h"

namespace webrtc {
namespace test {

AcmSendTest::AcmSendTest(InputAudioFile* audio_source,
                         int source_rate_hz,
                         int test_duration_ms)
    : clock_(0),
      audio_source_(audio_source),
      source_rate_hz_(source_rate_hz),
      input_block_size_samples_(
          static_cast<size_t>(source_rate_hz_ * kBlockSizeMs / 1000)),
      codec_registered_(false),
      test_duration_ms_(test_duration_ms),
      frame_type_(kAudioFrameSpeech),
      payload_type_(0),
      timestamp_(0),
      sequence_number_(0) {
  webrtc::AudioCoding::Config config;
  config.clock = &clock_;
  config.transport = this;
  acm_.reset(webrtc::AudioCoding::Create(config));
  input_frame_.sample_rate_hz_ = source_rate_hz_;
  input_frame_.num_channels_ = 1;
  input_frame_.samples_per_channel_ = input_block_size_samples_;
  assert(input_block_size_samples_ * input_frame_.num_channels_ <=
         AudioFrame::kMaxDataSizeSamples);
}

bool AcmSendTest::RegisterCodec(int codec_type,
                                int channels,
                                int payload_type,
                                int frame_size_samples) {
  codec_registered_ =
      acm_->RegisterSendCodec(codec_type, payload_type, frame_size_samples);
  input_frame_.num_channels_ = channels;
  assert(input_block_size_samples_ * input_frame_.num_channels_ <=
         AudioFrame::kMaxDataSizeSamples);
  return codec_registered_;
}

Packet* AcmSendTest::NextPacket() {
  assert(codec_registered_);
  if (filter_.test(static_cast<size_t>(payload_type_))) {
    // This payload type should be filtered out. Since the payload type is the
    // same throughout the whole test run, no packet at all will be delivered.
    // We can just as well signal that the test is over by returning NULL.
    return NULL;
  }
  // Insert audio and process until one packet is produced.
  while (clock_.TimeInMilliseconds() < test_duration_ms_) {
    clock_.AdvanceTimeMilliseconds(kBlockSizeMs);
    RTC_CHECK(
        audio_source_->Read(input_block_size_samples_, input_frame_.data_));
    if (input_frame_.num_channels_ > 1) {
      InputAudioFile::DuplicateInterleaved(input_frame_.data_,
                                           input_block_size_samples_,
                                           input_frame_.num_channels_,
                                           input_frame_.data_);
    }
    int32_t encoded_bytes = acm_->Add10MsAudio(input_frame_);
    EXPECT_GE(encoded_bytes, 0);
    input_frame_.timestamp_ += static_cast<uint32_t>(input_block_size_samples_);
    if (encoded_bytes > 0) {
      // Encoded packet received.
      return CreatePacket();
    }
  }
  // Test ended.
  return NULL;
}

// This method receives the callback from ACM when a new packet is produced.
int32_t AcmSendTest::SendData(FrameType frame_type,
                              uint8_t payload_type,
                              uint32_t timestamp,
                              const uint8_t* payload_data,
                              size_t payload_len_bytes,
                              const RTPFragmentationHeader* fragmentation) {
  // Store the packet locally.
  frame_type_ = frame_type;
  payload_type_ = payload_type;
  timestamp_ = timestamp;
  last_payload_vec_.assign(payload_data, payload_data + payload_len_bytes);
  assert(last_payload_vec_.size() == payload_len_bytes);
  return 0;
}

Packet* AcmSendTest::CreatePacket() {
  const size_t kRtpHeaderSize = 12;
  size_t allocated_bytes = last_payload_vec_.size() + kRtpHeaderSize;
  uint8_t* packet_memory = new uint8_t[allocated_bytes];
  // Populate the header bytes.
  packet_memory[0] = 0x80;
  packet_memory[1] = static_cast<uint8_t>(payload_type_);
  packet_memory[2] = (sequence_number_ >> 8) & 0xFF;
  packet_memory[3] = (sequence_number_) & 0xFF;
  packet_memory[4] = (timestamp_ >> 24) & 0xFF;
  packet_memory[5] = (timestamp_ >> 16) & 0xFF;
  packet_memory[6] = (timestamp_ >> 8) & 0xFF;
  packet_memory[7] = timestamp_ & 0xFF;
  // Set SSRC to 0x12345678.
  packet_memory[8] = 0x12;
  packet_memory[9] = 0x34;
  packet_memory[10] = 0x56;
  packet_memory[11] = 0x78;

  ++sequence_number_;

  // Copy the payload data.
  memcpy(packet_memory + kRtpHeaderSize,
         &last_payload_vec_[0],
         last_payload_vec_.size());
  Packet* packet =
      new Packet(packet_memory, allocated_bytes, clock_.TimeInMilliseconds());
  assert(packet);
  assert(packet->valid_header());
  return packet;
}

}  // namespace test
}  // namespace webrtc
