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 }