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 }