/*
 *  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.
 */

// Unit tests for test Packet class.

#include "webrtc/modules/audio_coding/neteq/tools/packet.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace webrtc {
namespace test {

namespace {
const int kHeaderLengthBytes = 12;

void MakeRtpHeader(int payload_type,
                   int seq_number,
                   uint32_t timestamp,
                   uint32_t ssrc,
                   uint8_t* rtp_data) {
  rtp_data[0] = 0x80;
  rtp_data[1] = static_cast<uint8_t>(payload_type);
  rtp_data[2] = (seq_number >> 8) & 0xFF;
  rtp_data[3] = (seq_number) & 0xFF;
  rtp_data[4] = timestamp >> 24;
  rtp_data[5] = (timestamp >> 16) & 0xFF;
  rtp_data[6] = (timestamp >> 8) & 0xFF;
  rtp_data[7] = timestamp & 0xFF;
  rtp_data[8] = ssrc >> 24;
  rtp_data[9] = (ssrc >> 16) & 0xFF;
  rtp_data[10] = (ssrc >> 8) & 0xFF;
  rtp_data[11] = ssrc & 0xFF;
}
}  // namespace

TEST(TestPacket, RegularPacket) {
  const size_t kPacketLengthBytes = 100;
  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
  const uint8_t kPayloadType = 17;
  const uint16_t kSequenceNumber = 4711;
  const uint32_t kTimestamp = 47114711;
  const uint32_t kSsrc = 0x12345678;
  MakeRtpHeader(
      kPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
  const double kPacketTime = 1.0;
  // Hand over ownership of |packet_memory| to |packet|.
  Packet packet(packet_memory, kPacketLengthBytes, kPacketTime);
  ASSERT_TRUE(packet.valid_header());
  EXPECT_EQ(kPayloadType, packet.header().payloadType);
  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
  EXPECT_EQ(kTimestamp, packet.header().timestamp);
  EXPECT_EQ(kSsrc, packet.header().ssrc);
  EXPECT_EQ(0, packet.header().numCSRCs);
  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
            packet.payload_length_bytes());
  EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
            packet.virtual_payload_length_bytes());
  EXPECT_EQ(kPacketTime, packet.time_ms());
}

TEST(TestPacket, DummyPacket) {
  const size_t kPacketLengthBytes = kHeaderLengthBytes;  // Only RTP header.
  const size_t kVirtualPacketLengthBytes = 100;
  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
  const uint8_t kPayloadType = 17;
  const uint16_t kSequenceNumber = 4711;
  const uint32_t kTimestamp = 47114711;
  const uint32_t kSsrc = 0x12345678;
  MakeRtpHeader(
      kPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
  const double kPacketTime = 1.0;
  // Hand over ownership of |packet_memory| to |packet|.
  Packet packet(packet_memory,
                kPacketLengthBytes,
                kVirtualPacketLengthBytes,
                kPacketTime);
  ASSERT_TRUE(packet.valid_header());
  EXPECT_EQ(kPayloadType, packet.header().payloadType);
  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
  EXPECT_EQ(kTimestamp, packet.header().timestamp);
  EXPECT_EQ(kSsrc, packet.header().ssrc);
  EXPECT_EQ(0, packet.header().numCSRCs);
  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
            packet.payload_length_bytes());
  EXPECT_EQ(kVirtualPacketLengthBytes, packet.virtual_packet_length_bytes());
  EXPECT_EQ(kVirtualPacketLengthBytes - kHeaderLengthBytes,
            packet.virtual_payload_length_bytes());
  EXPECT_EQ(kPacketTime, packet.time_ms());
}

namespace {
// Writes one RED block header starting at |rtp_data|, according to RFC 2198.
// returns the number of bytes written (1 or 4).
//
// Format if |last_payoad| is false:
// 0                   1                    2                   3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3  4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// |1|   block PT  |  timestamp offset         |   block length    |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
// Format if |last_payoad| is true:
// 0 1 2 3 4 5 6 7
// +-+-+-+-+-+-+-+-+
// |0|   Block PT  |
// +-+-+-+-+-+-+-+-+

int MakeRedHeader(int payload_type,
                  uint32_t timestamp_offset,
                  int block_length,
                  bool last_payload,
                  uint8_t* rtp_data) {
  rtp_data[0] = 0x80 | (payload_type & 0x7F);  // Set the first bit to 1.
  if (last_payload) {
    rtp_data[0] &= 0x7F;  // Reset the first but to 0 to indicate last block.
    return 1;
  }
  rtp_data[1] = timestamp_offset >> 6;
  rtp_data[2] = (timestamp_offset & 0x3F) << 2;
  rtp_data[2] |= block_length >> 8;
  rtp_data[3] = block_length & 0xFF;
  return 4;
}
}  // namespace

TEST(TestPacket, RED) {
  const size_t kPacketLengthBytes = 100;
  uint8_t* packet_memory = new uint8_t[kPacketLengthBytes];
  const uint8_t kRedPayloadType = 17;
  const uint16_t kSequenceNumber = 4711;
  const uint32_t kTimestamp = 47114711;
  const uint32_t kSsrc = 0x12345678;
  MakeRtpHeader(
      kRedPayloadType, kSequenceNumber, kTimestamp, kSsrc, packet_memory);
  // Create four RED headers.
  // Payload types are just the same as the block index the offset is 100 times
  // the block index.
  const int kRedBlocks = 4;
  uint8_t* payload_ptr =
      &packet_memory[kHeaderLengthBytes];  // First byte after header.
  for (int i = 0; i < kRedBlocks; ++i) {
    int payload_type = i;
    // Offset value is not used for the last block.
    uint32_t timestamp_offset = 100 * i;
    int block_length = 10 * i;
    bool last_block = (i == kRedBlocks - 1) ? true : false;
    payload_ptr += MakeRedHeader(
        payload_type, timestamp_offset, block_length, last_block, payload_ptr);
  }
  const double kPacketTime = 1.0;
  // Hand over ownership of |packet_memory| to |packet|.
  Packet packet(packet_memory, kPacketLengthBytes, kPacketTime);
  ASSERT_TRUE(packet.valid_header());
  EXPECT_EQ(kRedPayloadType, packet.header().payloadType);
  EXPECT_EQ(kSequenceNumber, packet.header().sequenceNumber);
  EXPECT_EQ(kTimestamp, packet.header().timestamp);
  EXPECT_EQ(kSsrc, packet.header().ssrc);
  EXPECT_EQ(0, packet.header().numCSRCs);
  EXPECT_EQ(kPacketLengthBytes, packet.packet_length_bytes());
  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
            packet.payload_length_bytes());
  EXPECT_EQ(kPacketLengthBytes, packet.virtual_packet_length_bytes());
  EXPECT_EQ(kPacketLengthBytes - kHeaderLengthBytes,
            packet.virtual_payload_length_bytes());
  EXPECT_EQ(kPacketTime, packet.time_ms());
  std::list<RTPHeader*> red_headers;
  EXPECT_TRUE(packet.ExtractRedHeaders(&red_headers));
  EXPECT_EQ(kRedBlocks, static_cast<int>(red_headers.size()));
  int block_index = 0;
  for (std::list<RTPHeader*>::reverse_iterator it = red_headers.rbegin();
       it != red_headers.rend();
       ++it) {
    // Reading list from the back, since the extraction puts the main payload
    // (which is the last one on wire) first.
    RTPHeader* red_block = *it;
    EXPECT_EQ(block_index, red_block->payloadType);
    EXPECT_EQ(kSequenceNumber, red_block->sequenceNumber);
    if (block_index == kRedBlocks - 1) {
      // Last block has zero offset per definition.
      EXPECT_EQ(kTimestamp, red_block->timestamp);
    } else {
      EXPECT_EQ(kTimestamp - 100 * block_index, red_block->timestamp);
    }
    EXPECT_EQ(kSsrc, red_block->ssrc);
    EXPECT_EQ(0, red_block->numCSRCs);
    ++block_index;
  }
  Packet::DeleteRedHeaders(&red_headers);
}

}  // namespace test
}  // namespace webrtc
