| Index: webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
 | 
| diff --git a/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..b992d2da909345272eb4de4c84bab955d7ce1a4b
 | 
| --- /dev/null
 | 
| +++ b/webrtc/modules/rtp_rtcp/source/rtp_packet_unittest.cc
 | 
| @@ -0,0 +1,252 @@
 | 
| +/*
 | 
| + *  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/rtp_rtcp/source/rtp_packet_received.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/source/rtp_packet_to_send.h"
 | 
| +
 | 
| +#include "testing/gmock/include/gmock/gmock.h"
 | 
| +#include "testing/gtest/include/gtest/gtest.h"
 | 
| +#include "webrtc/base/random.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h"
 | 
| +#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
 | 
| +
 | 
| +using testing::ElementsAreArray;
 | 
| +using testing::make_tuple;
 | 
| +
 | 
| +namespace webrtc {
 | 
| +namespace {
 | 
| +constexpr int8_t kPayloadType = 100;
 | 
| +constexpr uint32_t kSsrc = 0x12345678;
 | 
| +constexpr uint16_t kSeqNum = 88;
 | 
| +constexpr uint32_t kTimestamp = 0x65431278;
 | 
| +constexpr uint8_t kTransmissionOffsetExtensionId = 1;
 | 
| +constexpr uint8_t kAudioLevelExtensionId = 9;
 | 
| +constexpr int32_t kTimeOffset = 0x56ce;
 | 
| +constexpr bool kVoiceActive = true;
 | 
| +constexpr uint8_t kAudioLevel = 0x5a;
 | 
| +constexpr size_t kMaxPaddingSize = 224u;
 | 
| +constexpr uint8_t kMinimumPacket[] = {
 | 
| +    0x80, kPayloadType, 0x00, kSeqNum,
 | 
| +    0x65, 0x43, 0x12, 0x78,
 | 
| +    0x12, 0x34, 0x56, 0x78};
 | 
| +constexpr uint8_t kPacketWithTO[] = {
 | 
| +    0x90, kPayloadType, 0x00, kSeqNum,
 | 
| +    0x65, 0x43, 0x12, 0x78,
 | 
| +    0x12, 0x34, 0x56, 0x78,
 | 
| +    0xbe, 0xde, 0x00, 0x01,
 | 
| +    0x12, 0x00, 0x56, 0xce};
 | 
| +
 | 
| +constexpr uint8_t kPacketWithTOAndAL[] = {
 | 
| +    0x90, kPayloadType, 0x00, kSeqNum,
 | 
| +    0x65, 0x43, 0x12, 0x78,
 | 
| +    0x12, 0x34, 0x56, 0x78,
 | 
| +    0xbe, 0xde, 0x00, 0x02,
 | 
| +    0x12, 0x00, 0x56, 0xce,
 | 
| +    0x90, 0x80|kAudioLevel, 0x00, 0x00};
 | 
| +
 | 
| +constexpr uint32_t kCsrcs[] = {0x34567890, 0x32435465};
 | 
| +constexpr uint8_t kPayload[] = {'p', 'a', 'y', 'l', 'o', 'a', 'd'};
 | 
| +constexpr uint8_t kPacketPaddingSize = 8;
 | 
| +constexpr uint8_t kPacket[] = {
 | 
| +    0xb2, kPayloadType, 0x00, kSeqNum,
 | 
| +    0x65, 0x43, 0x12, 0x78,
 | 
| +    0x12, 0x34, 0x56, 0x78,
 | 
| +    0x34, 0x56, 0x78, 0x90,
 | 
| +    0x32, 0x43, 0x54, 0x65,
 | 
| +    0xbe, 0xde, 0x00, 0x01,
 | 
| +    0x12, 0x00, 0x56, 0xce,
 | 
| +    'p', 'a', 'y', 'l', 'o', 'a', 'd',
 | 
| +    'p', 'a', 'd', 'd', 'i', 'n', 'g', kPacketPaddingSize};
 | 
| +
 | 
| +}  // namespace
 | 
| +
 | 
| +TEST(RtpPacketTest, CreateMinimum) {
 | 
| +  RtpPacketToSend packet(nullptr);
 | 
| +  packet.SetPayloadType(kPayloadType);
 | 
| +  packet.SetSequenceNumber(kSeqNum);
 | 
| +  packet.SetTimestamp(kTimestamp);
 | 
| +  packet.SetSsrc(kSsrc);
 | 
| +  EXPECT_THAT(kMinimumPacket, ElementsAreArray(packet.data(), packet.size()));
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, CreateWithExtension) {
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +  RtpPacketToSend packet(&extensions);
 | 
| +  packet.SetPayloadType(kPayloadType);
 | 
| +  packet.SetSequenceNumber(kSeqNum);
 | 
| +  packet.SetTimestamp(kTimestamp);
 | 
| +  packet.SetSsrc(kSsrc);
 | 
| +  packet.SetExtension<TransmissionOffset>(kTimeOffset);
 | 
| +  EXPECT_THAT(kPacketWithTO, ElementsAreArray(packet.data(), packet.size()));
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, CreateWith2Extensions) {
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +  extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
 | 
| +  RtpPacketToSend packet(&extensions);
 | 
| +  packet.SetPayloadType(kPayloadType);
 | 
| +  packet.SetSequenceNumber(kSeqNum);
 | 
| +  packet.SetTimestamp(kTimestamp);
 | 
| +  packet.SetSsrc(kSsrc);
 | 
| +  packet.SetExtension<TransmissionOffset>(kTimeOffset);
 | 
| +  packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel);
 | 
| +  EXPECT_THAT(kPacketWithTOAndAL,
 | 
| +              ElementsAreArray(packet.data(), packet.size()));
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, SetReservedExtensionsAfterPayload) {
 | 
| +  const size_t kPayloadSize = 4;
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +  extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
 | 
| +  RtpPacketToSend packet(&extensions);
 | 
| +
 | 
| +  EXPECT_TRUE(packet.ReserveExtension<TransmissionOffset>());
 | 
| +  packet.AllocatePayload(kPayloadSize);
 | 
| +  // Can't set extension after payload.
 | 
| +  EXPECT_FALSE(packet.SetExtension<AudioLevel>(kVoiceActive, kAudioLevel));
 | 
| +  // Unless reserved.
 | 
| +  EXPECT_TRUE(packet.SetExtension<TransmissionOffset>(kTimeOffset));
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, CreatePurePadding) {
 | 
| +  const size_t kPaddingSize = kMaxPaddingSize - 1;
 | 
| +  RtpPacketToSend packet(nullptr, 12 + kPaddingSize);
 | 
| +  packet.SetPayloadType(kPayloadType);
 | 
| +  packet.SetSequenceNumber(kSeqNum);
 | 
| +  packet.SetTimestamp(kTimestamp);
 | 
| +  packet.SetSsrc(kSsrc);
 | 
| +  Random random(0x123456789);
 | 
| +
 | 
| +  EXPECT_LT(packet.size(), packet.capacity());
 | 
| +  EXPECT_FALSE(packet.SetPadding(kPaddingSize + 1, &random));
 | 
| +  EXPECT_TRUE(packet.SetPadding(kPaddingSize, &random));
 | 
| +  EXPECT_EQ(packet.size(), packet.capacity());
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, CreateUnalignedPadding) {
 | 
| +  const size_t kPayloadSize = 3;  // Make padding start at unaligned address.
 | 
| +  RtpPacketToSend packet(nullptr, 12 + kPayloadSize + kMaxPaddingSize);
 | 
| +  packet.SetPayloadType(kPayloadType);
 | 
| +  packet.SetSequenceNumber(kSeqNum);
 | 
| +  packet.SetTimestamp(kTimestamp);
 | 
| +  packet.SetSsrc(kSsrc);
 | 
| +  packet.AllocatePayload(kPayloadSize);
 | 
| +  Random r(0x123456789);
 | 
| +
 | 
| +  EXPECT_LT(packet.size(), packet.capacity());
 | 
| +  EXPECT_TRUE(packet.SetPadding(kMaxPaddingSize, &r));
 | 
| +  EXPECT_EQ(packet.size(), packet.capacity());
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseMinimum) {
 | 
| +  RtpPacketReceived packet;
 | 
| +  EXPECT_TRUE(packet.Parse(kMinimumPacket, sizeof(kMinimumPacket)));
 | 
| +  EXPECT_EQ(kPayloadType, packet.PayloadType());
 | 
| +  EXPECT_EQ(kSeqNum, packet.SequenceNumber());
 | 
| +  EXPECT_EQ(kTimestamp, packet.Timestamp());
 | 
| +  EXPECT_EQ(kSsrc, packet.Ssrc());
 | 
| +  EXPECT_EQ(0u, packet.padding_size());
 | 
| +  EXPECT_EQ(0u, packet.payload_size());
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseBuffer) {
 | 
| +  rtc::Buffer unparsed(kMinimumPacket);
 | 
| +  const uint8_t* raw = unparsed.data();
 | 
| +
 | 
| +  RtpPacketReceived packet;
 | 
| +  EXPECT_TRUE(packet.Parse(std::move(unparsed)));
 | 
| +  EXPECT_EQ(raw, packet.data());  // Expect packet took over the buffer.
 | 
| +  EXPECT_EQ(kSeqNum, packet.SequenceNumber());
 | 
| +  EXPECT_EQ(kTimestamp, packet.Timestamp());
 | 
| +  EXPECT_EQ(kSsrc, packet.Ssrc());
 | 
| +  EXPECT_EQ(0u, packet.padding_size());
 | 
| +  EXPECT_EQ(0u, packet.payload_size());
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseWithExtension) {
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +
 | 
| +  RtpPacketReceived packet(&extensions);
 | 
| +  EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
 | 
| +  EXPECT_EQ(kPayloadType, packet.PayloadType());
 | 
| +  EXPECT_EQ(kSeqNum, packet.SequenceNumber());
 | 
| +  EXPECT_EQ(kTimestamp, packet.Timestamp());
 | 
| +  EXPECT_EQ(kSsrc, packet.Ssrc());
 | 
| +  int32_t time_offset;
 | 
| +  EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
 | 
| +  EXPECT_EQ(kTimeOffset, time_offset);
 | 
| +  EXPECT_EQ(0u, packet.payload_size());
 | 
| +  EXPECT_EQ(0u, packet.padding_size());
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseWith2Extensions) {
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +  extensions.Register(kRtpExtensionAudioLevel, kAudioLevelExtensionId);
 | 
| +  RtpPacketReceived packet(&extensions);
 | 
| +  EXPECT_TRUE(packet.Parse(kPacketWithTOAndAL, sizeof(kPacketWithTOAndAL)));
 | 
| +  int32_t time_offset;
 | 
| +  EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
 | 
| +  EXPECT_EQ(kTimeOffset, time_offset);
 | 
| +  bool voice_active;
 | 
| +  uint8_t audio_level;
 | 
| +  EXPECT_TRUE(packet.GetExtension<AudioLevel>(&voice_active, &audio_level));
 | 
| +  EXPECT_EQ(kVoiceActive, voice_active);
 | 
| +  EXPECT_EQ(kAudioLevel, audio_level);
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseWithAllFeatures) {
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +  RtpPacketReceived packet(&extensions);
 | 
| +  EXPECT_TRUE(packet.Parse(kPacket, sizeof(kPacket)));
 | 
| +  EXPECT_EQ(kPayloadType, packet.PayloadType());
 | 
| +  EXPECT_EQ(kSeqNum, packet.SequenceNumber());
 | 
| +  EXPECT_EQ(kTimestamp, packet.Timestamp());
 | 
| +  EXPECT_EQ(kSsrc, packet.Ssrc());
 | 
| +  EXPECT_THAT(packet.Csrcs(), ElementsAreArray(kCsrcs));
 | 
| +  EXPECT_THAT(make_tuple(packet.payload(), packet.payload_size()),
 | 
| +              ElementsAreArray(kPayload));
 | 
| +  EXPECT_EQ(kPacketPaddingSize, packet.padding_size());
 | 
| +  int32_t time_offset;
 | 
| +  EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
 | 
| +}
 | 
| +
 | 
| +TEST(RtpPacketTest, ParseWithExtensionDelayed) {
 | 
| +  RtpPacketReceived packet;
 | 
| +  EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
 | 
| +  EXPECT_EQ(kPayloadType, packet.PayloadType());
 | 
| +  EXPECT_EQ(kSeqNum, packet.SequenceNumber());
 | 
| +  EXPECT_EQ(kTimestamp, packet.Timestamp());
 | 
| +  EXPECT_EQ(kSsrc, packet.Ssrc());
 | 
| +
 | 
| +  RtpPacketToSend::ExtensionManager extensions;
 | 
| +  extensions.Register(kRtpExtensionTransmissionTimeOffset,
 | 
| +                      kTransmissionOffsetExtensionId);
 | 
| +
 | 
| +  int32_t time_offset;
 | 
| +  EXPECT_FALSE(packet.GetExtension<TransmissionOffset>(&time_offset));
 | 
| +  packet.IdentifyExtensions(&extensions);
 | 
| +  EXPECT_TRUE(packet.GetExtension<TransmissionOffset>(&time_offset));
 | 
| +  EXPECT_EQ(kTimeOffset, time_offset);
 | 
| +  EXPECT_EQ(0u, packet.payload_size());
 | 
| +  EXPECT_EQ(0u, packet.padding_size());
 | 
| +}
 | 
| +
 | 
| +}  // namespace webrtc
 | 
| 
 |