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