Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / rtp_rtcp / source / rtp_payload_registry_unittest.cc
1 /*
2  *  Copyright (c) 2013 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/rtp_rtcp/interface/rtp_payload_registry.h"
12
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "webrtc/modules/rtp_rtcp/source/mock/mock_rtp_payload_strategy.h"
16 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
17 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
18
19 namespace webrtc {
20
21 using ::testing::Eq;
22 using ::testing::Return;
23 using ::testing::_;
24
25 static const char* kTypicalPayloadName = "name";
26 static const uint8_t kTypicalChannels = 1;
27 static const int kTypicalFrequency = 44000;
28 static const int kTypicalRate = 32 * 1024;
29
30 class RtpPayloadRegistryTest : public ::testing::Test {
31  public:
32   void SetUp() {
33     // Note: the payload registry takes ownership of the strategy.
34     mock_payload_strategy_ = new testing::NiceMock<MockRTPPayloadStrategy>();
35     rtp_payload_registry_.reset(new RTPPayloadRegistry(mock_payload_strategy_));
36   }
37
38  protected:
39   RtpUtility::Payload* ExpectReturnOfTypicalAudioPayload(uint8_t payload_type,
40                                                          uint32_t rate) {
41     bool audio = true;
42     RtpUtility::Payload returned_payload = {
43         "name",
44         audio,
45         {// Initialize the audio struct in this case.
46          {kTypicalFrequency, kTypicalChannels, rate}}};
47
48     // Note: we return a new payload since the payload registry takes ownership
49     // of the created object.
50     RtpUtility::Payload* returned_payload_on_heap =
51         new RtpUtility::Payload(returned_payload);
52     EXPECT_CALL(*mock_payload_strategy_,
53         CreatePayloadType(kTypicalPayloadName, payload_type,
54             kTypicalFrequency,
55             kTypicalChannels,
56             rate)).WillOnce(Return(returned_payload_on_heap));
57     return returned_payload_on_heap;
58   }
59
60   scoped_ptr<RTPPayloadRegistry> rtp_payload_registry_;
61   testing::NiceMock<MockRTPPayloadStrategy>* mock_payload_strategy_;
62 };
63
64 TEST_F(RtpPayloadRegistryTest, RegistersAndRemembersPayloadsUntilDeregistered) {
65   uint8_t payload_type = 97;
66   RtpUtility::Payload* returned_payload_on_heap =
67       ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
68
69   bool new_payload_created = false;
70   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
71       kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
72       kTypicalRate, &new_payload_created));
73
74   EXPECT_TRUE(new_payload_created) << "A new payload WAS created.";
75
76   RtpUtility::Payload* retrieved_payload = NULL;
77   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
78                                                           retrieved_payload));
79
80   // We should get back the exact pointer to the payload returned by the
81   // payload strategy.
82   EXPECT_EQ(returned_payload_on_heap, retrieved_payload);
83
84   // Now forget about it and verify it's gone.
85   EXPECT_EQ(0, rtp_payload_registry_->DeRegisterReceivePayload(payload_type));
86   EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
87       payload_type, retrieved_payload));
88 }
89
90 TEST_F(RtpPayloadRegistryTest, DoesNotCreateNewPayloadTypeIfRed) {
91   EXPECT_CALL(*mock_payload_strategy_,
92       CreatePayloadType(_, _, _, _, _)).Times(0);
93
94   bool new_payload_created = false;
95   uint8_t red_type_of_the_day = 104;
96   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
97       "red", red_type_of_the_day, kTypicalFrequency, kTypicalChannels,
98       kTypicalRate, &new_payload_created));
99   ASSERT_FALSE(new_payload_created);
100
101   ASSERT_EQ(red_type_of_the_day, rtp_payload_registry_->red_payload_type());
102
103   RtpUtility::Payload* retrieved_payload = NULL;
104   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(red_type_of_the_day,
105                                                           retrieved_payload));
106   EXPECT_FALSE(retrieved_payload->audio);
107   EXPECT_STRCASEEQ("red", retrieved_payload->name);
108 }
109
110 TEST_F(RtpPayloadRegistryTest,
111        DoesNotAcceptSamePayloadTypeTwiceExceptIfPayloadIsCompatible) {
112   uint8_t payload_type = 97;
113
114   bool ignored = false;
115   RtpUtility::Payload* first_payload_on_heap =
116       ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
117   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
118       kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
119       kTypicalRate, &ignored));
120
121   EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
122       kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
123       kTypicalRate, &ignored)) << "Adding same codec twice = bad.";
124
125   RtpUtility::Payload* second_payload_on_heap =
126       ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
127   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
128       kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
129       kTypicalChannels, kTypicalRate, &ignored)) <<
130           "With a different payload type is fine though.";
131
132   // Ensure both payloads are preserved.
133   RtpUtility::Payload* retrieved_payload = NULL;
134   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type,
135                                                           retrieved_payload));
136   EXPECT_EQ(first_payload_on_heap, retrieved_payload);
137   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(payload_type - 1,
138                                                           retrieved_payload));
139   EXPECT_EQ(second_payload_on_heap, retrieved_payload);
140
141   // Ok, update the rate for one of the codecs. If either the incoming rate or
142   // the stored rate is zero it's not really an error to register the same
143   // codec twice, and in that case roughly the following happens.
144   ON_CALL(*mock_payload_strategy_, PayloadIsCompatible(_, _, _, _))
145       .WillByDefault(Return(true));
146   EXPECT_CALL(*mock_payload_strategy_,
147               UpdatePayloadRate(first_payload_on_heap, kTypicalRate));
148   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
149       kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
150       kTypicalRate, &ignored));
151 }
152
153 TEST_F(RtpPayloadRegistryTest,
154        RemovesCompatibleCodecsOnRegistryIfCodecsMustBeUnique) {
155   ON_CALL(*mock_payload_strategy_, PayloadIsCompatible(_, _, _, _))
156       .WillByDefault(Return(true));
157   ON_CALL(*mock_payload_strategy_, CodecsMustBeUnique())
158       .WillByDefault(Return(true));
159
160   uint8_t payload_type = 97;
161
162   bool ignored = false;
163   ExpectReturnOfTypicalAudioPayload(payload_type, kTypicalRate);
164   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
165       kTypicalPayloadName, payload_type, kTypicalFrequency, kTypicalChannels,
166       kTypicalRate, &ignored));
167   ExpectReturnOfTypicalAudioPayload(payload_type - 1, kTypicalRate);
168   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
169       kTypicalPayloadName, payload_type - 1, kTypicalFrequency,
170       kTypicalChannels, kTypicalRate, &ignored));
171
172   RtpUtility::Payload* retrieved_payload = NULL;
173   EXPECT_FALSE(rtp_payload_registry_->PayloadTypeToPayload(
174       payload_type, retrieved_payload)) << "The first payload should be "
175           "deregistered because the only thing that differs is payload type.";
176   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
177       payload_type - 1, retrieved_payload)) <<
178           "The second payload should still be registered though.";
179
180   // Now ensure non-compatible codecs aren't removed.
181   ON_CALL(*mock_payload_strategy_, PayloadIsCompatible(_, _, _, _))
182       .WillByDefault(Return(false));
183   ExpectReturnOfTypicalAudioPayload(payload_type + 1, kTypicalRate);
184   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
185       kTypicalPayloadName, payload_type + 1, kTypicalFrequency,
186       kTypicalChannels, kTypicalRate, &ignored));
187
188   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
189       payload_type - 1, retrieved_payload)) <<
190           "Not compatible; both payloads should be kept.";
191   EXPECT_TRUE(rtp_payload_registry_->PayloadTypeToPayload(
192       payload_type + 1, retrieved_payload)) <<
193           "Not compatible; both payloads should be kept.";
194 }
195
196 TEST_F(RtpPayloadRegistryTest,
197        LastReceivedCodecTypesAreResetWhenRegisteringNewPayloadTypes) {
198   rtp_payload_registry_->set_last_received_payload_type(17);
199   EXPECT_EQ(17, rtp_payload_registry_->last_received_payload_type());
200
201   bool media_type_unchanged = rtp_payload_registry_->ReportMediaPayloadType(18);
202   EXPECT_FALSE(media_type_unchanged);
203   media_type_unchanged = rtp_payload_registry_->ReportMediaPayloadType(18);
204   EXPECT_TRUE(media_type_unchanged);
205
206   bool ignored;
207   ExpectReturnOfTypicalAudioPayload(34, kTypicalRate);
208   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload(
209       kTypicalPayloadName, 34, kTypicalFrequency, kTypicalChannels,
210       kTypicalRate, &ignored));
211
212   EXPECT_EQ(-1, rtp_payload_registry_->last_received_payload_type());
213   media_type_unchanged = rtp_payload_registry_->ReportMediaPayloadType(18);
214   EXPECT_FALSE(media_type_unchanged);
215 }
216
217 class ParameterizedRtpPayloadRegistryTest :
218     public RtpPayloadRegistryTest,
219     public ::testing::WithParamInterface<int> {
220 };
221
222 TEST_P(ParameterizedRtpPayloadRegistryTest,
223        FailsToRegisterKnownPayloadsWeAreNotInterestedIn) {
224   int payload_type = GetParam();
225
226   bool ignored;
227   EXPECT_EQ(-1, rtp_payload_registry_->RegisterReceivePayload(
228       "whatever", static_cast<uint8_t>(payload_type), 19, 1, 17,
229       &ignored));
230 }
231
232 INSTANTIATE_TEST_CASE_P(TestKnownBadPayloadTypes,
233                         ParameterizedRtpPayloadRegistryTest,
234                         testing::Values(64, 72, 73, 74, 75, 76, 77, 78, 79));
235
236 class RtpPayloadRegistryGenericTest :
237     public RtpPayloadRegistryTest,
238     public ::testing::WithParamInterface<int> {
239 };
240
241 TEST_P(RtpPayloadRegistryGenericTest, RegisterGenericReceivePayloadType) {
242   int payload_type = GetParam();
243
244   bool ignored;
245
246   EXPECT_EQ(0, rtp_payload_registry_->RegisterReceivePayload("generic-codec",
247     static_cast<int8_t>(payload_type),
248     19, 1, 17, &ignored)); // dummy values, except for payload_type
249 }
250
251 INSTANTIATE_TEST_CASE_P(TestDynamicRange, RtpPayloadRegistryGenericTest,
252                         testing::Range(96, 127+1));
253
254 }  // namespace webrtc