• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2022 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 #define HST_LOG_TAG "HttpSourcePlugin"
16 
17 #include "http_source_plugin.h"
18 #include "download/http_curl_client.h"
19 #include "foundation/log.h"
20 #include "hls/hls_media_downloader.h"
21 #include "http/http_media_downloader.h"
22 #include "monitor/download_monitor.h"
23 #undef ERROR_INVALID_OPERATION
24 
25 namespace OHOS {
26 namespace Media {
27 namespace Plugin {
28 namespace HttpPlugin {
29 namespace {
30 constexpr int DEFAULT_BUFFER_SIZE = 200 * 1024;
31 }
32 
HttpSourcePluginCreater(const std::string & name)33 std::shared_ptr<SourcePlugin> HttpSourcePluginCreater(const std::string& name)
34 {
35     return std::make_shared<HttpSourcePlugin>(name);
36 }
37 
HttpSourceRegister(std::shared_ptr<Register> reg)38 Status HttpSourceRegister(std::shared_ptr<Register> reg)
39 {
40     SourcePluginDef definition;
41     definition.name = "HttpSource";
42     definition.description = "Http source";
43     definition.rank = 100; // 100
44     definition.protocol.emplace_back(ProtocolType::HTTP);
45     definition.protocol.emplace_back(ProtocolType::HTTPS);
46     definition.creator = HttpSourcePluginCreater;
47     return reg->AddPlugin(definition);
48 }
__anonb75eb0cd0202null49 PLUGIN_DEFINITION(HttpSource, LicenseType::APACHE_V2, HttpSourceRegister, [] {});
50 
HttpSourcePlugin(std::string name)51 HttpSourcePlugin::HttpSourcePlugin(std::string name) noexcept
52     : SourcePlugin(std::move(name)),
53       bufferSize_(DEFAULT_BUFFER_SIZE),
54       waterline_(0),
55       downloader_(nullptr)
56 {
57     MEDIA_LOG_D("HttpSourcePlugin enter.");
58 }
59 
~HttpSourcePlugin()60 HttpSourcePlugin::~HttpSourcePlugin()
61 {
62     MEDIA_LOG_D("~HttpSourcePlugin enter.");
63     CloseUri();
64 }
65 
Init()66 Status HttpSourcePlugin::Init()
67 {
68     MEDIA_LOG_D("Init enter.");
69     return Status::OK;
70 }
71 
Deinit()72 Status HttpSourcePlugin::Deinit()
73 {
74     MEDIA_LOG_D("Deinit enter.");
75     CloseUri();
76     return Status::OK;
77 }
78 
Prepare()79 Status HttpSourcePlugin::Prepare()
80 {
81     MEDIA_LOG_D("Prepare enter.");
82     if (delayReady) {
83         return Status::ERROR_DELAY_READY;
84     }
85     return Status::OK;
86 }
87 
Reset()88 Status HttpSourcePlugin::Reset()
89 {
90     MEDIA_LOG_D("Reset enter.");
91     CloseUri();
92     return Status::OK;
93 }
94 
Start()95 Status HttpSourcePlugin::Start()
96 {
97     MEDIA_LOG_D("Start enter.");
98     return Status::OK;
99 }
100 
Stop()101 Status HttpSourcePlugin::Stop()
102 {
103     MEDIA_LOG_I("Stop enter.");
104     CloseUri();
105     return Status::OK;
106 }
107 
108 #undef ERROR_INVALID_PARAMETER
109 
GetParameter(Tag tag,ValueType & value)110 Status HttpSourcePlugin::GetParameter(Tag tag, ValueType& value)
111 {
112     MEDIA_LOG_D("GetParameter enter.");
113     switch (tag) {
114         case Tag::BUFFERING_SIZE:
115             value = bufferSize_;
116             return Status::OK;
117         case Tag::WATERLINE_HIGH:
118             value = waterline_;
119             return Status::OK;
120         default:
121             return Status::ERROR_INVALID_PARAMETER;
122     }
123 }
124 
SetParameter(Tag tag,const ValueType & value)125 Status HttpSourcePlugin::SetParameter(Tag tag, const ValueType& value)
126 {
127     MEDIA_LOG_D("SetParameter enter.");
128     switch (tag) {
129         case Tag::BUFFERING_SIZE:
130             bufferSize_ = AnyCast<uint32_t>(value);
131             return Status::OK;
132         case Tag::WATERLINE_HIGH:
133             waterline_ = AnyCast<uint32_t>(value);
134             return Status::OK;
135         default:
136             return Status::ERROR_INVALID_PARAMETER;
137     }
138 }
139 
SetCallback(Callback * cb)140 Status HttpSourcePlugin::SetCallback(Callback* cb)
141 {
142     MEDIA_LOG_D("SetCallback enter.");
143     callback_ = cb;
144     OSAL::ScopedLock lock(mutex_);
145     if (downloader_ != nullptr) {
146         downloader_->SetCallback(cb);
147     }
148     return Status::OK;
149 }
150 
SetSource(std::shared_ptr<MediaSource> source)151 Status HttpSourcePlugin::SetSource(std::shared_ptr<MediaSource> source)
152 {
153     MEDIA_LOG_D("SetSource enter.");
154     OSAL::ScopedLock lock(mutex_);
155     FALSE_RETURN_V(downloader_ == nullptr, Status::ERROR_INVALID_OPERATION); // not allowed set again
156     auto uri = source->GetSourceUri();
157     if (uri.find(".m3u8") != std::string::npos) {
158         downloader_ = std::make_shared<DownloadMonitor>(std::make_shared<HlsMediaDownloader>());
159         delayReady = false;
160     } else if (uri.compare(0, 4, "http") == 0) { // 0 : position, 4: count
161         downloader_ = std::make_shared<DownloadMonitor>(std::make_shared<HttpMediaDownloader>());
162     }
163     FALSE_RETURN_V(downloader_ != nullptr, Status::ERROR_NULL_POINTER);
164 
165     if (callback_ != nullptr) {
166         downloader_->SetCallback(callback_);
167     }
168 
169     MEDIA_LOG_I("SetSource: " PUBLIC_LOG_S, uri.c_str());
170     FALSE_RETURN_V(downloader_->Open(uri), Status::ERROR_UNKNOWN);
171     return Status::OK;
172 }
173 
GetAllocator()174 std::shared_ptr<Allocator> HttpSourcePlugin::GetAllocator()
175 {
176     MEDIA_LOG_D("GetAllocator enter.");
177     return nullptr;
178 }
179 
Read(std::shared_ptr<Buffer> & buffer,size_t expectedLen)180 Status HttpSourcePlugin::Read(std::shared_ptr<Buffer>& buffer, size_t expectedLen)
181 {
182     MEDIA_LOG_D("Read enter.");
183     OSAL::ScopedLock lock(mutex_);
184     FALSE_RETURN_V(downloader_ != nullptr, Status::ERROR_NULL_POINTER);
185 
186     if (buffer == nullptr) {
187         buffer = std::make_shared<Buffer>();
188     }
189 
190     std::shared_ptr<Memory>bufData;
191     if (buffer->IsEmpty()) {
192         bufData = buffer->AllocMemory(GetAllocator(), expectedLen);
193     } else {
194         bufData = buffer->GetMemory();
195     }
196 
197     bool isEos = false;
198     unsigned int realReadSize = 0;
199     bool result = downloader_->Read(bufData->GetWritableAddr(expectedLen), expectedLen, realReadSize, isEos);
200     bufData->UpdateDataSize(realReadSize);
201     MEDIA_LOG_D("Read finished, read size = " PUBLIC_LOG_ZU ", isEos " PUBLIC_LOG_D32, bufData->GetSize(), isEos);
202     return result ? Status::OK : Status::END_OF_STREAM;
203 }
204 
GetSize(uint64_t & size)205 Status HttpSourcePlugin::GetSize(uint64_t& size)
206 {
207     MEDIA_LOG_D("GetSize enter.");
208     OSAL::ScopedLock lock(mutex_);
209     FALSE_RETURN_V(downloader_ != nullptr, Status::ERROR_NULL_POINTER);
210     size = static_cast<uint64_t>(downloader_->GetContentLength());
211     return Status::OK;
212 }
213 
GetSeekable()214 Seekable HttpSourcePlugin::GetSeekable()
215 {
216     MEDIA_LOG_D("GetSeekable enter.");
217     OSAL::ScopedLock lock(mutex_);
218     FALSE_RETURN_V(downloader_ != nullptr, Seekable::INVALID);
219     return downloader_->GetSeekable();
220 }
221 
SeekTo(uint64_t offset)222 Status HttpSourcePlugin::SeekTo(uint64_t offset)
223 {
224     MEDIA_LOG_I("SeekTo enter, offset = " PUBLIC_LOG_U64, offset);
225     OSAL::ScopedLock lock(mutex_);
226     FALSE_RETURN_V(downloader_ != nullptr, Status::ERROR_NULL_POINTER);
227     FALSE_RETURN_V(downloader_->GetSeekable() == Seekable::SEEKABLE, Status::ERROR_INVALID_OPERATION);
228     FALSE_RETURN_V(offset <= downloader_->GetContentLength(), Status::ERROR_INVALID_PARAMETER);
229     FALSE_RETURN_V(downloader_->Seek(offset), Status::ERROR_UNKNOWN);
230     return Status::OK;
231 }
232 
CloseUri()233 void HttpSourcePlugin::CloseUri()
234 {
235     OSAL::ScopedLock lock(mutex_);
236     if (downloader_ != nullptr) {
237         MEDIA_LOG_D("Close uri");
238         downloader_->Close(false);
239         downloader_ = nullptr;
240     }
241 }
242 }
243 }
244 }
245 }