1 /*
2 * Copyright (c) 2024 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 "dash_media_downloader_unit_test.h"
17 #include <iostream>
18 #include "dash_media_downloader.h"
19 #include "http_server_demo.h"
20
21 namespace OHOS {
22 namespace Media {
23 namespace Plugins {
24 namespace HttpPlugin {
25 using namespace testing::ext;
26 namespace {
27 constexpr int32_t SERVERPORT = 47777;
28 static const std::string MPD_SEGMENT_BASE = "http://127.0.0.1:47777/test_dash/segment_base/index.mpd";
29 static const std::string MPD_SEGMENT_LIST = "http://127.0.0.1:47777/test_dash/segment_list/index.mpd";
30 static const std::string MPD_SEGMENT_TEMPLATE = "http://127.0.0.1:47777/test_dash/segment_template/index.mpd";
31 static const std::string MPD_MULTI_AUDIO_SUB = "http://127.0.0.1:47777/test_dash/segment_base/index_audio_subtitle.mpd";
32 constexpr int32_t WAIT_FOR_SIDX_TIME = 100 * 1000; // wait sidx download and parse for 100ms
33 constexpr uint32_t DEFAULT_WIDTH = 1280;
34 constexpr uint32_t DEFAULT_HEIGHT = 720;
35 constexpr uint32_t DEFAULT_DURATION = 20;
36 }
37
38 std::unique_ptr<MediaAVCodec::HttpServerDemo> g_server = nullptr;
39 std::shared_ptr<DashMediaDownloader> g_mediaDownloader = nullptr;
40 bool g_result = false;
SetUpTestCase(void)41 void DashMediaDownloaderUnitTest::SetUpTestCase(void)
42 {
43 g_server = std::make_unique<MediaAVCodec::HttpServerDemo>();
44 g_server->StartServer(SERVERPORT);
45 std::cout << "start" << std::endl;
46
47 g_mediaDownloader = std::make_shared<DashMediaDownloader>();
48 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
49 std::shared_ptr<DownloadRequest>& request) {};
50 g_mediaDownloader->SetStatusCallback(statusCallback);
51 g_mediaDownloader->SetIsTriggerAutoMode(true);
52 std::string testUrl = MPD_SEGMENT_BASE;
53 std::map<std::string, std::string> httpHeader;
54 g_result = g_mediaDownloader->Open(testUrl, httpHeader);
55 }
56
TearDownTestCase(void)57 void DashMediaDownloaderUnitTest::TearDownTestCase(void)
58 {
59 g_mediaDownloader->Pause();
60 g_mediaDownloader->Resume();
61 g_mediaDownloader->SetInterruptState(true);
62 g_mediaDownloader->SetDemuxerState(0);
63 g_mediaDownloader->Close(false);
64 g_mediaDownloader = nullptr;
65
66 g_server->StopServer();
67 g_server = nullptr;
68 }
69
SetUp(void)70 void DashMediaDownloaderUnitTest::SetUp(void)
71 {
72 if (g_server == nullptr) {
73 g_server = std::make_unique<MediaAVCodec::HttpServerDemo>();
74 g_server->StartServer(SERVERPORT);
75 std::cout << "start server" << std::endl;
76 }
77 }
78
TearDown(void)79 void DashMediaDownloaderUnitTest::TearDown(void) {}
80
81 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_CONTENT_LENGTH, TestSize.Level1)
82 {
83 EXPECT_EQ(g_mediaDownloader->GetContentLength(), 0);
84 }
85
86 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_STARTED_STATUS, TestSize.Level1)
87 {
88 EXPECT_TRUE(g_mediaDownloader->GetStartedStatus());
89 }
90
91 HWTEST_F(DashMediaDownloaderUnitTest, TEST_OPEN, TestSize.Level1)
92 {
93 EXPECT_TRUE(g_result);
94 }
95
96 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_SEEKABLE, TestSize.Level1)
97 {
98 Seekable seekable = g_mediaDownloader->GetSeekable();
99 EXPECT_EQ(seekable, Seekable::SEEKABLE);
100 }
101
102 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_DURATION, TestSize.Level1)
103 {
104 EXPECT_GE(g_mediaDownloader->GetDuration(), 0);
105 }
106
107 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_BITRATES, TestSize.Level1)
108 {
109 std::vector<uint32_t> bitrates = g_mediaDownloader->GetBitRates();
110 EXPECT_GE(bitrates.size(), 0);
111 }
112
113 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_STREAM_INFO, TestSize.Level1)
114 {
115 std::vector<StreamInfo> streams;
116 Status status = g_mediaDownloader->GetStreamInfo(streams);
117 EXPECT_EQ(status, Status::OK);
118 EXPECT_GE(streams.size(), 0);
119 }
120
121 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SET_BITRATE, TestSize.Level1)
122 {
123 Status status = g_mediaDownloader->SetCurrentBitRate(1, 0);
124 EXPECT_EQ(status, Status::OK);
125 }
126
127 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_BITRATE, TestSize.Level1)
128 {
129 std::vector<StreamInfo> streams;
130 g_mediaDownloader->GetStreamInfo(streams);
131 EXPECT_GE(streams.size(), 0);
132
133 unsigned int switchingBitrate = 0;
134 int32_t usingStreamId = -1;
135 for (auto stream : streams) {
136 if (stream.type != VIDEO) {
137 continue;
138 }
139
140 if (usingStreamId == -1) {
141 usingStreamId = stream.streamId;
142 continue;
143 }
144
145 if (stream.streamId != usingStreamId) {
146 switchingBitrate = stream.bitRate;
147 break;
148 }
149 }
150
151 bool result = false;
152 if (switchingBitrate > 0) {
153 result = g_mediaDownloader->SelectBitRate(switchingBitrate);
154 }
155
156 EXPECT_TRUE(result);
157 }
158
159 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_AUDIO, TestSize.Level1)
160 {
161 std::vector<StreamInfo> streams;
162 g_mediaDownloader->GetStreamInfo(streams);
163 EXPECT_GE(streams.size(), 0);
164
165 int32_t switchingStreamId = -1;
166 for (auto stream : streams) {
167 if (stream.type != AUDIO) {
168 continue;
169 }
170
171 switchingStreamId = stream.streamId;
172 break;
173 }
174
175 Status status = Status::OK;
176 if (switchingStreamId != -1) {
177 status = g_mediaDownloader->SelectStream(switchingStreamId);
178 g_mediaDownloader->SeekToTime(1, SeekMode::SEEK_NEXT_SYNC);
179 }
180
181 EXPECT_EQ(status, Status::OK);
182 }
183
184 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_VIDEO, TestSize.Level1)
185 {
186 std::vector<StreamInfo> streams;
187 g_mediaDownloader->GetStreamInfo(streams);
188 EXPECT_GE(streams.size(), 0);
189
190 int32_t switchingStreamId = -1;
191 for (auto stream : streams) {
192 if (stream.type != VIDEO) {
193 continue;
194 }
195
196 switchingStreamId = stream.streamId;
197 break;
198 }
199
200 Status status = Status::OK;
201 if (switchingStreamId != -1) {
202 status = g_mediaDownloader->SelectStream(switchingStreamId);
203 }
204
205 EXPECT_EQ(status, Status::OK);
206 }
207
208 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_SUBTITLE, TestSize.Level1)
209 {
210 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
211 std::string testUrl = MPD_MULTI_AUDIO_SUB;
212 std::map<std::string, std::string> httpHeader;
213 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0302(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 214 std::shared_ptr<DownloadRequest>& request) {
215 };
216 mediaDownloader->SetStatusCallback(statusCallback);
217 std::shared_ptr<PlayStrategy> playStrategy = std::make_shared<PlayStrategy>();
218 playStrategy->width = DEFAULT_WIDTH;
219 playStrategy->height = DEFAULT_HEIGHT;
220 playStrategy->duration = DEFAULT_DURATION;
221 playStrategy->audioLanguage = "eng";
222 playStrategy->subtitleLanguage = "en_GB";
223 mediaDownloader->SetPlayStrategy(playStrategy);
224
225 mediaDownloader->Open(testUrl, httpHeader);
226 mediaDownloader->GetSeekable();
227
228 std::vector<StreamInfo> streams;
229 mediaDownloader->GetStreamInfo(streams);
230 EXPECT_GE(streams.size(), 0);
231
232 int32_t usingStreamId = -1;
233 int32_t switchingStreamId = -1;
234 for (auto stream : streams) {
235 if (stream.type != SUBTITLE) {
236 continue;
237 }
238
239 if (usingStreamId == -1) {
240 usingStreamId = stream.streamId;
241 continue;
242 }
243
244 if (stream.streamId != usingStreamId) {
245 switchingStreamId = stream.streamId;
246 break;
247 }
248 }
249
250 Status status = Status::OK;
251
252 if (switchingStreamId != -1) {
253 status = mediaDownloader->SelectStream(switchingStreamId);
254 mediaDownloader->SeekToTime(1, SeekMode::SEEK_NEXT_SYNC);
255 }
256
257 usleep(WAIT_FOR_SIDX_TIME);
258 mediaDownloader->Close(false);
259 mediaDownloader = nullptr;
260 EXPECT_EQ(status, Status::OK);
261 }
262
263 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_BITRATE_AFTER_SWITCH, TestSize.Level1)
264 {
265 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
266 std::string testUrl = MPD_MULTI_AUDIO_SUB;
267 std::map<std::string, std::string> httpHeader;
268 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0402(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 269 std::shared_ptr<DownloadRequest>& request) {
270 };
271 mediaDownloader->SetStatusCallback(statusCallback);
272
273 mediaDownloader->Open(testUrl, httpHeader);
274 mediaDownloader->GetSeekable();
275
276 std::vector<StreamInfo> streams;
277 mediaDownloader->GetStreamInfo(streams);
278 EXPECT_GE(streams.size(), 0);
279
280 int32_t usingAudioStreamId = -1;
281 int32_t switchingAudioStreamId = -1;
282 int32_t usingVideoStreamId = -1;
283 unsigned int switchingBitrate = 0;
284 for (auto stream : streams) {
285 if (stream.type == AUDIO) {
286 if (usingAudioStreamId == -1) {
287 usingAudioStreamId = stream.streamId;
288 continue;
289 }
290
291 if (stream.streamId != usingAudioStreamId) {
292 switchingAudioStreamId = stream.streamId;
293 continue;
294 }
295 } else if (stream.type == VIDEO) {
296 if (usingVideoStreamId == -1) {
297 usingVideoStreamId = stream.streamId;
298 continue;
299 }
300
301 if (stream.streamId != usingVideoStreamId) {
302 switchingBitrate = stream.bitRate;
303 continue;
304 }
305 } else {
306 continue;
307 }
308 }
309
310 Status status = mediaDownloader->SelectStream(switchingAudioStreamId);
311 bool result = mediaDownloader->SelectBitRate(switchingBitrate);
312
313 usleep(WAIT_FOR_SIDX_TIME);
314 mediaDownloader->Close(false);
315 mediaDownloader = nullptr;
316 EXPECT_EQ(status, Status::OK);
317 EXPECT_TRUE(result);
318 }
319
320 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SELECT_SUBTITLE_AFTER_SWITCH, TestSize.Level1)
321 {
322 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
323 std::string testUrl = MPD_MULTI_AUDIO_SUB;
324 std::map<std::string, std::string> httpHeader;
325 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0502(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 326 std::shared_ptr<DownloadRequest>& request) {
327 };
328 mediaDownloader->SetStatusCallback(statusCallback);
329
330 mediaDownloader->Open(testUrl, httpHeader);
331 mediaDownloader->GetSeekable();
332
333 std::vector<StreamInfo> streams;
334 mediaDownloader->GetStreamInfo(streams);
335 EXPECT_GE(streams.size(), 0);
336
337 int32_t usingSubtitleStreamId = -1;
338 int32_t switchingSubtitleStreamId = -1;
339 int32_t usingVideoStreamId = -1;
340 unsigned int switchingBitrate = 0;
341 for (auto stream : streams) {
342 if (stream.type == SUBTITLE) {
343 if (usingSubtitleStreamId == -1) {
344 usingSubtitleStreamId = stream.streamId;
345 continue;
346 }
347
348 if (stream.streamId != usingSubtitleStreamId) {
349 switchingSubtitleStreamId = stream.streamId;
350 continue;
351 }
352 } else if (stream.type == VIDEO) {
353 if (usingVideoStreamId == -1) {
354 usingVideoStreamId = stream.streamId;
355 continue;
356 }
357
358 if (stream.streamId != usingVideoStreamId) {
359 switchingBitrate = stream.bitRate;
360 continue;
361 }
362 } else {
363 continue;
364 }
365 }
366
367 bool result = mediaDownloader->SelectBitRate(switchingBitrate);
368 Status status = mediaDownloader->SelectStream(switchingSubtitleStreamId);
369
370 usleep(WAIT_FOR_SIDX_TIME);
371 mediaDownloader->Close(false);
372 mediaDownloader = nullptr;
373 EXPECT_EQ(status, Status::OK);
374 EXPECT_TRUE(result);
375 }
376
377 HWTEST_F(DashMediaDownloaderUnitTest, TEST_SEEK_TO_TIME, TestSize.Level1)
378 {
379 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
380 std::string testUrl = MPD_SEGMENT_TEMPLATE;
381 std::map<std::string, std::string> httpHeader;
382 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0602(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 383 std::shared_ptr<DownloadRequest>& request) {
384 };
385 mediaDownloader->SetStatusCallback(statusCallback);
386
387 mediaDownloader->Open(testUrl, httpHeader);
388 mediaDownloader->GetSeekable();
389
390 bool result = mediaDownloader->SeekToTime(1, SeekMode::SEEK_NEXT_SYNC);
391 mediaDownloader->Close(false);
392 mediaDownloader = nullptr;
393 EXPECT_TRUE(result);
394 }
395
396 HWTEST_F(DashMediaDownloaderUnitTest, TEST_GET_READ, TestSize.Level1)
397 {
398 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
399 std::string testUrl = MPD_SEGMENT_LIST;
400 std::map<std::string, std::string> httpHeader;
401 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0702(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 402 std::shared_ptr<DownloadRequest>& request) {
403 };
404 mediaDownloader->SetStatusCallback(statusCallback);
405
406 mediaDownloader->Open(testUrl, httpHeader);
407 mediaDownloader->GetSeekable();
408
409 std::vector<StreamInfo> streams;
410 mediaDownloader->GetStreamInfo(streams);
411 EXPECT_GT(streams.size(), 0);
412
413 unsigned char buff[1024];;
414 ReadDataInfo readDataInfo;
415 readDataInfo.streamId_ = streams[0].streamId;
416 readDataInfo.nextStreamId_ = streams[0].streamId;
417 readDataInfo.wantReadLength_ = 1024;
418 mediaDownloader->Read(buff, readDataInfo);
419 mediaDownloader->SetDownloadErrorState();
420 mediaDownloader->Read(buff, readDataInfo);
421 mediaDownloader->Close(false);
422 mediaDownloader = nullptr;
423 EXPECT_GE(readDataInfo.realReadLength_, 0);
424 }
425
426 HWTEST_F(DashMediaDownloaderUnitTest, GET_PLAYBACK_INFO_001, TestSize.Level1)
427 {
428 std::shared_ptr<DashMediaDownloader> mediaDownloader = std::make_shared<DashMediaDownloader>();
429 std::string testUrl = MPD_SEGMENT_LIST;
430 std::map<std::string, std::string> httpHeader;
431 auto statusCallback = [] (DownloadStatus&& status, std::shared_ptr<Downloader>& downloader,
__anon6d43d72c0802(DownloadStatus&& status, std::shared_ptr<Downloader>& downloader, std::shared_ptr<DownloadRequest>& request) 432 std::shared_ptr<DownloadRequest>& request) {
433 };
434 mediaDownloader->SetStatusCallback(statusCallback);
435 mediaDownloader->Open(testUrl, httpHeader);
436 mediaDownloader->GetSeekable();
437 std::vector<StreamInfo> streams;
438 mediaDownloader->GetStreamInfo(streams);
439 EXPECT_GT(streams.size(), 0);
440
441 PlaybackInfo playbackInfo;
442 mediaDownloader->GetPlaybackInfo(playbackInfo);
443 EXPECT_EQ(playbackInfo.serverIpAddress, "127.0.0.1");
444 EXPECT_EQ(playbackInfo.averageDownloadRate, 0);
445 EXPECT_EQ(playbackInfo.isDownloading, false);
446 EXPECT_EQ(playbackInfo.downloadRate, 0);
447 EXPECT_EQ(playbackInfo.bufferDuration, 0);
448 mediaDownloader->Close(false);
449 mediaDownloader = nullptr;
450 }
451
452 }
453 }
454 }
455 }