1 /**
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18 #include <AudioConfig.h>
19 #include <VideoConfig.h>
20 #include <TextConfig.h>
21 #include <RtpEncoderNode.h>
22 #include <RtpDecoderNode.h>
23 #include <string.h>
24
25 using namespace android::telephony::imsmedia;
26 using namespace android;
27
28 // RtpConfig
29 const int32_t kMediaDirection = RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE;
30 const String8 kRemoteAddress("127.0.0.1");
31 const int32_t kRemotePort = 10000;
32 const int8_t kDscp = 0;
33 const int8_t kRxPayload = 96;
34 const int8_t kTxPayload = 96;
35 const int8_t kSamplingRate = 16;
36
37 // RtcpConfig
38 const String8 kCanonicalName("name");
39 const int32_t kTransmitPort = 10001;
40 const int32_t kIntervalSec = 5;
41 const int32_t kRtcpXrBlockTypes = 0;
42
43 // AudioConfig
44 const int8_t kPTimeMillis = 20;
45 const int32_t kMaxPtimeMillis = 100;
46 const int8_t kcodecModeRequest = 15;
47 const bool kDtxEnabled = true;
48 const int8_t kDtmfPayloadTypeNumber = 103;
49 const int8_t kDtmfsamplingRateKHz = 16;
50
51 // AmrParam
52 const int32_t kAmrMode = AmrParams::AMR_MODE_6;
53 const bool kOctetAligned = false;
54 const int32_t kMaxRedundancyMillis = 240;
55
56 // EvsParam
57 const int32_t kEvsBandwidth = EvsParams::EVS_BAND_NONE;
58 const int32_t kEvsMode = 8;
59 const int8_t kChannelAwareMode = 3;
60 const bool kUseHeaderFullOnly = false;
61
62 // VideoConfig
63 const int32_t kVideoMode = VideoConfig::VIDEO_MODE_PREVIEW;
64 const int32_t kMtu = 1500;
65 const int32_t kFramerate = DEFAULT_FRAMERATE;
66 const int32_t kBitrate = DEFAULT_BITRATE;
67 const int32_t kCodecProfile = VideoConfig::AVC_PROFILE_BASELINE;
68 const int32_t kCodecLevel = VideoConfig::AVC_LEVEL_12;
69 const int32_t kIntraFrameIntervalSec = 1;
70 const int32_t kPacketizationMode = VideoConfig::MODE_NON_INTERLEAVED;
71 const int32_t kCameraId = 0;
72 const int32_t kCameraZoom = 10;
73 const int32_t kResolutionWidth = DEFAULT_RESOLUTION_WIDTH;
74 const int32_t kResolutionHeight = DEFAULT_RESOLUTION_HEIGHT;
75 const android::String8 kPauseImagePath("data/user_de/0/com.android.telephony.imsmedia/test.jpg");
76 const int32_t kDeviceOrientationDegree = 0;
77 const int32_t kCvoValue = 1;
78 const int32_t kRtcpFbTypes = VideoConfig::RTP_FB_NONE;
79
80 // TextConfig
81 const int8_t kRedundantPayload = 102;
82 const int8_t kRedundantLevel = 2;
83 const bool kKeepRedundantLevel = true;
84
85 class FakeRtpDecoderCallback : public BaseSessionCallback
86 {
87 public:
FakeRtpDecoderCallback()88 FakeRtpDecoderCallback()
89 {
90 dtmfDigit = 0;
91 dtmfDuration = 0;
92 listExtensions = nullptr;
93 }
~FakeRtpDecoderCallback()94 virtual ~FakeRtpDecoderCallback()
95 {
96 if (listExtensions != nullptr)
97 {
98 delete listExtensions;
99 }
100 }
onEvent(int32_t type,uint64_t param1,uint64_t param2)101 virtual void onEvent(int32_t type, uint64_t param1, uint64_t param2)
102 {
103 if (type == kAudioDtmfReceivedInd)
104 {
105 dtmfDigit = static_cast<uint8_t>(param1);
106 dtmfDuration = static_cast<uint32_t>(param2);
107 }
108 else if (type == kImsMediaEventHeaderExtensionReceived)
109 {
110 if (listExtensions != nullptr)
111 {
112 delete listExtensions;
113 }
114
115 listExtensions = reinterpret_cast<std::list<RtpHeaderExtension>*>(param1);
116 }
117 }
GetDtmfDigit()118 uint8_t GetDtmfDigit() { return dtmfDigit; }
GetDtmfDuration()119 uint32_t GetDtmfDuration() { return dtmfDuration; }
GetListExtension()120 std::list<RtpHeaderExtension>* GetListExtension() { return listExtensions; }
121
122 private:
123 uint8_t dtmfDigit;
124 uint32_t dtmfDuration;
125 std::list<RtpHeaderExtension>* listExtensions;
126 };
127
128 class FakeRtpDecoderNode : public BaseNode
129 {
130 public:
FakeRtpDecoderNode(BaseSessionCallback * callback=nullptr)131 explicit FakeRtpDecoderNode(BaseSessionCallback* callback = nullptr) :
132 BaseNode(callback)
133 {
134 frameSize = 0;
135 memset(dataFrame, 0, sizeof(dataFrame));
136 subType = MEDIASUBTYPE_UNDEFINED;
137 }
~FakeRtpDecoderNode()138 virtual ~FakeRtpDecoderNode() {}
Start()139 virtual ImsMediaResult Start() { return RESULT_SUCCESS; }
Stop()140 virtual void Stop() {}
IsRunTime()141 virtual bool IsRunTime() { return true; }
IsSourceNode()142 virtual bool IsSourceNode() { return false; }
SetConfig(void * config)143 virtual void SetConfig(void* config) { (void)config; }
OnDataFromFrontNode(ImsMediaSubType type,uint8_t * data,uint32_t size,uint32_t,bool,uint32_t,ImsMediaSubType,uint32_t)144 virtual void OnDataFromFrontNode(ImsMediaSubType type, uint8_t* data, uint32_t size,
145 uint32_t /*timestamp*/, bool /*mark*/, uint32_t /*seq*/, ImsMediaSubType /*dataType*/,
146 uint32_t /*arrivalTime*/)
147 {
148 if (subType == MEDIASUBTYPE_REFRESHED)
149 {
150 return;
151 }
152
153 if (data != nullptr && size > 0)
154 {
155 memset(dataFrame, 0, sizeof(dataFrame));
156 memcpy(dataFrame, data, size);
157 frameSize = size;
158 subType = type;
159 }
160 }
161
GetState()162 virtual kBaseNodeState GetState() { return kNodeStateRunning; }
163
GetFrameSize()164 uint32_t GetFrameSize() { return frameSize; }
GetDataFrame()165 uint8_t* GetDataFrame() { return dataFrame; }
GetSubType()166 ImsMediaSubType GetSubType() { return subType; }
167
168 private:
169 uint32_t frameSize;
170 uint8_t dataFrame[DEFAULT_MTU];
171 ImsMediaSubType subType;
172 };
173
174 class RtpDecoderNodeTest : public ::testing::Test
175 {
176 public:
RtpDecoderNodeTest()177 RtpDecoderNodeTest()
178 {
179 encoder = nullptr;
180 decoder = nullptr;
181 fakeNode = nullptr;
182 }
~RtpDecoderNodeTest()183 virtual ~RtpDecoderNodeTest() {}
184
185 protected:
186 AmrParams amr;
187 EvsParams evs;
188 AudioConfig audioConfig;
189 VideoConfig videoConfig;
190 TextConfig textConfig;
191 RtcpConfig rtcp;
192 RtpEncoderNode* encoder;
193 RtpDecoderNode* decoder;
194 FakeRtpDecoderNode* fakeNode;
195 FakeRtpDecoderCallback callback;
196 std::list<BaseNode*> nodes;
197
SetUp()198 virtual void SetUp() override
199 {
200 rtcp.setCanonicalName(kCanonicalName);
201 rtcp.setTransmitPort(kTransmitPort);
202 rtcp.setIntervalSec(kIntervalSec);
203 rtcp.setRtcpXrBlockTypes(kRtcpXrBlockTypes);
204 }
205
TearDown()206 virtual void TearDown() override
207 {
208 while (nodes.size() > 0)
209 {
210 BaseNode* node = nodes.front();
211 node->Stop();
212 delete node;
213 nodes.pop_front();
214 }
215 }
216
217 public:
setupNodes(ImsMediaType type,RtpConfig * config)218 void setupNodes(ImsMediaType type, RtpConfig* config)
219 {
220 encoder = new RtpEncoderNode(&callback);
221 encoder->SetMediaType(type);
222 encoder->SetConfig(config);
223 encoder->SetLocalAddress(RtpAddress(kRemoteAddress, kRemotePort));
224 nodes.push_back(encoder);
225
226 decoder = new RtpDecoderNode(&callback);
227 decoder->SetMediaType(type);
228 decoder->SetConfig(config);
229 encoder->SetLocalAddress(RtpAddress(kRemoteAddress, kRemotePort));
230 nodes.push_back(decoder);
231 encoder->ConnectRearNode(decoder);
232
233 fakeNode = new FakeRtpDecoderNode(&callback);
234 fakeNode->SetMediaType(type);
235 fakeNode->SetConfig(config);
236 nodes.push_back(fakeNode);
237 decoder->ConnectRearNode(fakeNode);
238 }
239
setupAudioConfig()240 void setupAudioConfig()
241 {
242 amr.setAmrMode(kAmrMode);
243 amr.setOctetAligned(kOctetAligned);
244 amr.setMaxRedundancyMillis(kMaxRedundancyMillis);
245
246 evs.setEvsBandwidth(kEvsBandwidth);
247 evs.setEvsMode(kEvsMode);
248 evs.setChannelAwareMode(kChannelAwareMode);
249 evs.setUseHeaderFullOnly(kUseHeaderFullOnly);
250 evs.setCodecModeRequest(kcodecModeRequest);
251
252 audioConfig.setMediaDirection(kMediaDirection);
253 audioConfig.setRemoteAddress(kRemoteAddress);
254 audioConfig.setRemotePort(kRemotePort);
255 audioConfig.setRtcpConfig(rtcp);
256 audioConfig.setDscp(kDscp);
257 audioConfig.setRxPayloadTypeNumber(kRxPayload);
258 audioConfig.setTxPayloadTypeNumber(kTxPayload);
259 audioConfig.setSamplingRateKHz(kSamplingRate);
260 audioConfig.setPtimeMillis(kPTimeMillis);
261 audioConfig.setMaxPtimeMillis(kMaxPtimeMillis);
262 audioConfig.setDtxEnabled(kDtxEnabled);
263 audioConfig.setCodecType(AudioConfig::CODEC_AMR);
264 audioConfig.setTxDtmfPayloadTypeNumber(kDtmfPayloadTypeNumber);
265 audioConfig.setRxDtmfPayloadTypeNumber(kDtmfPayloadTypeNumber);
266 audioConfig.setDtmfsamplingRateKHz(kDtmfsamplingRateKHz);
267 audioConfig.setAmrParams(amr);
268 audioConfig.setEvsParams(evs);
269
270 setupNodes(IMS_MEDIA_AUDIO, &audioConfig);
271 }
272
setupVideoConfig()273 void setupVideoConfig()
274 {
275 videoConfig.setMediaDirection(kMediaDirection);
276 videoConfig.setRemoteAddress(kRemoteAddress);
277 videoConfig.setRemotePort(kRemotePort);
278 videoConfig.setRtcpConfig(rtcp);
279 videoConfig.setMaxMtuBytes(kMtu);
280 videoConfig.setDscp(kDscp);
281 videoConfig.setRxPayloadTypeNumber(kRxPayload);
282 videoConfig.setTxPayloadTypeNumber(kTxPayload);
283 videoConfig.setSamplingRateKHz(kSamplingRate);
284 videoConfig.setVideoMode(kVideoMode);
285 videoConfig.setCodecType(VideoConfig::CODEC_AVC);
286 videoConfig.setFramerate(kFramerate);
287 videoConfig.setBitrate(kBitrate);
288 videoConfig.setCodecProfile(kCodecProfile);
289 videoConfig.setCodecLevel(kCodecLevel);
290 videoConfig.setIntraFrameInterval(kIntraFrameIntervalSec);
291 videoConfig.setPacketizationMode(kPacketizationMode);
292 videoConfig.setCameraId(kCameraId);
293 videoConfig.setCameraZoom(kCameraZoom);
294 videoConfig.setResolutionWidth(kResolutionWidth);
295 videoConfig.setResolutionHeight(kResolutionHeight);
296 videoConfig.setPauseImagePath(kPauseImagePath);
297 videoConfig.setDeviceOrientationDegree(kDeviceOrientationDegree);
298 videoConfig.setCvoValue(kCvoValue);
299 videoConfig.setRtcpFbType(kRtcpFbTypes);
300
301 setupNodes(IMS_MEDIA_VIDEO, &videoConfig);
302 }
303
setupTextConfig()304 void setupTextConfig()
305 {
306 textConfig.setMediaDirection(kMediaDirection);
307 textConfig.setRemoteAddress(kRemoteAddress);
308 textConfig.setRemotePort(kRemotePort);
309 textConfig.setRtcpConfig(rtcp);
310 textConfig.setDscp(kDscp);
311 textConfig.setRxPayloadTypeNumber(kRxPayload);
312 textConfig.setTxPayloadTypeNumber(kTxPayload);
313 textConfig.setSamplingRateKHz(kSamplingRate);
314 textConfig.setCodecType(TextConfig::TEXT_T140_RED);
315 textConfig.setBitrate(kBitrate);
316 textConfig.setRedundantPayload(kRedundantPayload);
317 textConfig.setRedundantLevel(kRedundantLevel);
318 textConfig.setKeepRedundantLevel(kKeepRedundantLevel);
319
320 setupNodes(IMS_MEDIA_TEXT, &textConfig);
321 }
322 };
323
TEST_F(RtpDecoderNodeTest,startFail)324 TEST_F(RtpDecoderNodeTest, startFail)
325 {
326 setupAudioConfig();
327 audioConfig.setRxPayloadTypeNumber(0);
328 decoder->SetConfig(&audioConfig);
329 EXPECT_EQ(decoder->Start(), RESULT_INVALID_PARAM);
330
331 audioConfig.setTxPayloadTypeNumber(0);
332 decoder->SetConfig(&audioConfig);
333 EXPECT_EQ(decoder->Start(), RESULT_INVALID_PARAM);
334 }
335
TEST_F(RtpDecoderNodeTest,startAudioAndUpdate)336 TEST_F(RtpDecoderNodeTest, startAudioAndUpdate)
337 {
338 setupAudioConfig();
339 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
340
341 // no update
342 EXPECT_EQ(decoder->UpdateConfig(&audioConfig), RESULT_SUCCESS);
343
344 // update
345 audioConfig.setTxDtmfPayloadTypeNumber(102);
346 EXPECT_EQ(decoder->UpdateConfig(&audioConfig), RESULT_SUCCESS);
347 }
348
TEST_F(RtpDecoderNodeTest,testAudioDataProcess)349 TEST_F(RtpDecoderNodeTest, testAudioDataProcess)
350 {
351 setupAudioConfig();
352 EXPECT_EQ(encoder->Start(), RESULT_SUCCESS);
353 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
354
355 // AMR mode 6 payload frame
356 uint8_t testFrame[] = {0x1c, 0x51, 0x06, 0x40, 0x32, 0xba, 0x8e, 0xc1, 0x25, 0x42, 0x2f, 0xc7,
357 0xaf, 0x6e, 0xe0, 0xbb, 0xb2, 0x91, 0x09, 0xa5, 0xa6, 0x08, 0x18, 0x6f, 0x08, 0x1c,
358 0x1c, 0x44, 0xd8, 0xe0, 0x48, 0x8c, 0x7c, 0xf8, 0x4c, 0x22, 0xd0};
359
360 encoder->OnDataFromFrontNode(MEDIASUBTYPE_UNDEFINED, testFrame, sizeof(testFrame), 0, false, 0);
361 encoder->ProcessData();
362 EXPECT_EQ(fakeNode->GetFrameSize(), sizeof(testFrame));
363 EXPECT_EQ(strncmp(reinterpret_cast<const char*>(fakeNode->GetDataFrame()),
364 reinterpret_cast<const char*>(testFrame), fakeNode->GetFrameSize()),
365 0);
366 }
367
TEST_F(RtpDecoderNodeTest,testAudioDtmfDataProcess)368 TEST_F(RtpDecoderNodeTest, testAudioDtmfDataProcess)
369 {
370 setupAudioConfig();
371 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
372
373 // dtmf rtp
374 uint8_t dtmfFrame[] = {0x80, 0xe7, 0x7b, 0xaa, 0x00, 0x00, 0xc2, 0x5a, 0x6f, 0x88, 0xd8, 0x02,
375 0x01, 0x0a, 0x00, 0xa0};
376
377 decoder->OnDataFromFrontNode(MEDIASUBTYPE_UNDEFINED, dtmfFrame, sizeof(dtmfFrame), 0, true, 0,
378 MEDIASUBTYPE_UNDEFINED, 0);
379 EXPECT_EQ(callback.GetDtmfDigit(), 0);
380 EXPECT_EQ(callback.GetDtmfDuration(), 0);
381
382 uint8_t dtmfFrame2[] = {0x80, 0x67, 0x7b, 0xb3, 0x00, 0x00, 0xc2, 0x5a, 0x6f, 0x88, 0xd8, 0x02,
383 0x01, 0x8a, 0x06, 0x40};
384
385 decoder->OnDataFromFrontNode(MEDIASUBTYPE_UNDEFINED, dtmfFrame2, sizeof(dtmfFrame2), 0, false,
386 0, MEDIASUBTYPE_UNDEFINED, 0);
387 EXPECT_EQ(callback.GetDtmfDigit(), 0x01);
388 EXPECT_EQ(callback.GetDtmfDuration(), 100);
389 }
390
TEST_F(RtpDecoderNodeTest,testAudioRtpExtension)391 TEST_F(RtpDecoderNodeTest, testAudioRtpExtension)
392 {
393 setupAudioConfig();
394 EXPECT_EQ(encoder->Start(), RESULT_SUCCESS);
395 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
396
397 // AMR mode 6 payload frame
398 uint8_t testFrame[] = {0x1c, 0x51, 0x06, 0x40, 0x32, 0xba, 0x8e, 0xc1, 0x25, 0x42, 0x2f, 0xc7,
399 0xaf, 0x6e, 0xe0, 0xbb, 0xb2, 0x91, 0x09, 0xa5, 0xa6, 0x08, 0x18, 0x6f, 0x08, 0x1c,
400 0x1c, 0x44, 0xd8, 0xe0, 0x48, 0x8c, 0x7c, 0xf8, 0x4c, 0x22, 0xd0};
401
402 const uint8_t testExtension1[] = {0xFF, 0xF2};
403 const uint8_t testExtension2[] = {0xFF, 0xF2};
404
405 std::list<RtpHeaderExtension> listExtension;
406
407 RtpHeaderExtension extension1;
408 extension1.setLocalIdentifier(1);
409 extension1.setExtensionData(testExtension1, 2);
410 listExtension.push_back(extension1);
411
412 RtpHeaderExtension extension2;
413 extension2.setLocalIdentifier(2);
414 extension2.setExtensionData(testExtension2, 2);
415 listExtension.push_back(extension2);
416
417 encoder->SetRtpHeaderExtension(&listExtension);
418 encoder->OnDataFromFrontNode(MEDIASUBTYPE_UNDEFINED, testFrame, sizeof(testFrame), 0, false, 0);
419 encoder->ProcessData();
420
421 std::list<RtpHeaderExtension>* receivedExtension = callback.GetListExtension();
422 ASSERT_TRUE(receivedExtension != nullptr);
423
424 for (auto& extension : *receivedExtension)
425 {
426 EXPECT_EQ(extension, listExtension.front());
427 listExtension.pop_front();
428 }
429 }
430
TEST_F(RtpDecoderNodeTest,startVideoAndUpdate)431 TEST_F(RtpDecoderNodeTest, startVideoAndUpdate)
432 {
433 setupVideoConfig();
434 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
435
436 // no update
437 EXPECT_EQ(decoder->UpdateConfig(&videoConfig), RESULT_SUCCESS);
438
439 // update
440 videoConfig.setTxPayloadTypeNumber(99);
441 EXPECT_EQ(decoder->UpdateConfig(&videoConfig), RESULT_SUCCESS);
442 }
443
TEST_F(RtpDecoderNodeTest,testVideoDataProcess)444 TEST_F(RtpDecoderNodeTest, testVideoDataProcess)
445 {
446 setupVideoConfig();
447 EXPECT_EQ(encoder->Start(), RESULT_SUCCESS);
448 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
449
450 // H.264 payload of sps frame
451 uint8_t testFrame[] = {0x67, 0x42, 0xc0, 0x0c, 0xda, 0x0f, 0x0a, 0x69, 0xa8, 0x10, 0x10, 0x10,
452 0x3c, 0x58, 0xba, 0x80};
453
454 EXPECT_TRUE(encoder->SetCvoExtension(0, 90)); // rear camera and 90 degree
455
456 encoder->OnDataFromFrontNode(
457 MEDIASUBTYPE_VIDEO_IDR_FRAME, testFrame, sizeof(testFrame), 0, true, 0);
458 encoder->ProcessData();
459 EXPECT_EQ(fakeNode->GetFrameSize(), sizeof(testFrame));
460 EXPECT_EQ(strncmp(reinterpret_cast<const char*>(fakeNode->GetDataFrame()),
461 reinterpret_cast<const char*>(testFrame), fakeNode->GetFrameSize()),
462 0);
463 EXPECT_EQ(fakeNode->GetSubType(), MEDIASUBTYPE_ROT270);
464 }
465
TEST_F(RtpDecoderNodeTest,startTextAndUpdate)466 TEST_F(RtpDecoderNodeTest, startTextAndUpdate)
467 {
468 setupTextConfig();
469 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
470
471 // no update
472 EXPECT_EQ(decoder->UpdateConfig(&textConfig), RESULT_SUCCESS);
473
474 // update
475 textConfig.setTxPayloadTypeNumber(99);
476 EXPECT_EQ(decoder->UpdateConfig(&textConfig), RESULT_SUCCESS);
477 }
478
TEST_F(RtpDecoderNodeTest,testTextDataProcess)479 TEST_F(RtpDecoderNodeTest, testTextDataProcess)
480 {
481 setupTextConfig();
482 EXPECT_EQ(encoder->Start(), RESULT_SUCCESS);
483 EXPECT_EQ(decoder->Start(), RESULT_SUCCESS);
484
485 // RED payload
486 uint8_t testFrame[] = {0xef, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, 0x6f, 0x74};
487
488 encoder->OnDataFromFrontNode(
489 MEDIASUBTYPE_BITSTREAM_T140_RED, testFrame, sizeof(testFrame), 0, true, 0);
490 encoder->ProcessData();
491 EXPECT_EQ(fakeNode->GetFrameSize(), sizeof(testFrame));
492 EXPECT_EQ(strncmp(reinterpret_cast<const char*>(fakeNode->GetDataFrame()),
493 reinterpret_cast<const char*>(testFrame), fakeNode->GetFrameSize()),
494 0);
495 }