1 /*
2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "audio_sink_unit_test.h"
17
18 using namespace testing;
19 using namespace testing::ext;
20
21 namespace OHOS {
22 namespace Media {
23 namespace Test {
24 constexpr const int32_t INVALID_NUM = -3;
25 constexpr const int32_t TEST_NUM = 12;
26 constexpr const int32_t LENGTH_NUM = 128;
27 constexpr const int32_t VALUE1_NUM = 9;
28 constexpr const int32_t VALUE2_NUM = -50;
29 constexpr const int32_t VALUE3_NUM = -30;
30 constexpr const int32_t TIME_NUM = 20;
31
AudioSinkUnitCreate()32 std::shared_ptr<AudioSink> AudioSinkUnitCreate()
33 {
34 auto audioSink = std::make_shared<AudioSink>();
35 std::shared_ptr<Pipeline::EventReceiver> testEventReceiver = std::make_shared<TestEventReceiver>();
36 auto meta = std::make_shared<Meta>();
37 auto initStatus = audioSink->Init(meta, testEventReceiver);
38 if (initStatus == Status::OK) {
39 return audioSink;
40 } else {
41 return nullptr;
42 }
43 }
44
45 /**
46 * @tc.name Test CopyDataToBufferDesc API
47 * @tc.number CopyDataToBufferDesc_001
48 * @tc.desc Test swapOutputBuffers_.empty()
49 */
50 HWTEST(TestAudioSink, CopyDataToBufferDesc_001, TestSize.Level1)
51 {
52 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
53 ASSERT_TRUE(audioSink != nullptr);
54
55 AudioStandard::BufferDesc bufferDesc;
56
57 AVBufferConfig config;
58 config.size = VALUE1_NUM;
59 config.capacity = VALUE1_NUM;
60 config.memoryType = MemoryType::VIRTUAL_MEMORY;
61 std::shared_ptr<AVBuffer> avBuffer = AVBuffer::CreateAVBuffer(config);
62 MessageParcel parcel;
63 avBuffer->memory_ = AVMemory::CreateAVMemory(parcel, true);
64 avBuffer->flag_ = BUFFER_FLAG_EOS;
65 audioSink->swapOutputBuffers_.push(avBuffer);
66 audioSink->availOutputBuffers_.push(avBuffer);
67 audioSink->plugin_ = nullptr;
68
69 size_t size = LENGTH_NUM;
70 bool isAudioVividsize = true;
71 bool result = audioSink->CopyDataToBufferDesc(size, isAudioVividsize, bufferDesc);
72 ASSERT_EQ(result, false);
73 }
74
75 /*
76 * @tc.name Test WriteDataToRender API
77 * @tc.number WriteDataToRender_001
78 * @tc.desc Test IsEosBuffer(filledOutputBuffer)
79 */
80 HWTEST(TestAudioSink, WriteDataToRender_001, TestSize.Level1)
81 {
82 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
83 ASSERT_TRUE(audioSink != nullptr);
84
85 AVBufferConfig config;
86 config.size = VALUE1_NUM;
87 config.capacity = VALUE1_NUM;
88 config.memoryType = MemoryType::VIRTUAL_MEMORY;
89 std::shared_ptr<AVBuffer> avBuffer = AVBuffer::CreateAVBuffer(config);
90 audioSink->isApe_ = false;
91 avBuffer->flag_ = BUFFER_FLAG_EOS;
92
93 audioSink->WriteDataToRender(avBuffer);
94 ASSERT_EQ(audioSink->isApe_, false);
95 }
96
97 /*
98 * @tc.name Test WriteDataToRender API
99 * @tc.number WriteDataToRender_002
100 * @tc.desc Test calMaxAmplitudeCbStatus_ == false
101 */
102 HWTEST(TestAudioSink, WriteDataToRender_002, TestSize.Level1)
103 {
104 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
105 ASSERT_TRUE(audioSink != nullptr);
106
107 AVBufferConfig config;
108 config.size = VALUE1_NUM;
109 config.capacity = VALUE1_NUM;
110 config.memoryType = MemoryType::VIRTUAL_MEMORY;
111 std::shared_ptr<AVBuffer> avBuffer = AVBuffer::CreateAVBuffer(config);
112 audioSink->isApe_ = false;
113 avBuffer->flag_ = 2;
114 audioSink->playRangeEndTime_ = INVALID_NUM;
115
116 std::shared_ptr<TestAudioSinkUnitMock> plugin = std::make_shared<TestAudioSinkUnitMock>("test");
117 audioSink->plugin_ = plugin;
118 audioSink->calMaxAmplitudeCbStatus_ = false;
119
120 audioSink->WriteDataToRender(avBuffer);
121 ASSERT_EQ(audioSink->calMaxAmplitudeCbStatus_, false);
122 }
123
124 /*
125 * @tc.name Test DetectAudioUnderrun API
126 * @tc.number DetectAudioUnderrun_001
127 * @tc.desc Test lastClkTime_ == HST_TIME_NONE
128 */
129 HWTEST(TestAudioSink, DetectAudioUnderrun_001, TestSize.Level1)
130 {
131 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
132 ASSERT_TRUE(audioSink != nullptr);
133
134 int64_t clkTime = 0;
135 int64_t latency = 0;
136 audioSink->underrunDetector_.lastClkTime_ = HST_TIME_NONE;
137
138 audioSink->underrunDetector_.DetectAudioUnderrun(clkTime, latency);
139 EXPECT_EQ(audioSink->underrunDetector_.lastClkTime_, 0);
140 }
141
142 /*
143 * @tc.name Test DetectAudioUnderrun API
144 * @tc.number DetectAudioUnderrun_002
145 * @tc.desc Test underrunTimeUs <= 0
146 */
147 HWTEST(TestAudioSink, DetectAudioUnderrun_002, TestSize.Level1)
148 {
149 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
150 ASSERT_TRUE(audioSink != nullptr);
151
152 int64_t clkTime = INVALID_NUM;
153 int64_t latency = 0;
154 int64_t durationUs = 1;
155 audioSink->underrunDetector_.Reset();
156 audioSink->underrunDetector_.UpdateBufferTimeNoLock(clkTime, latency);
157 audioSink->underrunDetector_.SetLastAudioBufferDuration(durationUs);
158
159 audioSink->underrunDetector_.DetectAudioUnderrun(clkTime, latency);
160 int64_t underrunTimeUs = clkTime - audioSink->underrunDetector_.lastClkTime_ -
161 (audioSink->underrunDetector_.lastLatency_ + audioSink->underrunDetector_.lastBufferDuration_);
162 ASSERT_TRUE(underrunTimeUs < 0);
163 }
164
165 /*
166 * @tc.name Test DetectAudioUnderrun API
167 * @tc.number DetectAudioUnderrun_003
168 * @tc.desc Test underrunTimeUs > 0 && eventReceiver == nullptr
169 */
170 HWTEST(TestAudioSink, DetectAudioUnderrun_003, TestSize.Level1)
171 {
172 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
173 ASSERT_TRUE(audioSink != nullptr);
174
175 int64_t clkTime = TEST_NUM;
176 int64_t latency = 0;
177 int64_t durationUs = 1;
178 audioSink->underrunDetector_.Reset();
179 audioSink->underrunDetector_.UpdateBufferTimeNoLock(clkTime, latency);
180 audioSink->underrunDetector_.SetLastAudioBufferDuration(durationUs);
181 int64_t clkTimeTemp = VALUE1_NUM;
182
183 std::shared_ptr<Pipeline::EventReceiver> testEventReceiver = nullptr;
184 audioSink->underrunDetector_.SetEventReceiver(testEventReceiver);
185
186 audioSink->underrunDetector_.DetectAudioUnderrun(clkTimeTemp, latency);
187 int64_t underrunTimeUs = clkTime - audioSink->underrunDetector_.lastClkTime_ -
188 (audioSink->underrunDetector_.lastLatency_ + audioSink->underrunDetector_.lastBufferDuration_);
189 EXPECT_GE(underrunTimeUs, 0);
190 EXPECT_EQ(testEventReceiver, nullptr);
191 }
192
193 /*
194 * @tc.name Test CalcLag API
195 * @tc.number CalcLag_001
196 * @tc.desc Test maxMediaTime < currentMediaTime
197 */
198 HWTEST(TestAudioSink, CalcLag_001, TestSize.Level1)
199 {
200 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
201 ASSERT_TRUE(audioSink != nullptr);
202
203 AudioSink::AudioLagDetector::AudioDrainTimeGroup group;
204 group.lastAnchorPts = 1;
205 group.anchorDuration = 1;
206 group.writeDuration = 1;
207 group.nowClockTime = VALUE1_NUM;
208
209 audioSink->lagDetector_.Reset();
210 audioSink->lagDetector_.UpdateDrainTimeGroup(group);
211
212 std::shared_ptr<AVBuffer> avBuffer = nullptr;
213
214 bool result = audioSink->lagDetector_.CalcLag(avBuffer);
215 ASSERT_EQ(result, true);
216 }
217
218 /*
219 * @tc.name Test CalcLag API
220 * @tc.number CalcLag_002
221 * @tc.desc Test maxMediaTime >= currentMediaTime
222 */
223 HWTEST(TestAudioSink, CalcLag_002, TestSize.Level1)
224 {
225 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
226 ASSERT_TRUE(audioSink != nullptr);
227
228 AudioSink::AudioLagDetector::AudioDrainTimeGroup group;
229 group.lastAnchorPts = 1;
230 group.anchorDuration = 1;
231 group.writeDuration = 1;
232 group.nowClockTime = 1;
233
234 audioSink->lagDetector_.Reset();
235 audioSink->lagDetector_.UpdateDrainTimeGroup(group);
236
237 std::shared_ptr<AVBuffer> avBuffer = nullptr;
238
239 bool result = audioSink->lagDetector_.CalcLag(avBuffer);
240 ASSERT_EQ(result, false);
241 }
242
243 /*
244 * @tc.name Test CalcLag API
245 * @tc.number CalcLag_003
246 * @tc.desc Test drainTimeDiff > DRAIN_TIME_DIFF_WARN_MS
247 */
248 HWTEST(TestAudioSink, CalcLag_003, TestSize.Level1)
249 {
250 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
251 ASSERT_TRUE(audioSink != nullptr);
252
253 AudioSink::AudioLagDetector::AudioDrainTimeGroup group;
254 group.lastAnchorPts = 1;
255 group.anchorDuration = 1;
256 group.writeDuration = VALUE2_NUM;
257 group.nowClockTime = TIME_NUM;
258
259 audioSink->lagDetector_.Reset();
260 audioSink->lagDetector_.UpdateDrainTimeGroup(group);
261
262 std::shared_ptr<AVBuffer> avBuffer = nullptr;
263
264 bool result = audioSink->lagDetector_.CalcLag(avBuffer);
265 ASSERT_EQ(result, true);
266 }
267
268 /*
269 * @tc.name Test CalcLag API
270 * @tc.number CalcLag_004
271 * @tc.desc Test drainTimeDiff > 20
272 */
273 HWTEST(TestAudioSink, CalcLag_004, TestSize.Level1)
274 {
275 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
276 ASSERT_TRUE(audioSink != nullptr);
277
278 AudioSink::AudioLagDetector::AudioDrainTimeGroup group;
279 group.lastAnchorPts = 1;
280 group.anchorDuration = 1;
281 group.writeDuration = VALUE3_NUM;
282 group.nowClockTime = TIME_NUM;
283
284 audioSink->lagDetector_.Reset();
285 audioSink->lagDetector_.UpdateDrainTimeGroup(group);
286
287 std::shared_ptr<AVBuffer> avBuffer = nullptr;
288
289 bool result = audioSink->lagDetector_.CalcLag(avBuffer);
290 ASSERT_EQ(result, true);
291 }
292
293 /*
294 * @tc.name Test CalcLag API
295 * @tc.number CalcLag_005
296 * @tc.desc Test drainTimeDiff < 20
297 */
298 HWTEST(TestAudioSink, CalcLag_005, TestSize.Level1)
299 {
300 std::shared_ptr<AudioSink> audioSink = AudioSinkUnitCreate();
301 ASSERT_TRUE(audioSink != nullptr);
302
303 AudioSink::AudioLagDetector::AudioDrainTimeGroup group;
304 group.lastAnchorPts = 1;
305 group.anchorDuration = 1;
306 group.writeDuration = 0;
307 group.nowClockTime = TIME_NUM;
308
309 audioSink->lagDetector_.Reset();
310 audioSink->lagDetector_.UpdateDrainTimeGroup(group);
311
312 std::shared_ptr<AVBuffer> avBuffer = nullptr;
313
314 bool result = audioSink->lagDetector_.CalcLag(avBuffer);
315 ASSERT_EQ(result, true);
316 }
317 } // namespace Test
318 } // namespace Media
319 } // namespace OHOS
320