1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/video_coding/codecs/test/packet_manipulator.h" 12 13 #include <queue> 14 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 17 #include "webrtc/modules/video_coding/codecs/test/predictive_packet_manipulator.h" 18 #include "webrtc/test/testsupport/unittest_utils.h" 19 #include "webrtc/typedefs.h" 20 21 namespace webrtc { 22 namespace test { 23 24 const double kNeverDropProbability = 0.0; 25 const double kAlwaysDropProbability = 1.0; 26 const int kBurstLength = 1; 27 28 class PacketManipulatorTest : public PacketRelatedTest { 29 protected: 30 PacketReader packet_reader_; 31 EncodedImage image_; 32 NetworkingConfig drop_config_; 33 NetworkingConfig no_drop_config_; 34 35 PacketManipulatorTest() { 36 image_._buffer = packet_data_; 37 image_._length = kPacketDataLength; 38 image_._size = kPacketDataLength; 39 40 drop_config_.packet_size_in_bytes = kPacketSizeInBytes; 41 drop_config_.packet_loss_probability = kAlwaysDropProbability; 42 drop_config_.packet_loss_burst_length = kBurstLength; 43 drop_config_.packet_loss_mode = kUniform; 44 45 no_drop_config_.packet_size_in_bytes = kPacketSizeInBytes; 46 no_drop_config_.packet_loss_probability = kNeverDropProbability; 47 no_drop_config_.packet_loss_burst_length = kBurstLength; 48 no_drop_config_.packet_loss_mode = kUniform; 49 } 50 51 virtual ~PacketManipulatorTest() {} 52 53 void SetUp() { PacketRelatedTest::SetUp(); } 54 55 void TearDown() { PacketRelatedTest::TearDown(); } 56 57 void VerifyPacketLoss(int expected_nbr_packets_dropped, 58 int actual_nbr_packets_dropped, 59 size_t expected_packet_data_length, 60 uint8_t* expected_packet_data, 61 const EncodedImage& actual_image) { 62 EXPECT_EQ(expected_nbr_packets_dropped, actual_nbr_packets_dropped); 63 EXPECT_EQ(expected_packet_data_length, image_._length); 64 EXPECT_EQ(0, memcmp(expected_packet_data, actual_image._buffer, 65 expected_packet_data_length)); 66 } 67 }; 68 69 TEST_F(PacketManipulatorTest, Constructor) { 70 PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false); 71 } 72 73 TEST_F(PacketManipulatorTest, DropNone) { 74 PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false); 75 int nbr_packets_dropped = manipulator.ManipulatePackets(&image_); 76 VerifyPacketLoss(0, nbr_packets_dropped, kPacketDataLength, packet_data_, 77 image_); 78 } 79 80 TEST_F(PacketManipulatorTest, UniformDropNoneSmallFrame) { 81 size_t data_length = 400; // smaller than the packet size 82 image_._length = data_length; 83 PacketManipulatorImpl manipulator(&packet_reader_, no_drop_config_, false); 84 int nbr_packets_dropped = manipulator.ManipulatePackets(&image_); 85 86 VerifyPacketLoss(0, nbr_packets_dropped, data_length, packet_data_, image_); 87 } 88 89 TEST_F(PacketManipulatorTest, UniformDropAll) { 90 PacketManipulatorImpl manipulator(&packet_reader_, drop_config_, false); 91 int nbr_packets_dropped = manipulator.ManipulatePackets(&image_); 92 VerifyPacketLoss(kPacketDataNumberOfPackets, nbr_packets_dropped, 0, 93 packet_data_, image_); 94 } 95 96 // Use our customized test class to make the second packet being lost 97 TEST_F(PacketManipulatorTest, UniformDropSinglePacket) { 98 drop_config_.packet_loss_probability = 0.5; 99 PredictivePacketManipulator manipulator(&packet_reader_, drop_config_); 100 manipulator.AddRandomResult(1.0); 101 manipulator.AddRandomResult(0.3); // less than 0.5 will cause packet loss 102 manipulator.AddRandomResult(1.0); 103 104 // Execute the test target method: 105 int nbr_packets_dropped = manipulator.ManipulatePackets(&image_); 106 107 // Since we setup the predictive packet manipulator, it will throw away the 108 // second packet. The third packet is also lost because when we have lost one, 109 // the remains shall also be discarded (in the current implementation). 110 VerifyPacketLoss(2, nbr_packets_dropped, kPacketSizeInBytes, packet1_, 111 image_); 112 } 113 114 // Use our customized test class to make the second packet being lost 115 TEST_F(PacketManipulatorTest, BurstDropNinePackets) { 116 // Create a longer packet data structure (10 packets) 117 const int kNbrPackets = 10; 118 const size_t kDataLength = kPacketSizeInBytes * kNbrPackets; 119 uint8_t data[kDataLength]; 120 uint8_t* data_pointer = data; 121 // Fill with 0s, 1s and so on to be able to easily verify which were dropped: 122 for (int i = 0; i < kNbrPackets; ++i) { 123 memset(data_pointer + i * kPacketSizeInBytes, i, kPacketSizeInBytes); 124 } 125 // Overwrite the defaults from the test fixture: 126 image_._buffer = data; 127 image_._length = kDataLength; 128 image_._size = kDataLength; 129 130 drop_config_.packet_loss_probability = 0.5; 131 drop_config_.packet_loss_burst_length = 5; 132 drop_config_.packet_loss_mode = kBurst; 133 PredictivePacketManipulator manipulator(&packet_reader_, drop_config_); 134 manipulator.AddRandomResult(1.0); 135 manipulator.AddRandomResult(0.3); // less than 0.5 will cause packet loss 136 for (int i = 0; i < kNbrPackets - 2; ++i) { 137 manipulator.AddRandomResult(1.0); 138 } 139 140 // Execute the test target method: 141 int nbr_packets_dropped = manipulator.ManipulatePackets(&image_); 142 143 // Should discard every packet after the first one. 144 VerifyPacketLoss(9, nbr_packets_dropped, kPacketSizeInBytes, data, image_); 145 } 146 147 } // namespace test 148 } // namespace webrtc 149