• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 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 #ifndef RECORDER_ELEMENT_H
17 #define RECORDER_ELEMENT_H
18 
19 #include <memory>
20 #include <unordered_map>
21 #include <type_traits>
22 #include <mutex>
23 #include <set>
24 #include <gst/gstelement.h>
25 #include "nocopyable.h"
26 #include "recorder_param.h"
27 #include "recorder_inner_defines.h"
28 #include "recorder_message_handler.h"
29 
30 namespace OHOS {
31 namespace Media {
32 class RecorderElement : public RecorderMsgHandler {
33 public:
34     struct CreateParam {
35         // The source element's description that this element uniquely dependents to.
36         // For multiplexer, the description is invalid.
37         RecorderSourceDesc srcDesc;
38         std::string name;
39     };
40 
41     explicit RecorderElement(const CreateParam &createParam);
42     virtual ~RecorderElement();
43 
44     /**
45      * @brief Get this element's sourceId
46      * @return sourceId.
47      */
GetSourceId()48     inline int32_t GetSourceId() const
49     {
50         return desc_.handle_;
51     }
52 
53     /**
54      * @brief Get this element's name
55      * @return sourceId.
56      */
GetName()57     inline std::string GetName() const
58     {
59         return name_;
60     }
61 
62     /**
63      * @brief Initialize the element after it created.
64      * @return MSERR_OK if success, or failed.
65      */
66     virtual int32_t Init() = 0;
67 
68     /**
69      * @brief Configure the element. This will be called before CheckConfigReady.
70      * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter.
71      * @return MSERR_OK if success, or failed.
72      */
Configure(const RecorderParam & recParam)73     virtual int32_t Configure(const RecorderParam &recParam)
74     {
75         (void)recParam;
76         return MSERR_OK;
77     }
78 
79     /**
80      * @brief This interface will be called before Prepare to ensure that all static recorder parameters required
81      * by this element are configured completely.
82      * @return MSERR_OK if success, or failed.
83      */
CheckConfigReady()84     virtual int32_t CheckConfigReady()
85     {
86         return MSERR_OK;
87     }
88 
89     /**
90      * @brief This interface is invoked before the corresponding gstreamer element's state changed from NULL to
91      * PAUSED, and during the process when the RecorderPipeline's Prepare invoked.
92      * @return MSERR_OK if success, or failed.
93      */
Prepare()94     virtual int32_t Prepare()
95     {
96         return MSERR_OK;
97     }
98 
99     /**
100      * @brief This interface is invoked before the corresponding gstreamer element's state changed from PAUSED to
101      * PLAYING. and during the process when the RecorderPipeline's Start invoked.
102      * @return MSERR_OK if success, or failed.
103      */
Start()104     virtual int32_t Start()
105     {
106         return MSERR_OK;
107     }
108 
109     /**
110      * @brief This interface is invoked before the corresponding gstreamer element's state changed from PLAYING to
111      * PAUSED. and during the process when the RecorderPipeline's Pause invoked.
112      * @return MSERR_OK if success, or failed.
113      */
Pause()114     virtual int32_t Pause()
115     {
116         return MSERR_OK;
117     }
118 
119     /**
120      * @brief This interface is invoked before the corresponding gstreamer element's state changed from PAUSED to
121      * PLAYING. and during the process when the RecorderPipeline's Resume invoked.
122      * @return MSERR_OK if success, or failed.
123      */
Resume()124     virtual int32_t Resume()
125     {
126         return MSERR_OK;
127     }
128 
129     /**
130      * @brief This interface is invoked before the Stop interface called. The components could send EOS event to
131      * relevant gstreamer element through this interface to only drain out all itself cached buffer before changing
132      * state to NULL. It is designed to speed up the whole pipeline's stopping process. If the user requires a fast
133      * stop, the components could firstly send FLUSH event to relevant gstreamer element. The upper layer will decide
134      * to whether need to wait the GST_MESSAGE_EOS according to this interface's return value.
135      * @return MSERR_OK if success, or failed.
136      */
137     int32_t DrainAll(bool isDrain);
138 
139     /**
140      * @brief This interface is invoked before the corresponding gstreamer element's state changed from PLAYING or
141      * PAUSED to NULL. and during the process when the RecorderPipeline's Stop invoked.
142      * @return MSERR_OK if success, or failed.
143      */
Stop()144     virtual int32_t Stop()
145     {
146         return MSERR_OK;
147     }
148 
149     /**
150      * @brief This interface is invoked during the process when the RecorderPipeline's Reset invoked.
151      * @return MSERR_OK if success, or failed.
152      */
Reset()153     virtual int32_t Reset()
154     {
155         return MSERR_OK;
156     }
157 
158     /**
159      * @brief Set dynamic parameter to this element, this will be called after Prepare and before Stop
160      * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter.
161      * @return MSERR_OK if success, or failed.
162      */
SetParameter(const RecorderParam & recParam)163     virtual int32_t SetParameter(const RecorderParam &recParam)
164     {
165         (void)recParam;
166         return MSERR_OK;
167     }
168 
169     /**
170      * @brief Get Parameter of this elements
171      * @param recParam: RecorderParam, this is the base type of specific type's recorder parameter.
172      * @return MSERR_OK if success, or failed.
173      */
GetParameter(RecorderParam & recParam)174     virtual int32_t GetParameter(RecorderParam &recParam)
175     {
176         (void)recParam;
177         return MSERR_OK;
178     }
179 
180     /**
181      * @brief Process raw message from gstreamer's element to inner message format.
182      * @param msg: GstMessage, this is the raw message from gstreamer
183      * @param prettyMsg: RecorderMessage, this is the processed result
184      * @return see @RecorderMsgProcResult
185      */
186     RecorderMsgProcResult OnMessageReceived(GstMessage &rawMsg, RecorderMessage &prettyMsg) final;
187 
188     /**
189      * @brief Dump all dynamic or static configuration info.
190      */
Dump()191     virtual void Dump() {}
192 
193 protected:
194     /**
195      * @brief Mark one parameter successfully configured to this element.
196      * @param paramType: the enum value of RecorderParamType
197      * @return None.
198      */
MarkParameter(int32_t paramType)199     void MarkParameter(int32_t paramType)
200     {
201         (void)configedParams_.insert(paramType);
202     }
203 
204     /**
205      * @brief Check whether the specified type's parameter is configured.
206      * @param paramType: the enum value of RecorderParamType
207      * @return true if configured, false if not configured.
208      */
CheckParameter(int32_t paramType)209     bool CheckParameter(int32_t paramType) const
210     {
211         return configedParams_.find(paramType) != configedParams_.end();
212     }
213 
214     /**
215      * @brief Check whether the all specified type's parameters is configured.
216      * @param expectedParams: the enum value set of RecorderParamType
217      * @return true if all specified type's parameters configured, false if not all.
218      */
219     bool CheckAllParamsConfiged(const std::set<int32_t> &expectedParams) const;
220 
221     /**
222      * @brief Check whether the any one specified type's parameters is configured.
223      * @param expectedParams: the enum value set of RecorderParamType
224      * @return true if any one specified type's parameters configured, false if no one.
225      */
226     bool CheckAnyParamConfiged(const std::set<int32_t> &expectedParams) const;
227 
228     /**
229      * @brief Subclass implement to process the raw message from gstreamer's element
230      * @param msg: GstMessage, this is the raw message from gstreamer
231      * @param prettyMsg: RecorderMessage, this is the processed result
232      * @return see @RecorderMsgProcResult
233      */
DoProcessMessage(GstMessage & msg,RecorderMessage & prettyMsg)234     virtual RecorderMsgProcResult DoProcessMessage(GstMessage &msg, RecorderMessage &prettyMsg)
235     {
236         return RecorderMsgProcResult::REC_MSG_PROC_IGNORE;
237     }
238 
239     friend class RecorderPipelineLinkHelper;
240 
241     RecorderSourceDesc desc_;
242     std::string name_;
243     GstElement *gstElem_ = nullptr;
244 
245 private:
246     std::set<int32_t> configedParams_;
247 };
248 
249 /**
250  * @brief Provides the factory to register the derived class iinstantiation method and
251  * create the RecorderElement instance.
252  */
253 class RecorderElementFactory  {
254 public:
GetInstance()255     static RecorderElementFactory &GetInstance()
256     {
257         static RecorderElementFactory inst;
258         return inst;
259     }
260 
261     using ElementCreator = std::function<std::shared_ptr<RecorderElement>(const RecorderElement::CreateParam&)>;
262 
263     int32_t RegisterElement(const std::string &key, const ElementCreator creator);
264     std::shared_ptr<RecorderElement> CreateElement(const std::string key, const RecorderElement::CreateParam &param);
265 
266 private:
267     RecorderElementFactory() = default;
268     ~RecorderElementFactory() = default;
269 
270     std::unordered_map<std::string, ElementCreator> creatorTbl_;
271     std::mutex tblMutex_;
272 };
273 
274 template<typename T,
275          typename = std::enable_if_t<std::is_base_of_v<RecorderElement, std::decay_t<T>>>>
276 class RecorderElementRegister : public NoCopyable {
277 public:
RecorderElementRegister(const std::string & key)278     RecorderElementRegister(const std::string &key)
279     {
280         (void)RecorderElementFactory::GetInstance().RegisterElement(
281             key, [](const RecorderElement::CreateParam &param) {
282                 return std::make_shared<std::decay_t<T>>(param);
283             }
284         );
285     }
286 
287     ~RecorderElementRegister() = default;
288 };
289 
290 /**
291  * @brief Provides the RecorderElement register macro to simplify the registration.
292  */
293 #define REGISTER_RECORDER_ELEMENT(__classname__) \
294     static std::shared_ptr<RecorderElementRegister<__classname__>> g_##__classname__##register = \
295         std::make_shared<RecorderElementRegister<__classname__>>(#__classname__)
296 } // namespace Media
297 } // namespace OHOS
298 #endif
299