/*
 *  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);
    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
