• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2021 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 #define HST_LOG_TAG "FilterBase"
17 
18 #include "filter_base.h"
19 #include <algorithm>
20 #include "common/plugin_settings.h"
21 #include "common/plugin_utils.h"
22 #include "foundation/log.h"
23 #include "plugin_attr_desc.h"
24 
25 namespace OHOS {
26 namespace Media {
27 namespace Pipeline {
FilterBase(std::string name)28 FilterBase::FilterBase(std::string name)
29     : name_(std::move(name)), state_(FilterState::CREATED), eventReceiver_(nullptr), callback_(nullptr)
30 {
31     inPorts_.reserve(MAX_PORT_NUMBER);
32     outPorts_.reserve(MAX_PORT_NUMBER);
33     routeMap_.reserve(MAX_ROUTE_NUMBER);
34 }
35 
Init(EventReceiver * receiver,FilterCallback * callback)36 void FilterBase::Init(EventReceiver* receiver, FilterCallback* callback)
37 {
38     this->eventReceiver_ = receiver;
39     this->callback_ = callback;
40     InitPorts();
41     state_ = FilterState::INITIALIZED;
42 }
43 
GetInPort(const std::string & name)44 std::shared_ptr<InPort> FilterBase::GetInPort(const std::string& name)
45 {
46     auto port = FindPort(inPorts_, name);
47     FALSE_RETURN_V(port != nullptr, EmptyInPort::GetInstance());
48     return port;
49 }
50 
GetOutPort(const std::string & name)51 std::shared_ptr<OutPort> FilterBase::GetOutPort(const std::string& name)
52 {
53     auto port = FindPort(outPorts_, name);
54     FALSE_RETURN_V(port != nullptr, EmptyOutPort::GetInstance());
55     return port;
56 }
57 
Prepare()58 ErrorCode FilterBase::Prepare()
59 {
60     MEDIA_LOG_I("prepare called");
61     FALSE_RETURN_V_MSG_W(state_ == FilterState::INITIALIZED, ErrorCode::ERROR_INVALID_OPERATION,
62                          "filter is not in init state");
63     state_ = FilterState::PREPARING;
64 
65     // Filter默认InPort按Push方式获取数据
66     // 只有 Demuxer 的 Prepare() 需要覆写此实现, Demuxer的 InPort可能按 Pull 或 Push 方式获取数据
67     WorkMode mode;
68     return GetInPort(PORT_NAME_DEFAULT)->Activate({WorkMode::PUSH}, mode);
69 }
70 
Start()71 ErrorCode FilterBase::Start()
72 {
73     state_ = FilterState::RUNNING;
74     return ErrorCode::SUCCESS;
75 }
76 
Pause()77 ErrorCode FilterBase::Pause()
78 {
79     state_ = FilterState::PAUSED;
80     return ErrorCode::SUCCESS;
81 }
82 
Stop()83 ErrorCode FilterBase::Stop()
84 {
85     state_ = FilterState::INITIALIZED;
86     mediaTypeCntMap_.clear();
87     return ErrorCode::SUCCESS;
88 }
89 
UnlinkPrevFilters()90 void FilterBase::UnlinkPrevFilters()
91 {
92     for (auto&& inPort : inPorts_) {
93         auto peer = inPort->GetPeerPort();
94         inPort->Disconnect();
95         if (peer) {
96             peer->Disconnect();
97         }
98     }
99 }
100 
GetNextFilters()101 std::vector<Filter*> FilterBase::GetNextFilters()
102 {
103     std::vector<Filter*> nextFilters;
104     nextFilters.reserve(outPorts_.size());
105     for (auto&& outPort : outPorts_) {
106         auto peerPort = outPort->GetPeerPort();
107         if (!peerPort) {
108             MEDIA_LOG_I("Filter " PUBLIC_LOG_S " outport " PUBLIC_LOG_S " has no peer port (" PUBLIC_LOG_ZU
109                         ").", name_.c_str(), outPort->GetName().c_str(), outPorts_.size());
110             continue;
111         }
112         auto filter = const_cast<Filter*>(dynamic_cast<const Filter*>(peerPort->GetOwnerFilter()));
113         if (filter) {
114             nextFilters.emplace_back(filter);
115         }
116     }
117     return nextFilters;
118 }
119 
GetPreFilters()120 std::vector<Filter*> FilterBase::GetPreFilters()
121 {
122     std::vector<Filter*> preFilters;
123     preFilters.reserve(inPorts_.size());
124     for (auto&& inPort : inPorts_) {
125         auto peerPort = inPort->GetPeerPort();
126         if (!peerPort) {
127             MEDIA_LOG_I("Filter " PUBLIC_LOG_S " inport " PUBLIC_LOG_S " has no peer port (" PUBLIC_LOG_ZU
128                         ").", name_.c_str(), inPort->GetName().c_str(), inPorts_.size());
129             continue;
130         }
131         auto filter = const_cast<Filter*>(dynamic_cast<const Filter*>(peerPort->GetOwnerFilter()));
132         if (filter) {
133             preFilters.emplace_back(filter);
134         }
135     }
136     return preFilters;
137 }
138 
PushData(const std::string & inPort,const AVBufferPtr & buffer,int64_t offset)139 ErrorCode FilterBase::PushData(const std::string& inPort, const AVBufferPtr& buffer, int64_t offset)
140 {
141     UNUSED_VARIABLE(inPort);
142     UNUSED_VARIABLE(buffer);
143     UNUSED_VARIABLE(offset);
144     return ErrorCode::SUCCESS;
145 }
146 
PullData(const std::string & outPort,uint64_t offset,size_t size,AVBufferPtr & data)147 ErrorCode FilterBase::PullData(const std::string& outPort, uint64_t offset, size_t size, AVBufferPtr& data)
148 {
149     UNUSED_VARIABLE(outPort);
150     UNUSED_VARIABLE(offset);
151     UNUSED_VARIABLE(size);
152     UNUSED_VARIABLE(data);
153     return ErrorCode::SUCCESS;
154 }
155 
OnEvent(const Event & event)156 void FilterBase::OnEvent(const Event& event)
157 {
158     // Receive event from port, pass it to pipeline
159     if (eventReceiver_) {
160         eventReceiver_->OnEvent(event);
161     }
162 }
163 
InitPorts()164 void FilterBase::InitPorts()
165 {
166     inPorts_.clear();
167     outPorts_.clear();
168 
169     auto inPort = std::make_shared<InPort>(this);
170     inPorts_.push_back(inPort);
171 
172     auto outPort = std::make_shared<OutPort>(this);
173     outPorts_.push_back(outPort);
174     routeMap_.emplace_back(inPort->GetName(), outPort->GetName());
175 }
176 
177 template <typename T>
FindPort(const std::vector<T> & list,const std::string & name)178 T FilterBase::FindPort(const std::vector<T>& list, const std::string& name)
179 {
180     auto find = std::find_if(list.begin(), list.end(), [name](const T& item) {
181         if (item == nullptr) {
182             return false;
183         }
184         return name == item->GetName();
185     });
186     if (find != list.end()) {
187         return *find;
188     }
189     MEDIA_LOG_E("Find port(" PUBLIC_LOG_S ") failed.", name.c_str());
190     return nullptr;
191 }
192 
ConfigPluginWithMeta(Plugin::Base & plugin,const Plugin::Meta & meta)193 ErrorCode FilterBase::ConfigPluginWithMeta(Plugin::Base& plugin, const Plugin::Meta& meta)
194 {
195     auto parameterMap = PluginParameterTable::FindAllowedParameterMap(filterType_);
196     for (const auto& keyPair : parameterMap) {
197         if ((keyPair.second.second & PARAM_SET) == 0) {
198             continue;
199         }
200         auto outValPtr = meta.GetData(static_cast<Plugin::MetaID>(keyPair.first));
201         if (outValPtr && keyPair.second.first(keyPair.first, *outValPtr)) {
202             if (plugin.SetParameter(keyPair.first, *outValPtr) != Plugin::Status::OK) {
203                 MEDIA_LOG_W("set parameter " PUBLIC_LOG_S "(" PUBLIC_LOG_D32 ") on plugin " PUBLIC_LOG_S " failed",
204                             GetTagStrName(keyPair.first), keyPair.first, plugin.GetName().c_str());
205             }
206         } else {
207             if (!HasTagInfo(keyPair.first)) {
208                 MEDIA_LOG_W("tag " PUBLIC_LOG_D32 " is not in map, may be update it?", keyPair.first);
209             } else {
210                 MEDIA_LOG_W("parameter " PUBLIC_LOG_S " in meta is not found or type mismatch",
211                             GetTagStrName(keyPair.first));
212             }
213         }
214     }
215     return ErrorCode::SUCCESS;
216 }
217 
NamePort(const std::string & mime)218 std::string FilterBase::NamePort(const std::string& mime)
219 {
220     auto type = mime.substr(0, mime.find_first_of('/'));
221     if (type.empty()) {
222         type = "default";
223     }
224     auto cnt = ++(mediaTypeCntMap_[name_ + type]);
225     auto portName = type + "_" + std::to_string(cnt);
226     return portName;
227 }
228 
GetRouteInPort(const std::string & outPortName)229 PInPort FilterBase::GetRouteInPort(const std::string& outPortName)
230 {
231     auto ite = std::find_if(routeMap_.begin(), routeMap_.end(),
232                             [&outPortName](const PairPort& pp) { return outPortName == pp.second; });
233     if (ite == routeMap_.end()) {
234         MEDIA_LOG_W("out port " PUBLIC_LOG_S " has no route map port", outPortName.c_str());
235         return nullptr;
236     }
237     return GetInPort(ite->first);
238 }
239 
GetRouteOutPort(const std::string & inPortName)240 POutPort FilterBase::GetRouteOutPort(const std::string& inPortName)
241 {
242     auto ite = std::find_if(routeMap_.begin(), routeMap_.end(),
243                             [&inPortName](const PairPort& pp) { return inPortName == pp.first; });
244     if (ite == routeMap_.end()) {
245         MEDIA_LOG_W("in port " PUBLIC_LOG_S " has no route map port", inPortName.c_str());
246         return nullptr;
247     }
248     return GetOutPort(ite->second);
249 }
250 
251 template <typename T>
UpdateAndInitPluginByInfo(std::shared_ptr<T> & plugin,std::shared_ptr<Plugin::PluginInfo> & pluginInfo,const std::shared_ptr<Plugin::PluginInfo> & selectedPluginInfo,const std::function<std::shared_ptr<T> (const std::string &)> & pluginCreator)252 bool FilterBase::UpdateAndInitPluginByInfo(std::shared_ptr<T>& plugin, std::shared_ptr<Plugin::PluginInfo>& pluginInfo,
253     const std::shared_ptr<Plugin::PluginInfo>& selectedPluginInfo,
254     const std::function<std::shared_ptr<T>(const std::string&)>& pluginCreator)
255 {
256     if (selectedPluginInfo == nullptr) {
257         MEDIA_LOG_W("no available info to update plugin");
258         return false;
259     }
260     if (plugin != nullptr) {
261         if (pluginInfo != nullptr && pluginInfo->name == selectedPluginInfo->name) {
262             if (plugin->Reset() == Plugin::Status::OK) {
263                 return true;
264             }
265             MEDIA_LOG_W("reuse previous plugin " PUBLIC_LOG_S " failed, will create new plugin",
266                         pluginInfo->name.c_str());
267         }
268         plugin->Deinit();
269     }
270 
271     plugin = pluginCreator(selectedPluginInfo->name);
272     if (plugin == nullptr) {
273         MEDIA_LOG_E("cannot create plugin " PUBLIC_LOG_S, selectedPluginInfo->name.c_str());
274         return false;
275     }
276     auto err = TranslatePluginStatus(plugin->Init());
277     if (err != ErrorCode::SUCCESS) {
278         MEDIA_LOG_E("plugin " PUBLIC_LOG_S " init error", selectedPluginInfo->name.c_str());
279         return false;
280     }
281     pluginInfo = selectedPluginInfo;
282     return true;
283 }
284 template bool FilterBase::UpdateAndInitPluginByInfo(std::shared_ptr<Plugin::Codec>& plugin,
285     std::shared_ptr<Plugin::PluginInfo>& pluginInfo,
286     const std::shared_ptr<Plugin::PluginInfo>& selectedPluginInfo,
287     const std::function<std::shared_ptr<Plugin::Codec>(const std::string&)>& pluginCreator);
288 template bool FilterBase::UpdateAndInitPluginByInfo(std::shared_ptr<Plugin::AudioSink>& plugin,
289     std::shared_ptr<Plugin::PluginInfo>& pluginInfo,
290     const std::shared_ptr<Plugin::PluginInfo>& selectedPluginInfo,
291     const std::function<std::shared_ptr<Plugin::AudioSink>(const std::string&)>& pluginCreator);
292 template bool FilterBase::UpdateAndInitPluginByInfo(std::shared_ptr<Plugin::VideoSink>& plugin,
293     std::shared_ptr<Plugin::PluginInfo>& pluginInfo,
294     const std::shared_ptr<Plugin::PluginInfo>& selectedPluginInfo,
295     const std::function<std::shared_ptr<Plugin::VideoSink>(const std::string&)>& pluginCreator);
296 template bool FilterBase::UpdateAndInitPluginByInfo(std::shared_ptr<Plugin::OutputSink>& plugin,
297     std::shared_ptr<Plugin::PluginInfo>& pluginInfo,
298     const std::shared_ptr<Plugin::PluginInfo>& selectedPluginInfo,
299     const std::function<std::shared_ptr<Plugin::OutputSink>(const std::string&)>& pluginCreator);
300 
OnEvent(const Plugin::PluginEvent & event)301 void FilterBase::OnEvent(const Plugin::PluginEvent &event)
302 {
303     if (eventReceiver_ != nullptr) {
304         if (event.type == Plugin::PluginEventType::CLIENT_ERROR ||
305             event.type == Plugin::PluginEventType::SERVER_ERROR ||
306             event.type == Plugin::PluginEventType::OTHER_ERROR) {
307             eventReceiver_->OnEvent({name_, EventType::EVENT_PLUGIN_ERROR, event});
308         } else {
309             eventReceiver_->OnEvent({name_, EventType::EVENT_PLUGIN_EVENT, event});
310         }
311     }
312 }
313 
SetSyncCenter(std::weak_ptr<IMediaSyncCenter> syncCenter)314 void FilterBase::SetSyncCenter(std::weak_ptr<IMediaSyncCenter> syncCenter)
315 {
316     syncCenter_ = syncCenter;
317 }
318 } // namespace Pipeline
319 } // namespace Media
320 } // namespace OHOS
321