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